Repository navigation
Expand file tree
/
Copy pathlib.typ
More file actions
247 lines (227 loc) · 5.54 KB
/
Copy pathlib.typ
File metadata and controls
247 lines (227 loc) · 5.54 KB
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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
/// Load the default tutor config.
///
/// The tutor configuration holds all settings for the individual utilities provided by tutor.
///
/// #example(`
/// let cfg = tutor.default-config()
/// [#cfg]
/// `)
///
/// -> dictionary
#let default-config() = {
let cfg = (
sol: false,
level: 1,
test: true,
utils: (
lines: (spacing: 10mm),
grid: (spacing: 4mm),
checkbox: (
sym_true: "☒",
sym_false: "☐",
sym_question: "☐",
),
totalpoints: (
outline: false,
),
),
)
return cfg
}
/// Show a checkbox.
///
/// *Example in Question Mode:*
///
/// #example(`
/// let cfg = tutor.default-config()
/// [What does FHIR stand for?
/// - #tutor.checkbox(cfg, false) Finally He Is Real
/// - #tutor.checkbox(cfg, true) Fast Health Interoperability Resources]
/// `)
///
/// *Example in Solution Mode:*
///
/// #example(`
/// let cfg = tutor.default-config()
/// (cfg.sol = true) // enable solutions
/// [What does FHIR stand for?
/// - #tutor.checkbox(cfg, false) Finally He Is Real
/// - #tutor.checkbox(cfg, true) Fast Health Interoperability Resources]
/// `)
///
/// - cfg (dictionary): Global Tutor configuration
/// - answer (boolean): Wheter the checkbox should be filled in solution mode.
/// -> content
#let checkbox(cfg, answer) = {
if cfg.sol {
if answer {
cfg.utils.checkbox.sym_true
} else {
cfg.utils.checkbox.sym_false
}
} else {
cfg.utils.checkbox.sym_question
}
}
/// Print a blank line with a solution text.
///
/// *Example in Question Mode:*
///
/// #example(`
/// let cfg = tutor.default-config()
/// [Word for top of mountain: #tutor.blankline(cfg, 2cm, [peak])]
/// `)
///
/// *Example in Solution Mode:*
///
/// #example(`
/// let cfg = tutor.default-config()
/// (cfg.sol = true) // enable solutions
/// [Word for top of mountain: #tutor.blankline(cfg, 2cm, [peak])]
/// `)
///
/// - cfg (dictionary): Global Tutor configuration
/// - width (length): Line length.
/// - answer (content): Answer to display in solution mode.
/// -> content
#let blankline(cfg, width, answer) = {
if cfg.sol {
box(width: width, baseline: 5pt, stroke: (bottom: black), text(baseline: -5pt)[#answer])
} else {
box(width: width, baseline: 5pt, stroke: (bottom: black))[]
}
}
/// Print lines for students to write answers.
///
/// *Example:*
///
/// #example(`
/// let cfg = tutor.default-config()
/// (cfg.utils.lines.spacing = 2mm)
/// [Write answer here:]
/// tutor.lines(cfg, 3)`)
///
///
///
/// - cfg (dictionary): Global Tutor configuration
/// - count (integer): Number of lines to display.
/// -> content
#let lines(cfg, count) = {
let content = []
let spacing = cfg.utils.lines.spacing
if type(spacing) == str {
spacing = eval(spacing)
}
for n in range(count) {
content += [#v(spacing) #line(length: 100%) ]
}
return content
}
/// Print a grid for students to write answers.
///
/// *Example:*
///
/// #example(`
/// let cfg = tutor.default-config()
/// [Write answer here:]
/// tutor.grid(cfg, 4cm, 2cm)`)
///
///
///
/// - cfg (dictionary): Global Tutor configuration
/// - width (length): Width of grid box.
/// - height (length): Length of grid box.
/// -> content
#let grid(cfg, width, height) = {
let spacing = cfg.utils.grid.spacing
if type(spacing) == str {
spacing = eval(spacing)
}
let pat = tiling(size: (spacing, spacing))[
#place(line(start: (0%, 0%), end: (0%, 100%), stroke: 0.2pt))
#place(line(start: (0%, 0%), end: (100%, 0%), stroke: 0.2pt))
]
align(center, rect(fill: pat, width: width, height: height, stroke: 0.2pt))
}
/// Maximum points that can be achieved for a question. Will be internally added up to the total points counter.
///
/// *Example:*
///
/// #example(`[In this question a maxiumum of #tutor.points(4.5) points can be achieved.]`)
///
///
///
/// - num (integer, float): Number of points.
/// -> content
#let points(num) = {
let c = state("points", 0.0)
c.update(points => points + num)
[#num]
}
/// Display the total points of this exam, typically in the exam header.
///
/// *Example:*
///
/// #example(`
/// let cfg = tutor.default-config()
/// [In this a exam a total of #tutor.totalpoints(cfg) points can be achieved.]`)
///
///
/// - cfg (dictionary): Global Tutor configuration
/// -> content
#let totalpoints(cfg) = {
context {
let c = state("points", 0.0)
let points = c.final()
if cfg.utils.totalpoints.outline {
points = points / 2
}
[ #points ]
}
}
/// Display only in solution mode.
///
/// - cfg (dictionary): Global Tutor configuration
/// - sol (content): Content to be shown in solution mode
/// -> content
#let if-sol(cfg, sol) = {
if cfg.sol {
sol
}
}
/// Display different content in solution and question mode.
///
/// - cfg (dictionary): Global Tutor configuration
/// - sol (content): Content to be shown in solution mode
/// - question (content): Content to be shown in question mode
/// -> content
#let if-sol-else(cfg, sol, question) = {
if cfg.sol {
sol
} else {
question
}
}
/// Display only in test mode.
///
/// - cfg (dictionary): Global Tutor configuration
/// - test (content): Content to be shown in test mode
/// -> content
#let if-test(cfg, test) = {
if cfg.test {
test
}
}
/// Display different content in solution and question mode.
///
/// - cfg (dictionary): Global Tutor configuration
/// - test (content): Content to be shown in test mode
/// - exercise (content): Content to be shown in exercise mode
/// -> content
#let if-test-else(cfg, test, exercise) = {
if cfg.test {
test
} else {
exercise
}
}