grelin_templates/tech-report/data/body.typ
MORRO 5c1039c62d Simplify tech-report body layer and remove glossary.
Replace metropole-grelin with body.typ, merge styling into md.typ, drop glossary support, and clean unused theme tokens.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 16:53:50 +08:00

187 lines
4.4 KiB
Plaintext

#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 == <table-full-width> {
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
}