diff --git a/examples/import-terms-from-yaml-file/glossary.yml b/examples/import-terms-from-yaml-file/glossary.yml index 52afcea..03a9995 100644 --- a/examples/import-terms-from-yaml-file/glossary.yml +++ b/examples/import-terms-from-yaml-file/glossary.yml @@ -3,11 +3,17 @@ ntc: short: NTC long: Nonlinear Transform Coding - description: | + description: | This is the opposite of @ltc. + group: Nonlinear ltc: short: LTC long: Linear Transform Coding description: | - Transform Coding constraint to linear transforms. \ No newline at end of file + Transform Coding constraint to linear transforms. + group: Linear + +bor: + short: DEF + long: Default \ No newline at end of file diff --git a/examples/import-terms-from-yaml-file/main.pdf b/examples/import-terms-from-yaml-file/main.pdf index 320b3f4..89e32a2 100644 Binary files a/examples/import-terms-from-yaml-file/main.pdf and b/examples/import-terms-from-yaml-file/main.pdf differ diff --git a/examples/import-terms-from-yaml-file/main.typ b/examples/import-terms-from-yaml-file/main.typ index 0ebce98..ead1b5e 100644 --- a/examples/import-terms-from-yaml-file/main.typ +++ b/examples/import-terms-from-yaml-file/main.typ @@ -4,7 +4,7 @@ -#import "@local/glossarium:0.2.6": * +#import "../../glossarium.typ": * // Replace the local import with a import to the preview namespace. // If you don't know what that mean, please go read typst documentation on how to import packages at https://typst.app/docs/packages/. @@ -25,7 +25,7 @@ for key in v.keys() { assert( - key in ("short", "long", "description"), + key in ("short", "long", "description", "group"), message: "Found unexpected key `" + key + "` in glossary entry `" + k + "` in `" + file + "`", ) } @@ -48,13 +48,21 @@ message: "The description of glossary entry `" + k + "` in `" + file + "` is not a string", ) } - } + + if "group" in v { + assert( + type(v.group) == str, + message: "The optional group of glossary entry `" + k + "` in `" + file + "` is not a string", + ) + } +} return entries.pairs().map(((key, entry)) => ( key: key, short: eval(entry.short, mode: "markup"), long: eval(entry.at("long", default: ""), mode: "markup"), desc: eval(entry.at("description", default: ""), mode: "markup"), + group: entry.at("group", default: ""), file: file, )) } @@ -87,6 +95,7 @@ = Test Document -Reference to @ntc +Reference to @ntc \ +Reference to @bor #glossary("glossary.yml") \ No newline at end of file diff --git a/glossarium.typ b/glossarium.typ index 3e48ccd..2d12af7 100644 --- a/glossarium.typ +++ b/glossarium.typ @@ -15,44 +15,36 @@ SOFTWARE.*/ #let __query_labels_with_key(loc, key, before: false) = { if before { - query( - selector(label(__glossary_label_prefix + key)).before(loc, inclusive: false), - loc, - ) + query(selector(label(__glossary_label_prefix + key)).before(loc, inclusive: false), loc) } else { - query( - selector(label(__glossary_label_prefix + key)), - loc, - ) + query(selector(label(__glossary_label_prefix + key)), loc) } } // Reference a term #let gls(key, suffix: none, long: none, display: none) = { - locate( - loc => { - let __glossary_entries = __glossary_entries.final(loc); - if key in __glossary_entries { - let entry = __glossary_entries.at(key) - - let gloss = __query_labels_with_key(loc, key, before: true) - - let is_first = gloss == (); - let entlong = entry.at("long", default: "") - let textLink = if display !=none { - [#display] - } else if (is_first or long == true) and entlong != [] and entlong != "" and long != false { - [#entry.short#suffix (#emph(entlong))] - } else { - [#entry.short#suffix] - } - - [#link(label(entry.key), textLink)#label(__glossary_label_prefix + entry.key)] + context { + let __glossary_entries = __glossary_entries.final(here()) + if key in __glossary_entries { + let entry = __glossary_entries.at(key) + + let gloss = __query_labels_with_key(here(), key, before: true) + + let is_first = gloss == () + let entlong = entry.at("long", default: "") + let textLink = if display != none { + [#display] + } else if (is_first or long == true) and entlong != [] and entlong != "" and long != false { + [#entry.short#suffix (#emph(entlong))] } else { - text(fill: red, "Glossary entry not found: " + key) + [#entry.short#suffix] } - }, - ) + + [#link(label(entry.key), textLink)#label(__glossary_label_prefix + entry.key)] + } else { + text(fill: red, "Glossary entry not found: " + key) + } + } } // reference to term with pluralisation @@ -71,84 +63,78 @@ SOFTWARE.*/ body } -#let print-glossary(entries, show-all: false, disable-back-references: false) = { - __glossary_entries.update( - (x) => { - for entry in entries { - x.insert( - entry.key, - ( - key: entry.key, - short: entry.short, - long: entry.at("long", default: ""), - desc: entry.at("desc", default: ""), - ), - ) - } - - x - }, - ) - - for entry in entries.sorted(key: (x) => x.key) { - [ - #show figure.where(kind: __glossarium_figure): it => it.caption - #par( - hanging-indent: 1em, - first-line-indent: 0em, - )[ - #figure( - supplement: "", - kind: __glossarium_figure, - numbering: none, - caption: { - locate( - loc => { - let term_references = __query_labels_with_key(loc, entry.key) - if term_references.len() != 0 or show-all { - let desc = entry.at("desc", default: "") - let long = entry.at("long", default: "") - let hasLong = long != "" and long != [] - let hasDesc = desc != "" and desc != [] - - { - set text(weight: 600) - if hasLong { - emph(entry.short) + [ -- ] + entry.long - } - else { - emph(entry.short) +#let print-glossary(entries, show-all: false, disable-back-references: false, group-pagebreak: false) = { + __glossary_entries.update(x => { + for entry in entries { + x.insert( + entry.key, + ( + key: entry.key, + short: entry.short, + long: entry.at("long", default: ""), + desc: entry.at("desc", default: ""), + group: entry.at("group", default: ""), + ), + ) + } + + x + }) + + let groups = entries.map(x => x.at("group", default: "")).dedup() + // move no group to the front + groups.insert(0, "") + groups.pop() + + for group in groups.sorted() { + if group != "" [#heading(group, level: 2) ] + for entry in entries.sorted(key: x => x.key) { + if entry.group == group { + [ + #show figure.where(kind: __glossarium_figure): it => it.caption + #par(hanging-indent: 1em, first-line-indent: 0em)[ + #figure( + supplement: "", + kind: __glossarium_figure, + numbering: none, + caption: { + context { + let term_references = __query_labels_with_key(here(), entry.key) + if term_references.len() != 0 or show-all { + let desc = entry.at("desc", default: "") + let long = entry.at("long", default: "") + let hasLong = long != "" and long != [] + let hasDesc = desc != "" and desc != [] + { + set text(weight: 600) + if hasLong { + emph(entry.short) + [ -- ] + entry.long + } else { + emph(entry.short) + } + } + if hasDesc [: #desc ] else [. ] + if disable-back-references != true { + term_references.map(x => x.location()).sorted(key: x => x.page()).fold( + (values: (), pages: ()), + ((values, pages), x) => if pages.contains(x.page()) { + (values: values, pages: pages) + } else { + values.push(x) + pages.push(x.page()) + (values: values, pages: pages) + }, + ).values.map(x => link(x)[#numbering(x.page-numbering(), ..counter(page).at(x))]).join(", ") + } } } - if hasDesc [: #desc ] else [. ] - if disable-back-references != true { - term_references.map((x) => x.location()) - .sorted(key: (x) => x.page()) - .fold( - (values: (), pages: ()), - ((values, pages), x) => if pages.contains(x.page()) { - (values: values, pages: pages) - } else { - values.push(x) - pages.push(x.page()) - (values: values, pages: pages) - }, - ) - .values - .map( - (x) => link( - x, - )[#numbering(x.page-numbering(), ..counter(page).at(x))], - ) - .join(", ") - } - } - }, - ) - }, - )[] #label(entry.key) - ] - #parbreak() - ] + }, + )[] #label(entry.key) + ] + #parbreak() + ] + } + } + if group-pagebreak {pagebreak(weak: true)} } };