-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtemplate.typ
128 lines (116 loc) · 3.31 KB
/
template.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
#let buildMainHeader(mainHeadingContent) = {
[
#align(center, smallcaps(mainHeadingContent))
#line(length: 100%)
]
}
#let buildSecondaryHeader(mainHeadingContent, secondaryHeadingContent) = {
[
#smallcaps(mainHeadingContent) #h(1fr) #emph(secondaryHeadingContent)
#line(length: 100%)
]
}
// To know if the secondary heading appears after the main heading
#let isAfter(secondaryHeading, mainHeading) = {
let secHeadPos = secondaryHeading.location().position()
let mainHeadPos = mainHeading.location().position()
if (secHeadPos.at("page") > mainHeadPos.at("page")) {
return true
}
if (secHeadPos.at("page") == mainHeadPos.at("page")) {
return secHeadPos.at("y") > mainHeadPos.at("y")
}
return false
}
#let getHeader() = {
locate(loc => {
// Find if there is a level 1 heading on the current page
let nextMainHeading = query(selector(heading).after(loc), loc).find(headIt => {
headIt.location().page() == loc.page() and headIt.level == 1
})
if (nextMainHeading != none) {
return buildMainHeader(nextMainHeading.body)
}
// Find the last previous level 1 heading -- at this point surely there's one :-)
let lastMainHeading = query(selector(heading).before(loc), loc).filter(headIt => {
headIt.level == 1
}).last()
// Find if the last level > 1 heading in previous pages
let previousSecondaryHeadingArray = query(selector(heading).before(loc), loc).filter(headIt => {
headIt.level > 1
})
let lastSecondaryHeading = if (previousSecondaryHeadingArray.len() != 0) {previousSecondaryHeadingArray.last()} else {none}
// Find if the last secondary heading exists and if it's after the last main heading
if (lastSecondaryHeading != none and isAfter(lastSecondaryHeading, lastMainHeading)) {
return buildSecondaryHeader(lastMainHeading.body, lastSecondaryHeading.body)
}
return buildMainHeader(lastMainHeading.body)
})
}
#let project(
title: "",
abstract: [],
authors: (),
logo: none,
body
) = {
// Set the document's basic properties.
set document(author: authors.map(a => a.name), title: title)
set text(font: "New Computer Modern", lang: "en")
show math.equation: set text(weight: 400)
set heading(numbering: "1.1")
set par(justify: true)
// Title page.
v(0.25fr)
align(center)[
#text(2em, weight: 700, title)
]
// Author information.
pad(
top: 0.7em,
grid(
columns: (1fr),
gutter: 1em,
..authors.map(author => align(center)[
*#author.name* \
#author.email \
#author.affiliation \
#author.postal \
#author.phone
]),
),
)
// Logo
if logo != none {
v(0.25fr)
align(center, image(logo, width: 26%))
v(0.50fr)
} else {
v(0.75fr)
}
pagebreak()
// Abstract page.
set page(numbering: "I", number-align: center)
v(1fr)
align(center)[
#heading(
outlined: false,
numbering: none,
text(0.85em, smallcaps[Abstract]),
)
]
abstract
v(1.618fr)
counter(page).update(1)
pagebreak()
// Table of contents.
outline(depth: 3, indent: true)
pagebreak()
// Main body.
set page(numbering: "1", number-align: center)
set par(first-line-indent: 20pt)
show bibliography: set par(first-line-indent: 0pt)
set page(header: getHeader())
counter(page).update(1)
body
}