#import "theme.typ": * #let page-numbering-started = state("page-numbering-started", false) #let start-body-page-numbering() = { page-numbering-started.update(true) counter(page).update(1) } #let report-body( title: none, author: none, date: none, paper-size: "a4", language: "zh", font-size: size-body, leading-ratio: leading-ratio, body-font: body-font, heading-font: heading-font, raw-font: mono-font, margin-x: body-margin-x, margin-y: body-margin-y, accent-color: color-primary, body-text-color: color-body-text, body, ) = { let scale = 1.25 let caption-size = font-size * calc.pow(scale, -1) let lead-size = font-size * calc.pow(scale, 1) let heading-size = font-size * calc.pow(scale, 2) let line-height = font-size * leading-ratio let muted-color = color.mix( (rgb("#000000"), 5), (rgb("#ffffff"), 3), space: oklab, ) set document(title: title, date: date) if author != none { set document(author: author) } set text( font: body-font, size: font-size, fill: body-text-color, lang: language, ) show raw: set text(font: raw-font) set par( leading: line-height - font-size, spacing: line-height, justify: true, ) set page( paper: paper-size, margin: (x: margin-x, top: margin-y, bottom: margin-y), header: none, footer: context { v(line-height / 2) if page-numbering-started.at(here()) { align(right, text( font: heading-font, size: caption-size, fill: muted-color, counter(page).display("1 / 1", both: true), )) } }, footer-descent: line-height, ) let report-heading(it, size, above, below, title-fill: rgb("#000000")) = block( width: 100%, breakable: false, above: above, below: below, )[ #context { if it.numbering != none { let number = counter(heading).display(it.numbering) text(font: heading-font, size: size, weight: "bold")[ #text(fill: accent-color)[#number] #h(0.35em) #text(fill: title-fill)[#it.body] ] } else { text(font: heading-font, size: size, weight: "bold", fill: title-fill, it.body) } } ] show heading.where(level: 1): it => { report-heading(it, heading-size, line-height * 2, line-height, title-fill: accent-color) } show heading.where(level: 2): it => { report-heading(it, lead-size, line-height * 2, line-height * 0.85) } show heading.where(level: 3): it => { report-heading(it, font-size, line-height, line-height * 0.75) } show heading.where(level: 4): it => { report-heading(it, caption-size, line-height * 0.85, line-height * 0.65) } set list( indent: 0pt, body-indent: line-height / 2, marker: text(font: heading-font, fill: accent-color, weight: "bold")[•], ) set enum( indent: 0pt, body-indent: line-height / 2, numbering: (..nums) => text( font: heading-font, fill: accent-color, weight: "medium", numbering("1.a.i.", ..nums), ), ) show quote.where(block: true): it => { v(line-height * 0.75, weak: true) block(width: 100%)[ #block( width: 100%, inset: (left: tw(3.5)), stroke: (left: quote-bar-stroke + quote-bar-color), )[ #text(font: body-font, fill: body-text-color, it.body) ] ] v(line-height * 0.75, weak: true) } show table: it => { if it.has("label") and it.label == { it } else { [#table( columns: (1fr,) * it.columns.len(), ..it.children, )#label("table-full-width")] } } set table( stroke: none, inset: (x: line-height / 2, y: line-height / 2), fill: (x, y) => if y == 0 { accent-color } else if calc.even(y) { color-block-bg } else { none }, ) show table.cell.where(y: 0): it => { text(font: heading-font, weight: "bold", size: caption-size, fill: white, it) } show raw.where(block: true): block.with( inset: (x: line-height, y: line-height / 2), width: 100%, fill: color-block-bg, radius: code-block-radius, ) show raw.where(block: true): set par(justify: false) show raw.where(block: false): box.with( inset: (x: 3pt, y: 0pt), outset: (y: 3pt), fill: color-block-bg, radius: code-inline-radius, ) show link: it => { if type(it.dest) != str { it } else { text(fill: accent-color, underline(it.body)) } } body }