chore(glossy): format with typestyle

This commit is contained in:
swaits committed 2025-10-26 16:00:23 -06:00
1 parent 6d83a858c8
commit 022892df88
28 files changed
+668 -532

No files matched your search

+1 -1
View File
@@ -1,2 +1,2 @@
#import "src/gloss.typ": init-glossary, glossary
#import "src/gloss.typ": glossary, init-glossary
#import "src/themes.typ": *
+107 -46
View File
@@ -59,7 +59,7 @@
longplural: entry.at("longplural", default: __pluralize(long)),
longarticle: entry.at("longarticle", default: __determine_article(long)),
description: entry.at("description", default: none),
group: entry.at("group", default: "")
group: entry.at("group", default: ""),
)
}
@@ -149,7 +149,9 @@
counter(__gloss_label_prefix + key).step()
}
if count-as-first-use {
counter(__gloss_label_prefix + key + __gloss_first_use_counter_postfix).step()
counter(
__gloss_label_prefix + key + __gloss_first_use_counter_postfix,
).step()
}
}
@@ -164,7 +166,7 @@
//
#let __is_term_ever_referenced(key, location: none) = {
let c = counter(__gloss_label_prefix + key)
c = if location == none {c.final()} else {c.at(location)}
c = if location == none { c.final() } else { c.at(location) }
c.at(0) > 0
}
@@ -181,8 +183,10 @@
// boolean: If the entry is used above the location in the document
//
#let __is_term_first_used(key, location: none) = {
let c = counter(__gloss_label_prefix + key + __gloss_first_use_counter_postfix)
c = if location == none {c.final()} else {c.at(location)}
let c = counter(
__gloss_label_prefix + key + __gloss_first_use_counter_postfix,
)
c = if location == none { c.final() } else { c.at(location) }
c.at(0) > 0
}
@@ -195,7 +199,9 @@
// none: Updates state as a side effect
//
#let __reset_term_first_used(key, location: none) = {
counter(__gloss_label_prefix + key + __gloss_first_use_counter_postfix).update(0)
counter(
__gloss_label_prefix + key + __gloss_first_use_counter_postfix,
).update(0)
}
// Determine if the glossary contains a visible entry
@@ -236,8 +242,23 @@
// content: The fully formatted term, including optional article, capitalization,
// usage tracking metadata, and the chosen form (short, long, or both).
//
#let __gls(key, modes-modifiers: array, format-term: function, show-term: function, term-links: true, display-text: none) = {
let possible_modes = ("auto", "both", "short", "long", "supplement", "description", "reset")
#let __gls(
key,
modes-modifiers: array,
format-term: function,
show-term: function,
term-links: true,
display-text: none,
) = {
let possible_modes = (
"auto",
"both",
"short",
"long",
"supplement",
"description",
"reset",
)
// ---------------------------------------------------------------------------
// Normalize mode & modifier inputs AND check if the modifiers are valid
// ---------------------------------------------------------------------------
@@ -255,7 +276,10 @@
} else if it in ("both", "short", "long", "reset", "cap", "pl") {
return it
} else if it in ("auto", "description", "supplement") {
panic(it, "is a valid mode, but is not used by applying a modifier with this name. Read the documentation.")
panic(
it,
"is a valid mode, but is not used by applying a modifier with this name. Read the documentation.",
)
} else {
panic(it, "is not a recognized mode or modifier.")
}
@@ -269,17 +293,19 @@
// Determine the requested modes (plural) and the modifier array
// ---------------------------------------------------------------------------
modes-modifiers.push("__MIDDLE_ITEM") // unused modifier
let (requested_modes, modifiers) = modes-modifiers.sorted(key: it => {
if it in possible_modes {
// It is a 'mode'
return -1
} else if it == "__MIDDLE_ITEM" {
return 0
} else {
// It is a 'modifier'
return 1
}
}).split("__MIDDLE_ITEM")
let (requested_modes, modifiers) = modes-modifiers
.sorted(key: it => {
if it in possible_modes {
// It is a 'mode'
return -1
} else if it == "__MIDDLE_ITEM" {
return 0
} else {
// It is a 'modifier'
return 1
}
})
.split("__MIDDLE_ITEM")
// ---------------------------------------------------------------------------
// Check for illegal mode and/or modifier combinations
@@ -335,12 +361,18 @@
// Manage term usage counting and determine if it's the first reference
// ---------------------------------------------------------------------------
let is_first_use = not __is_term_first_used(key, location: here())
let default-count-as-first-use = (requested_mode == "auto" or requested_mode == "both")
let default-count-as-first-use = (
requested_mode == "auto" or requested_mode == "both"
)
let force-count-as-first-use = "use" in modifiers
let force-skip-as-first-use = "no-use" in modifiers
let wants_reference = "noindex" not in modifiers
__mark_term_used(key, wants_reference, force-count-as-first-use
or (not force-skip-as-first-use and default-count-as-first-use))
__mark_term_used(
key,
wants_reference,
force-count-as-first-use
or (not force-skip-as-first-use and default-count-as-first-use),
)
// ---------------------------------------------------------------------------
// Helper Functions
@@ -376,7 +408,7 @@
// - If mode is "short", return the short article.
// - If mode is "long" or "both", return the long article.
// The calling logic ensures that when mode = "long" or "both", a long form exists.
let get_article = (mode) => {
let get_article = mode => {
let wants_article = "an" in modifiers
if not wants_article {
none
@@ -406,7 +438,10 @@
}
let long_available = entry.long != none
let mode = if (requested_mode == "both" or requested_mode == "long") and not long_available {
let mode = if (
(requested_mode == "both" or requested_mode == "long")
and not long_available
) {
// The fall back case, because long form is not available, but it is requested
"short"
} else {
@@ -481,9 +516,13 @@
//
#let __create_backlinks(key) = {
return query(__term_label(key)) // find all reference
.map(meta => { // extract location and page number (or symbol)
.map(meta => {
// extract location and page number (or symbol)
let loc = meta.location()
let page = numbering(__default(loc.page-numbering(), "1"), ..counter(page).at(loc))
let page = numbering(
__default(loc.page-numbering(), "1"),
..counter(page).at(loc),
)
(loc, page)
})
.dedup(key: ((loc, page)) => page) // deduplicate by page
@@ -508,14 +547,14 @@
// string: The formatted term based on the specified mode.
//
#let __default-format-term(mode, short-form, long-form) = {
if mode == "short" {
short-form
} else if mode == "long" {
long-form
} else {
// mode assumed to be "both"
long-form + " (" + short-form + ")"
}
if mode == "short" {
short-form
} else if mode == "long" {
long-form
} else {
// mode assumed to be "both"
long-form + " (" + short-form + ")"
}
}
// Styles a term to control its display in a document.
@@ -559,17 +598,23 @@
format-term: __default-format-term,
show-term: __default-show-term,
term-links: false,
body
body,
) = context {
// Type checking
let checked-entries = (:)
for (key, entry) in entries {
let checked-key = z.parse(key, z.string(), scope: ("dictionary key",))
let checked-entry = z.parse(entry, dict-schema, scope: ("dictionary entry",))
let checked-entry = z.parse(entry, dict-schema, scope: (
"dictionary entry",
))
checked-entries.insert(checked-key, checked-entry)
}
let checked-format-term = z.parse(show-term, z.function(), scope: ("format-term",))
let checked-show-term = z.parse(show-term, z.function(), scope: ("show-term",))
let checked-format-term = z.parse(show-term, z.function(), scope: (
"format-term",
))
let checked-show-term = z.parse(show-term, z.function(), scope: (
"show-term",
))
let checked-body = z.parse(body, z.content(), scope: ("body",))
// Process and store each glossary entry
@@ -590,7 +635,12 @@
// - That "key" does not correspond to an actual entry,
// - There is at least one modifier,
// - The first modifier corresponds to an existing entry key.
let can_swap = (lower(raw_key) == "a" or lower(raw_key) == "an") and not __has_entry(raw_key) and raw_modifiers.len() > 0 and __has_entry(raw_modifiers.first())
let can_swap = (
(lower(raw_key) == "a" or lower(raw_key) == "an")
and not __has_entry(raw_key)
and raw_modifiers.len() > 0
and __has_entry(raw_modifiers.first())
)
// If we can swap, use the first modifier as the key and insert "a" as the first modifier.
let (key, modifiers) = if can_swap {
@@ -602,7 +652,14 @@
// Now see if this is an actual glossary term key
if __has_entry(key) {
// Found in dictionary, render via __gls()
__gls(key, modes-modifiers: modifiers.map(lower), format-term: format-term, show-term: show-term, term-links: term-links, display-text: supplement)
__gls(
key,
modes-modifiers: modifiers.map(lower),
format-term: format-term,
show-term: show-term,
term-links: term-links,
display-text: supplement,
)
} else {
// Not one of ours, so just pass it through
r
@@ -658,7 +715,9 @@
// Type checking
let checked-title = z.parse(title, z.content(), scope: ("title",))
let checked-groups = z.parse(groups, groups-list-schema, scope: ("groups",))
let checked-ignore-case = z.parse(ignore-case, z.boolean(), scope: ("ignore-case",))
let checked-ignore-case = z.parse(ignore-case, z.boolean(), scope: (
"ignore-case",
))
let checked-theme = z.parse(theme, theme-schema, scope: ("theme",))
// Collect and organize entries by group
@@ -706,7 +765,7 @@
long: entry.at("long"),
description: entry.at("description"),
label: [#metadata(key)#__entry_label(key)],
pages: __create_backlinks(key)
pages: __create_backlinks(key),
))
}
}
@@ -719,7 +778,9 @@
let sorted_entries = if sort {
current_entries
// 1. create array of tuples with (lower [if ignore-case], entry)
.map(e => { if ignore-case { (lower(e.short), e) } else { (e.short, e) } })
.map(e => {
if ignore-case { (lower(e.short), e) } else { (e.short, e) }
})
// 2. sort the tuples (by first element then second)
.sorted() // NOTE: sorted() is NOT language-aware
// 3. strip away the tuple's first element, leaving an array of entries
@@ -747,10 +808,10 @@
output.len(),
for (i, entry) in entries.enumerate() {
(checked-theme.entry)(entry, i, entries.len())
}
},
)
group_index += 1
}
},
)
]
}
+3 -3
View File
@@ -10,8 +10,8 @@
longplural: z.content(optional: true),
description: z.content(optional: true),
group: z.content(optional: true),
)
)
),
),
)
#let theme-schema = z.dictionary(
@@ -19,7 +19,7 @@
section: z.function(),
group: z.function(),
entry: z.function(),
)
),
)
#let groups-list-schema = z.array(pre-transform: z.coerce.array)
+3 -5
View File
@@ -5,7 +5,6 @@
v(1em)
body
},
group: (name, index, total, body) => {
if name != "" and total > 1 {
v(1.5em)
@@ -16,7 +15,6 @@
}
body
},
entry: (entry, index, total) => {
let short-display = text(weight: "bold", entry.short)
let long-display = if entry.long == none {
@@ -40,10 +38,10 @@
columns: (1fr, auto),
gutter: 0.75em,
[#short-display#long-display#description#entry.label],
text(fill: rgb("#666666"), entry.pages.join(", "))
text(fill: rgb("#666666"), entry.pages.join(", ")),
)
}
)
},
),
)
},
)
+3 -5
View File
@@ -15,7 +15,6 @@
heading(level: 1, title)
body
},
// Renders a group of related glossary terms
// Parameters:
// name: Group name (empty string for ungrouped terms)
@@ -28,7 +27,6 @@
}
body
},
// Renders a single glossary entry with term, definition, and page references
// Parameters:
// entry: Dictionary containing term data:
@@ -62,9 +60,9 @@
left: 1em,
bottom: 0.5em,
block(
[#term#entry.label#long-form#description #h(1em) (pp. #entry.pages.join(", "))]
)
)
[#term#entry.label#long-form#description #h(1em) (pp. #entry.pages.join(", "))],
),
),
)
},
)
+4 -6
View File
@@ -5,7 +5,6 @@
heading(level: 1, smallcaps(title))
body
},
group: (name, index, total, body) => {
if name != "" and total > 1 {
v(1em)
@@ -14,13 +13,12 @@
}
body
},
entry: (entry, index, total) => {
let short-display = text(weight: "regular", entry.short)
let long-display = if entry.long == none {
[]
} else {
[ — #entry.long] // Using em-dash for Chicago style
[ — #entry.long] // Using em-dash for Chicago style
}
let description = if entry.description == none {
@@ -38,10 +36,10 @@
columns: (1fr, auto),
gutter: 1em,
[#short-display#entry.label#long-display#description#entry.label],
[#entry.pages.join(", ")]
[#entry.pages.join(", ")],
)
}
)
},
),
)
},
)
+7 -9
View File
@@ -17,7 +17,6 @@
heading(level: 1, outlined: false, text(weight: "bold", size: 1.1em, title))
body
},
// Renders a group of related glossary terms
// Parameters:
// name: Group name (empty string for ungrouped terms)
@@ -30,13 +29,12 @@
spacing: 0.5em,
pad(
top: 0.5em,
text(weight: "bold", size: 0.9em, name)
)
text(weight: "bold", size: 0.9em, name),
),
)
}
body
},
// Renders a single glossary entry with term, definition, and page references
// Parameters:
// entry: Dictionary containing term data:
@@ -53,7 +51,7 @@
size: 0.65em,
weight: "medium",
fill: gray.darken(60%),
entry.short
entry.short,
)
let long-form = if entry.long == none {
@@ -73,7 +71,7 @@
spacing: 0.4em,
grid(
columns: (auto, 1fr, auto),
align: left+bottom,
align: left + bottom,
gutter: 0.5em,
// Term and description column
box[#term#entry.label#long-form #description],
@@ -83,9 +81,9 @@
text(
size: 0.6em,
fill: gray.darken(20%),
entry.pages.join(", ")
)
)
entry.pages.join(", "),
),
),
)
},
)
+10 -6
View File
@@ -4,13 +4,13 @@
heading(level: 1, title)
body
},
group: (name, index, total, body) => {
if name != "" and total > 1 {
heading(level: 2, name)
}
table(columns: 4,
table(
columns: 4,
stroke: none,
inset: (x, y) => {
if (x == 0) {
@@ -22,11 +22,15 @@
}
},
table.header([*Abbreviation*], [*Full Name*], [*Description*], [*Pages*]),
..body
..body,
)
},
entry: (entry, index, total) => {
(entry.short + entry.label, entry.long, entry.description, entry.pages.join(", "))
}
(
entry.short + entry.label,
entry.long,
entry.description,
entry.pages.join(", "),
)
},
)
+10 -8
View File
@@ -15,7 +15,6 @@
heading(level: 1, title)
columns(2, body)
},
// Renders a group of related glossary terms
// Parameters:
// name: Group name (empty string for ungrouped terms)
@@ -28,7 +27,6 @@
}
body
},
// Renders a single glossary entry with term, definition, and page references
// Parameters:
// entry: Dictionary containing term data:
@@ -60,13 +58,17 @@
size: 0.75em,
weight: "light",
grid(
columns: (auto,1fr,1em,auto),
columns: (auto, 1fr, 1em, auto),
align: (left, center, center, right),
[#short-display#entry.label#long-display#description], // Term with label
[#repeat(h(0.25em) + "." + h(0.25em))], // Dotted leader line
[ . ], // A 1em wide dot so we definitely get some break between term and pages
[#entry.pages.join(", ")] // Page references
)
[#short-display#entry.label#long-display#description],
// Term with label
[#repeat(h(0.25em) + "." + h(0.25em))],
// Dotted leader line
[ . ],
// A 1em wide dot so we definitely get some break between term and pages
[#entry.pages.join(", ")],
// Page references
),
)
},
)
+29 -18
View File
@@ -16,8 +16,8 @@
}
// Helper functions for checking endings
let ends_with = (suffix) => lower(word).ends-with(suffix)
let ends_with_any = (suffixes) => suffixes.any((suffix) => ends_with(suffix))
let ends_with = suffix => lower(word).ends-with(suffix)
let ends_with_any = suffixes => suffixes.any(suffix => ends_with(suffix))
// Map of irregular plurals for common words
let irregulars = (
@@ -80,7 +80,18 @@
// Irregular suffixes
let f_to_ves = ("leaf", "loaf", "calf", "half", "wolf", "thief")
let fe_to_ves = ("wife", "knife", "life")
let o_to_os = ("photo", "piano", "halo", "radio", "video", "studio", "solo", "taco", "memo", "zero")
let o_to_os = (
"photo",
"piano",
"halo",
"radio",
"video",
"studio",
"solo",
"taco",
"memo",
"zero",
)
// Convenience
let w = lower(word)
@@ -123,7 +134,7 @@
} else if ends_with("is") {
word.slice(0, -2) + "es"
} else if ends_with("on") {
word + "s"
word + "s"
} else if ends_with("o") {
if o_to_os.contains(w) {
word + "s"
@@ -203,7 +214,7 @@
if is_acronym {
// Use acronym rules
let first_char = upper_word.codepoints().slice(0,1).first()
let first_char = upper_word.codepoints().slice(0, 1).first()
if acronym_vowels.contains(first_char) {
"an"
} else {
@@ -211,17 +222,17 @@
}
} else {
// Non-acronym rules
let first_char = lower_word.codepoints().slice(0,1).first()
let first_char = lower_word.codepoints().slice(0, 1).first()
// Special cases for words matching a set of known 'silent h' prefixes
let silent_h_words = (
"heir", // "air"
"herb", // "erb" (in American English)
"heir", // "air"
"herb", // "erb" (in American English)
"homage", // "oh-mij" or "ah-mij"
"honest", // "on-est"
"honor", // "on-or" (American English)
"honor", // "on-or" (American English)
"honour", // "on-our" (British English)
"hour", // "our"
"hour", // "our"
)
if silent_h_words.any(w => lower_word.starts-with(w)) {
return "an"
@@ -235,15 +246,15 @@
// Words starting with 'u', that get the 'yoo' sound
if first_char == "u" {
let yoo_sounds = (
"ubi", // ubiquitous
"uni", // unicycle, uniform, universe, university, unilateral, unique, union, etc.
"usa", // usage, usability
"use", // use, useful, useless
"usu", // usual, usually
"ubi", // ubiquitous
"uni", // unicycle, uniform, universe, university, unilateral, unique, union, etc.
"usa", // usage, usability
"use", // use, useful, useless
"usu", // usual, usually
"usur", // usurp
"ute", // utensil, uterus
"uti", // utility, utilize, utilization
"uto", // utopia, utopian
"ute", // utensil, uterus
"uti", // utility, utilize, utilization
"uto", // utopia, utopian
)
if yoo_sounds.any(w => lower_word.starts-with(w)) {
return "a"
+38 -17
View File
@@ -6,10 +6,11 @@
tps: (
short: "TPS",
long: "test procedure specification",
description: "A document on how to run all the test procedures"),
description: "A document on how to run all the test procedures",
),
)
#show: init-glossary.with(myGlossary, show-term: (body) => [#emph(body)])
#show: init-glossary.with(myGlossary, show-term: body => [#emph(body)])
#set heading(numbering: "1.1")
#set page(numbering: "1")
@@ -43,8 +44,15 @@ Now make sure I get your @tps:short reports by 2pm!
These modifiers are semantically mutually exclusive. When multiple are used,
`glossy` throws an error to the compiler, explaining the problem.
#import "/src/gloss.typ": __gls, __default-format-term
#let manual-gls(key, mods) = __gls(key, modes-modifiers: mods, format-term: __default-format-term, show-term: (body) => [#strong(body)], term-links: false, display-text: none)
#import "/src/gloss.typ": __default-format-term, __gls
#let manual-gls(key, mods) = __gls(
key,
modes-modifiers: mods,
format-term: __default-format-term,
show-term: body => [#strong(body)],
term-links: false,
display-text: none,
)
#assert-panic(manual-gls.with("tps", ("short", "long")))
#let msg-short-long = "panicked with: \"Cannot mix modes \", (\"short\", \"long\"), \", pick one.\""
#let msg-short-both = "panicked with: \"Cannot mix modes \", (\"short\", \"both\"), \", pick one.\""
@@ -55,14 +63,29 @@ These modifiers are semantically mutually exclusive. When multiple are used,
columns: 2,
table.header([*Input*], [*Error*]),
[`@tps:short:long` ], [#assert.eq(catch(manual-gls.with("tps", ("short", "long"))),
msg-short-long)#msg-short-long],
[`@tps:short:both` ], [#assert.eq(catch(manual-gls.with("tps", ("short", "both"))),
msg-short-both)#msg-short-both],
[`@tps:long:both` ], [#assert.eq(catch(manual-gls.with("tps", ("long", "both"))),
msg-long-both)#msg-long-both],
[`@tps:short:long:both`], [#assert.eq(catch(manual-gls.with("tps", ("short", "long", "both"))),
msg-short-long-both)#msg-short-long-both],
[`@tps:short:long` ],
[#assert.eq(
catch(manual-gls.with("tps", ("short", "long"))),
msg-short-long,
)#msg-short-long],
[`@tps:short:both` ],
[#assert.eq(
catch(manual-gls.with("tps", ("short", "both"))),
msg-short-both,
)#msg-short-both],
[`@tps:long:both` ],
[#assert.eq(
catch(manual-gls.with("tps", ("long", "both"))),
msg-long-both,
)#msg-long-both],
[`@tps:short:long:both`],
[#assert.eq(
catch(manual-gls.with("tps", ("short", "long", "both"))),
msg-short-long-both,
)#msg-short-long-both],
)
#let my-theme = (
@@ -88,12 +111,10 @@ These modifiers are semantically mutually exclusive. When multiple are used,
block(
grid(
columns: (auto, 1fr, auto),
output,
repeat([#h(0.25em) . #h(0.25em)]),
entry.pages.join(", "),
)
output, repeat([#h(0.25em) . #h(0.25em)]), entry.pages.join(", "),
),
)
}
},
)
#glossary(theme: my-theme)
+53 -22
View File
@@ -7,20 +7,23 @@
short: "HTML",
long: "Hypertext Markup Language",
description: "A standard language for creating web pages",
group: "Web"),
group: "Web",
),
css: (
short: "CSS",
long: "Cascading Style Sheets",
description: "A language used for describing the presentation of a document",
group: "Web"),
group: "Web",
),
tps: (
short: "TPS",
long: "test procedure specification",
description: "A document on how to run all the test procedures"),
unused: "Unused term, which shouldn't print in the glossary."
description: "A document on how to run all the test procedures",
),
unused: "Unused term, which shouldn't print in the glossary.",
)
#show: init-glossary.with(myGlossary, show-term: (body) => [#emph(body)])
#show: init-glossary.with(myGlossary, show-term: body => [#emph(body)])
#set heading(numbering: "1.1")
#set page(height: auto, width: 6.5in, margin: 1em, numbering: "1")
@@ -81,8 +84,15 @@ Articles are incompatible with the `pl` (plural) modifier.
These modifiers are semantically mutually exclusive. When multiple are used,
`glossy` throws an error to the compiler, explaining the problem.
#import "/src/gloss.typ": __gls, __default-format-term
#let manual-gls(key, mods) = __gls(key, modes-modifiers: mods, format-term: __default-format-term, show-term: (body) => [#strong(body)], term-links: false, display-text: none)
#import "/src/gloss.typ": __default-format-term, __gls
#let manual-gls(key, mods) = __gls(
key,
modes-modifiers: mods,
format-term: __default-format-term,
show-term: body => [#strong(body)],
term-links: false,
display-text: none,
)
#assert-panic(manual-gls.with("tps", ("short", "long")))
#let msg-short-long = "panicked with: \"Cannot mix modes \", (\"short\", \"long\"), \", pick one.\""
#let msg-short-both = "panicked with: \"Cannot mix modes \", (\"short\", \"both\"), \", pick one.\""
@@ -93,14 +103,29 @@ These modifiers are semantically mutually exclusive. When multiple are used,
columns: 2,
table.header([*Input*], [*Error*]),
[`@tps:short:long` ], [#assert.eq(catch(manual-gls.with("tps", ("short", "long"))),
msg-short-long)#msg-short-long],
[`@tps:short:both` ], [#assert.eq(catch(manual-gls.with("tps", ("short", "both"))),
msg-short-both)#msg-short-both],
[`@tps:long:both` ], [#assert.eq(catch(manual-gls.with("tps", ("long", "both"))),
msg-long-both)#msg-long-both],
[`@tps:short:long:both`], [#assert.eq(catch(manual-gls.with("tps", ("short", "long", "both"))),
msg-short-long-both)#msg-short-long-both],
[`@tps:short:long` ],
[#assert.eq(
catch(manual-gls.with("tps", ("short", "long"))),
msg-short-long,
)#msg-short-long],
[`@tps:short:both` ],
[#assert.eq(
catch(manual-gls.with("tps", ("short", "both"))),
msg-short-both,
)#msg-short-both],
[`@tps:long:both` ],
[#assert.eq(
catch(manual-gls.with("tps", ("long", "both"))),
msg-long-both,
)#msg-long-both],
[`@tps:short:long:both`],
[#assert.eq(
catch(manual-gls.with("tps", ("short", "long", "both"))),
msg-short-long-both,
)#msg-short-long-both],
)
#let my-theme = (
@@ -126,14 +151,20 @@ These modifiers are semantically mutually exclusive. When multiple are used,
block(
grid(
columns: (auto, 1fr, auto),
output,
repeat([#h(0.25em) . #h(0.25em)]),
entry.pages.join(", "),
)
output, repeat([#h(0.25em) . #h(0.25em)]), entry.pages.join(", "),
),
)
}
},
)
#glossary(theme: my-theme)
#glossary(title: "Glossary with just empty group", groups: ("",), theme: theme-basic)
#glossary(title: "Glossary with just Web group", groups: ("Web",), theme: theme-compact)
#glossary(
title: "Glossary with just empty group",
groups: ("",),
theme: theme-basic,
)
#glossary(
title: "Glossary with just Web group",
groups: ("Web",),
theme: theme-compact,
)
+244 -255
View File
@@ -2,285 +2,274 @@
#let tests = (
// Main tests (covers most of English language)
("Europe","a"),
("European","a"),
("Hannah","a"),
("T-shirt","a"),
("Xerox","a"),
("Zebra","a"),
("aardvark","an"),
("apple","an"),
("boat","a"),
("car","a"),
("cat","a"),
("chair","a"),
("dog","a"),
("egg","an"),
("elephant","an"),
("emu","an"),
("eucalyptus","a"),
("eulogy","a"),
("euphemism","a"),
("exhausted","an"),
("ghost","a"),
("hat","a"),
("heir","an"),
("heiress","an"),
("herb","an"),
("herbal","an"),
("historic","a"),
("history","a"),
("homage","an"),
("honest","an"),
("honestly","an"),
("honor","an"),
("honorary","an"),
("honour","an"),
("horse","a"),
("hour","an"),
("hourglass","an"),
("house","a"),
("iris","an"),
("orange","an"),
("owl","an"),
("table","a"),
("ugly","an"),
("umbrella","an"),
("umpire","an"),
("unicorn","a"),
("unique","a"),
("university","a"),
("urn","an"),
("usage","a"),
("user","a"),
("utensil","a"),
("Europe", "a"),
("European", "a"),
("Hannah", "a"),
("T-shirt", "a"),
("Xerox", "a"),
("Zebra", "a"),
("aardvark", "an"),
("apple", "an"),
("boat", "a"),
("car", "a"),
("cat", "a"),
("chair", "a"),
("dog", "a"),
("egg", "an"),
("elephant", "an"),
("emu", "an"),
("eucalyptus", "a"),
("eulogy", "a"),
("euphemism", "a"),
("exhausted", "an"),
("ghost", "a"),
("hat", "a"),
("heir", "an"),
("heiress", "an"),
("herb", "an"),
("herbal", "an"),
("historic", "a"),
("history", "a"),
("homage", "an"),
("honest", "an"),
("honestly", "an"),
("honor", "an"),
("honorary", "an"),
("honour", "an"),
("horse", "a"),
("hour", "an"),
("hourglass", "an"),
("house", "a"),
("iris", "an"),
("orange", "an"),
("owl", "an"),
("table", "a"),
("ugly", "an"),
("umbrella", "an"),
("umpire", "an"),
("unicorn", "a"),
("unique", "a"),
("university", "a"),
("urn", "an"),
("usage", "a"),
("user", "a"),
("utensil", "a"),
// Acronym tests
("ASCII","an"),
("CFO","a"),
("F.A.Q.","an"),
("FBI","an"),
("GIF","a"),
("HIV","an"),
("JPEG","a"),
("LED","an"),
("MRI","an"),
("NATO","an"),
("PNG","a"),
("Q&A","a"),
("RF","an"),
("RNG","an"),
("SAS","an"),
("SMS","an"),
("SOS","an"),
("SQL","an"),
("UFO","a"),
("URL","a"),
("VCR","a"),
("WWW","a"),
("X.Y.Z.","an"),
("YAML","a"),
("ASCII", "an"),
("CFO", "a"),
("F.A.Q.", "an"),
("FBI", "an"),
("GIF", "a"),
("HIV", "an"),
("JPEG", "a"),
("LED", "an"),
("MRI", "an"),
("NATO", "an"),
("PNG", "a"),
("Q&A", "a"),
("RF", "an"),
("RNG", "an"),
("SAS", "an"),
("SMS", "an"),
("SOS", "an"),
("SQL", "an"),
("UFO", "a"),
("URL", "a"),
("VCR", "a"),
("WWW", "a"),
("X.Y.Z.", "an"),
("YAML", "a"),
// Extra tests (courtesy of LLM)
// Common English words starting with vowels
("idea","an"),
("island","an"),
("offer","an"),
("option","an"),
("operation","an"),
("appletree","an"),
("iguana","an"),
("octopus","an"),
("atom","an"),
("item","an"),
("idea", "an"),
("island", "an"),
("offer", "an"),
("option", "an"),
("operation", "an"),
("appletree", "an"),
("iguana", "an"),
("octopus", "an"),
("atom", "an"),
("item", "an"),
// Words starting with vowel but "yoo" sound (thus 'a')
("universe","a"),
("unicycle","a"),
("uniform","a"),
("union","a"),
("united","a"),
("unique","a"), // already tested, reaffirmed
("usual","a"),
("useful","a"),
("utility","a"),
("utopia","a"),
("universe", "a"),
("unicycle", "a"),
("uniform", "a"),
("union", "a"),
("united", "a"),
("unique", "a"), // already tested, reaffirmed
("usual", "a"),
("useful", "a"),
("utility", "a"),
("utopia", "a"),
// More common vowel words with a/an
("umbrella","an"), // repeated but reaffirming
("eggplant","an"),
("insect","an"),
("eleven","an"),
("olive","an"),
("impulse","an"),
("ox","an"),
("aroma","an"),
("ear","an"),
("ocean","an"),
("umbrella", "an"), // repeated but reaffirming
("eggplant", "an"),
("insect", "an"),
("eleven", "an"),
("olive", "an"),
("impulse", "an"),
("ox", "an"),
("aroma", "an"),
("ear", "an"),
("ocean", "an"),
// Words starting with 'h' but pronounced, so 'a'
("house","a"), // repeated for emphasis
("hammer","a"),
("helmet","a"),
("history","a"), // repeated
("hero","a"),
("hill","a"),
("hobby","a"),
("holiday","a"),
("harmony","a"),
("hover","a"),
("house", "a"), // repeated for emphasis
("hammer", "a"),
("helmet", "a"),
("history", "a"), // repeated
("hero", "a"),
("hill", "a"),
("hobby", "a"),
("holiday", "a"),
("harmony", "a"),
("hover", "a"),
// More silent 'h' words (already in set, but variations)
("honorific","an"),
("honorarium","an"),
("honesties","an"),
("hourly","an"),
("heirloom","an"),
("honorific", "an"),
("honorarium", "an"),
("honesties", "an"),
("hourly", "an"),
("heirloom", "an"),
// Words starting with 'e' + 'u' combo with "yoo" sound
("Europe","a"), // repeated
("European","a"), // repeated
("euphoric","a"),
("eureka","a"),
("euphemistic","a"),
("euphonious","a"),
("eucalyptus","a"), // repeated
("euthanasia","a"),
("eugenics","a"),
("Eurasia","a"),
("Europe", "a"), // repeated
("European", "a"), // repeated
("euphoric", "a"),
("eureka", "a"),
("euphemistic", "a"),
("euphonious", "a"),
("eucalyptus", "a"), // repeated
("euthanasia", "a"),
("eugenics", "a"),
("Eurasia", "a"),
// Common consonant-start words
("book","a"),
("pen","a"),
("fork","a"),
("spoon","a"),
("knife","a"),
("ball","a"),
("tree","a"),
("river","a"),
("mountain","a"),
("cloud","a"),
("book", "a"),
("pen", "a"),
("fork", "a"),
("spoon", "a"),
("knife", "a"),
("ball", "a"),
("tree", "a"),
("river", "a"),
("mountain", "a"),
("cloud", "a"),
// More vowel-start words
("ostrich","an"),
("amphibian","an"),
("eleven","an"), // repeated
("issue","an"),
("incense","an"),
("antenna","an"),
("echo","an"),
("aisle","an"),
("oracle","an"),
("overcoat","an"),
("ostrich", "an"),
("amphibian", "an"),
("eleven", "an"), // repeated
("issue", "an"),
("incense", "an"),
("antenna", "an"),
("echo", "an"),
("aisle", "an"),
("oracle", "an"),
("overcoat", "an"),
// More acronym/initialism tests:
("ATM","an"), // A = 'ay'
("EPA","an"), // E = 'ee'
("FAQ","an"), // F = 'eff', repeated as F.A.Q.
("HTML","an"), // H = 'aitch'
("IBM","an"), // I = 'eye'
("LAN","an"), // L = 'el'
("NFL","an"), // N = 'en'
("OSHA","an"), // O = 'oh'
("RAM","an"), // R = 'ar'
("SMS","an"), // repeated, S = 'ess'
("ATM", "an"), // A = 'ay'
("EPA", "an"), // E = 'ee'
("FAQ", "an"), // F = 'eff', repeated as F.A.Q.
("HTML", "an"), // H = 'aitch'
("IBM", "an"), // I = 'eye'
("LAN", "an"), // L = 'el'
("NFL", "an"), // N = 'en'
("OSHA", "an"), // O = 'oh'
("RAM", "an"), // R = 'ar'
("SMS", "an"), // repeated, S = 'ess'
// Acronyms starting with consonant sound letters
("GIF","a"), // G = 'jee', repeated
("CFO","a"), // C = 'see', repeated (consonant sound 's')
("CEO","a"), // C = 'see'
("DNA","a"), // D = 'dee' starts with 'd' consonant sound
("PGA","a"), // P = 'pee' starts with 'p' consonant sound
("QVC","a"), // Q = 'kyoo' starts with 'k' consonant sound
("TNT","a"), // T = 'tee' starts with 't' consonant sound
("UPS","a"), // U = 'yoo' sound, hence 'a'
("VIP","a"), // V = 'vee' starts with 'v' consonant sound
("WIPO","a"), // W = 'double-u' starts with 'd' consonant sound
("GIF", "a"), // G = 'jee', repeated
("CFO", "a"), // C = 'see', repeated (consonant sound 's')
("CEO", "a"), // C = 'see'
("DNA", "a"), // D = 'dee' starts with 'd' consonant sound
("PGA", "a"), // P = 'pee' starts with 'p' consonant sound
("QVC", "a"), // Q = 'kyoo' starts with 'k' consonant sound
("TNT", "a"), // T = 'tee' starts with 't' consonant sound
("UPS", "a"), // U = 'yoo' sound, hence 'a'
("VIP", "a"), // V = 'vee' starts with 'v' consonant sound
("WIPO", "a"), // W = 'double-u' starts with 'd' consonant sound
// More tricky 'u' words with 'yoo' sound for 'a'
("unify","a"),
("unilateral","a"),
("ubiquitous","a"), // 'yoo-bik...'
("usurp","a"),
("usuary","a"), // 'yoo-zhoo-ary' (rare, but treat like usual)
("uterus","a"), // 'yoo-terus'
("usher","an"), // 'uh-sher' vowel sound
("ugly","an"), // repeated, 'uh-glee'
("upper","an"), // 'uh-pur' (vowel sound but actually 'uh' sound = 'an'? Actually "upper" starts with a simple vowel sound 'uh', so should it be 'an'? It's commonly "an upper hand".
("update","an"), // 'up-date' starts with 'uh' vowel sound → 'an update' normally. Actually we say "an update" commonly. Correcting to 'an':
("unify", "a"),
("unilateral", "a"),
("ubiquitous", "a"), // 'yoo-bik...'
("usurp", "a"),
("usuary", "a"), // 'yoo-zhoo-ary' (rare, but treat like usual)
("uterus", "a"), // 'yoo-terus'
("usher", "an"), // 'uh-sher' vowel sound
("ugly", "an"), // repeated, 'uh-glee'
("upper", "an"), // 'uh-pur' (vowel sound but actually 'uh' sound = 'an'? Actually "upper" starts with a simple vowel sound 'uh', so should it be 'an'? It's commonly "an upper hand".
("update", "an"), // 'up-date' starts with 'uh' vowel sound → 'an update' normally. Actually we say "an update" commonly. Correcting to 'an':
// Words starting with 'u' that actually take "an"
// (because they start with a vowel sound 'uh'):
("under","an"),
("understand","an"),
("unusual","an"),
("unreal","an"),
("unemployed","an"),
("unequal","an"),
("unopened","an"),
("unarmed","an"),
("uneasy","an"),
("united","a"), // 'yoo-nited' is 'a united front'
("universal","a"),
("umbrella","an"), // repeated
("upset","an"), // 'uh-pset' vowel start
("under", "an"),
("understand", "an"),
("unusual", "an"),
("unreal", "an"),
("unemployed", "an"),
("unequal", "an"),
("unopened", "an"),
("unarmed", "an"),
("uneasy", "an"),
("united", "a"), // 'yoo-nited' is 'a united front'
("universal", "a"),
("umbrella", "an"), // repeated
("upset", "an"), // 'uh-pset' vowel start
// More vowel words to ensure coverage:
("animal","an"),
("image","an"),
("order","an"),
("arrow","an"),
("ace","an"),
("acre","an"),
("agent","an"),
("artist","an"),
("idea","an"), // repeated
("aim","an"),
("item","an"), // repeated
("isotope","an"),
("opera","an"),
("animal", "an"),
("image", "an"),
("order", "an"),
("arrow", "an"),
("ace", "an"),
("acre", "an"),
("agent", "an"),
("artist", "an"),
("idea", "an"), // repeated
("aim", "an"),
("item", "an"), // repeated
("isotope", "an"),
("opera", "an"),
// Words starting with vowels but pronounced with consonant sound 'y' → 'a'
("euphemistic","a"), // repeated
("euphoric","a"),
("eulogy","a"), // repeated
("Europe","a"), // repeated
("European","a"), // repeated
("eugenics","a"), // repeated
("euphemism","a"), // repeated
("eureka","a"), // repeated
("euphonious","a"),
("Eurasia","a"),
("euphemistic", "a"), // repeated
("euphoric", "a"),
("eulogy", "a"), // repeated
("Europe", "a"), // repeated
("European", "a"), // repeated
("eugenics", "a"), // repeated
("euphemism", "a"), // repeated
("eureka", "a"), // repeated
("euphonious", "a"),
("Eurasia", "a"),
// Common consonant-start words:
("milk","a"),
("road","a"),
("stone","a"),
("book","a"), // repeated
("pen","a"), // repeated
("fork","a"), // repeated
("spoon","a"), // repeated
("knife","a"), // 'knife' actually starts with /n/ sound because 'k' is silent. "a knife" or "an knife"? It's "a knife" (starts with 'n' consonant sound?), actually 'kn' in 'knife' is silent, so 'knife' is pronounced 'nife' with a consonant sound 'n', so "a knife" is correct.
("glass","a"),
("window","a"),
("milk", "a"),
("road", "a"),
("stone", "a"),
("book", "a"), // repeated
("pen", "a"), // repeated
("fork", "a"), // repeated
("spoon", "a"), // repeated
("knife", "a"), // 'knife' actually starts with /n/ sound because 'k' is silent. "a knife" or "an knife"? It's "a knife" (starts with 'n' consonant sound?), actually 'kn' in 'knife' is silent, so 'knife' is pronounced 'nife' with a consonant sound 'n', so "a knife" is correct.
("glass", "a"),
("window", "a"),
// Final checks with tricky silent letters:
("gnome","a"), // 'g' silent, pronounced 'nome' with 'n' consonant sound → 'a gnome'
("gnat","a"), // 'nat' consonant sound → 'a gnat'
("xylophone","a"), // 'zylophone' → 'z' consonant sound → 'a xylophone'
("xenon","a"), // 'zee-non' consonant sound 'z' → 'a xenon'
("honorific","an"), // repeated but reaffirming
("hourly","an"), // repeated but reaffirming
("honorably","an"),
("honorifics","an"),
("honors","an"),
("gnome", "a"), // 'g' silent, pronounced 'nome' with 'n' consonant sound → 'a gnome'
("gnat", "a"), // 'nat' consonant sound → 'a gnat'
("xylophone", "a"), // 'zylophone' → 'z' consonant sound → 'a xylophone'
("xenon", "a"), // 'zee-non' consonant sound 'z' → 'a xenon'
("honorific", "an"), // repeated but reaffirming
("hourly", "an"), // repeated but reaffirming
("honorably", "an"),
("honorifics", "an"),
("honors", "an"),
)
#for (word, article) in tests {
let chosen = __determine_article(word)
if chosen != article {
panic("bad choice! word: " + word + ", article: " + article + ", chosen: " + chosen)
panic(
"bad choice! word: "
+ word
+ ", article: "
+ article
+ ", chosen: "
+ chosen,
)
}
}
+34 -25
View File
@@ -5,20 +5,24 @@
short: "HTML",
long: "Hypertext Markup Language",
description: "A standard language for creating web pages",
group: "Web"),
group: "Web",
),
css: (
short: "CSS",
long: "Cascading Style Sheets",
description: "A language used for describing the presentation of a document",
group: "Web"),
group: "Web",
),
tps: (
short: "TPS",
long: "test procedure specification",
description: "A document on how to run all the test procedures"),
description: "A document on how to run all the test procedures",
),
concise: "Concise syntax!",
shortonly: (
short: "shortonly!!!"),
unused: "Unused term, which shouldn't print in the glossary."
short: "shortonly!!!",
),
unused: "Unused term, which shouldn't print in the glossary.",
)
#set page(width: 6.5in, height: auto, margin: 1em)
@@ -26,23 +30,21 @@
#let test-content = {
table(
columns: 3,
table.header(
[`short`], [`long`], [`both`],
),
table.header([`short`], [`long`], [`both`]),
[@html:short], [@html:long], [@html:both],
[@css:short], [@css:long], [@css:both],
[@tps:short], [@tps:long], [@tps:both:nouse],
[@concise:short], [@concise:long], [@concise:both],
[@html:short], [@html:long], [@html:both],
[@css:short], [@css:long], [@css:both],
[@tps:short], [@tps:long], [@tps:both:nouse],
[@concise:short], [@concise:long], [@concise:both],
[@shortonly:short], [@shortonly:long], [@shortonly:both],
table.hline(stroke: 2pt),
[@html:short:cap], [@html:long:cap], [@html:both:cap],
[@a:css:short], [@a:css:long], [@a:css:both],
[@tps:short:pl], [@tps:long:pl], [@tps:both:nouse:pl],
[@concise:a:cap:short], [@concise:a:cap:long], [@concise:a:cap:both],
[@an:shortonly:short], [@an:shortonly:long], [@an:shortonly:both],
[@html:short:cap], [@html:long:cap], [@html:both:cap],
[@a:css:short], [@a:css:long], [@a:css:both],
[@tps:short:pl], [@tps:long:pl], [@tps:both:nouse:pl],
[@concise:a:cap:short], [@concise:a:cap:long], [@concise:a:cap:both],
[@an:shortonly:short], [@an:shortonly:long], [@an:shortonly:both],
)
[@a:tps:cap is @tps:def.]
@@ -54,7 +56,7 @@
if mode == "short" {
short-form
} else if mode == "long" {
long-form
long-form
} else {
long-form + " (" + short-form + ")"
}
@@ -79,7 +81,7 @@
// ---------------------------------------------------------------------------------
#let format-uppercase-short(mode, short-form, long-form) = {
let short-up = upper(short-form);
let short-up = upper(short-form)
if mode == "short" {
short-up
} else if mode == "long" {
@@ -108,8 +110,8 @@
// ---------------------------------------------------------------------------------
#let format-conditional-separator(mode, short-form, long-form) = {
let separator = if short-form.len() > 4 { " / " } else { ", " };
let has_long = long-form != none and long-form != "";
let separator = if short-form.len() > 4 { " / " } else { ", " }
let has_long = long-form != none and long-form != ""
if mode == "short" {
short-form
@@ -124,7 +126,10 @@
}
}
#init-glossary(myGlossary, format-term: format-conditional-separator)[#test-content]
#init-glossary(
myGlossary,
format-term: format-conditional-separator,
)[#test-content]
// ---------------------------------------------------------------------------------
// 1. Braces and Labels
@@ -145,7 +150,9 @@
// 2. Mode-Based Prefix
// Idea: Add a prefix indicating the mode, and then show the term(s).
#let format-mode-prefix(mode, short-form, long-form) = {
let prefix = if mode == "short" { "S:" } else if mode == "long" { "L:" } else { "B:" };
let prefix = if mode == "short" { "S:" } else if mode == "long" {
"L:"
} else { "B:" }
if mode == "short" {
prefix + short-form
} else if mode == "long" {
@@ -161,7 +168,7 @@
// 3. Conditional Fallback for Missing Long
// Idea: If no long-form is provided, use the short-form in all cases.
#let format-fallback-long(mode, short-form, long-form) = {
let has_long = long-form != none and long-form != "";
let has_long = long-form != none and long-form != ""
if mode == "short" {
short-form
} else if mode == "long" {
@@ -193,7 +200,9 @@
// Idea: In both mode, append the length of each string.
#let format-length-info(mode, short-form, long-form) = {
let s_len = str(short-form.len())
let l_len = if long-form != none and long-form != "" { str(long-form.len()) } else { "0" }
let l_len = if long-form != none and long-form != "" {
str(long-form.len())
} else { "0" }
if mode == "short" {
short-form + " [len:" + s_len + "]"
+2 -2
View File
@@ -19,7 +19,7 @@
This should be a link, too: @WWW
#glossary()
]
],
)
// -----------------------------------------------------------------------------
@@ -41,5 +41,5 @@
This should be a link, too: @ML
#print-glossary(entry-list)
]
],
)
+6 -6
View File
@@ -12,22 +12,22 @@ Reference: @pbr, @zbuffer
]
#t("abbreviations") // "string" : str
#t(("abbreviations")) // ("string") : str
#t("abbreviations") // ("string") : str
#t(("abbreviations",)) // ("string",) : array(str)
#t(("abbreviations","abbreviations")) // ("string","string",) : array(str)
#t(("abbreviations", "abbreviations")) // ("string","string",) : array(str)
#pagebreak(weak: true)
#t("") // empty string should be the empty group
#t(("")) // empty string should be the empty group
#t("") // empty string should be the empty group
#t(("",)) // empty string should be the empty group
#t(("","")) // empty string should be the empty group
#t(("", "")) // empty string should be the empty group
#pagebreak(weak: true)
#t(none) // none should be all groups
#t((none)) // none should be all groups
#t(none) // none should be all groups
#pagebreak(weak: true)
#t(("abbreviations",none)) // try to get both groups
#t(("abbreviations", none)) // try to get both groups
+7 -4
View File
@@ -5,17 +5,20 @@
short: "HTML",
long: "Hypertext Markup Language",
description: "A standard language for creating web pages",
group: "Web"),
group: "Web",
),
css: (
short: "CSS",
long: "Cascading Style Sheets",
description: "A language used for describing the presentation of a document",
group: "Web"),
group: "Web",
),
tps: (
short: "TPS",
long: "test procedure specification",
description: "A document on how to run all the test procedures"),
unused: "Unused term, which shouldn't print in the glossary."
description: "A document on how to run all the test procedures",
),
unused: "Unused term, which shouldn't print in the glossary.",
)
#show: init-glossary.with(myGlossary)
+1 -1
View File
@@ -1,4 +1,4 @@
#import "/lib.typ":*
#import "/lib.typ": *
#show: init-glossary.with(yaml("glossary.yml"))
+4 -4
View File
@@ -2,10 +2,10 @@
// Our test glossary
#show: init-glossary.with((
Normal: "this is a normal term",
NoRef: "this term is noref'd",
NoIndex: "this term is noindex'd",
NoRefNoIndex: "this term is noref'd and noindex'd",
Normal: "this is a normal term",
NoRef: "this term is noref'd",
NoIndex: "this term is noindex'd",
NoRefNoIndex: "this term is noref'd and noindex'd",
))
// Configure styling
+7 -4
View File
@@ -5,17 +5,20 @@
short: "HTML",
long: "Hypertext Markup Language",
description: "A standard language for creating web pages",
group: "Web"),
group: "Web",
),
css: (
short: "CSS",
long: "Cascading Style Sheets",
description: "A language used for describing the presentation of a document",
group: "Web"),
group: "Web",
),
tps: (
short: "TPS",
long: "test procedure specification",
description: "A document on how to run all the test procedures"),
unused: "Unused term, which shouldn't print in the glossary."
description: "A document on how to run all the test procedures",
),
unused: "Unused term, which shouldn't print in the glossary.",
)
#show: init-glossary.with(myGlossary)
+1 -1
View File
@@ -20,7 +20,7 @@
tps: (
short: "TPS",
long: "test procedure specification",
description: "A document on how to run all the test procedures"
description: "A document on how to run all the test procedures",
),
)
+5 -5
View File
@@ -294,11 +294,11 @@
if result != expected {
panic(
"Pluralization failed for: "
+ (if singular == none { "none" } else { str(singular) })
+ ". Expected: "
+ (if expected == none { "none" } else { str(expected) })
+ ", got: "
+ (if result == none { "none" } else { str(result) })
+ (if singular == none { "none" } else { str(singular) })
+ ". Expected: "
+ (if expected == none { "none" } else { str(expected) })
+ ", got: "
+ (if result == none { "none" } else { str(result) }),
)
}
}
+61 -54
View File
@@ -37,79 +37,68 @@
short: "HTML",
long: "Hypertext Markup Language",
description: "A standard language for creating web pages",
group: "Web"
group: "Web",
),
css: (
short: "CSS",
long: "Cascading Style Sheets",
description: "A language used for describing the presentation of documents",
group: "Web"
group: "Web",
),
// Term with no description
js: (
short: "JS",
long: "JavaScript",
group: "Web"
group: "Web",
),
// Term with only a short field
tcp: (
short: "TCP",
group: "Networking"
group: "Networking",
),
// Term with only a long field
// should panic!
//udp: (
// long: "User Datagram Protocol",
// group: "Networking"
//),
// Term with short and description, but no long
ip: (
short: "IP",
description: "A unique identifier for a host or network interface",
group: "Networking"
group: "Networking",
),
// Term with custom articles and everything defined
api: (
short: "API",
long: "Application Programming Interface",
description: "A set of protocols and tools for building software",
article: "an", // custom article for short form
longarticle: "an", // custom article for long form
group: "Software"
article: "an", // custom article for short form
longarticle: "an", // custom article for long form
group: "Software",
),
// Term starting with a vowel, no custom article, to test default a/an logic
xml: (
short: "XML",
long: "Extensible Markup Language",
description: "A markup language defining rules for encoding documents",
group: "Data"
group: "Data",
),
// Term starting with a consonant, no custom article
cpu: (
short: "CPU",
long: "Central Processing Unit",
description: "The primary component of a computer that performs calculations",
group: "Hardware"
group: "Hardware",
),
// Term without any fields (just a string), should be handled gracefully
bare: "A bare term with no fields",
// Term with only description
// should panic!
//desconly: (
// description: "Just a description, no short or long",
// group: "Misc"
//),
// Term with article fields but missing short and long (should test fallback)
// should panic!
//articonly: (
@@ -118,51 +107,46 @@
// description: "Has only articles and a description",
// group: "Misc"
//),
// Term with uppercase key
SSL: (
short: "SSL",
long: "Secure Sockets Layer",
description: "A protocol for encrypting information over the internet",
group: "Security"
group: "Security",
),
// Term that will not be referenced
unusedterm: (
short: "UNUSED",
long: "Unused Term",
description: "Should not appear since it's never referenced"
description: "Should not appear since it's never referenced",
),
// Term that tests pluralization with custom fields maybe
doc: (
short: "doc",
long: "document",
description: "A single piece of written matter",
group: "Misc"
group: "Misc",
),
// Terms that might require checking conflicting modifiers
tps: (
short: "TPS",
long: "test procedure specification",
description: "A document describing test procedures",
group: "Testing"
group: "Testing",
),
// Term that might appear multiple times
http: (
short: "HTTP",
long: "Hypertext Transfer Protocol",
description: "A protocol for distributed, collaborative, hypermedia information systems",
group: "Web"
)
group: "Web",
),
)
// Initialize the glossary with a custom show-term callback
#show: init-glossary.with(
exhaustiveGlossary,
show-term: (body) => [#strong(body)]
show-term: body => [#strong(body)],
)
#set heading(numbering: "1.1")
@@ -294,8 +278,15 @@ This document tries all reference forms and modifiers on a large set of terms.
== Conflicting multiple modifiers combined (short, long, both together)
Assert that a panic occurs.
#import "/src/gloss.typ": __gls, __default-format-term
#let manual-gls(key, mods) = __gls(key, modes-modifiers: mods, format-term: __default-format-term, show-term: (body) => [#strong(body)], term-links: false, display-text: none)
#import "/src/gloss.typ": __default-format-term, __gls
#let manual-gls(key, mods) = __gls(
key,
modes-modifiers: mods,
format-term: __default-format-term,
show-term: body => [#strong(body)],
term-links: false,
display-text: none,
)
//- @tps:short:long
#assert-panic(manual-gls.with("tps", ("short", "long")))
//- @tps:short:both
@@ -348,19 +339,19 @@ Assert that a panic occurs.
#table(
columns: 3,
table.header([*Input*],[*Output*],[*Comment*]),
[`@api` ], [@api], ["default"],
[`@api:short` ], [@api:short], ["short only"],
[`@api:long` ], [@api:long], ["long only"],
[`@api:both` ], [@api:both], ["both"],
[`@api:def` ], [@api:def], ["definition (long)"],
[`@api:desc` ], [@api:desc], ["description"],
[`@a:api` ], [@a:api], ["article before key"],
[`@api:a` ], [@api:a], ["article after key"],
[`@api:cap` ], [@api:cap], ["capitalize"],
[`@api:pl` ], [@api:pl], ["plural"],
[`@api:long:cap`], [@api:long:cap],["long + cap"],
[`@api:both:pl` ], [@api:both:pl], ["both + pl"]
table.header([*Input*], [*Output*], [*Comment*]),
[`@api` ], [@api], ["default"],
[`@api:short` ], [@api:short], ["short only"],
[`@api:long` ], [@api:long], ["long only"],
[`@api:both` ], [@api:both], ["both"],
[`@api:def` ], [@api:def], ["definition (long)"],
[`@api:desc` ], [@api:desc], ["description"],
[`@a:api` ], [@a:api], ["article before key"],
[`@api:a` ], [@api:a], ["article after key"],
[`@api:cap` ], [@api:cap], ["capitalize"],
[`@api:pl` ], [@api:pl], ["plural"],
[`@api:long:cap`], [@api:long:cap], ["long + cap"],
[`@api:both:pl` ], [@api:both:pl], ["both + pl"],
)
== Multiple glossaries with themes and group filtering
@@ -377,25 +368,41 @@ Assert that a panic occurs.
== Networking Only
#glossary(title: "Networking Terms", groups: ("Networking",), theme: theme-basic)
#glossary(
title: "Networking Terms",
groups: ("Networking",),
theme: theme-basic,
)
== Misc and Data
#glossary(title: "Misc & Data", groups: ("Misc","Data"), theme: theme-basic)
#glossary(title: "Misc & Data", groups: ("Misc", "Data"), theme: theme-basic)
== Just Testing terms
#glossary(title: "Testing Terms", groups: ("Testing",), theme: theme-chicago-index)
#glossary(
title: "Testing Terms",
groups: ("Testing",),
theme: theme-chicago-index,
)
== Hardware group
#glossary(title: "Hardware Terms", groups: ("Hardware",), theme: theme-chicago-index)
#glossary(
title: "Hardware Terms",
groups: ("Hardware",),
theme: theme-chicago-index,
)
== Unreferenced entries
#glossary(title: "Unreferenced (Should Contain Unused?)", groups: ("Security",), theme: theme-chicago-index)
#glossary(
title: "Unreferenced (Should Contain Unused?)",
groups: ("Security",),
theme: theme-chicago-index,
)
== Empty group glossary
#glossary(title: "Empty Group Glossary", groups: (""), theme: theme-basic)
#glossary(title: "Empty Group Glossary", groups: "", theme: theme-basic)
= End of Brutal Test
+15 -12
View File
@@ -2,14 +2,14 @@
// Our test glossary
#show: init-glossary.with((
ShortInHeader: "short used in header",
ShortInCaption: "short used in caption",
LongInHeader: "long used in header",
LongInCaption: "long used in caption",
BothInHeader: "both used in header",
BothInCaption: "both used in caption",
NormalInHeader: "unmodified use in header",
NormalInCaption: "unmodified use in caption",
ShortInHeader: "short used in header",
ShortInCaption: "short used in caption",
LongInHeader: "long used in header",
LongInCaption: "long used in caption",
BothInHeader: "both used in header",
BothInCaption: "both used in caption",
NormalInHeader: "unmodified use in header",
NormalInCaption: "unmodified use in caption",
))
// Configure styling
@@ -21,11 +21,11 @@
// Outlines
#outline(title:"Table of Contents", indent: auto)
#outline(title: "Table of Contents", indent: auto)
#outline(title: "List of Figures", target: figure.where(kind: image))
#block(
height:7em,
glossary(title: "List of Abbreviations", theme: theme-twocol)
height: 7em,
glossary(title: "List of Abbreviations", theme: theme-twocol),
)
#line(length: 100%)
@@ -47,7 +47,10 @@
#figure([], caption: [`@ShortInCaption:short` = "@ShortInCaption:short"])
#figure([], caption: [`@LongInCaption:long` = "@LongInCaption:long"])
#figure([], caption: [`@BothInCaption:both:nospend` = "@BothInCaption:both:nospend"])
#figure(
[],
caption: [`@BothInCaption:both:nospend` = "@BothInCaption:both:nospend"],
)
#figure([], caption: [`@NormalInCaption` = "@NormalInCaption"])
#line(length: 100%)
+4 -4
View File
@@ -2,7 +2,7 @@
#show: init-glossary.with((
one: "this is term one",
two: "term two also"
two: "term two also",
))
#set page(
@@ -19,15 +19,15 @@ shown anyway.
#glossary(
theme: theme-chicago-index,
show-all: true
show-all: true,
)
#glossary(
theme: theme-compact,
show-all: true
show-all: true,
)
#glossary(
theme: theme-table,
show-all: true
show-all: true,
)
+2 -2
View File
@@ -22,11 +22,11 @@
tps: (
short: "TPS",
long: "test procedure specification",
description: "A document on how to run all the test procedures"
description: "A document on how to run all the test procedures",
),
)
#show: init-glossary.with(myGlossary, show-term: (body) => [#emph(body)])
#show: init-glossary.with(myGlossary, show-term: body => [#emph(body)])
#set page(numbering: "1")
+6 -6
View File
@@ -8,7 +8,7 @@
),
iphone: (
short: "iPhone",
description: "Revolutionized phones."
description: "Revolutionized phones.",
),
css: (
short: "CSS",
@@ -21,11 +21,11 @@
tps: (
short: "TPS",
long: "test procedure specification",
description: "A document on how to run all the test procedures"
description: "A document on how to run all the test procedures",
),
)
#show: init-glossary.with(myGlossary, show-term: (body) => [#emph(body)])
#show: init-glossary.with(myGlossary, show-term: body => [#emph(body)])
#set page(
margin: 1cm,
@@ -35,7 +35,7 @@
#text(size: 24pt, weight: "bold")[`glossy`: theme gallery]
#text(size: 1pt, fill: rgb(0,0,0,0))[
#text(size: 1pt, fill: rgb(0, 0, 0, 0))[
First, we refer to each term at least once so they'll actually show up in the
glossaries. Our terms include: @atom, @iphone, @html:cap, @css, and @tps.
]
@@ -48,8 +48,8 @@
width: 100%,
spacing: 2em,
inset: 1em,
stroke: 1pt+gray,
stroke: 1pt + gray,
height: if theme.first() == "theme-twocol" { 1.5in } else { auto },
glossary(title: raw(theme.first()), theme: theme.last(), ignore-case: true)
glossary(title: raw(theme.first()), theme: theme.last(), ignore-case: true),
)
}
+1 -1
View File
@@ -1,4 +1,4 @@
#import "/lib.typ":*
#import "/lib.typ": *
#set text(lang: "cs", region: "CZ")