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>
187 lines
4.4 KiB
Plaintext
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
|
|
}
|