main
1#import "../utils/invisible-heading.typ": invisible-heading
2#import "../utils/style.typ": 字体, 字号
3
4// 本科生中文目录
5#let bachelor-outline-page(
6 // documentclass 传入参数
7 twoside: false,
8 fonts: (:),
9 // 其他参数
10 depth: 3,
11 title: "目 录",
12 outlined: false,
13 title-vspace: 14pt,
14 title-text-args: auto,
15 // 引用页码字体与字号
16 reference-font: auto,
17 reference-size: 字号.小四,
18 // 字体与字号
19 font: auto,
20 size: (字号.四号, 字号.小四),
21 // 目录样式
22 above: (20pt, 14pt),
23 below: (14pt, 14pt),
24 indent: (0pt, 18pt, 28pt),
25 fill: (repeat([.], gap: 0.15em),),
26 gap: .3em,
27) = {
28 // 1. 默认参数
29 fonts = 字体 + fonts
30 if title-text-args == auto {
31 title-text-args = (font: fonts.黑体, size: 字号.小三)
32 }
33 if reference-font == auto {
34 reference-font = fonts.宋体
35 }
36 if font == auto {
37 font = (fonts.黑体, fonts.黑体, fonts.宋体)
38 }
39
40 // 2. 正式渲染
41 pagebreak(weak: true, to: if twoside { "odd" })
42
43 // 默认显示的字体
44 set text(font: reference-font, size: reference-size)
45
46 {
47 set align(center)
48 text(..title-text-args, title)
49 // 标记一个不可见的标题用于目录生成
50 invisible-heading(level: 1, outlined: outlined, title)
51 }
52
53 v(title-vspace)
54
55 // 目录样式
56 set outline(indent: level => indent
57 .slice(0, calc.min(level + 1, indent.len()))
58 .sum())
59 show outline.entry: entry => block(
60 above: above.at(entry.level - 1, default: above.last()),
61 below: below.at(entry.level - 1, default: below.last()),
62 link(
63 entry.element.location(),
64 entry.indented(
65 none,
66 {
67 text(
68 font: font.at(entry.level - 1, default: font.last()),
69 size: size.at(entry.level - 1, default: size.last()),
70 {
71 if entry.prefix() not in (none, []) {
72 entry.prefix()
73 h(gap)
74 }
75 entry.body()
76 },
77 )
78 box(width: 1fr, inset: (x: .25em), fill.at(
79 entry.level - 1,
80 default: fill.last(),
81 ))
82 entry.page()
83 },
84 gap: 0pt,
85 ),
86 ),
87 )
88
89 // 显示目录
90 outline(title: none, depth: depth)
91}