Skip to content

Commit

Permalink
glossarium:0.2.4 (#236)
Browse files Browse the repository at this point in the history
  • Loading branch information
slashformotion authored Nov 16, 2023
1 parent b076a32 commit 8a99f13
Show file tree
Hide file tree
Showing 10 changed files with 448 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/preview/glossarium/0.2.4/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
glossarium.pdf
21 changes: 21 additions & 0 deletions packages/preview/glossarium/0.2.4/LICENCE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) [2023] [Enib Community]

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
124 changes: 124 additions & 0 deletions packages/preview/glossarium/0.2.4/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# Typst glossary

> Glossarium is based in great part of the work of [Sébastien d'Herbais de Thun](https://github.com/Dherse) from his master thesis available at: <https://github.com/Dherse/masterproef>. His glossary is available under the MIT license [here](https://github.com/Dherse/masterproef/blob/main/elems/acronyms.typ).
Glossarium is a simple, easily customizable typst glossary inspired by [LaTeX glossaries package](https://www.ctan.org/pkg/glossaries) . You can see an example showing the different features in [`example.typ`](example/example.typ).

![Screenshot](example/example.png)

## Manual

### Import and setup

This manual assume you have a good enough understanding of typst markup and scripting.

For Typst 0.6.0 or later import the package from the typst preview repository:

```ts
#import "@preview/glossarium:0.2.4": make-glossary, print-glossary, gls, glspl
```

For Typst before 0.6.0 or to use **glossarium** as a local module, download the package files into your project folder and import `glossarium.typ`:

```js
#import "glossarium.typ": make-glossary, print-glossary, gls, glspl
```

After importing the package and before making any calls to `gls`,` print-glossary` or `glspl`, please ***MAKE SURE*** you add this line
```js
#show: make-glossary
```

> *WHY DO WE NEED THAT ?* : In order to be able to create references to the terms in your glossary using typst ref syntax `@key` glossarium needs to setup some [show rules](https://typst.app/docs/tutorial/advanced-styling/) before any references exist. This is due to the way typst works, there is no workaround.
>
>Therefore I recommend that you always put the `#show: ...` statement on the line just below the `#import` statement.

### Printing the glossary

First we have to define the terms.
A term is a [dictionary](https://typst.app/docs/reference/types/dictionary/) composed of 2 required and 2 optional elements:

- `key` (string) *required*: used to make reference to the term.
- `short` (string) *required*: the short form of the term replacing the term citation.
- `long` (string or content) *optional*: The long form of the term, displayed in the glossary and on the first citation of the term.
- `desc` (string or content) *optional*: The description of the term.

Then the terms are passed as a list to `print-glossary`

```ts
#print-glossary((
// minimal term
(key: "kuleuven", short: "KU Leuven"),
// a term with a long form
(key: "unamur", short: "UNamur", long: "Université de Namur"),
// no long form here
(key: "kdecom", short: "KDE Community", desc:"An international team developing and distributing Open Source software."),
// a full term with description containing markup
(
key: "oidc",
short: "OIDC",
long: "OpenID Connect",
desc: [OpenID is an open standard and decentralized authentication protocol promoted by the non-profit
#link("https://en.wikipedia.org/wiki/OpenID#OpenID_Foundation")[OpenID Foundation].]),
))
```

By default, the terms that are not referenced in the document are not shown in the glossary, you can force their appearance by setting the `show-all` argument to true

You can call this function from anywhere.

### Referencing terms.

Referencing terms is done using the key of the terms using the `gls` function or the reference syntax.

```ts
// referencing the OIDC term using gls
#gls("oidc")
// displaying the long form forcibly
#gls("oidc", long: true)

// referencing the OIDC term using the reference syntax
@oidc
```

#### Handling plurals

You can use the `glspl` function and the references supplements to pluralize terms:

```ts
#glspl("oidc") // equivalent of `#gls("oidc", suffix: "s")`
// or
@oidc[s]
```

#### Overriding the text shown

You can also override the text displayed by setting the `display` argument.

```ts
#gls("oidc", display: "whatever you want")
```

## Final tips

I recommend setting a show rule for the links to that your reader understand that they can click on the references to go to the term in the glossary.

```ts
#show link: set text(fill: blue.darken(60%))
// links are now blue !
```

## Changelog

### 0.2.4

### Fixed

- Fixed a bug where the reference would a long ref even when "long" was set to false (e4644f4) by [@dscso](https://github.com/dscso)

### Changed

- The glossary appearance have been improved slightly (a1ee80e) by [@JuliDi](https://github.com/JuliDi)

### Previous versions did not have a changelog entry
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
84 changes: 84 additions & 0 deletions packages/preview/glossarium/0.2.4/example/example.typ
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#import "../glossarium.typ": make-glossary, print-glossary, gls, glspl
#show: make-glossary

#set page(numbering: "1", paper: "a5")

//I recommend setting a show rule for the links to that your reader understand that they can click on the references to go to the term in the glossary.
#show link: set text(fill: blue.darken(60%))

There are many Belgian universities, like @kuleuven and @ulb. When repeating their names, they won't show as a long version: @kuleuven, @ulb. But we can still force them to be long using the `gls` function: #gls("kuleuven", long: true). We can also force them to be short: #gls("kuleuven", long: false). Finally, we can make them plural using the `suffix` parameter: #gls("kuleuven", suffix: "s") or using the additional `supplement` onto the `ref`: @kuleuven[s]. We can also use the plural function function `#glspl(key: "kuleuven")` #glspl("kuleuven").



You can also override the text shown by setting the `display` argument: #gls("kuleuven", display: "whatever you want")


#pagebreak()

Numbering is, of course, correct when referencing the glossary: @kuleuven, @ulb, @ughent, @vub, @ulb, @umons, @uliege, @unamur. They are also sorted based on where the page is in the document and not the textual representation.

#pagebreak()

At the moment, customization is not built-in to the function and instead follows a modified version of @ughent's template. But you can easily customize it by modifying `glossary.typ`. It is short enough and well documented enough to be easily understood. Additionally, you can load data externally and pass it as a parameter to the `glossary.with` function to load data from an external format.


#pagebreak()
= Glossary
#print-glossary(
(
(
key: "kuleuven",
short: "KU Leuven",
long: "Katholieke Universiteit Leuven",
desc: [Fugiat do fugiat est minim ullamco est eu duis minim nisi tempor adipisicing do _sunt_. #gls("vub")],
),
(
key: "uclouvain",
short: "UCLouvain",
long: "Université catholique de Louvain",
desc: "Sunt pariatur deserunt irure dolore veniam voluptate cillum in. Officia nulla laborum nostrud mollit officia aliqua. Laborum tempor aute proident fugiat adipisicing qui laborum tempor ad officia. Nulla ipsum voluptate in proident laborum labore nulla culpa sunt deserunt sit ad aliqua culpa.",
),
(
key: "ughent",
short: "UGent",
long: "Universiteit Gent",
desc: "Labore officia commodo dolor sunt eu sunt excepteur enim nisi ex ad officia magna. Nostrud elit ullamco quis amet id eu. Cupidatat elit cupidatat ad nulla laboris irure elit.",
),
(
key: "vub",
short: "VUB",
long: "Vrije Universiteit Brussel",
desc: [Proident veniam non aliquip commodo sunt cupidatat. Enim est cupidatat occaecat elit et. Adipisicing irure id consequat ullamco non. Labore sunt tempor et mollit. #gls("kuleuven", long: true)],
),
(
key: "ulb",
short: "ULB",
long: "",
desc: "Magna do officia sit reprehenderit anim esse. Eu Lorem ullamco incididunt minim quis sit sunt id mollit sit amet cupidatat. Labore incididunt enim culpa ex magna veniam proident non sint dolor. Incididunt proident esse culpa nostrud tempor cupidatat culpa consectetur excepteur ipsum deserunt duis exercitation. Non consectetur dolore culpa laboris in quis. Cupidatat aliquip exercitation id elit ipsum amet enim nostrud elit reprehenderit velit. Irure labore pariatur non dolore non officia laborum quis deserunt adipisicing cillum incididunt.",
),
(
key: "umons",
short: "UMons",
long: "Université de Mons",
desc: "Aliquip incididunt elit aliquip eu fugiat sit consectetur officia veniam sunt labore consequat sint eu. Minim occaecat irure consequat sint non enim. Ea consectetur do occaecat aliqua exercitation exercitation consectetur Lorem pariatur officia nostrud. Consequat duis minim veniam laboris nulla anim esse fugiat. Ullamco aliquip irure adipisicing quis est laboris.",
),
(
key: "uliege",
short: "ULiège",
long: "Université de Liège",
desc: "Tempor deserunt commodo reprehenderit eiusmod enim. Ut ullamco deserunt in elit commodo ipsum nisi voluptate proident culpa. Sunt do mollit velit et et amet consectetur tempor proident Lorem. Eu officia amet do ea occaecat velit fugiat qui tempor sunt aute. Magna Lorem veniam duis ea eiusmod labore non anim labore irure culpa Lorem dolor officia. Laboris reprehenderit eiusmod nostrud duis excepteur nisi officia.",
),
(
key: "unamur",
short: "UNamur",
long: "Université de Namur",
),
(
key: "notused",
short: "Not used",
desc: [This key is not cited anywhere, it won't be in the glossary unless the `show-all` argument is set to true],
),
),
// show all term even if they are not referenced, default to true
show-all: true
)
154 changes: 154 additions & 0 deletions packages/preview/glossarium/0.2.4/glossarium.typ
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.*/

// glossarium figure kind
#let __glossarium_figure = "glossarium_entry"
// prefix of label for references query
#let __glossary_label_prefix = "glossary:"
// global state containing the glossary entry and their location
#let __glossary_entries = state("__glossary_entries", (:))

#let __query_labels_with_key(loc, key, before: false) = {
if before {
query(
selector(label(__glossary_label_prefix + key)).before(loc, inclusive: false),
loc,
)
} else {
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)]
} else {
text(fill: red, "Glossary entry not found: " + key)
}
},
)
}

// reference to term with pluralisation
#let glspl(key) = gls(key, suffix: "s")

// show rule to make the references for glossarium
#let make-glossary(body) = {
show ref: r => {
if r.element != none and r.element.func() == figure and r.element.kind == __glossarium_figure {
// call to the general citing function
gls(str(r.target), suffix: r.citation.supplement)
} else {
r
}
}
body
}

#let print-glossary(entries, show-all: 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)
}
}
if hasDesc [: #desc ] else [. ]

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()
]
}
};

Loading

0 comments on commit 8a99f13

Please sign in to comment.