Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

acrostiche:0.4.0 #1206

Merged
merged 47 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
8579a58
update to version 0.2.0. Major bug fix and add index title parameter
Jul 7, 2023
0dfbeff
fix typos
Jul 7, 2023
bc77f00
Merge branch 'typst:main' into main
Grisely Jul 10, 2023
c68a2b2
Merge branch 'typst:main' into main
Grisely Jul 13, 2023
943eff4
Merge branch 'typst:main' into main
Grisely Aug 13, 2023
60760cf
Add delimiter option for index, update readme, add repo entry in typs…
Aug 13, 2023
625aa39
fix missing version updates in readme
Aug 22, 2023
5c58db0
Add Array-Check for print-index
caemor Nov 27, 2023
6fc662a
Merge branch 'typst:main' into main
Grisely Dec 22, 2023
2ad0e51
Merge remote-tracking branch 'upstream/main'
Jan 6, 2024
ed54c29
Merge pull request #1 from caemor/caemor-patch-1
Grisely Jan 6, 2024
b105b00
reset to upstream version after merge
Jan 6, 2024
001b78c
new version with trailing comma fix and updated readme
Jan 6, 2024
db8d9b2
Create version 0.3.2
AurelWeinhold Feb 6, 2024
e61f2dc
Print as a single table instead of many tables with one entry
AurelWeinhold Feb 6, 2024
3e5e925
Add documentation
AurelWeinhold Feb 6, 2024
c56dea0
Add heading parameter numbering (default none) for heading of list of
AurelWeinhold Feb 18, 2024
e75f66f
Replace inset with row-gutter parameter to actually be able to adjust
AurelWeinhold Feb 18, 2024
2f9ec33
Merge pull request #3 from typst/main
Grisely Jul 9, 2024
df5b345
Merge pull request #2 from AurelWeinhold/main
Grisely Jul 10, 2024
1120ec4
version change and linebreaks
Jul 10, 2024
94c9f98
feat: new version that supports printing the full version of an acronym
daniel-eder Aug 19, 2024
442eb73
Merge remote-tracking branch 'upstream/main'
Sep 24, 2024
975dc82
update readme and package infos
Sep 24, 2024
73085f8
Merge branch 'daniel-eder-main'
Sep 24, 2024
1c8d3ae
Merge branch 'typst:main' into main
Grisely Oct 22, 2024
741ebe8
fix package to remove dependency on state's display method
Oct 22, 2024
eb2e0bb
update readme
Oct 22, 2024
b01da8f
fix: acrpl does not display contracted form in plural
daniel-eder Oct 27, 2024
4357c75
Merge pull request #5 from daniel-eder/main
Grisely Oct 27, 2024
897434c
bump version and add keyword and categories fields to typst.toml
Oct 27, 2024
460d35b
Merge branch 'typst:main' into main
Grisely Oct 27, 2024
f5fb7a8
fix: Allow disabling acronym sorting in the index
iostapyshyn Oct 28, 2024
180bc25
Merge pull request #6 from iostapyshyn/main
Grisely Oct 28, 2024
d23bf48
remove erroneous comment for argument
Oct 28, 2024
c877e9e
Merge branch 'typst:main' into main
Grisely Oct 28, 2024
856debb
update contributors list
Oct 28, 2024
dcd7ea7
comment for new feature
Oct 28, 2024
08ddb41
add argument to only display used acronyms in the index
Oct 29, 2024
702f0e2
major refactoring of the acronym storage object. Remove individual st…
Oct 30, 2024
89b4511
set space between definition and acronym to be non-breaking
Oct 30, 2024
e6f1ebd
start writing a test file for more comprehensive testing before update
Oct 30, 2024
ff44bad
update readme with shortcuts
Oct 30, 2024
fe8ac1b
update readme again
Oct 30, 2024
8221d0a
move to next medium version number
Oct 30, 2024
d792186
Merge branch 'typst:main' into main
Grisely Oct 30, 2024
8b1d4a5
exclude test file
Oct 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/preview/acrostiche/0.4.0/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.pdf
22 changes: 22 additions & 0 deletions packages/preview/acrostiche/0.4.0/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
MIT License

Copyright (c) 2023 Arthur Grisel-Davy
Copyright (c) 2023 Aurel Weinhold

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.
122 changes: 122 additions & 0 deletions packages/preview/acrostiche/0.4.0/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# Acrostiche (0.4.0)

Manages acronyms so you don't have to.

## Quick Start

```
#import "@preview/acrostiche:0.4.0": *

#init-acronyms((
"WTP": ("Wonderful Typst Package","Wonderful Typst Packages"),
))

Acrostiche is a #acr("WTP")! This #acr("WTP") enables easy acronyms manipulation.

Its main features are auto-expansion of the first occurence, global or selective expansion reset #reset-all-acronyms(), implicit or manual plural form support (there may be multiple #acrpl("WTP")), and customizable index printing. Have Fun!
```


## Usage

The main goal of Acrostiche is to keep track of which acronyms to define.

### Define acronyms
First, define the acronyms in a dictionary, with the keys being the acronyms and the values being arrays of their definitions.
If there is only a singular version of the definition, the array contains only one value.
If there are both singular and plural versions, define the definition as an array where the first item is the singular definition and the second item is the plural.
Then, initialize Arostiche with the acronyms you just defined with the `#init-acronyms(...)` function:

Here is a sample of the `acronyms.typ` file:
```
#import "@preview/acrostiche:0.4.0": *

#init-acronyms((
"NN": ("Neural Network"),
"OS": ("Operating System",),
"BIOS": ("Basic Input/Output System", "Basic Input/Output Systems"),
))
```

### Call Acrostiche functions
Once the acronyms are defined, you can use them in the text with the `#acr(...)` function.
The argument is the acronym as a string (for example, "BIOS"). On the first call of the function, it prints the acronym with its definition (for example, "Basic Input/Output System (BIOS)").
On the next calls, it prints only the acronym.

To get the plural version of the acronym, you can use the `#acrpl(...)` function that adds an 's' after the acronym.
If a plural version of the definition is provided, it will be used if the first use of the acronym is plural.
Otherwise, the singular version is used, and a trailing 's' is added.

To intentionally print the full version of the acronym (definition + acronym, as for the first instance), without affecting the state, you can use the `#acrfull(...)` function. For the plural version, use the `#acrfullpl(...)` function.
Both functions have shortcuts with `#acrf(...)` and `#acrfpl(...)`.

At any point in the document, you can reset acronyms with the functions `#reset-acronym(...)` (for a single acronym) or `reset-all-acronyms()` (to reset all acronyms). After a reset, the next use of the acronym is expanded.
Both functions have shortcuts with `#racr(...)` and `#raacr(...)`.

You can also print an index of all acronyms used in the document with the `#print-index()` function.
The index is printed as a section for which you can choose the heading level, the numbering, and the outline parameters (with respectively the `level: int`, `numbering: none | string | function`, and `outlined: bool` parameters).
You can also choose their order with the `sorted: string` parameter that accepts either an empty string (print in the order they are defined), "up" (print in ascending alphabetical order), or "down" (print in descending alphabetical order).
By default, the index contains all the acronyms you defined. You can choose to only display acronyms that are actually used in the document by passing `used-only: true` to the function. Warning, the detection of used acronym uses the states at the end of the document. Thus, if you reset an acronym and do not use it again until the end, it will not appear in the index.
You can use the `title: string` parameter to change the name of the heading for the index section.
The default value is "Acronyms Index". Passing an empty string for `title` results in the index having no heading (i.e., no section for the index).
You can customize the string displayed after the acronym in the list with the `delimiter: ":"` parameter.
To adjust the spacing between the acronyms adjust the `row-gutter: auto | int | relative | fraction | array` parameter, the default is `2pt`.

Finally, you can call the `#display-def(...)` function to display the definition of an acronym. Set the `plural` parameter to true to get the plural version.

### Functions Summary:

| **Function** | **Description** |
|-------------------------------|---------------------------------------------------------------------------------------------------------------------|
| **#init-acronyms(...)** | Initializes the acronyms by defining them in a dictionary where the keys are acronyms and the values are definitions. |
| **#acr(...)** | Prints the acronym with its definition on the first call, then just the acronym in subsequent calls. |
| **#acrpl(...)** | Prints the plural version of the acronym. Uses plural definition if available, otherwise adds an 's' to the acronym. |
| **#acrfull(...)** | Displays the full (long) version of the acronym without affecting the state or tracking its usage. |
| **#acrfullpl(...)** | Displays the full plural version of the acronym without affecting the state or tracking its usage. |
| **#reset-acronym(...)** | Resets a single acronym so the next usage will include its definition again. |
| **#reset-all-acronyms()** | Resets all acronyms so the next usage will include their definitions again. |
| **#print-index(...)** | Prints an index of all acronyms used, with customizable heading level, order, and display parameters. |
| **#display-def(...)** | Displays the definition of an acronym. Use `plural: true` to display the plural version of the definition. |
| **racr, raacr, acrf, acrfpl** | Shortcuts names for respectively `reset-acronym`, `reset-all-acronyms`, `acrfull`, and `acrfullpl`. |

## Advanced Definitions
This is a bit of a hacky feature coming from pure serendipity.
There is no enforcement of the type of the definitions.
Most users would naturally use strings as definitions, but any other content is acceptable.
For example, you set your definition to a content block with rainbow-fille text, or even an image.
The rainbow text is kinda cool because the gradient depend on the position in the page so depending on the position of first use the acronym will have a pseudo-random color.

If you use anything else than string for the definition, do not forget the trailing comma to force the definition to be an array (an array of a single element is not an array in Typst at the time of writing this).
I cannot guarantee that arbitrary content will remain available in future versions but I will do my best to keep it as it is kinda cool.
If you find cool uses, please reach out to show me!


PS: For the smart trouble-maker in the back that are thinking about nesting an acronym call in the definition of an acronym, I am way ahead of you and yes it is (kinda) possible.
If you point to another acronym, it all works fine.
If you point to the same acronym, you obviously create a recursive situation, and it fails.
It will not converge, and the compiler will warn you and will panic.
Be nice to the compiler, don't throw recursive traps.


Here is a minimal working example of funky acronyms:

```
#import "@preview/acrostiche:0.4.0": *
#init-acronyms((
"RFA": ([#text(fill: gradient.linear(..color.map.rainbow))[Rainbow Filled Acronym]],),
"NA": ([Nested #acr("RFA") Acronym],)
))
#acr("NA")
```

## Possible Errors:

* If an acronym is not defined, an error will tell you which one is causing the error. Simply add it to the dictionary or check the spelling.
* `display-def` leverages the state `display` function and only works if the return value is actually printed in the document. For more information on states, see the Typst documentation on states.
* Acrostiche uses a state named `acronyms` to keep track of the definitions and usage. If you redefined this state or use it manually in your document, unexpacted behaviour might happen.

# Acknowledgments

Thank you to the contributors: **caemor**, **AurelWeinhold**, **daniel-eder**, **iostapyshyn**.

If you notice any bug or want to contribute a new feature, please open an issue or a merge request on the fork [Grisely/packages](https://github.com/Grisely/packages)
177 changes: 177 additions & 0 deletions packages/preview/acrostiche/0.4.0/acrostiche.typ
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
// Acrostiche package for Typst
// Author: Grizzly


#let acros = state("acronyms",none)
#let init-acronyms(acronyms) = {
let states = (:)
for (acr, defs) in acronyms{
let data = (defs, false)
states.insert(acr,data)
}
acros.update(states)
}

#let display-def(plural: false, acr) = {
// Display the definition of an acronym by fetching it in the "acronyms" state's value (should be a dictionary).

// First, grab the dictionary of definitions of acronyms from the "acronyms" state
context{
let acronyms = acros.get()
if acr in acronyms{
let defs = acronyms.at(acr).at(0)
if type(defs) == "string"{ // If user defined only one version and forgot the trailing comma the type is string
if plural{panic("You requested the plural version of the acronym but it seems like you only provided the singular version in #init-acronyms(dict)")}
else{defs} // All is good, we return the definition found as the singular version
}
else if type(defs) == "array"{
if defs.len() == 0{ // The user could have provided an empty array, unlikely but possible.
panic("No definitions found for acronym "+acr+". Make sure it is defined in the dictionary passed to #init-acronyms(dict)")
}else if defs.len() == 1{ // User provided only one version, we make the plural by adding an "s" at the end.
if plural{defs.at(0)+"s"}
else{defs.at(0)}
}else{ // User provided more than one version. We assume the first is singular and the second is plural. All other are useless.
if plural{defs.at(1)}
else{defs.at(0)}
}
}else{
panic("Definitions should be arrays of one or two strings. Definition of "+acr+ " is "+defs+" of type: "+type(defs))
}
}else{
panic(acr+" is not a key in the acronyms dictionary.")
}
}

}

#let acr(acr, plural:false) = {
// Display an acronym in the singular form by default. Expands it if used for the first time.

// Generate the key associated with this acronym
let state-key = "acronym-state-" + acr
// Test if the state for this acronym already exists and if the acronym was already used
// to choose what to display.
context{
let data = acros.get()
if acr in data{
let short = if plural{[#acr\s]}else{acr}
if data.at(acr).at(1){
short
}else{
[#display-def(plural: plural, acr)~(#short)]
}
data.at(acr).at(1) = true
}else{
panic("You requested the acronym "+acr+" that you did not define first.")
}
acros.update(data)
}
}

#let acrpl(acronym) = {acr(acronym,plural:true)} // argument renamed acronym to differentiate with function acr

#let acrfull(acr) = {
//Intentionally display an acronym in its full form. Do not update state.
[#display-def(plural: false, acr) (#acr)]
}

#let acrfullpl(acr) = {
//Intentionally display an acronym in its full form in plural. Do not update state.
[#display-def(plural: true, acr) (#acr\s)]
}

// define shortcuts


#let reset-acronym(acr) = {
// Reset a specific acronym. It will be expanded on next use.
context{
let data = acros.get()
if acr in data{
data.at(acr).at(1) = false
}else{
panic("You requested the acronym "+acr+" that you did not define first.")
}
acros.update(data)
}
}

#let reset-all-acronyms() = {
// Reset all acronyms. They will all be expanded on the next use.
context{
let acronyms = acros.get()
for acr in acronyms.keys(){
reset-acronym(acr)
}
}
}

// Define shortcuts
#let acrf(acr) = {acrfull(acr)}
#let acrfpl(acr) = {acrfullpl(acr)}
#let racr(acr) = {reset-acronym(acr)}
#let raacr() = reset-all-acronyms()


#let print-index(level: 1, numbering: none, outlined: false, sorted:"",
title:"Acronyms Index", delimiter:":", row-gutter: 2pt, used-only: false) = {
//Print an index of all the acronyms and their definitions.
// Args:
// level: level of the heading. Default to 1.
// outlined: make the index section outlined. Default to false
// sorted: define if and how to sort the acronyms: "up" for alphabetical order, "down" for reverse alphabetical order, "" for no sort (print in the order they are defined). Default to "".
// title: set the title of the heading. Default to "Acronyms Index". Passing an empty string will result in removing the heading.
// delimiter: String to place after the acronym in the list. Defaults to ":"
// used-only: if true, only include in the index the acronyms that are used in the document. Warning, if you reset acronyms and don't used them after, they may not appear.

// assert on input values to avoid cryptic error messages
assert(sorted in ("","up","down"), message:"Sorted must be a string either \"\", \"up\" or \"down\"")

if title != ""{
heading(level: level, numbering: numbering, outlined: outlined)[#title]
}

context{
let acronyms = acros.get()

// Updated
// Build acronym list
let acr-list = acronyms.keys()

if used-only{
// Select only acronyms where state is true at the end of the document.
// TODO Ideally, the code would check if the acronym is used anywhere in the document,
// but I don't know how to do that yet. Feel free to propose changes.
let used-acr-list = ()
for acr in acr-list{
if acros.final().at(acr).at(1) {
used-acr-list.push(acr)
}
}
acr-list = used-acr-list
}

// FEATURE: allow ordering by occurences position in the document. Not sure if possible yet.

// order list depending on the sorted argument
if sorted=="down"{
acr-list = acr-list.sorted().rev()
}else if sorted=="up"{
acr-list = acr-list.sorted()
}

// print the acronyms
table(
columns: (20%,80%),
stroke: none,
row-gutter: row-gutter,
..for acr in acr-list{
let desc = if type(acronyms.at(acr).at(0)) == array {
acronyms.at(acr).at(0).at(0)
} else {acronyms.at(acr).at(0)}
([*#acr#delimiter*], desc)
}
)
}
}

61 changes: 61 additions & 0 deletions packages/preview/acrostiche/0.4.0/test.typ
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#import "@preview/acrostiche:0.4.0": *

#init-acronyms((
"PFT": ("Package For Typst","Packages For Typst"),
"AJT": ("Amicale des Joyeux Typistes"),
"TEA": ("The Extra Acronym",),
))

#let ref(str) = [#text(fill:green)[#str]]

== Acronym with Two Definitions.

First use of #acr("PFT") and second use of #acr("PFT").\
#ref("First use of Package For Typst (PFT) and second use of PFT.")

Reset acronyms. #reset-acronym("PFT")

First use of plural #acrpl("PFT") and second use of plural #acrpl("PFT").\
#ref("First use of plural Packages For Typst (PFTs) and second use of plural PFTs.")

Reset acronyms. #racr("PFT")

Full definition of #acrfull("PFT") and full plural definition of #acrfullpl("PFT").
Full definition of #acrf("PFT") and full plural definition of #acrfpl("PFT").
#ref("Full definition of Package For Typst (PFT) and full plural definition of Packages For Typst (PFTs).")

== Acronym with a Single Definition.

First use of #acr("AJT") and second use of #acr("AJT").\
#ref("First use of Amicale des Joyeux Typistes (AJT) and second use of AJT.")


Reset acronyms. #racr("AJT")

Full definition of #acrfull("AJT").\
Full definition of #acrf("AJT").\
#ref("Full definition of Amicale des Joyeux Typistes (AJT)")

== Reset All Acronyms

Use #acr("PFT") and #acr("AJT").\
Reset.#reset-all-acronyms()\
Use again #acr("PFT") and #acr("AJT").

#ref("
Use Package For Typst (PFT) and Amicale des Joyeux Typistes (AJT).
Reset.
Use again Package For Typst (PFT) and Amicale des Joyeux Typistes (AJT).
")

== Print Index Variations

#print-index()

#print-index(title:"Sorted Empty",sorted:"")
#print-index(title:"Sorted up", sorted:"up")
#print-index(title:"Sorted down", sorted:"down")

#print-index(title:"Used only up", sorted: "up", used-only:true)
#print-index(title:"Used only down", sorted: "down", used-only:true)

11 changes: 11 additions & 0 deletions packages/preview/acrostiche/0.4.0/typst.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "acrostiche"
version = "0.4.0"
entrypoint = "acrostiche.typ"
repository = "https://github.com/Grisely/packages"
authors = ["Grizzly"]
license = "MIT"
keywords = ["acronyms"]
categories = ["utility","model"]
exclude = ["test.typ"]
description = "Manage acronyms and their definitions in Typst."
Loading