174 lines
5.7 KiB
Typst
174 lines
5.7 KiB
Typst
#let multi-target(htmlfn, pagedfn, ..args) = context {
|
|
if target() == "html" {htmlfn(..args)}
|
|
else if target() == "paged" {pagedfn(..args)}
|
|
else {panic("Unsuported target: " + target())}
|
|
}
|
|
|
|
|
|
#let setup(doc) = multi-target(
|
|
(body) => {
|
|
show regex("[\u{e3e0}-\u{e3ff}]+(\s+[\u{e3e0}-\u{e3ff}]+)*"): {
|
|
html.span.with(class: "scr-nahan")
|
|
}
|
|
show figure.where(kind: table): it => {
|
|
html.details({
|
|
html.summary[
|
|
*Table #numbering(it.numbering, ..counter(figure.where(kind: table)).get())*: #it.caption.body
|
|
]
|
|
it.body
|
|
}, open: true )
|
|
}
|
|
show figure.where(kind: "gloss"): it => {
|
|
html.details({
|
|
html.summary[
|
|
*Example #numbering(it.numbering, ..counter(figure.where(kind: "gloss")).get())*: #it.caption.body
|
|
]
|
|
it.body
|
|
}, open: true )
|
|
}
|
|
show raw.where(block: true): it => {
|
|
html.pre(html.code(class: "language-" + it.lang, it.text))
|
|
}
|
|
show raw.where(block: false): it => {
|
|
html.code(class: "language-" + it.lang, it.text)
|
|
}
|
|
body
|
|
},
|
|
(body) => {
|
|
show regex("[\u{e3e0}-\u{e3ff}]+(\s+[\u{e3e0}-\u{e3ff}]+)*"): {
|
|
text.with(font: "AndikaAmbNaran")
|
|
}
|
|
body
|
|
},
|
|
doc
|
|
)
|
|
|
|
#let low(it) = multi-target(
|
|
html.span.with(class: "low"),
|
|
text.with(size: .8em, style: "italic"),
|
|
it
|
|
)
|
|
#let high(it) = multi-target(
|
|
html.span.with(class: "high"),
|
|
text.with(weight: 900, fill: color.rgb("#af3a03")),
|
|
it
|
|
)
|
|
|
|
|
|
#let gloss-raw(
|
|
txt: none,
|
|
translit: none,
|
|
split: (),
|
|
phono: (),
|
|
morphemes: (),
|
|
translation: [],
|
|
) = multi-target(
|
|
(txt: none, translit: none, split: (), phono: (), morphemes: (), translation: []) => {
|
|
assert(split.len() == phono.len() and split.len() == morphemes.len())
|
|
html.div(class: "gloss-box", {
|
|
if txt != none {
|
|
html.div(class: "gloss-text", txt)
|
|
}
|
|
if translit != none {
|
|
html.div(class: "gloss-translit", translit)
|
|
}
|
|
html.div(class: "gloss-row", {
|
|
split.zip(phono, morphemes).map(((s,p,m)) => {
|
|
html.div(class: "gloss-col", {
|
|
html.div(class: "gloss-split", s)
|
|
html.div(class: "gloss-phono", p)
|
|
html.div(class: "gloss-morph", m)
|
|
})
|
|
}).join()
|
|
})
|
|
html.div(class: "gloss-translation", translation)
|
|
})
|
|
|
|
},
|
|
(txt: none, translit: none, split: (), phono: (), morphemes: (), translation: []) => {
|
|
assert(split.len() == phono.len() and split.len() == morphemes.len())
|
|
grid(columns: split.len(), align: left,
|
|
row-gutter: .5em,
|
|
column-gutter: .5em,
|
|
grid.cell(colspan: split.len(), text(weight: "bold", txt)),
|
|
grid.cell(colspan: split.len(), low(translit)),
|
|
..split,
|
|
..phono.map(low),
|
|
..morphemes,
|
|
grid.cell(colspan: split.len(), text(style: "italic", translation))
|
|
)
|
|
},
|
|
txt: txt, translit: translit, split: split, phono: phono, morphemes: morphemes,
|
|
translation: translation,
|
|
)
|
|
|
|
|
|
#let ref(id, ..opts) = multi-target(
|
|
(id, ..opts) => std.ref(label(id), ..opts),
|
|
(id, ..opts) => std.ref(label(id + "--pdf"), ..opts),
|
|
id, ..opts
|
|
)
|
|
|
|
#let dictionary(p, data_path, htmlinputclasses: (), sortby: (a, b) => a.t <= b.t) = multi-target(
|
|
(p, data_path, htmlinputclasses, sortby) => [
|
|
= Dictionary
|
|
#html.input(
|
|
class: htmlinputclasses,
|
|
id: "searchdict",
|
|
type: "text",
|
|
placeholder: "Search in dictionary ..."
|
|
)
|
|
#let data_in = toml(data_path)
|
|
#let words = data_in.words.sorted(by: sortby)
|
|
#html.ul(id: "dictbox",{
|
|
for word in words {html.elem(
|
|
"li", attrs: (data-dict-l: word.l, data-dict-d: word.d.replace("\n", " "),
|
|
data-dict-i: word.i, data-dict-t: word.t, data-dict-p: word.p))[
|
|
#high(word.l) #low(word.t) [#word.i] #{word.p}.
|
|
|
|
#eval(mode: "markup", word.d, scope: (low: low, high: high))
|
|
]}
|
|
})
|
|
#html.script(`initDictionary();`.text, defer: true);
|
|
],
|
|
(p, data_path, htmlinputclasses, sortby) => [
|
|
#pagebreak(weak: true)
|
|
= Dictionary
|
|
#low[Note: the web version of the dictionary has a search function.]
|
|
#let data = toml(data_path).words
|
|
#let words = data.sorted(by: sortby)
|
|
#let last = ""
|
|
#columns(2, {for word in words [
|
|
#set heading(numbering: none, outlined: false)
|
|
#if word.l.clusters().at(0) != last {
|
|
last = word.l.clusters().at(0)
|
|
heading(level: 2)[
|
|
#box(baseline: -.25em, line(length: 2em))
|
|
#last
|
|
#box(baseline: -.25em, line(length: 2em))
|
|
]
|
|
}
|
|
/ #high(word.l) #low(word.t): [#word.i] #{word.p}.\
|
|
#eval(mode: "markup", word.d, scope: (low: low, high: high))
|
|
]})
|
|
#pagebreak(weak: true)
|
|
],
|
|
p, data_path, htmlinputclasses, sortby
|
|
)
|
|
|
|
#let figure(..args) = multi-target(
|
|
(label: none, ..args) => [
|
|
#std.figure(..args) #if label != none {std.label(label)}
|
|
],
|
|
(label: none, ..args) => [
|
|
#std.figure(..args) #if label != none {std.label(label + "--pdf")}
|
|
],
|
|
..args
|
|
)
|
|
|
|
#let gloss(
|
|
caption,
|
|
label: none,
|
|
..args
|
|
) = figure(kind: "gloss", supplement: "Example", gloss-raw(..args), caption: caption, label: label)
|