-
Notifications
You must be signed in to change notification settings - Fork 14
/
mainmatter.typ
176 lines (169 loc) · 5.42 KB
/
mainmatter.typ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#import "@preview/anti-matter:0.0.2": anti-front-end
#import "@preview/i-figured:0.2.4"
#import "../utils/style.typ": 字号, 字体
#import "../utils/custom-numbering.typ": custom-numbering
#import "../utils/custom-heading.typ": heading-display, active-heading, current-heading
#import "../utils/indent.typ": fake-par
#import "../utils/unpairs.typ": unpairs
#let mainmatter(
// documentclass 传入参数
twoside: false,
fonts: (:),
// 其他参数
leading: 1.5 * 15.6pt - 0.7em,
spacing: 1.5 * 15.6pt - 0.7em,
justify: true,
first-line-indent: 2em,
numbering: custom-numbering.with(first-level: "第一章 ", depth: 4, "1.1 "),
// 正文字体与字号参数
text-args: auto,
// 标题字体与字号
heading-font: auto,
heading-size: (字号.四号,),
heading-weight: ("regular",),
heading-above: (2 * 15.6pt - 0.7em, 2 * 15.6pt - 0.7em),
heading-below: (2 * 15.6pt - 0.7em, 1.5 * 15.6pt - 0.7em),
heading-pagebreak: (true, false),
heading-align: (center, auto),
// 页眉
header-render: auto,
header-vspace: 0em,
display-header: false,
skip-on-first-level: true,
stroke-width: 0.5pt,
reset-footnote: true,
// caption 的 separator
separator: " ",
// caption 样式
caption-style: strong,
caption-size: 字号.五号,
// figure 计数
show-figure: i-figured.show-figure,
// equation 计数
show-equation: i-figured.show-equation,
..args,
it,
) = {
// 0. 标志前言结束
anti-front-end()
// 1. 默认参数
fonts = 字体 + fonts
if (text-args == auto) {
text-args = (font: fonts.宋体, size: 字号.小四)
}
// 1.1 字体与字号
if (heading-font == auto) {
heading-font = (fonts.黑体,)
}
// 1.2 处理 heading- 开头的其他参数
let heading-text-args-lists = args.named().pairs()
.filter((pair) => pair.at(0).starts-with("heading-"))
.map((pair) => (pair.at(0).slice("heading-".len()), pair.at(1)))
// 2. 辅助函数
let array-at(arr, pos) = {
arr.at(calc.min(pos, arr.len()) - 1)
}
// 3. 设置基本样式
// 3.1 文本和段落样式
set text(..text-args)
set par(
leading: leading,
justify: justify,
first-line-indent: first-line-indent
)
show par: set block(spacing: spacing)
show raw: set text(font: fonts.等宽)
// 3.2 脚注样式
show footnote.entry: set text(font: fonts.宋体, size: 字号.五号)
// 3.3 设置 figure 的编号
show heading: i-figured.reset-counters
show figure: show-figure
// 3.4 设置 equation 的编号和假段落首行缩进
show math.equation.where(block: true): show-equation
// 3.5 表格表头置顶 + 不用冒号用空格分割 + 样式
show figure.where(
kind: table
): set figure.caption(position: top)
set figure.caption(separator: separator)
show figure.caption: caption-style
show figure.caption: set text(font: fonts.宋体, size: 字号.五号)
// 3.6 优化列表显示
// 术语列表 terms 不应该缩进
show terms: set par(first-line-indent: 0pt)
// 4. 处理标题
// 4.1 设置标题的 Numbering
set heading(numbering: numbering)
// 4.2 设置字体字号并加入假段落模拟首行缩进
show heading: it => {
set text(
font: array-at(heading-font, it.level),
size: array-at(heading-size, it.level),
weight: array-at(heading-weight, it.level),
..unpairs(heading-text-args-lists
.map((pair) => (pair.at(0), array-at(pair.at(1), it.level))))
)
set block(
above: array-at(heading-above, it.level),
below: array-at(heading-below, it.level),
)
it
fake-par
}
// 4.3 标题居中与自动换页
show heading: it => {
if (array-at(heading-pagebreak, it.level)) {
// 如果打上了 no-auto-pagebreak 标签,则不自动换页
if ("label" not in it.fields() or str(it.label) != "no-auto-pagebreak") {
pagebreak(weak: true)
}
}
if (array-at(heading-align, it.level) != auto) {
set align(array-at(heading-align, it.level))
it
} else {
it
}
}
// 5. 处理页眉
set page(..(if display-header {
(
header: {
// 重置 footnote 计数器
if reset-footnote {
counter(footnote).update(0)
}
locate(loc => {
// 5.1 获取当前页面的一级标题
let cur-heading = current-heading(level: 1, loc)
// 5.2 如果当前页面没有一级标题,则渲染页眉
if not skip-on-first-level or cur-heading == none {
if header-render == auto {
// 一级标题和二级标题
let first-level-heading = if not twoside or calc.rem(loc.page(), 2) == 0 { heading-display(active-heading(level: 1, loc)) } else { "" }
let second-level-heading = if not twoside or calc.rem(loc.page(), 2) == 2 { heading-display(active-heading(level: 2, prev: false, loc)) } else { "" }
set text(font: fonts.楷体, size: 字号.五号)
stack(
first-level-heading + h(1fr) + second-level-heading,
v(0.25em),
if first-level-heading != "" or second-level-heading != "" { line(length: 100%, stroke: stroke-width + black) },
)
} else {
header-render(loc)
}
v(header-vspace)
}
})
}
)
} else {
(
header: {
// 重置 footnote 计数器
if reset-footnote {
counter(footnote).update(0)
}
}
)
}))
it
}