#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)