Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d296f3a3f1
|
||
|
|
338fee564f
|
||
|
|
1e095a8b26
|
||
|
|
df889d8d72 | ||
|
|
c008b5bd86
|
||
|
|
842166c211
|
No files matched your search
@@ -17,6 +17,9 @@ links below to their main page.
|
||||
into everyday docs.
|
||||
- [**swank-tex**](https://typst.app/universe/package/swank-tex): Render those
|
||||
funky logos for TeX, LaTeX, and friends.
|
||||
- [**tasteful-pairings**](https://typst.app/universe/package/tasteful-pairings):
|
||||
A carefully curated collection of font pairings focusing on readability and
|
||||
typographic harmony.
|
||||
|
||||
## Templates
|
||||
|
||||
|
||||
+4
-3
@@ -41,7 +41,7 @@ different goals:
|
||||
### Import the package
|
||||
|
||||
```typst
|
||||
#import "@preview/glossy:0.5.0": *
|
||||
#import "@preview/glossy:0.5.1": *
|
||||
```
|
||||
|
||||
### Defining Glossary Terms
|
||||
@@ -186,8 +186,9 @@ Display the glossary using the `glossary()` function:
|
||||
|
||||
```typst
|
||||
#glossary(
|
||||
title: "Web Development Glossary", // Optional: defaults to Glossary
|
||||
theme: my-theme, // Optionaal: defaults to theme-twocol
|
||||
title: "Web Development Glossary", // Optional: defaults to Glossary theme:
|
||||
my-theme, // Optional: defaults to theme-academic
|
||||
sort: true, // Optional: whether or not to sort the glossary
|
||||
ignore-case: false, // Optional: ignore case when sorting terms
|
||||
groups: ("Web") // Optional: Filter to specific groups
|
||||
)
|
||||
|
||||
+12
-7
@@ -541,6 +541,7 @@
|
||||
#let glossary(
|
||||
title: "Glossary",
|
||||
theme: theme-academic,
|
||||
sort: true,
|
||||
ignore-case: false,
|
||||
groups: (),
|
||||
) = context {
|
||||
@@ -601,13 +602,17 @@
|
||||
group = if group == none { "" } else { group }
|
||||
|
||||
// sort entries by case insensitivity if requested
|
||||
let sorted_entries = 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) } })
|
||||
// 2. sort the tuples (by first element then second)
|
||||
.sorted(key: t => t.first())
|
||||
// 3. strip away the tuple's first element, leaving an array of entries
|
||||
.map(t => t.last())
|
||||
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) } })
|
||||
// 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
|
||||
.map(t => t.last())
|
||||
} else {
|
||||
current_entries
|
||||
}
|
||||
|
||||
// add entries to this group's output map
|
||||
output.insert(group, sorted_entries)
|
||||
|
||||
@@ -203,7 +203,7 @@
|
||||
|
||||
if is_acronym {
|
||||
// Use acronym rules
|
||||
let first_char = upper_word.slice(0,1)
|
||||
let first_char = upper_word.codepoints().slice(0,1).first()
|
||||
if acronym_vowels.contains(first_char) {
|
||||
"an"
|
||||
} else {
|
||||
@@ -211,7 +211,7 @@
|
||||
}
|
||||
} else {
|
||||
// Non-acronym rules
|
||||
let first_char = lower_word.slice(0,1)
|
||||
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 = (
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
first:
|
||||
short: "DAL"
|
||||
long: "first"
|
||||
|
||||
second:
|
||||
short: "cab"
|
||||
long: "second"
|
||||
|
||||
third:
|
||||
short: "delta"
|
||||
long: "third"
|
||||
|
||||
fourth:
|
||||
short: "COO"
|
||||
long: "fourth"
|
||||
|
||||
fifth:
|
||||
short: "cuckoo"
|
||||
long: "fifth"
|
||||
|
||||
sixth:
|
||||
short: "ČR"
|
||||
long: "sixth"
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 183 KiB |
@@ -0,0 +1,13 @@
|
||||
#import "/lib.typ":*
|
||||
|
||||
#show: init-glossary.with(yaml("glossary.yml"))
|
||||
|
||||
@first, @second, @third, @fourth, @fifth, @sixth
|
||||
|
||||
#glossary(ignore-case: false, sort: true)
|
||||
#line(length: 20em)
|
||||
#glossary(ignore-case: true, sort: true)
|
||||
#line(length: 20em)
|
||||
#glossary(ignore-case: false, sort: false)
|
||||
#line(length: 20em)
|
||||
#glossary(ignore-case: true, sort: false)
|
||||
@@ -0,0 +1,23 @@
|
||||
cab:
|
||||
short: "cab"
|
||||
long: "taxi cab"
|
||||
|
||||
coo:
|
||||
short: "COO"
|
||||
long: "Chief Operations Officer"
|
||||
|
||||
cuckoo:
|
||||
short: "cuckoo"
|
||||
long: "really crazy"
|
||||
|
||||
delta:
|
||||
short: "delta"
|
||||
long: "difference between two values"
|
||||
|
||||
dal:
|
||||
short: "DAL"
|
||||
long: "Delta Airlines"
|
||||
|
||||
čr:
|
||||
short: "ČR"
|
||||
long: "Česká Republika"
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 133 KiB |
@@ -0,0 +1,20 @@
|
||||
#import "/lib.typ":*
|
||||
|
||||
#set text(lang: "cs", region: "CZ")
|
||||
|
||||
#show: init-glossary.with(yaml("glossary.yml"))
|
||||
#glossary(ignore-case: true)
|
||||
|
||||
#line(length: 20em)
|
||||
|
||||
@čr
|
||||
|
||||
@cab
|
||||
|
||||
@coo
|
||||
|
||||
@cuckoo
|
||||
|
||||
@delta
|
||||
|
||||
@dal
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "glossy"
|
||||
version = "0.5.0"
|
||||
version = "0.5.1"
|
||||
entrypoint = "lib.typ"
|
||||
authors = ["Stephen Waits <steve@waits.net>"]
|
||||
license = "MIT"
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
tests/**/out/
|
||||
tests/**/diff/
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Stephen Waits <steve@waits.net>
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,57 @@
|
||||
# Tasteful Pairings
|
||||
|
||||
A carefully curated collection of font pairings for [Typst](https://typst.app/),
|
||||
focusing on readability and typographic harmony. Each pairing combines a
|
||||
sans-serif heading font with a serif body font, following established
|
||||
typographic principles for clear visual hierarchy and optimal reading
|
||||
experience.
|
||||
|
||||
## Installation
|
||||
|
||||
```typ
|
||||
#import "@preview/tasteful-pairings:0.1.0": *
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```typ
|
||||
#let pairing = font-pairings.at("modern-heritage")
|
||||
|
||||
#show heading: set text(font: pairing.heading)
|
||||
#set text(font: pairing.body)
|
||||
|
||||
= Your Document Title
|
||||
Your content here...
|
||||
```
|
||||
|
||||
## Available Pairings
|
||||
|
||||
- **`ibm-plex`** - Modern corporate-friendly superfamily
|
||||
- **`noto`** - Extensive language support, highly legible
|
||||
- **`source`** - Adobe's refined open-source pair
|
||||
- **`friendly-weather`** - Open Fira Sans with space-efficient Merriweather
|
||||
- **`android`** - Complete Roboto family look
|
||||
- **`kindle`** - Amazon's reading-optimized fonts
|
||||
- **`office`** - Classic Microsoft Office combination
|
||||
- **`modern-heritage`** - Contemporary Montserrat with timeless Georgia Pro
|
||||
- **`legible`** - Reading-focused Lexend and Literata
|
||||
|
||||
## Gallery
|
||||
|
||||

|
||||
|
||||
## Philosophy
|
||||
|
||||
The pairings in this collection follow these principles:
|
||||
|
||||
1. **Sans for Headlines, Serif for Body** - Following traditional typographic
|
||||
wisdom for clear hierarchy
|
||||
2. **Readability First** - Each pairing is tested for optimal reading experience
|
||||
3. **Complementary Characteristics** - Fonts are matched based on x-height,
|
||||
weight balance, and character width
|
||||
4. **Practical Applications** - Selected for real-world use cases from corporate
|
||||
documents to digital reading
|
||||
|
||||
## License
|
||||
|
||||
[MIT License](LICENSE).
|
||||
@@ -0,0 +1 @@
|
||||
#import "src/main.typ": font-pairings
|
||||
@@ -0,0 +1,55 @@
|
||||
#let font-pairings = (
|
||||
"ibm-plex": (
|
||||
heading: "IBM Plex Sans",
|
||||
body: "IBM Plex Serif",
|
||||
description: "A modern corporate-friendly superfamily with a wide weight range. Clean, neutral, and highly legible."
|
||||
),
|
||||
|
||||
"noto": (
|
||||
heading: "Noto Sans",
|
||||
body: "Noto Serif",
|
||||
description: "Huge language coverage, highly legible, and neutral. Great for multilingual documents."
|
||||
),
|
||||
|
||||
"source": (
|
||||
heading: "Source Sans 3",
|
||||
body: "Source Serif 4",
|
||||
description: "Adobe's open-source pair. Clean, highly readable, and well-hinted for both screen and print."
|
||||
),
|
||||
|
||||
"friendly-weather": (
|
||||
heading: "Fira Sans",
|
||||
body: "Merriweather",
|
||||
description: "Open, friendly sans plus a space-efficient modern serif. Good for text-heavy documents."
|
||||
),
|
||||
|
||||
"android": (
|
||||
heading: "Roboto",
|
||||
body: "Roboto Serif",
|
||||
description: "A complete Android-friendly look. Roboto is extremely common; Roboto Serif is its matching new serif companion."
|
||||
),
|
||||
|
||||
"kindle": (
|
||||
heading: "Amazon Ember",
|
||||
body: "Bookerly",
|
||||
description: "The Kindle pairing. Bookerly is a warm, book-like serif; Amazon Ember is a clean, readable sans."
|
||||
),
|
||||
|
||||
"office": (
|
||||
heading: "Calibri",
|
||||
body: "Cambria",
|
||||
description: "A classic Microsoft Office pairing. Calibri (sans) for headings, Cambria (serif) for body text."
|
||||
),
|
||||
|
||||
"modern-heritage": (
|
||||
heading: "Montserrat",
|
||||
body: "Georgia Pro",
|
||||
description: "Merges the warm, traditional forms of Georgia Pro with Montserrat’s clean, geometric lines. A modern-yet-classic pairing, equally suited to formal reports or stylish web layouts."
|
||||
),
|
||||
|
||||
"legible": (
|
||||
heading: "Lexend",
|
||||
body: "Literata",
|
||||
description: "An ultra-legible pairing designed for reading fluency. Lexend’s tall x-height and open shapes reduce visual stress, while Literata brings a warm, bookish feel to body text."
|
||||
),
|
||||
)
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 994 KiB |
@@ -0,0 +1,23 @@
|
||||
#import "/lib.typ": *
|
||||
|
||||
#set page(margin: 1em, height: auto, width: 5.5in)
|
||||
#set par(justify: true, linebreaks: "optimized")
|
||||
|
||||
#let keys = font-pairings.keys().sorted()
|
||||
|
||||
#for key in keys {
|
||||
block(
|
||||
stroke: 1pt + navy,
|
||||
inset: 1em,
|
||||
radius: 1em,
|
||||
[
|
||||
#let pairing = font-pairings.at(key)
|
||||
#show heading: set text(font: pairing.heading, weight: "bold")
|
||||
= #pairing.heading & #pairing.body #h(1fr) #text(fill: eastern, weight: "light", size: 0.8em, baseline: -3pt, ["#key"])
|
||||
#set text(font: pairing.body, weight: "light")
|
||||
#pairing.description
|
||||
|
||||
#lorem(20)
|
||||
]
|
||||
)
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 366 KiB |
@@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "tasteful-pairings"
|
||||
version = "0.1.0"
|
||||
entrypoint = "lib.typ"
|
||||
authors = ["Stephen Waits <steve@waits.net>"]
|
||||
license = "MIT"
|
||||
description = "A carefully curated collection of font pairings."
|
||||
keywords = ["font", "pairing", "typography"]
|
||||
repository = "https://github.com/swaits/typst-collection"
|
||||
exclude = ["thumbnail.png", "tests"]
|
||||
Reference in new issue
Block a user