feat(glossy): add type-checking
- adds type-checking via the valkyrie package - fixes handling of groups parameter on #glossary() - new test for relevant changes
This commit is contained in:
9 files changed
+112
-10
No files matched your search
@@ -168,6 +168,19 @@ Display the glossary using the `glossary()` function:
|
||||
)
|
||||
```
|
||||
|
||||
Note that if you want to display terms without a group, you specify that with an
|
||||
empty string. For example, to show the empty group and then the _Web_ group:
|
||||
|
||||
```typst
|
||||
#glossary(groups: ("", "Web"))
|
||||
```
|
||||
|
||||
Or to just show the empty group (i.e. terms without a group):
|
||||
|
||||
```typst
|
||||
#glossary(groups: (""))
|
||||
```
|
||||
|
||||
### Customizing Term Display
|
||||
|
||||
Control how terms appear in the document by providing a custom `show-term` function:
|
||||
|
||||
+29
-10
@@ -1,3 +1,7 @@
|
||||
// TODO: replace with @preview when back online
|
||||
#import "@preview/valkyrie:0.2.1" as z
|
||||
|
||||
#import "./schemas.typ": *
|
||||
#import "./themes.typ": *
|
||||
#import "./utils.typ": *
|
||||
|
||||
@@ -332,10 +336,15 @@
|
||||
show-term: (term-body) => term-body,
|
||||
body
|
||||
) = context {
|
||||
// Validate entries parameter type
|
||||
if type(entries) != dictionary {
|
||||
panic("entries must be a dictionary, instead got: " + repr(entries))
|
||||
// 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",))
|
||||
checked-entries.insert(checked-key, checked-entry)
|
||||
}
|
||||
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
|
||||
for (key, entry) in entries {
|
||||
@@ -396,6 +405,12 @@
|
||||
ignore-case: false,
|
||||
groups: (),
|
||||
) = context {
|
||||
// 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-theme = z.parse(theme, theme-schema, scope: ("theme",))
|
||||
|
||||
// Collect and organize entries by group
|
||||
let output = (:)
|
||||
let all_entries = __gloss_entries.final()
|
||||
@@ -405,19 +420,23 @@
|
||||
let all_groups = all_entries
|
||||
.values()
|
||||
.map(e => e.at("group"))
|
||||
.map(g => { if g == none { "" } else { g } })
|
||||
.dedup()
|
||||
.sorted()
|
||||
|
||||
let target_groups = if groups.len() == 0 {
|
||||
let target_groups = if checked-groups.len() == 0 {
|
||||
all_groups
|
||||
} else {
|
||||
// Validate requested groups exist
|
||||
for g in groups {
|
||||
for g in checked-groups {
|
||||
if g == none {
|
||||
g = ""
|
||||
}
|
||||
if g not in all_groups {
|
||||
panic("Requested group not found: " + g)
|
||||
panic("Requested group, '" + g + "', not found.")
|
||||
}
|
||||
}
|
||||
groups
|
||||
checked-groups
|
||||
}
|
||||
|
||||
// Process entries group by group
|
||||
@@ -459,15 +478,15 @@
|
||||
// Render the glossary using the theme
|
||||
let group_index = 0
|
||||
|
||||
(theme.section)(
|
||||
(checked-theme.section)(
|
||||
title,
|
||||
for (group, entries) in output {
|
||||
(theme.group)(
|
||||
(checked-theme.group)(
|
||||
group,
|
||||
group_index,
|
||||
output.len(),
|
||||
for (i, entry) in entries.enumerate() {
|
||||
(theme.entry)(entry, i, entries.len())
|
||||
(checked-theme.entry)(entry, i, entries.len())
|
||||
}
|
||||
)
|
||||
group_index += 1
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
// TODO: change to @preview when online
|
||||
#import "@preview/valkyrie:0.2.1" as z
|
||||
|
||||
#let dict-schema = z.either(
|
||||
z.string(),
|
||||
z.dictionary(
|
||||
(
|
||||
short: z.content(), // this is the only required field
|
||||
plural: z.content(optional: true),
|
||||
long: z.content(optional: true),
|
||||
longplural: z.content(optional: true),
|
||||
description: z.content(optional: true),
|
||||
group: z.content(optional: true),
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
#let theme-schema = z.dictionary(
|
||||
(
|
||||
section: z.function(),
|
||||
group: z.function(),
|
||||
entry: z.function(),
|
||||
)
|
||||
)
|
||||
|
||||
#let groups-list-schema = z.array(pre-transform: z.coerce.array)
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"zbuffer": {
|
||||
"short": "z-bufer",
|
||||
"long": "the depth buffer"
|
||||
},
|
||||
"pbr": {
|
||||
"short": "PBR",
|
||||
"long": "physically based rendering",
|
||||
"group": "abbreviations"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 184 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 132 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 118 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 76 KiB |
@@ -0,0 +1,33 @@
|
||||
#import "/lib.typ": *
|
||||
|
||||
#show: init-glossary.with(json("abbreviations.json"))
|
||||
|
||||
Reference: @pbr, @zbuffer
|
||||
|
||||
|
||||
#let t(g) = [
|
||||
#line(length: 100%)
|
||||
*TESTING:* `#glossary(groups: ` #repr(g) `)`
|
||||
#glossary(groups: g)
|
||||
]
|
||||
|
||||
#t("abbreviations") // "string" : str
|
||||
#t(("abbreviations")) // ("string") : str
|
||||
#t(("abbreviations",)) // ("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
|
||||
|
||||
#pagebreak(weak: true)
|
||||
|
||||
#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
|
||||
Reference in new issue
Block a user