Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7117a1e60f
|
||
|
|
9be60483a5 | ||
|
|
214a956f42 | ||
|
|
eebb2a9d7e | ||
|
|
c179c25fe9 | ||
|
|
d90cdc1894 | ||
|
|
f0961eeb8b | ||
|
|
7d40e146fb | ||
|
|
8f3ef0d1d0
|
||
|
|
4e4e93e096
|
||
|
|
5b0bdf333f
|
||
|
|
a903bf0fc8
|
||
|
|
ee570f7487
|
||
|
|
ef03fdfbc4
|
No files matched your search
@@ -41,7 +41,7 @@ different goals:
|
||||
### Import the package
|
||||
|
||||
```typst
|
||||
#import "@preview/glossy:0.5.2": *
|
||||
#import "@preview/glossy:0.7.0": *
|
||||
```
|
||||
|
||||
### Defining Glossary Terms
|
||||
@@ -143,6 +143,7 @@ Available modifiers:
|
||||
- **short**: Shows only short form
|
||||
- **long**: Shows only long form
|
||||
- **def** or **desc**: Shows the description
|
||||
- **noref** or **noindex**: Don't show the term in the glossary.
|
||||
- **a** or **an**: Include the article (`an` is just an alias of `a`, they're
|
||||
equivalent)
|
||||
|
||||
@@ -160,6 +161,9 @@ Modifiers can be combined with colons:
|
||||
| `@tps:short:pl` | "TPSes" |
|
||||
| `@tps:both:pl:cap` | "Technical procedure specifications (TPSes)" |
|
||||
| `@tps:def` | "A formal document describing test steps and expected results" |
|
||||
| `@tps:desc` | _same as above, `desc` is an alias for `def`_ |
|
||||
| `@tps:noref` | _works as normal, just won't show up in glossary_ |
|
||||
| `@tps:noindex` | _same as above, `noindex` is an alias for `noref`_ |
|
||||
|
||||
The `a`/`an` modifier is special because it can either precede or follow the
|
||||
term's key.
|
||||
@@ -180,6 +184,18 @@ For example:
|
||||
Note that the `a`/`an` (article) modifier cannot be combined with the `pl`
|
||||
(plural) modifier.
|
||||
|
||||
### First use logic
|
||||
|
||||
Any use of the `short`, `long`, or `both` modifier will not count against the
|
||||
term's first use.
|
||||
|
||||
This is useful, for example, when you want to use a term in a heading or a
|
||||
caption. In that case, your term might end up in an `outline()` at the top of
|
||||
your document. Normally you don't want that to count as a term's first real use.
|
||||
Normally you want that to happen in the body of your document. So, by using
|
||||
these modifiers in such situations, you can not only specify exactly how you
|
||||
want your term to appear, but also control whether it counts as a "first use".
|
||||
|
||||
### Generating the Glossary
|
||||
|
||||
Display the glossary using the `glossary()` function:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#import "@preview/valkyrie:0.2.1" as z
|
||||
#import "@preview/valkyrie:0.2.2" as z
|
||||
|
||||
#import "./schemas.typ": *
|
||||
#import "./themes.typ": *
|
||||
@@ -7,6 +7,7 @@
|
||||
#let __gloss_entries = state("__gloss_entries", (:))
|
||||
|
||||
#let __gloss_label_prefix = "__gloss:"
|
||||
#let __gloss_first_use_counter_postfix = ":first-use-count"
|
||||
|
||||
// Normalizes a dictionary entry by ensuring all required and optional keys exist
|
||||
// with appropriate default values.
|
||||
@@ -38,7 +39,7 @@
|
||||
if not "short" in entry {
|
||||
panic("Entry must contain a 'short' key")
|
||||
}
|
||||
if type(entry.short) != "string" {
|
||||
if type(entry.short) != str {
|
||||
panic("Entry 'short' must be a string")
|
||||
}
|
||||
if entry.short.trim() == "" {
|
||||
@@ -129,11 +130,14 @@
|
||||
// Returns:
|
||||
// none: Updates state as a side effect
|
||||
//
|
||||
#let __mark_term_used(key) = {
|
||||
#let __mark_term_used(key, count-as-first-use) = {
|
||||
counter(__gloss_label_prefix + key).step()
|
||||
if count-as-first-use {
|
||||
counter(__gloss_label_prefix + key + __gloss_first_use_counter_postfix).step()
|
||||
}
|
||||
}
|
||||
|
||||
// Queries the term usage
|
||||
// Queries whether the term is used ANYWHERE
|
||||
//
|
||||
// Parameters:
|
||||
// key (string): The glossary entry key
|
||||
@@ -142,12 +146,29 @@
|
||||
// Returns:
|
||||
// boolean: If the entry is used above the location in the document
|
||||
//
|
||||
#let __is_term_used(key, location: none) = {
|
||||
#let __is_term_ever_used(key, location: none) = {
|
||||
let c = counter(__gloss_label_prefix + key)
|
||||
c = if location == none {c.final()} else {c.at(location)}
|
||||
c.at(0) > 0
|
||||
}
|
||||
|
||||
// Queries whether the term has been "first used"
|
||||
//
|
||||
// "First used" is used to determine how to display the term, either "long
|
||||
// (short)" or just "(short)"
|
||||
//
|
||||
// Parameters:
|
||||
// key (string): The glossary entry key
|
||||
// location (location): The location in the document. Use none for end of document
|
||||
//
|
||||
// Returns:
|
||||
// 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)}
|
||||
c.at(0) > 0
|
||||
}
|
||||
|
||||
// Determine if the glossary contains a visible entry
|
||||
//
|
||||
@@ -216,8 +237,12 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// Manage term usage counting and determine if it's the first reference
|
||||
// ---------------------------------------------------------------------------
|
||||
let is_first_use = not __is_term_used(key, location: here())
|
||||
__mark_term_used(key)
|
||||
let is_first_use = not __is_term_first_used(key, location: here())
|
||||
let count-as-first-use = ("short" not in modifiers and "long" not in modifiers and "both" not in modifiers)
|
||||
let wants_reference = ("noref" not in modifiers and "noindex" not in modifiers)
|
||||
if wants_reference {
|
||||
__mark_term_used(key, count-as-first-use)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Helper Functions
|
||||
@@ -322,7 +347,7 @@
|
||||
|
||||
// Apply format-term() to get the term
|
||||
let formatted-term = format-term(mode, short-form, long-form)
|
||||
if type(formatted-term) != "string" {
|
||||
if type(formatted-term) != str {
|
||||
// This is because we still need to capitalize the term, and we cannot do
|
||||
// that with content, thus requiring a string here.
|
||||
// TODO: consider if we want to capitalize *before* this. First intuition is
|
||||
@@ -342,15 +367,20 @@
|
||||
} else {
|
||||
term
|
||||
}
|
||||
[#article#show-term(linked-term)#metadata(term)#__term_label(key)]
|
||||
// |^^^^^^^|^^^^^^^^^ |^^^^^^^^ |^^^^^^^^^^^^
|
||||
// \_art. | | |
|
||||
let term-label = if wants_reference {
|
||||
__term_label(key)
|
||||
} else {
|
||||
[]
|
||||
}
|
||||
[#article#show-term(linked-term)#metadata(term)#term-label]
|
||||
// |^^^^^^^|^^^^^^^^^ |^^^^^^^^ |^^^^^^^^^^^^
|
||||
// \_art. | | |
|
||||
// \_ apply user formatting function to the term
|
||||
// | |
|
||||
// \_ metadata lets us label (ie it's "labelable")
|
||||
// |
|
||||
// \_ i.e. <__gloss:key>, etc.
|
||||
// for backlink from glossary
|
||||
// | |
|
||||
// \_ metadata lets us label (ie makes it "labelable")
|
||||
// |
|
||||
// \_ i.e. <__gloss:key>, etc.
|
||||
// for backlink from glossary
|
||||
}
|
||||
}
|
||||
|
||||
@@ -554,7 +584,7 @@
|
||||
// Collect and organize entries by group
|
||||
let output = (:)
|
||||
let all_entries = __gloss_entries.final()
|
||||
let all_used = all_entries.keys().filter(key => __is_term_used(key))
|
||||
let all_used = all_entries.keys().filter(key => __is_term_ever_used(key))
|
||||
|
||||
// Determine which groups to process
|
||||
let all_groups = all_entries
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#import "@preview/valkyrie:0.2.1" as z
|
||||
#import "@preview/valkyrie:0.2.2" as z
|
||||
|
||||
#let dict-schema = z.either(
|
||||
z.string(),
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Inspired by academic textbook glossaries
|
||||
#let theme-academic = (
|
||||
section: (title, body) => {
|
||||
set text(font: "New Computer Modern")
|
||||
heading(level: 1, title)
|
||||
v(1em)
|
||||
body
|
||||
|
||||
|
Before Width: | Height: | Size: 479 KiB After Width: | Height: | Size: 489 KiB |
|
Before Width: | Height: | Size: 844 KiB After Width: | Height: | Size: 884 KiB |
@@ -47,6 +47,8 @@ Now make sure I get @tps:a:SHORT report by 2pm! @an:tps:cap is very important!!!
|
||||
[`@tps:both:pl:cap`], [@tps:both:pl:cap],
|
||||
[`@tps:def` ], [@tps:def],
|
||||
[`@tps:desc` ], [@tps:desc],
|
||||
[`@tps:noref` ], [@tps:noref *(not listed in glossary)*],
|
||||
[`@tps:noindex` ], [@tps:noindex *(not listed in glossary)*],
|
||||
)
|
||||
|
||||
== Adding articles via `a`/`an` modifiers
|
||||
|
||||
|
Before Width: | Height: | Size: 2.5 MiB After Width: | Height: | Size: 2.5 MiB |
|
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 98 KiB |
@@ -1,5 +1,5 @@
|
||||
#import "/lib.typ": *
|
||||
#import "@preview/glossarium:0.5.1": *
|
||||
#import "@preview/glossarium:0.5.3": *
|
||||
|
||||
#set page(height: auto, width: 4.5in)
|
||||
#show link: set text(fill: red)
|
||||
|
||||
|
Before Width: | Height: | Size: 197 KiB After Width: | Height: | Size: 195 KiB |
|
Before Width: | Height: | Size: 141 KiB After Width: | Height: | Size: 139 KiB |
|
Before Width: | Height: | Size: 129 KiB After Width: | Height: | Size: 127 KiB |
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 184 KiB After Width: | Height: | Size: 179 KiB |
|
After Width: | Height: | Size: 55 KiB |
@@ -0,0 +1,26 @@
|
||||
#import "/lib.typ": *
|
||||
|
||||
// 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",
|
||||
))
|
||||
|
||||
// Configure styling
|
||||
|
||||
#set page(margin: 1em)
|
||||
#set page(width: 3.5in)
|
||||
#set page(height: auto)
|
||||
#set text(size: 10pt)
|
||||
|
||||
@Normal
|
||||
|
||||
@NoRef:noref
|
||||
|
||||
@NoIndex:noindex
|
||||
|
||||
@NoRefNoIndex:noref:noindex
|
||||
|
||||
#glossary()
|
||||
|
After Width: | Height: | Size: 674 KiB |
@@ -0,0 +1,82 @@
|
||||
#import "/lib.typ": *
|
||||
|
||||
// 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",
|
||||
))
|
||||
|
||||
// Configure styling
|
||||
|
||||
#set page(numbering: "1")
|
||||
#set page(margin: 0.5in)
|
||||
#set page(height: auto)
|
||||
#set text(size: 10pt)
|
||||
|
||||
// Outlines
|
||||
|
||||
#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)
|
||||
)
|
||||
|
||||
#line(length: 100%)
|
||||
|
||||
// Doc Body
|
||||
|
||||
// Use all the terms in headings
|
||||
#heading(level: 1, outlined: false, [Use terms in HEADERS])
|
||||
|
||||
=== `@ShortInHeader:short` = "@ShortInHeader:short"
|
||||
=== `@LongInHeader:long` = "@LongInHeader:long"
|
||||
=== `@BothInHeader:both` = "@BothInHeader:both"
|
||||
=== `@NormalInHeader` = "@NormalInHeader"
|
||||
|
||||
#line(length: 100%)
|
||||
|
||||
// Use all the terms in captions
|
||||
#heading(level: 1, outlined: false, [Use terms in CAPTIONS])
|
||||
|
||||
#figure([], caption: [`@ShortInCaption:short` = "@ShortInCaption:short"])
|
||||
#figure([], caption: [`@LongInCaption:long` = "@LongInCaption:long"])
|
||||
#figure([], caption: [`@BothInCaption:both` = "@BothInCaption:both"])
|
||||
#figure([], caption: [`@NormalInCaption` = "@NormalInCaption"])
|
||||
|
||||
#line(length: 100%)
|
||||
|
||||
// Now use the terms in the body to see if they handle "first use" correctly
|
||||
#heading(level: 1, outlined: false, [Use terms in BODY])
|
||||
|
||||
First `@ShortInHeader` = "@ShortInHeader".
|
||||
Second `@ShortInHeader` = "@ShortInHeader"
|
||||
|
||||
First `@LongInHeader` = "@LongInHeader".
|
||||
Second `@LongInHeader` = "@LongInHeader".
|
||||
|
||||
First `@BothInHeader` = "@BothInHeader".
|
||||
Second `@BothInHeader` = "@BothInHeader".
|
||||
|
||||
First `@NormalInHeader` = "@NormalInHeader".
|
||||
Second `@NormalInHeader` = "@NormalInHeader".
|
||||
|
||||
#v(0.5em)
|
||||
|
||||
First `@ShortInCaption` = "@ShortInCaption".
|
||||
Second `@ShortInCaption` = "@ShortInCaption"
|
||||
|
||||
First `@LongInCaption` = "@LongInCaption".
|
||||
Second `@LongInCaption` = "@LongInCaption".
|
||||
|
||||
First `@BothInCaption` = "@BothInCaption".
|
||||
Second `@BothInCaption` = "@BothInCaption".
|
||||
|
||||
First `@NormalInCaption` = "@NormalInCaption".
|
||||
Second `@NormalInCaption` = "@NormalInCaption".
|
||||
|
Before Width: | Height: | Size: 651 KiB After Width: | Height: | Size: 651 KiB |
|
Before Width: | Height: | Size: 651 KiB After Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 332 KiB After Width: | Height: | Size: 117 KiB |
@@ -1,6 +1,7 @@
|
||||
[package]
|
||||
name = "glossy"
|
||||
version = "0.5.2"
|
||||
version = "0.7.0"
|
||||
compiler = "0.13.0"
|
||||
entrypoint = "lib.typ"
|
||||
authors = ["Stephen Waits <steve@waits.net>"]
|
||||
license = "MIT"
|
||||
@@ -8,4 +9,4 @@ description = "A very simple glossary system with easily customizable output."
|
||||
categories = ["model"]
|
||||
keywords = ["glossary", "index", "dictionary", "gloss"]
|
||||
repository = "https://github.com/swaits/typst-collection"
|
||||
exclude = ["thumbnail.png", "themeshots.pjng", "tests", "bin"]
|
||||
exclude = ["thumbnail.png", "themeshots.png", "tests", "bin"]
|
||||