// 手册模板 —— 代码高亮、提示框 + 封面页 + 三线表 #import "@preview/codly:1.3.0": * #import "@preview/showybox:2.0.4": showybox #let primary = rgb("#1F4E79") #let secondary = rgb("#2C3E50") #let accent = rgb("#3467A8") #let light = rgb("#96A0AA") #let rule-blue = accent.lighten(46%) #let info-color = rgb("#0EA5E9") #let tip-color = rgb("#10B981") #let warn-color = rgb("#F59E0B") #let danger-color = rgb("#EF4444") #let cover-page(title, subtitle, date) = { page(margin: (top: 3cm, bottom: 3cm, left: 3cm, right: 3cm))[ #align(center + horizon)[ #v(2cm) #text(size: 28pt, weight: "bold", fill: primary, title) #if subtitle != none { v(0.8cm) text(size: 16pt, fill: accent, subtitle) } #if date != none { v(2cm) text(size: 12pt, fill: light, date) } ] ] } #let three-line-table(..args) = { let kwargs = args.named() let children = args.pos() let new_children = () let header_seen = false for child in children { if child.func() == table.header { new_children.push(table.hline(stroke: 1.25pt + rule-blue)) new_children.push(child) header_seen = true } else if header_seen and child.func() == table.hline { new_children.push(table.hline(stroke: 0.75pt + rule-blue)) header_seen = false } else { new_children.push(child) } } new_children.push(table.hline(stroke: 1.25pt + rule-blue)) kwargs.stroke = none kwargs.inset = (x: 8pt, y: 5pt) table(..new_children, ..kwargs) } #let manual( title: none, subtitle: none, date: none, body, ) = { if title != none { cover-page(title, subtitle, date) pagebreak() } set text( font: ( "Cambria", "PingFang SC", ), size: 10pt, lang: "zh", ) show raw: set text(font: ( "Courier New", "Menlo", "Monaco", "SimSun", )) // 10pt + code blocks: a touch denser than default 11pt, still spacing > leading set par(justify: true, leading: 0.76em, spacing: 1.08em) show: codly-init codly( stroke: 0.5pt + rule-blue, fill: rgb("#F8F9FA"), zebra-fill: none, lang-stroke: none, lang-fill: light.lighten(60%), radius: 4pt, number-format: n => text(fill: rgb("#6E7681"), str(n)), number-align: right, ) // Tight list: spacing close to leading (0.76em) but not below it set list(tight: true, indent: 1.2em, body-indent: 0.45em, spacing: 0.72em) set enum(tight: true, indent: 1.2em, body-indent: 0.45em, spacing: 0.72em) // Same heading vertical scale as textbook (long-form); H sizes differ by template show heading.where(level: 1): it => { v(1.45em) text(size: 18pt, weight: "bold", fill: primary, it) v(0.55em) } show heading.where(level: 2): it => { v(1.1em) text(size: 13pt, weight: "bold", fill: accent, it) v(0.5em) } show heading.where(level: 3): it => { v(0.8em) text(size: 11pt, weight: "bold", fill: secondary, it) v(0.4em) } set heading(numbering: none) set page( paper: "a4", margin: (top: 2.0cm, bottom: 2.0cm, left: 2.0cm, right: 2.0cm), header: context { let h = query(selector(heading.where(level: 1))) .filter(it => it.location().page() <= here().page()) if h.len() > 0 { let current = h.last() align(right)[ #text(size: 8pt, fill: light)[ #current.body ] ] } }, footer: context { align(center)[ #text(size: 8pt, fill: light)[ — #counter(page).display("1") — ] ] }, ) show link: it => text(fill: accent, it) outline(title: "目录", depth: 2) pagebreak() body } #let info-box(title: "Info", body) = showybox( title: title, title-style: (color: white, weight: "bold"), frame: (border-color: info-color, title-color: info-color, thickness: 1pt, radius: 4pt), body ) #let tip-box(title: "Tip", body) = showybox( title: title, title-style: (color: white, weight: "bold"), frame: (border-color: tip-color, title-color: tip-color, thickness: 1pt, radius: 4pt), body ) #let warn-box(title: "Warning", body) = showybox( title: title, title-style: (color: white, weight: "bold"), frame: (border-color: warn-color, title-color: warn-color, thickness: 1pt, radius: 4pt), body ) #let danger-box(title: "Danger", body) = showybox( title: title, title-style: (color: white, weight: "bold"), frame: (border-color: danger-color, title-color: danger-color, thickness: 1pt, radius: 4pt), body )