typst-lepizig-glossing/leipzig-gloss.typ

148 lines
4.2 KiB
Plaintext
Raw Normal View History

2023-09-19 01:22:15 -07:00
#import "abbreviations.typ"
#let gloss-count = counter("gloss_count")
2023-03-23 21:34:17 -07:00
#let build_gloss(item-spacing, formatters, gloss_line_lists) = {
2023-03-23 21:34:17 -07:00
assert(gloss_line_lists.len() > 0, message: "Gloss line lists cannot be empty")
let len = gloss_line_lists.at(0).len()
for line in gloss_line_lists {
assert(line.len() == len)
}
assert(formatters.len() == gloss_line_lists.len(), message: "The number of formatters and the number of gloss line lists should be equal")
let make_item_box(..args) = {
box(stack(dir: ttb, spacing: 0.5em, ..args))
}
for item_index in range(0, len) {
let args = ()
for (line_idx, formatter) in formatters.enumerate() {
2023-03-23 21:34:17 -07:00
let formatter_fn = if formatter == none {
(x) => x
} else {
formatter
}
let item = gloss_line_lists.at(line_idx).at(item_index)
args.push(formatter_fn(item))
}
make_item_box(..args)
h(item-spacing)
2023-03-23 21:34:17 -07:00
}
}
// a workround so we can use `label` as a variable name where it is shadowed by the function param `label`
// Once typst version 0.12 with https://github.com/typst/typst/pull/4038 is released we should be able
// to replace this workaround with `std.label`
#let cmdlabel = label
2023-03-23 21:34:17 -07:00
#let gloss(
header: none,
header-style: none,
source: (),
2023-09-19 03:40:56 -07:00
source-style: none,
2023-03-23 21:34:17 -07:00
transliteration: none,
transliteration-style: none,
2023-07-31 02:17:09 -07:00
morphemes: none,
morphemes-style: none,
additional-lines: (), //List of list of content
2023-03-23 21:34:17 -07:00
translation: none,
translation-style: none,
label: none,
label-supplement: [example],
2023-09-19 03:40:56 -07:00
item-spacing: 1em,
gloss-padding: 2.0em, //TODO document these
left_padding: 0.5em,
2023-03-23 21:34:17 -07:00
numbering: false,
breakable: false,
2023-03-23 21:34:17 -07:00
) = {
assert(type(source) == "array", message: "source needs to be an array; perhaps you forgot to type `(` and `)`, or a trailing comma?")
2023-03-23 21:34:17 -07:00
2023-07-31 02:17:09 -07:00
if morphemes != none {
assert(type(morphemes) == "array", message: "morphemes needs to be an array; perhaps you forgot to type `(` and `)`, or a trailing comma?")
assert(source.len() == morphemes.len(), message: "source and morphemes have different lengths")
2023-07-31 02:17:09 -07:00
}
2023-03-23 21:34:17 -07:00
if transliteration != none {
assert(transliteration.len() == source.len(), message: "source and transliteration have different lengths")
2023-03-23 21:34:17 -07:00
}
let gloss_items = {
if header != none {
if header-style != none {
header-style(header)
2023-07-04 01:52:43 -07:00
} else {
header
2023-07-04 01:52:43 -07:00
}
2023-03-23 21:34:17 -07:00
linebreak()
}
let formatters = (source-style,)
let gloss_line_lists = (source,)
2023-03-23 21:34:17 -07:00
if transliteration != none {
formatters.push(transliteration-style)
2023-03-23 21:34:17 -07:00
gloss_line_lists.push(transliteration)
}
2023-07-31 02:17:09 -07:00
if morphemes != none {
formatters.push(morphemes-style)
2023-07-31 02:17:09 -07:00
gloss_line_lists.push(morphemes)
}
2023-03-23 21:34:17 -07:00
for additional in additional-lines {
2023-03-23 21:34:17 -07:00
formatters.push(none) //TODO fix this
gloss_line_lists.push(additional)
}
build_gloss(item-spacing, formatters, gloss_line_lists)
2023-03-23 21:34:17 -07:00
if translation != none {
linebreak()
2023-07-04 01:52:43 -07:00
if translation-style == none {
2023-09-19 03:40:56 -07:00
translation
2023-07-04 01:52:43 -07:00
} else {
translation-style(translation)
2023-07-04 01:52:43 -07:00
}
2023-03-23 21:34:17 -07:00
}
}
if numbering {
gloss-count.step()
}
2023-07-04 01:41:26 -07:00
2023-03-23 21:34:17 -07:00
let gloss_number = if numbering {
[(#context gloss-count.display())]
2023-03-23 21:34:17 -07:00
} else {
none
}
style(styles => {
block(breakable: breakable)[
#figure(
kind: "ling-example",
supplement: label-supplement,
numbering: it => [#gloss-count.display()],
stack(
dir: ltr, //TODO this needs to be more flexible
left_padding,
[#gloss_number],
gloss-padding - left_padding - measure([#gloss_number],styles).width,
align(left)[#gloss_items],
),
) #if label != none {cmdlabel(label)}
]
}
)
2023-03-23 21:34:17 -07:00
}
#let numbered-gloss = gloss.with(numbering: true)