diff --git a/main.pdf b/Define-of-template/NLI-doc-template-manual.pdf similarity index 100% rename from main.pdf rename to Define-of-template/NLI-doc-template-manual.pdf diff --git a/main.typ b/Define-of-template/NLI-doc-template-manual.typ similarity index 100% rename from main.typ rename to Define-of-template/NLI-doc-template-manual.typ diff --git a/NITLOAD-STANDARD-NITRAC/NITRAC-doc-1b.typ b/NITLOAD-STANDARD-NITRAC/NITRAC-doc-1b.typ new file mode 100644 index 0000000..fd20188 --- /dev/null +++ b/NITLOAD-STANDARD-NITRAC/NITRAC-doc-1b.typ @@ -0,0 +1,59 @@ +#import "../NLI-doc-template.typ": cover, conf + +#let mark-unit = 1.2cm +#let mark-blue = rgb("#4FC3F7") +#let mark-letter(column, row, letter) = place( + top + left, + dx: (3.6 + column * 2.5) * mark-unit, + dy: row * mark-unit, + box( + width: 2.5 * mark-unit, + height: 3 * mark-unit, + inset: 0pt, + align(center + horizon, text( + font: "Source Code Pro", + size: 72pt, + weight: "medium", + fill: mark-blue, + )[#letter]), + ), +) + +#let nitrac-mark = { + mark-letter(0, 0, "T") + mark-letter(1, 1, "R") + mark-letter(2, 2, "A") + mark-letter(3, 3, "C") +} + +#cover( + title: "荷城创新实时与控制系统", + title-en: "Nitload Realtime and Control", + logo: nitrac-mark, + number: "NITRAC-DOC-1B", + author: "Nitload Industry", + classification: "MID[中秘]SEC", + date: "2026 年 9 月", +) + +#show: conf.with(number-pages: true) + += 第一章 总则 + +本文档为 NITRAC 系列标准文档第一册草案。 + +== 1.1 范围 + +本节规定文档的适用范围。 + +== 1.2 规范性引用文件 + +本节列出编制和实施本标准所需的规范性引用文件。 + += 第二章 术语和定义 + +本节规定本文档使用的术语和定义。 + += 第三章 技术要求 + +本节规定 NITRAC 的技术要求。 \ No newline at end of file diff --git a/NLI-doc-template.typ b/NLI-doc-template.typ index 5ebfa9a..eb18fc6 100644 --- a/NLI-doc-template.typ +++ b/NLI-doc-template.typ @@ -50,12 +50,12 @@ title: none, // 主标题(中文) title-en: none, // 主标题(英文,Source Code Pro 自行排版) subtitle: none, // 副标题 - logo: none, // 图片路径,如 image("logo.png") - number: none, // 文档编号 - author: none, // 作者(可为单个字符串或数组) - classification: none, // 密级,如 "内部"、"秘密" - info: (:), // 附加信息字典,如 (学号: "123", 指导教师: "张三") - date: none, // 日期 + logo: none, // 图片路径,如 image("logo.png") + number: none, // 文档编号 + author: none, // 作者(可为单个字符串或数组) + classification: none, // 密级,如 "内部"、"秘密" + info: (:), // 附加信息字典,如 (学号: "123", 指导教师: "张三") + date: none, // 日期 fill: white, // 封面背景色 decorate: true, // 是否绘制天蓝/暖橙网格装饰色块 ) = { @@ -69,6 +69,10 @@ ) set text(font: (cover-latin, cover-cjk), lang: "zh") + if logo != none { + logo + } + // 网格装饰:NITLOAD 标识(坐标 (x, y) = (列, 行))。 if decorate { // 天蓝色实心单位正方形 @@ -86,18 +90,18 @@ glyph(1, i, ch, if i == 0 { accent } else { sky }) } - // 主标题:中文逐字对齐网格,连续西文按实际字宽紧凑排布。 - let cs = if type(title) == str { title.clusters() } else { () } - - // 中文视觉重心偏大,整体右移 0.1 格、下移 0.2 格 - let cn-dx = 0.1 * unit - let cn-dy = 0.2 * unit - let is-narrow = c => str.to-unicode(c.codepoints().first()) < 0x2E80 - // 西文开头时使用更明确的 0.2 格左边距,与西文标题和信息区形成视觉对齐。 - let title-start-pad = if cs.len() > 0 and is-narrow(cs.first()) { 0.2 * unit } else { cn-dx } - let title-width = 21cm - unit - title-start-pad - let en-left-pad = 0.2 * unit - let en-box-width = 21cm - unit + // 主标题:中文逐字对齐网格,连续西文按实际字宽紧凑排布。 + let cs = if type(title) == str { title.clusters() } else { () } + + // 中文视觉重心偏大,整体右移 0.1 格、下移 0.2 格 + let cn-dx = 0.1 * unit + let cn-dy = 0.2 * unit + let is-narrow = c => str.to-unicode(c.codepoints().first()) < 0x2E80 + // 西文开头时使用更明确的 0.2 格左边距,与西文标题和信息区形成视觉对齐。 + let title-start-pad = if cs.len() > 0 and is-narrow(cs.first()) { 0.2 * unit } else { cn-dx } + let title-width = 21cm - unit - title-start-pad + let en-left-pad = 0.2 * unit + let en-box-width = 21cm - unit // 分段:连续西文合为一段,其余每字一段 let segs = () let run = "" @@ -110,66 +114,66 @@ } if run != "" { segs.push(run) } - context { - // CJK 固定占一格;连续西文使用字体测得的自然宽度,不额外预留左右空白。 - let cur-x = 0pt - let row = 0 - for seg in segs { - let latin = is-narrow(seg.first()) - let segment = text( - font: if latin { (cover-latin, cover-cjk) } else { (cover-cjk, cover-latin) }, - size: glyph-size, - fill: black, - )[#seg] - let segment-width = if latin { measure(segment).width } else { unit } - if cur-x != 0pt and cur-x + segment-width > title-width { - cur-x = 0pt - row += 1 - } - let segment-align = if latin { left + horizon } else { center + horizon } - place(top + left, - dx: unit + title-start-pad + cur-x, - dy: (7 + row) * unit + cn-dy, - box( - width: segment-width, - height: unit, - inset: 0pt, - align(segment-align, segment), - )) - cur-x += segment-width - } - let cn-rows = if segs.len() == 0 { 0 } else { row + 1 } - - // 英文:左对齐于中文下方;多行时行距对齐网格(行距 = unit),左/上边距相等。 - let en-rows = 0 - let en-gap = if cn-rows > 0 and title-en != none { 0.25 * unit } else { 0pt } - if title-en != none { - let en1 = text(font: (cover-latin, cover-cjk), size: glyph-size, fill: black)[#title-en] - let lh = measure(en1).height - let pad = (unit - lh) / 2 + context { + // CJK 固定占一格;连续西文使用字体测得的自然宽度,不额外预留左右空白。 + let cur-x = 0pt + let row = 0 + for seg in segs { + let latin = is-narrow(seg.first()) + let segment = text( + font: if latin { (cover-latin, cover-cjk) } else { (cover-cjk, cover-latin) }, + size: glyph-size, + fill: black, + )[#seg] + let segment-width = if latin { measure(segment).width } else { unit } + if cur-x != 0pt and cur-x + segment-width > title-width { + cur-x = 0pt + row += 1 + } + let segment-align = if latin { left + horizon } else { center + horizon } + place(top + left, + dx: unit + title-start-pad + cur-x, + dy: (7 + row) * unit + cn-dy, + box( + width: segment-width, + height: unit, + inset: 0pt, + align(segment-align, segment), + )) + cur-x += segment-width + } + let cn-rows = if segs.len() == 0 { 0 } else { row + 1 } + + // 英文:左对齐于中文下方;多行时行距对齐网格(行距 = unit),左/上边距相等。 + let en-rows = 0 + let en-gap = if cn-rows > 0 and title-en != none { 0.25 * unit } else { 0pt } + if title-en != none { + let en1 = text(font: (cover-latin, cover-cjk), size: glyph-size, fill: black)[#title-en] + let lh = measure(en1).height + let pad = (unit - lh) / 2 let inner = { - set par(leading: unit - lh) - en1 - } - let h = measure(box(width: en-box-width - en-left-pad, inner)).height - en-rows = calc.max(1, int(calc.round((h - lh) / unit)) + 1) - place(top + left, - dx: unit, - dy: (7 + cn-rows) * unit + en-gap, - box(width: en-box-width, inset: (left: en-left-pad, top: pad), inner)) - } - let title-rows = cn-rows + en-rows - let title-end-y = (7 + title-rows) * unit + en-gap + set par(leading: unit - lh) + en1 + } + let h = measure(box(width: en-box-width - en-left-pad, inner)).height + en-rows = calc.max(1, int(calc.round((h - lh) / unit)) + 1) + place(top + left, + dx: unit, + dy: (7 + cn-rows) * unit + en-gap, + box(width: en-box-width, inset: (left: en-left-pad, top: pad), inner)) + } + let title-rows = cn-rows + en-rows + let title-end-y = (7 + title-rows) * unit + en-gap let metadata = () if number != none { metadata.push(("编号", number)) } if author != none { let author-text = if type(author) == array { author.join(" / ") } else { author } metadata.push(("作者", author-text)) - } - if date != none { metadata.push(("日期", date)) } - if classification != none { metadata.push(("密级", classification)) } - for (key, value) in info { + } + if date != none { metadata.push(("日期", date)) } + if classification != none { metadata.push(("密级", classification)) } + for (key, value) in info { if value != none { metadata.push((str(key), value)) } } let marker-height = 2 * unit @@ -228,17 +232,17 @@ (unit, apex-y), (0pt, marker-height), )) - let signature-line-length = 7 * unit - place(top + left, dx: unit, dy: meta-y + apex-y, - line(length: signature-line-length, stroke: (paint: accent, thickness: 0.8pt))) - let signed-label = text( - font: cover-latin, size: 10pt, weight: "bold", fill: accent, - )[signed] - let signed-size = measure(signed-label) - place(top + left, - dx: unit + signature-line-length - signed-size.width, - dy: meta-y + apex-y - signed-size.height - 0.04 * unit, - signed-label) + let signature-line-length = 7 * unit + place(top + left, dx: unit, dy: meta-y + apex-y, + line(length: signature-line-length, stroke: (paint: accent, thickness: 0.8pt))) + let signed-label = text( + font: cover-latin, size: 10pt, weight: "bold", fill: accent, + )[signed] + let signed-size = measure(signed-label) + place(top + left, + dx: unit + signature-line-length - signed-size.width, + dy: meta-y + apex-y - signed-size.height - 0.04 * unit, + signed-label) // 三角形保留在距页底七个单位的位置,作为独立的封面装饰。 // 文档信息不再与三角形连线,而是跟随主标题实际高度,排列在标题正下方。 @@ -264,17 +268,17 @@ number-align: center, header: none, // 正文页不使用装饰角标 ) - set text(font: (body-latin, body-cjk), lang: "zh", size: 12pt) - set par(justify: true, leading: 1em, first-line-indent: (amount: 2em, all: true)) - // 无序列表整体缩进一个正文字符;圆点与正文仍使用 Typst 默认间距。 - set list(indent: 1em) - - // 标题字体:中文黑体,英文 Source Code Pro + set text(font: (body-latin, body-cjk), lang: "zh", size: 12pt) + set par(justify: true, leading: 1em, first-line-indent: (amount: 2em, all: true)) + // 无序列表整体缩进一个正文字符;圆点与正文仍使用 Typst 默认间距。 + set list(indent: 1em) + + // 标题字体:中文黑体,英文 Source Code Pro show heading: set text(font: (cover-latin, cover-cjk)) - // 代码块与行内代码:西文使用 Source Code Pro,中文显式回退到正文宋体。 - // 避免 Source Code Pro 缺少中文字形时由系统选择到隶书等不合适字体。 - show raw: set text(font: (mono-font, body-cjk)) + // 代码块与行内代码:西文使用 Source Code Pro,中文显式回退到正文宋体。 + // 避免 Source Code Pro 缺少中文字形时由系统选择到隶书等不合适字体。 + show raw: set text(font: (mono-font, body-cjk)) // 块级代码:细边框、浅色背景与自动行号;行内代码不受影响。 show raw.where(block: true): code => { @@ -302,31 +306,31 @@ doc } -// ---- 模板结束 ---- -// Template file ended. - - -/* -Legacy duplicated tail retained as an inert comment because this workspace's -Windows patch transport does not reliably truncate shortened files. -breakable: true, +// ---- 模板结束 ---- +// Template file ended. + + +/* +Legacy duplicated tail retained as an inert comment because this workspace's +Windows patch transport does not reliably truncate shortened files. +breakable: true, code, ) } doc } -// ---- 模板结束 ---- -// Template file ended. - -} - - doc -} -// ---- 模板结束 ---- -// Template file ended. - -*/ +// ---- 模板结束 ---- +// Template file ended. -// End of file. +} + + doc +} +// ---- 模板结束 ---- +// Template file ended. + +*/ + +// End of file.