punctilio 0.4.0 → 0.4.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,250 +1,99 @@
1
- # punctilio
1
+ > *punctilio* (n.): precise observance of formalities.
2
+
3
+ The best typography package for English.
4
+
5
+ ```typescript
6
+ import { transform } from 'punctilio'
7
+
8
+ transform('"It\'s a beautiful thing, the destruction of words..." -- 1984')
9
+ // → “It’s a beautiful thing, the destruction of words…” — 1984
10
+ ```
2
11
 
3
12
  [![Test](https://github.com/alexander-turner/punctilio/actions/workflows/test.yml/badge.svg)](https://github.com/alexander-turner/punctilio/actions/workflows/test.yml)
4
13
  [![Lint](https://github.com/alexander-turner/punctilio/actions/workflows/lint.yml/badge.svg)](https://github.com/alexander-turner/punctilio/actions/workflows/lint.yml)
5
14
  [![Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen)](https://github.com/alexander-turner/punctilio)
6
-
7
- > *punctilio* (n.): a fine point of conduct or procedure
8
-
9
- Smart typography transformations for JavaScript/TypeScript. Converts ASCII punctuation to typographically correct Unicode characters. Originally built for [my personal website](https://turntrout.com/design).
10
-
11
- ## Features
12
-
13
- | **Feature** | **Before** | **After** |
14
- |---------|--------|-------|
15
- | Smart quotes | "straight" | “curly” |
16
- | | 'apostrophes' | ‘apostrophes’ |
17
- | Em dashes | wait - why did you | wait—why did you |
18
- | En dashes | 1-5 | 1–5 |
19
- | | January-March | January–March |
20
- | Minus signs | -5 | −5 (proper Unicode minus) |
21
- | Ellipsis | ... | … |
22
- | Multiplication | 5x5 | 5×5 |
23
- | | 3*4 | 3×4 |
24
- | Math symbols | != | ≠ |
25
- | | +- | ± |
26
- | | <= | ≤ |
27
- | | >= | ≥ |
28
- | | ~= | ≈ |
29
- | Legal symbols | (c) | © |
30
- | | (r) | ® |
31
- | | (tm) | ™ |
32
- | Arrows | -> | → |
33
- | | <- | ← |
34
- | | <-> | ↔ |
35
- | Prime marks | 5'10" | 5′10″ |
36
- | Fractions (optional) | 1/2 | ½ |
37
- | | 3/4 | ¾ |
38
- | Degrees (optional) | 20 C | 20 °C |
39
-
40
- **Handles edge cases**: contractions, possessives, nested quotes, year abbreviations ('99), "rock 'n' roll"
41
-
42
- ## Why another typography library?
43
-
44
- Existing solutions like [SmartyPants](https://daringfireball.net/projects/smartypants/) struggle with:
45
-
46
- - **Apostrophe ambiguity**: Is `'Twas` an opening quote or apostrophe? (It's an apostrophe)
47
- - **Cross-element text**: When quotes span `<em>"Hello</em> world"`, most libraries fail
48
- - **Context sensitivity**: `'99` (year) vs `'hello'` (quoted) vs `don't` (contraction)
49
-
50
- `punctilio` handles these through thorough regex patterns and an optional separator character for processing text that spans HTML elements.
51
-
52
- ## Installation
53
-
15
+
54
16
  ```bash
55
17
  npm install punctilio
56
- # or
57
- pnpm add punctilio
58
18
  ```
59
19
 
60
- ## Usage
20
+ ## Why punctilio?
61
21
 
62
- ### Basic
22
+ As far as I can tell, `punctilio` is the most reliable and feature-complete. I built `punctilio` for [my website](https://turntrout.com/design). I wrote[^wrote] and sharpened the core regexes sporadically over several months, exhaustively testing edge cases. Eventually, I decided to spin off the functionality into its own package.
63
23
 
64
- ```typescript
65
- import { transform, niceQuotes, hyphenReplace } from 'punctilio'
66
-
67
- // Apply all transformations
68
- transform('"Hello," she said - "it\'s pages 1-5."')
69
- // → "Hello," she said—"it's pages 1–5."
24
+ [^wrote]: While Claude is the number one contributor to this repository, that’s just because Claude has helped me port my existing code and add minor features. The core regular expressions (e.g. dashes, quotes, multiplication signs) are human-written.
70
25
 
71
- // Symbol transforms are included by default
72
- transform('Wait... 5x5 != 25 (c) 2024')
73
- // → Wait… 5×5 ≠ 25 © 2024
26
+ I tested `punctilio` 0.4 against [`smartypants`](https://www.npmjs.com/package/smartypants) 0.2.2, [`tipograph`](https://www.npmjs.com/package/tipograph) 0.7.4, and [`smartquotes`](https://www.npmjs.com/package/smartquotes) 2.3.2.[^python] These other packages have spotty feature coverage and inconsistent impact on text. For example, `smartypants` ignores leading apostrophes:
74
27
 
75
- // Or use individual functions
76
- niceQuotes('"Hello", she said.')
77
- // → "Hello", she said.
28
+ [^python]: The Python libraries I found were closely related to the JavaScript packages, so I don’t include Python tests.
78
29
 
79
- hyphenReplace('word - word')
80
- // → word—word
81
- ```
30
+ | Input | `smartypants` | `punctilio` |
31
+ |:-----:|:-----------------:|:-------:|
32
+ | 'Twas the night | ‘Twas the night ✗ | ’Twas the night ✓ |
33
+ | the '99 season | the ‘99 season ✗ | the ’99 season ✓ |
34
+ | rock 'n' roll | rock ‘n’ roll ✗ | rock ’n’ roll ✓ |
82
35
 
83
- ### Transform Options
36
+ By running [`benchmark.mjs`](./benchmark.mjs), I basically graded all libraries on a subset of [my unit tests](./src/tests/), selected to represent a wide range of features.
84
37
 
85
- ```typescript
86
- import { transform } from 'punctilio'
87
-
88
- // Enable optional transforms
89
- transform('Add 1/2 cup at 20 C', {
90
- fractions: true, // 1/2 ½
91
- degrees: true // 20 C → 20 °C
92
- })
93
- // → Add ½ cup at 20 °C
38
+ | Package | Score |
39
+ |--------:|:------|
40
+ | `punctilio` | 79/82 (96%) |
41
+ | `tipograph` | 48/82 (59%) |
42
+ | `smartquotes` | 30/82 (37%) |
43
+ | `smartypants` | 28/82 (35%) |
94
44
 
95
- // Disable symbol transforms if you only want quotes/dashes
96
- transform('5x5 = 25', { symbols: false })
97
- //5x5 = 25 (unchanged)
45
+ | Feature | Example | `smartypants` | `tipograph` | `smartquotes` | `punctilio` |
46
+ |--------:|:-------:|:-------:|:-------:|:-------:|:-------:|
47
+ | Smart quotes | "hello" “hello” | | ✓ | ✓ | ✓ |
48
+ | Leading apostrophe | 'Twas → ’Twas | ✗ | ✗ | ✓ | ✓ |
49
+ | Em dash | -- → — | ✓ | ✗ | ✗ | ✓ |
50
+ | En dash (ranges) | 1-5 → 1–5 | ✗ | ✓ | ✗ | ✓ |
51
+ | Minus sign | -5 → −5 | ✗ | ✓ | ✗ | ✓ |
52
+ | Ellipsis | ... → … | ✓ | ✓ | ✗ | ✓ |
53
+ | Multiplication | 5x5 → 5×5 | ✗ | ✗ | ✗ | ✓ |
54
+ | Math symbols | != → ≠ | ✗ | ✓ | ✗ | ✓ |
55
+ | Legal symbols | (c) → © | ✗ | © only | ✗ | ✓ |
56
+ | Arrows | -> → → | ✗ | ✓ | ✗ | ✓ |
57
+ | Prime marks | 5'10" → 5′10″ | ✗ | ✓ | ✓ | ✓ |
58
+ | Degrees | 20 C → 20 °C | ✗ | ✗ | ✗ | ✓ |
59
+ | Fractions | 1/2 → ½ | ✗ | ✗ | ✗ | ✓ |
60
+ | Superscripts | 1st → 1ˢᵗ | ✗ | ✗ | ✗ | ✓ |
61
+ | Localization | American/British | ✗ | ✗ | ✗ | ✓ |
62
+ | Ligatures | ?? → ⁇ | ✗ | ✓ | ✗ | ✓ |
63
+ | Non-English quotes | „Hallo" (German) | ✗ | ✓ | ✗ | ✗ |
98
64
 
99
- // Punctuation style: american (default), british, or none
100
- transform('"Hello".', { punctuationStyle: 'american' }) // → "Hello."
101
- transform('"Hello."', { punctuationStyle: 'british' }) // → "Hello".
65
+ As far as I can tell, `punctilio`’s only missing feature is non-English quote support. I don’t have a personal reason to use non-English localization, but feel free to make a pull request!
102
66
 
103
- // Dash style: american (default), british, or none
104
- transform('word - word', { dashStyle: 'american' }) // → word—word
105
- transform('word - word', { dashStyle: 'british' }) // → word – word
106
- ```
67
+ ## Works with HTML DOMs via separation boundaries
107
68
 
108
- ### With HTML Element Boundaries
69
+ Other typography libraries either transform plain strings or operate on AST nodes individually (`retext-smartypants` [can't map changes back to HTML](https://github.com/rehypejs/rehype-retext)). But real HTML has text spanning multiple elements—if you concatenate text from `<em>Wait</em>...`, transform it, then try to split it back, you've lost track of where `</em>` belonged.
109
70
 
110
- When processing text that spans multiple HTML elements, use a separator character to mark boundaries:
71
+ `punctilio` introduces _separation boundaries_. First, insert a “separator” character (default: `U+E000`) at each element boundary before transforming (like at the start and end of an `<em>`). Every regex allows this character mid-pattern without breaking matches. For example, `.[SEP]..` still becomes `…[SEP]`. `punctilio` validates the output by ensuring the separator count remains the same.
111
72
 
112
73
  ```typescript
113
74
  import { transform, DEFAULT_SEPARATOR } from 'punctilio'
114
75
 
115
- // Your HTML: <p>"Hello <em>world</em>"</p>
116
- // Extract text with separator between elements:
117
- const text = `"Hello ${DEFAULT_SEPARATOR}world${DEFAULT_SEPARATOR}"`
118
-
119
- const result = transform(text, { separator: DEFAULT_SEPARATOR })
120
- // → "Hello \uE000world\uE000"
121
- // The separator is preserved; split on it to restore to your elements
76
+ transform(`"Wait${DEFAULT_SEPARATOR}"`)
77
+ // `“Wait”${DEFAULT_SEPARATOR}`
78
+ // The separator doesn't block the information that this should be an end-quote!
122
79
  ```
123
80
 
124
- For a complete implementation showing how to use this with a HAST (HTML AST) tree, see the [`transformElement` function in TurnTrout.com](https://github.com/alexander-turner/TurnTrout.com/blob/main/quartz/plugins/transformers/formatting_improvement_html.ts).
125
-
126
- ## API
127
-
128
- ### `transform(text, options?)`
129
-
130
- Applies all typography transformations. Options:
131
- - `separator`: Boundary marker for HTML elements (default: `"\uE000"`)
132
- - `symbols`: Include symbol transforms (default: `true`)
133
- - `fractions`: Convert common fractions like 1/2 → ½ (default: `false`)
134
- - `degrees`: Convert temperature notation like 20 C → 20 °C (default: `false`)
135
- - `punctuationStyle`: `"american"` (default) puts periods/commas inside quotes; `"british"` puts them outside; `"none"` leaves unchanged
136
- - `dashStyle`: `"american"` (default) uses unspaced em dash (—); `"british"` uses spaced en dash ( – ); `"none"` skips dash conversion
137
-
138
- ### Quote Functions
139
-
140
- #### `niceQuotes(text, options?)`
141
-
142
- Converts straight quotes to curly quotes. Options: `separator`, `punctuationStyle`.
143
-
144
- Handles: opening/closing quotes, contractions (`don't`), possessives (`dog's`), year abbreviations (`'99`), special cases (`'n'`).
145
-
146
- ### Dash Functions
147
-
148
- #### `hyphenReplace(text, options?)`
149
-
150
- Converts hyphens to proper dashes. Options: `separator`, `dashStyle`.
151
-
152
- Handles: em dashes (`word - word` → `word—word`), en dashes for ranges (`1-5` → `1–5`, `Jan-Mar` → `Jan–Mar`), minus signs (`-5` → `−5`). Preserves horizontal rules and compound words.
153
-
154
- #### `enDashNumberRange(text, options?)`
155
-
156
- Converts number ranges only: `pages 10-20` → `pages 10–20`
81
+ Your DOM walker tracks which text node each segment came from, inserts separators between them, transforms the combined string, then splits on separators to update each node. Use the `separator` option if `U+E000` conflicts with your content. For an example of how to integrate this functionality, see [my website’s code](https://github.com/alexander-turner/TurnTrout.com/blob/main/quartz/plugins/transformers/formatting_improvement_html.ts).
157
82
 
158
- #### `enDashDateRange(text, options?)`
83
+ ## Options
159
84
 
160
- Converts month ranges only: `January-March` `January–March`
85
+ `punctilio` doesn’t enable all transformations by default. Fractions and degrees tend to match too aggressively (perfectly applying the degree transformation requires semantic meaning). Superscript letters and punctuation ligatures have spotty font support—this README’s font doesn’t even support the example superscript! Furthermore, `ligatures = true` can change the meaning of text by collapsing question and exclamation marks.
161
86
 
162
- #### `minusReplace(text, options?)`
163
-
164
- Converts hyphens to minus signs in numerical contexts: `-5` → `−5`
165
-
166
- ### Symbol Functions
167
-
168
- #### `ellipsis(text, options?)`
169
-
170
- Converts three periods to ellipsis: `...` → `…`
171
-
172
- #### `multiplication(text, options?)`
173
-
174
- Converts multiplication patterns: `5x5` → `5×5`, `3*4` → `3×4`
175
-
176
- #### `mathSymbols(text)`
177
-
178
- Converts math operators:
179
- - `!=` → `≠`
180
- - `+-` or `+/-` → `±`
181
- - `<=` → `≤`
182
- - `>=` → `≥`
183
- - `~=` or `=~` → `≈`
184
-
185
- #### `legalSymbols(text)`
186
-
187
- Converts legal symbols:
188
- - `(c)` → `©`
189
- - `(r)` → `®`
190
- - `(tm)` → `™`
191
-
192
- #### `arrows(text, options?)`
193
-
194
- Converts arrow patterns:
195
- - `->` or `-->` → `→`
196
- - `<-` or `<--` → `←`
197
- - `<->` or `<-->` → `↔`
198
-
199
- #### `primeMarks(text, options?)`
200
-
201
- Converts straight quotes after numbers to prime marks:
202
- - `5'10"` → `5′10″` (feet and inches)
203
- - `45° 30' 15"` → `45° 30′ 15″` (coordinates)
204
-
205
- #### `fractions(text)`
206
-
207
- Converts common fractions: `1/2` → `½`, `1/4` → `¼`, `3/4` → `¾`, etc.
208
-
209
- #### `degrees(text)`
210
-
211
- Converts temperature notation: `20 C` → `20 °C`, `68 F` → `68 °F`
212
-
213
- #### `symbolTransform(text, options?)`
214
-
215
- Applies all symbol transforms except fractions and degrees.
216
-
217
- ### Constants
218
-
219
- - `DEFAULT_SEPARATOR`: The default separator character (`"\uE000"`)
220
- - `months`: Regex-ready string of month names for date range detection
221
-
222
- ## Character Reference
223
-
224
- | Input | Output | Unicode | Name |
225
- |-------|--------|---------|------|
226
- | `"` | `"` | U+201C | Left double quotation mark |
227
- | `"` | `"` | U+201D | Right double quotation mark |
228
- | `'` | `'` | U+2018 | Left single quotation mark |
229
- | `'` | `'` | U+2019 | Right single quotation mark (apostrophe) |
230
- | `--` | `—` | U+2014 | Em dash |
231
- | `-` (range) | `–` | U+2013 | En dash |
232
- | `-` (negative) | `−` | U+2212 | Minus sign |
233
- | `...` | `…` | U+2026 | Ellipsis |
234
- | `x` (multiply) | `×` | U+00D7 | Multiplication sign |
235
- | `!=` | `≠` | U+2260 | Not equal |
236
- | `+-` | `±` | U+00B1 | Plus-minus |
237
- | `<=` | `≤` | U+2264 | Less than or equal |
238
- | `>=` | `≥` | U+2265 | Greater than or equal |
239
- | `(c)` | `©` | U+00A9 | Copyright |
240
- | `(r)` | `®` | U+00AE | Registered |
241
- | `(tm)` | `™` | U+2122 | Trademark |
242
- | `->` | `→` | U+2192 | Right arrow |
243
- | `<-` | `←` | U+2190 | Left arrow |
244
- | `<->` | `↔` | U+2194 | Left-right arrow |
245
- | `'` (after digit) | `′` | U+2032 | Prime (feet, arcminutes) |
246
- | `"` (after digit) | `″` | U+2033 | Double prime (inches, arcseconds) |
247
-
248
- ## License
249
-
250
- MIT © Alexander Turner
87
+ ```typescript
88
+ transform(text, {
89
+ punctuationStyle: 'american' | 'british' | 'none', // default: 'american'
90
+ dashStyle: 'american' | 'british' | 'none', // default: 'american'
91
+
92
+ symbols: true, // math, legal, arrows
93
+ collapseSpaces: true, // normalize whitespace
94
+ fractions: false, // 1/2 → ½
95
+ degrees: false, // 20 C 20 °C
96
+ superscript: false, // 1st → 1ˢᵗ
97
+ ligatures: false, // ??? → ⁇, ?! → ⁈, !? → ⁉, !!! → !
98
+ })
99
+ ```
@@ -50,6 +50,14 @@ export declare const UNICODE_SYMBOLS: {
50
50
  readonly LEFT_SINGLE_QUOTE: "‘";
51
51
  readonly RIGHT_SINGLE_QUOTE: "’";
52
52
  readonly NBSP: " ";
53
+ readonly SUPERSCRIPT_ST: "ˢᵗ";
54
+ readonly SUPERSCRIPT_ND: "ⁿᵈ";
55
+ readonly SUPERSCRIPT_RD: "ʳᵈ";
56
+ readonly SUPERSCRIPT_TH: "ᵗʰ";
57
+ readonly DOUBLE_QUESTION: "⁇";
58
+ readonly QUESTION_EXCLAMATION: "⁈";
59
+ readonly EXCLAMATION_QUESTION: "⁉";
60
+ readonly DOUBLE_EXCLAMATION: "‼";
53
61
  };
54
62
  /**
55
63
  * Default separator character for text spanning HTML elements.
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;GAEG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwClB,CAAA;AAEV;;;GAGG;AACH,eAAO,MAAM,iBAAiB,WAAW,CAAA;AACzC,eAAO,MAAM,yBAAyB,QAA2D,CAAA"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;GAEG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkDlB,CAAA;AAEV;;;GAGG;AACH,eAAO,MAAM,iBAAiB,WAAW,CAAA;AACzC,eAAO,MAAM,yBAAyB,QAA2D,CAAA"}
package/dist/constants.js CHANGED
@@ -50,6 +50,16 @@ export const UNICODE_SYMBOLS = {
50
50
  LEFT_SINGLE_QUOTE: "\u2018",
51
51
  RIGHT_SINGLE_QUOTE: "\u2019",
52
52
  NBSP: "\u00A0",
53
+ // Superscript ordinal suffixes
54
+ SUPERSCRIPT_ST: "\u02E2\u1D57", // ˢᵗ
55
+ SUPERSCRIPT_ND: "\u207F\u1D48", // ⁿᵈ
56
+ SUPERSCRIPT_RD: "\u02B3\u1D48", // ʳᵈ
57
+ SUPERSCRIPT_TH: "\u1D57\u02B0", // ᵗʰ
58
+ // Punctuation ligatures
59
+ DOUBLE_QUESTION: "\u2047", // ⁇
60
+ QUESTION_EXCLAMATION: "\u2048", // ⁈
61
+ EXCLAMATION_QUESTION: "\u2049", // ⁉
62
+ DOUBLE_EXCLAMATION: "\u203C", // ‼
53
63
  };
54
64
  /**
55
65
  * Default separator character for text spanning HTML elements.
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,QAAQ,EAAE,QAAQ;IAClB,cAAc,EAAE,QAAQ;IACxB,SAAS,EAAE,QAAQ;IACnB,UAAU,EAAE,QAAQ;IACpB,SAAS,EAAE,QAAQ;IACnB,UAAU,EAAE,QAAQ;IACpB,SAAS,EAAE,QAAQ;IACnB,MAAM,EAAE,QAAQ;IAChB,WAAW,EAAE,QAAQ;IACrB,UAAU,EAAE,QAAQ;IACpB,gBAAgB,EAAE,QAAQ;IAC1B,WAAW,EAAE,QAAQ;IACrB,UAAU,EAAE,QAAQ;IACpB,aAAa,EAAE,QAAQ;IACvB,KAAK,EAAE,QAAQ;IACf,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,OAAO,EAAE,QAAQ;IACjB,OAAO,EAAE,QAAQ;IACjB,KAAK,EAAE,QAAQ;IACf,iBAAiB,EAAE,QAAQ;IAC3B,kBAAkB,EAAE,QAAQ;IAC5B,iBAAiB,EAAE,QAAQ;IAC3B,kBAAkB,EAAE,QAAQ;IAC5B,IAAI,EAAE,QAAQ;CACN,CAAA;AAEV;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,QAAQ,CAAA;AACzC,MAAM,CAAC,MAAM,yBAAyB,GAAG,iBAAiB,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAA"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,QAAQ,EAAE,QAAQ;IAClB,cAAc,EAAE,QAAQ;IACxB,SAAS,EAAE,QAAQ;IACnB,UAAU,EAAE,QAAQ;IACpB,SAAS,EAAE,QAAQ;IACnB,UAAU,EAAE,QAAQ;IACpB,SAAS,EAAE,QAAQ;IACnB,MAAM,EAAE,QAAQ;IAChB,WAAW,EAAE,QAAQ;IACrB,UAAU,EAAE,QAAQ;IACpB,gBAAgB,EAAE,QAAQ;IAC1B,WAAW,EAAE,QAAQ;IACrB,UAAU,EAAE,QAAQ;IACpB,aAAa,EAAE,QAAQ;IACvB,KAAK,EAAE,QAAQ;IACf,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,OAAO,EAAE,QAAQ;IACjB,OAAO,EAAE,QAAQ;IACjB,KAAK,EAAE,QAAQ;IACf,iBAAiB,EAAE,QAAQ;IAC3B,kBAAkB,EAAE,QAAQ;IAC5B,iBAAiB,EAAE,QAAQ;IAC3B,kBAAkB,EAAE,QAAQ;IAC5B,IAAI,EAAE,QAAQ;IACd,+BAA+B;IAC/B,cAAc,EAAE,cAAc,EAAE,KAAK;IACrC,cAAc,EAAE,cAAc,EAAE,KAAK;IACrC,cAAc,EAAE,cAAc,EAAE,KAAK;IACrC,cAAc,EAAE,cAAc,EAAE,KAAK;IACrC,wBAAwB;IACxB,eAAe,EAAE,QAAQ,EAAE,IAAI;IAC/B,oBAAoB,EAAE,QAAQ,EAAE,IAAI;IACpC,oBAAoB,EAAE,QAAQ,EAAE,IAAI;IACpC,kBAAkB,EAAE,QAAQ,EAAE,IAAI;CAC1B,CAAA;AAEV;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,QAAQ,CAAA;AACzC,MAAM,CAAC,MAAM,yBAAyB,GAAG,iBAAiB,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAA"}
package/dist/index.d.ts CHANGED
@@ -11,7 +11,7 @@ export { niceQuotes, type QuoteOptions, type PunctuationStyle } from "./quotes.j
11
11
  import type { PunctuationStyle } from "./quotes.js";
12
12
  export { hyphenReplace, enDashNumberRange, enDashDateRange, minusReplace, months, type DashOptions, type DashStyle, } from "./dashes.js";
13
13
  import type { DashStyle } from "./dashes.js";
14
- export { ellipsis, multiplication, mathSymbols, legalSymbols, arrows, degrees, fractions, primeMarks, collapseSpaces, symbolTransform, type SymbolOptions, } from "./symbols.js";
14
+ export { ellipsis, multiplication, mathSymbols, legalSymbols, arrows, degrees, fractions, primeMarks, collapseSpaces, superscript, punctuationLigatures, symbolTransform, type SymbolOptions, } from "./symbols.js";
15
15
  export interface TransformOptions {
16
16
  /**
17
17
  * A boundary marker character used when transforming text that spans
@@ -69,6 +69,18 @@ export interface TransformOptions {
69
69
  * Default: false (can be aggressive)
70
70
  */
71
71
  degrees?: boolean;
72
+ /**
73
+ * Whether to convert ordinal suffixes to Unicode superscript characters.
74
+ * Transforms numbers like "1st", "2nd", "3rd", "4th" to "1ˢᵗ", "2ⁿᵈ", "3ʳᵈ", "4ᵗʰ".
75
+ * Default: false
76
+ */
77
+ superscript?: boolean;
78
+ /**
79
+ * Whether to convert repeated punctuation marks to Unicode ligature characters.
80
+ * Squashes multiple marks: "???" → "⁇", "?!" → "⁈", "!?" → "⁉", "!!!" → "!"
81
+ * Default: false (poor font support)
82
+ */
83
+ ligatures?: boolean;
72
84
  }
73
85
  export { assertSeparatorCountPreserved, countSeparators } from "./utils.js";
74
86
  export { DEFAULT_SEPARATOR } from "./constants.js";
@@ -81,9 +93,11 @@ export { DEFAULT_SEPARATOR } from "./constants.js";
81
93
  * 2. primeMarks (feet/inches, arcminutes/arcseconds)
82
94
  * 3. niceQuotes (smart quotes)
83
95
  * 4. symbolTransform (ellipses, multiplication, math symbols, legal symbols, arrows)
84
- * 5. collapseSpaces (collapses multiple spaces into one)
85
- * 6. fractions (disabled by default)
86
- * 7. degrees (disabled by default)
96
+ * 5. fractions (disabled by default)
97
+ * 6. degrees (disabled by default)
98
+ * 7. superscript (disabled by default)
99
+ * 8. ligatures (disabled by default)
100
+ * 9. collapseSpaces (collapses multiple spaces into one)
87
101
  *
88
102
  * @param text - The text to transform
89
103
  * @param options - Configuration options
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAE,KAAK,YAAY,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAClF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AACnD,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,MAAM,EACN,KAAK,WAAW,EAChB,KAAK,SAAS,GACf,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EACL,QAAQ,EACR,cAAc,EACd,WAAW,EACX,YAAY,EACZ,MAAM,EACN,OAAO,EACP,SAAS,EACT,UAAU,EACV,cAAc,EACd,eAAe,EACf,KAAK,aAAa,GACnB,MAAM,cAAc,CAAA;AAErB,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IAEjB;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IAExB;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IAEnC;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,SAAS,CAAA;IAErB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IAEnB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAQD,OAAO,EAAE,6BAA6B,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAC3E,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAElD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,MAAM,CA4B9E"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAE,KAAK,YAAY,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAClF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AACnD,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,MAAM,EACN,KAAK,WAAW,EAChB,KAAK,SAAS,GACf,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EACL,QAAQ,EACR,cAAc,EACd,WAAW,EACX,YAAY,EACZ,MAAM,EACN,OAAO,EACP,SAAS,EACT,UAAU,EACV,cAAc,EACd,WAAW,EACX,oBAAoB,EACpB,eAAe,EACf,KAAK,aAAa,GACnB,MAAM,cAAc,CAAA;AAErB,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IAEjB;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IAExB;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IAEnC;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,SAAS,CAAA;IAErB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IAEnB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IAEjB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IAErB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAQD,OAAO,EAAE,6BAA6B,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAC3E,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAElD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,MAAM,CAoC9E"}
package/dist/index.js CHANGED
@@ -9,10 +9,10 @@
9
9
  */
10
10
  export { niceQuotes } from "./quotes.js";
11
11
  export { hyphenReplace, enDashNumberRange, enDashDateRange, minusReplace, months, } from "./dashes.js";
12
- export { ellipsis, multiplication, mathSymbols, legalSymbols, arrows, degrees, fractions, primeMarks, collapseSpaces, symbolTransform, } from "./symbols.js";
12
+ export { ellipsis, multiplication, mathSymbols, legalSymbols, arrows, degrees, fractions, primeMarks, collapseSpaces, superscript, punctuationLigatures, symbolTransform, } from "./symbols.js";
13
13
  import { niceQuotes } from "./quotes.js";
14
14
  import { hyphenReplace } from "./dashes.js";
15
- import { symbolTransform, fractions as fractionsTransform, degrees as degreesTransform, primeMarks, collapseSpaces as collapseSpacesTransform } from "./symbols.js";
15
+ import { symbolTransform, fractions as fractionsTransform, degrees as degreesTransform, superscript as superscriptTransform, primeMarks, collapseSpaces as collapseSpacesTransform, punctuationLigatures as ligaturesTransform } from "./symbols.js";
16
16
  import { assertSeparatorCountPreserved } from "./utils.js";
17
17
  import { DEFAULT_SEPARATOR } from "./constants.js";
18
18
  export { assertSeparatorCountPreserved, countSeparators } from "./utils.js";
@@ -26,9 +26,11 @@ export { DEFAULT_SEPARATOR } from "./constants.js";
26
26
  * 2. primeMarks (feet/inches, arcminutes/arcseconds)
27
27
  * 3. niceQuotes (smart quotes)
28
28
  * 4. symbolTransform (ellipses, multiplication, math symbols, legal symbols, arrows)
29
- * 5. collapseSpaces (collapses multiple spaces into one)
30
- * 6. fractions (disabled by default)
31
- * 7. degrees (disabled by default)
29
+ * 5. fractions (disabled by default)
30
+ * 6. degrees (disabled by default)
31
+ * 7. superscript (disabled by default)
32
+ * 8. ligatures (disabled by default)
33
+ * 9. collapseSpaces (collapses multiple spaces into one)
32
34
  *
33
35
  * @param text - The text to transform
34
36
  * @param options - Configuration options
@@ -51,7 +53,7 @@ export { DEFAULT_SEPARATOR } from "./constants.js";
51
53
  export function transform(text, options = {}) {
52
54
  const separator = options.separator ?? DEFAULT_SEPARATOR;
53
55
  const original = text;
54
- const { symbols = true, fractions = false, degrees = false, collapseSpaces = true, ...separatorOpts } = options;
56
+ const { symbols = true, fractions = false, degrees = false, superscript = false, ligatures = false, collapseSpaces = true, ...separatorOpts } = options;
55
57
  text = hyphenReplace(text, separatorOpts);
56
58
  text = primeMarks(text, separatorOpts);
57
59
  text = niceQuotes(text, separatorOpts);
@@ -64,6 +66,12 @@ export function transform(text, options = {}) {
64
66
  if (degrees) {
65
67
  text = degreesTransform(text);
66
68
  }
69
+ if (superscript) {
70
+ text = superscriptTransform(text, separatorOpts);
71
+ }
72
+ if (ligatures) {
73
+ text = ligaturesTransform(text, separatorOpts);
74
+ }
67
75
  if (collapseSpaces) {
68
76
  text = collapseSpacesTransform(text);
69
77
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAA4C,MAAM,aAAa,CAAA;AAElF,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,MAAM,GAGP,MAAM,aAAa,CAAA;AAEpB,OAAO,EACL,QAAQ,EACR,cAAc,EACd,WAAW,EACX,YAAY,EACZ,MAAM,EACN,OAAO,EACP,SAAS,EACT,UAAU,EACV,cAAc,EACd,eAAe,GAEhB,MAAM,cAAc,CAAA;AAmErB,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,eAAe,EAAE,SAAS,IAAI,kBAAkB,EAAE,OAAO,IAAI,gBAAgB,EAAE,UAAU,EAAE,cAAc,IAAI,uBAAuB,EAAE,MAAM,cAAc,CAAA;AACnK,OAAO,EAAE,6BAA6B,EAAE,MAAM,YAAY,CAAA;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAElD,OAAO,EAAE,6BAA6B,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAC3E,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAElD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,UAA4B,EAAE;IACpE,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,iBAAiB,CAAA;IACxD,MAAM,QAAQ,GAAG,IAAI,CAAA;IACrB,MAAM,EAAE,OAAO,GAAG,IAAI,EAAE,SAAS,GAAG,KAAK,EAAE,OAAO,GAAG,KAAK,EAAE,cAAc,GAAG,IAAI,EAAE,GAAG,aAAa,EAAE,GAAG,OAAO,CAAA;IAE/G,IAAI,GAAG,aAAa,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;IACzC,IAAI,GAAG,UAAU,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;IACtC,IAAI,GAAG,UAAU,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;IAEtC,IAAI,OAAO,EAAE,CAAC;QACZ,IAAI,GAAG,eAAe,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;IAC7C,CAAC;IAED,IAAI,SAAS,EAAE,CAAC;QACd,IAAI,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAA;IACjC,CAAC;IAED,IAAI,OAAO,EAAE,CAAC;QACZ,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAA;IAC/B,CAAC;IAED,IAAI,cAAc,EAAE,CAAC;QACnB,IAAI,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAA;IACtC,CAAC;IAED,6BAA6B,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,CAAC,CAAA;IAErE,OAAO,IAAI,CAAA;AACb,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAA4C,MAAM,aAAa,CAAA;AAElF,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,MAAM,GAGP,MAAM,aAAa,CAAA;AAEpB,OAAO,EACL,QAAQ,EACR,cAAc,EACd,WAAW,EACX,YAAY,EACZ,MAAM,EACN,OAAO,EACP,SAAS,EACT,UAAU,EACV,cAAc,EACd,WAAW,EACX,oBAAoB,EACpB,eAAe,GAEhB,MAAM,cAAc,CAAA;AAiFrB,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,eAAe,EAAE,SAAS,IAAI,kBAAkB,EAAE,OAAO,IAAI,gBAAgB,EAAE,WAAW,IAAI,oBAAoB,EAAE,UAAU,EAAE,cAAc,IAAI,uBAAuB,EAAE,oBAAoB,IAAI,kBAAkB,EAAE,MAAM,cAAc,CAAA;AACpP,OAAO,EAAE,6BAA6B,EAAE,MAAM,YAAY,CAAA;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAElD,OAAO,EAAE,6BAA6B,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAC3E,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAElD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,UAA4B,EAAE;IACpE,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,iBAAiB,CAAA;IACxD,MAAM,QAAQ,GAAG,IAAI,CAAA;IACrB,MAAM,EAAE,OAAO,GAAG,IAAI,EAAE,SAAS,GAAG,KAAK,EAAE,OAAO,GAAG,KAAK,EAAE,WAAW,GAAG,KAAK,EAAE,SAAS,GAAG,KAAK,EAAE,cAAc,GAAG,IAAI,EAAE,GAAG,aAAa,EAAE,GAAG,OAAO,CAAA;IAEvJ,IAAI,GAAG,aAAa,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;IACzC,IAAI,GAAG,UAAU,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;IACtC,IAAI,GAAG,UAAU,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;IAEtC,IAAI,OAAO,EAAE,CAAC;QACZ,IAAI,GAAG,eAAe,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;IAC7C,CAAC;IAED,IAAI,SAAS,EAAE,CAAC;QACd,IAAI,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAA;IACjC,CAAC;IAED,IAAI,OAAO,EAAE,CAAC;QACZ,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAA;IAC/B,CAAC;IAED,IAAI,WAAW,EAAE,CAAC;QAChB,IAAI,GAAG,oBAAoB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;IAClD,CAAC;IAED,IAAI,SAAS,EAAE,CAAC;QACd,IAAI,GAAG,kBAAkB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;IAChD,CAAC;IAED,IAAI,cAAc,EAAE,CAAC;QACnB,IAAI,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAA;IACtC,CAAC;IAED,6BAA6B,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,CAAC,CAAA;IAErE,OAAO,IAAI,CAAA;AACb,CAAC"}
package/dist/symbols.d.ts CHANGED
@@ -35,28 +35,10 @@ export declare function ellipsis(text: string, options?: SymbolOptions): string;
35
35
  * - Dimensions: "5x5" → "5×5"
36
36
  * - Trailing multiplier: "5x" → "5×" (when followed by word boundary)
37
37
  * - Asterisk multiplication: "5*3" → "5×3" (when between numbers)
38
- *
39
- * @example
40
- * ```ts
41
- * multiplication("The room is 10x12 feet")
42
- * // → "The room is 10×12 feet"
43
- *
44
- * multiplication("2x speed")
45
- * // → "2× speed"
46
- * ```
47
38
  */
48
39
  export declare function multiplication(text: string, options?: SymbolOptions): string;
49
40
  /**
50
41
  * Converts ASCII mathematical symbols to proper Unicode equivalents.
51
- *
52
- * @example
53
- * ```ts
54
- * mathSymbols("x != y and a <= b")
55
- * // → "x ≠ y and a ≤ b"
56
- *
57
- * mathSymbols("The answer is +- 5%")
58
- * // → "The answer is ± 5%"
59
- * ```
60
42
  */
61
43
  export declare function mathSymbols(text: string): string;
62
44
  /**
@@ -74,15 +56,6 @@ export declare function legalSymbols(text: string): string;
74
56
  *
75
57
  * Note: Only converts when surrounded by spaces or at word boundaries
76
58
  * to avoid false matches in code or URLs.
77
- *
78
- * @example
79
- * ```ts
80
- * arrows("A -> B -> C")
81
- * // → "A → B → C"
82
- *
83
- * arrows("left <-> right")
84
- * // → "left ↔ right"
85
- * ```
86
59
  */
87
60
  export declare function arrows(text: string, options?: SymbolOptions): string;
88
61
  /**
@@ -94,15 +67,6 @@ export declare function arrows(text: string, options?: SymbolOptions): string;
94
67
  *
95
68
  * Only matches when followed by C or F (case insensitive) to avoid
96
69
  * false positives.
97
- *
98
- * @example
99
- * ```ts
100
- * degrees("The temperature is 20 C")
101
- * // → "The temperature is 20 °C"
102
- *
103
- * degrees("Water boils at 212F")
104
- * // → "Water boils at 212 °F"
105
- * ```
106
70
  */
107
71
  export declare function degrees(text: string, options?: SymbolOptions): string;
108
72
  /**
@@ -114,15 +78,6 @@ export declare function degrees(text: string, options?: SymbolOptions): string;
114
78
  *
115
79
  * This should be called BEFORE smart quote transformations to prevent
116
80
  * quotes in measurements from being curled.
117
- *
118
- * @example
119
- * ```ts
120
- * primeMarks("He's 5'10\" tall")
121
- * // → "He's 5′10″ tall"
122
- *
123
- * primeMarks("Location: 45° 30' 15\"")
124
- * // → "Location: 45° 30′ 15″"
125
- * ```
126
81
  */
127
82
  export declare function primeMarks(text: string, options?: SymbolOptions): string;
128
83
  /**
@@ -144,6 +99,27 @@ export declare function primeMarks(text: string, options?: SymbolOptions): strin
144
99
  * ```
145
100
  */
146
101
  export declare function fractions(text: string, options?: SymbolOptions): string;
102
+ /**
103
+ * Converts ordinal suffixes to Unicode superscript characters.
104
+ *
105
+ * Handles ordinal numbers like:
106
+ * - "1st" → "1ˢᵗ"
107
+ * - "2nd" → "2ⁿᵈ"
108
+ * - "3rd" → "3ʳᵈ"
109
+ * - "4th" → "4ᵗʰ"
110
+ *
111
+ * Works with any number ending in appropriate suffixes (21st, 42nd, 103rd, etc.)
112
+ *
113
+ * @example
114
+ * ```ts
115
+ * superscript("The 1st place winner")
116
+ * // → "The 1ˢᵗ place winner"
117
+ *
118
+ * superscript("Born on the 30th of June")
119
+ * // → "Born on the 30ᵗʰ of June"
120
+ * ```
121
+ */
122
+ export declare function superscript(text: string, options?: SymbolOptions): string;
147
123
  /**
148
124
  * Collapses multiple consecutive spaces (including non-breaking spaces) into a single space.
149
125
  *
@@ -163,6 +139,20 @@ export declare function fractions(text: string, options?: SymbolOptions): string
163
139
  * ```
164
140
  */
165
141
  export declare function collapseSpaces(text: string): string;
142
+ /**
143
+ * Converts repeated punctuation marks to Unicode ligature characters,
144
+ * squashing multiple marks to a single character.
145
+ *
146
+ * Handles:
147
+ * - "??" or "???" etc → "⁇" (squashed to double question mark ligature)
148
+ * - "?!" or "?!!" etc → "⁈" (question exclamation mark)
149
+ * - "!?" or "!??" etc → "⁉" (exclamation question mark)
150
+ * - "!!" or "!!!" etc → "!" (squashed to single exclamation)
151
+ *
152
+ * Note: These ligatures have poor font support, so this function is
153
+ * disabled by default.
154
+ */
155
+ export declare function punctuationLigatures(text: string, options?: SymbolOptions): string;
166
156
  /**
167
157
  * Applies all symbol transformations.
168
158
  *
@@ -1 +1 @@
1
- {"version":3,"file":"symbols.d.ts","sourceRoot":"","sources":["../src/symbols.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AA6BD;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAe1E;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAkBhF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAShD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKjD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAyBxE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAWzE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CA+B5E;AAwBD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAkB3E;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CASjF"}
1
+ {"version":3,"file":"symbols.d.ts","sourceRoot":"","sources":["../src/symbols.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAoCD;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAe1E;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAkBhF;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAShD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKjD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAyBxE;AAED;;;;;;;;;GASG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAWzE;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CA+B5E;AAwBD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAkB3E;AAYD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAgB7E;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAiCtF;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CASjF"}
package/dist/symbols.js CHANGED
@@ -13,7 +13,7 @@ import { UNICODE_SYMBOLS, ESCAPED_DEFAULT_SEPARATOR } from "./constants.js";
13
13
  function escapeRegex(str) {
14
14
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
15
15
  }
16
- const { ELLIPSIS, MULTIPLICATION, NOT_EQUAL, PLUS_MINUS, COPYRIGHT, REGISTERED, TRADEMARK, DEGREE, ARROW_RIGHT, ARROW_LEFT, ARROW_LEFT_RIGHT, APPROXIMATE, LESS_EQUAL, GREATER_EQUAL, PRIME, DOUBLE_PRIME, NBSP, } = UNICODE_SYMBOLS;
16
+ const { ELLIPSIS, MULTIPLICATION, NOT_EQUAL, PLUS_MINUS, COPYRIGHT, REGISTERED, TRADEMARK, DEGREE, ARROW_RIGHT, ARROW_LEFT, ARROW_LEFT_RIGHT, APPROXIMATE, LESS_EQUAL, GREATER_EQUAL, PRIME, DOUBLE_PRIME, NBSP, SUPERSCRIPT_ST, SUPERSCRIPT_ND, SUPERSCRIPT_RD, SUPERSCRIPT_TH, DOUBLE_QUESTION, QUESTION_EXCLAMATION, EXCLAMATION_QUESTION } = UNICODE_SYMBOLS;
17
17
  /**
18
18
  * Converts three periods to a proper ellipsis character.
19
19
  *
@@ -43,15 +43,6 @@ export function ellipsis(text, options = {}) {
43
43
  * - Dimensions: "5x5" → "5×5"
44
44
  * - Trailing multiplier: "5x" → "5×" (when followed by word boundary)
45
45
  * - Asterisk multiplication: "5*3" → "5×3" (when between numbers)
46
- *
47
- * @example
48
- * ```ts
49
- * multiplication("The room is 10x12 feet")
50
- * // → "The room is 10×12 feet"
51
- *
52
- * multiplication("2x speed")
53
- * // → "2× speed"
54
- * ```
55
46
  */
56
47
  export function multiplication(text, options = {}) {
57
48
  const chr = options.separator
@@ -70,15 +61,6 @@ export function multiplication(text, options = {}) {
70
61
  }
71
62
  /**
72
63
  * Converts ASCII mathematical symbols to proper Unicode equivalents.
73
- *
74
- * @example
75
- * ```ts
76
- * mathSymbols("x != y and a <= b")
77
- * // → "x ≠ y and a ≤ b"
78
- *
79
- * mathSymbols("The answer is +- 5%")
80
- * // → "The answer is ± 5%"
81
- * ```
82
64
  */
83
65
  export function mathSymbols(text) {
84
66
  return text
@@ -110,15 +92,6 @@ export function legalSymbols(text) {
110
92
  *
111
93
  * Note: Only converts when surrounded by spaces or at word boundaries
112
94
  * to avoid false matches in code or URLs.
113
- *
114
- * @example
115
- * ```ts
116
- * arrows("A -> B -> C")
117
- * // → "A → B → C"
118
- *
119
- * arrows("left <-> right")
120
- * // → "left ↔ right"
121
- * ```
122
95
  */
123
96
  export function arrows(text, options = {}) {
124
97
  const chr = options.separator
@@ -142,15 +115,6 @@ export function arrows(text, options = {}) {
142
115
  *
143
116
  * Only matches when followed by C or F (case insensitive) to avoid
144
117
  * false positives.
145
- *
146
- * @example
147
- * ```ts
148
- * degrees("The temperature is 20 C")
149
- * // → "The temperature is 20 °C"
150
- *
151
- * degrees("Water boils at 212F")
152
- * // → "Water boils at 212 °F"
153
- * ```
154
118
  */
155
119
  export function degrees(text, options = {}) {
156
120
  const chr = options.separator
@@ -169,15 +133,6 @@ export function degrees(text, options = {}) {
169
133
  *
170
134
  * This should be called BEFORE smart quote transformations to prevent
171
135
  * quotes in measurements from being curled.
172
- *
173
- * @example
174
- * ```ts
175
- * primeMarks("He's 5'10\" tall")
176
- * // → "He's 5′10″ tall"
177
- *
178
- * primeMarks("Location: 45° 30' 15\"")
179
- * // → "Location: 45° 30′ 15″"
180
- * ```
181
136
  */
182
137
  export function primeMarks(text, options = {}) {
183
138
  const chr = options.separator
@@ -254,6 +209,47 @@ export function fractions(text, options = {}) {
254
209
  }
255
210
  return text;
256
211
  }
212
+ /**
213
+ * Map of ordinal suffixes to their Unicode superscript equivalents.
214
+ */
215
+ const ORDINAL_MAP = {
216
+ st: SUPERSCRIPT_ST,
217
+ nd: SUPERSCRIPT_ND,
218
+ rd: SUPERSCRIPT_RD,
219
+ th: SUPERSCRIPT_TH,
220
+ };
221
+ /**
222
+ * Converts ordinal suffixes to Unicode superscript characters.
223
+ *
224
+ * Handles ordinal numbers like:
225
+ * - "1st" → "1ˢᵗ"
226
+ * - "2nd" → "2ⁿᵈ"
227
+ * - "3rd" → "3ʳᵈ"
228
+ * - "4th" → "4ᵗʰ"
229
+ *
230
+ * Works with any number ending in appropriate suffixes (21st, 42nd, 103rd, etc.)
231
+ *
232
+ * @example
233
+ * ```ts
234
+ * superscript("The 1st place winner")
235
+ * // → "The 1ˢᵗ place winner"
236
+ *
237
+ * superscript("Born on the 30th of June")
238
+ * // → "Born on the 30ᵗʰ of June"
239
+ * ```
240
+ */
241
+ export function superscript(text, options = {}) {
242
+ const chr = options.separator
243
+ ? escapeRegex(options.separator)
244
+ : ESCAPED_DEFAULT_SEPARATOR;
245
+ // Match number + optional separator + ordinal suffix at word boundary
246
+ // Use case-insensitive matching for the suffix
247
+ const pattern = new RegExp(`(?<num>\\d${chr}?)(?<suffix>st|nd|rd|th)\\b`, "gi");
248
+ return text.replace(pattern, (_match, num, suffix) => {
249
+ const superscriptSuffix = ORDINAL_MAP[suffix.toLowerCase()];
250
+ return num + superscriptSuffix;
251
+ });
252
+ }
257
253
  /**
258
254
  * Collapses multiple consecutive spaces (including non-breaking spaces) into a single space.
259
255
  *
@@ -275,6 +271,35 @@ export function fractions(text, options = {}) {
275
271
  export function collapseSpaces(text) {
276
272
  return text.replace(new RegExp(`(?<first>[ ${NBSP}])[ ${NBSP}]+`, "g"), "$<first>");
277
273
  }
274
+ /**
275
+ * Converts repeated punctuation marks to Unicode ligature characters,
276
+ * squashing multiple marks to a single character.
277
+ *
278
+ * Handles:
279
+ * - "??" or "???" etc → "⁇" (squashed to double question mark ligature)
280
+ * - "?!" or "?!!" etc → "⁈" (question exclamation mark)
281
+ * - "!?" or "!??" etc → "⁉" (exclamation question mark)
282
+ * - "!!" or "!!!" etc → "!" (squashed to single exclamation)
283
+ *
284
+ * Note: These ligatures have poor font support, so this function is
285
+ * disabled by default.
286
+ */
287
+ export function punctuationLigatures(text, options = {}) {
288
+ const chr = options.separator
289
+ ? escapeRegex(options.separator)
290
+ : ESCAPED_DEFAULT_SEPARATOR;
291
+ // Order matters: handle mixed punctuation first, then repeated
292
+ // Patterns capture separators between characters and preserve them after the ligature
293
+ // ?!+ → ⁈ (question followed by one or more exclamation marks)
294
+ text = text.replace(new RegExp(`\\?(${chr})?!(?:${chr}?!)*`, "g"), (_match, sep) => QUESTION_EXCLAMATION + (sep || ""));
295
+ // !?+ → ⁉ (exclamation followed by one or more question marks)
296
+ text = text.replace(new RegExp(`!(${chr})?\\?(?:${chr}?\\?)*`, "g"), (_match, sep) => EXCLAMATION_QUESTION + (sep || ""));
297
+ // ??+ → ⁇ (two or more question marks squashed to ligature)
298
+ text = text.replace(new RegExp(`\\?(${chr})?\\?(?:${chr}?\\?)*`, "g"), (_match, sep) => DOUBLE_QUESTION + (sep || ""));
299
+ // !!+ → ! (two or more exclamation marks squashed to single)
300
+ text = text.replace(new RegExp(`!(${chr})?!(?:${chr}?!)*`, "g"), (_match, sep) => "!" + (sep || ""));
301
+ return text;
302
+ }
278
303
  /**
279
304
  * Applies all symbol transformations.
280
305
  *
@@ -1 +1 @@
1
- {"version":3,"file":"symbols.js","sourceRoot":"","sources":["../src/symbols.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"symbols.js","sourceRoot":"","sources":["../src/symbols.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "punctilio",
3
- "version": "0.4.0",
3
+ "version": "0.4.14",
4
4
  "description": "Smart typography transformations: curly quotes, em-dashes, en-dashes, and more",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -44,6 +44,9 @@
44
44
  "eslint": "^9.39.2",
45
45
  "eslint-plugin-regexp": "^3.0.0",
46
46
  "jest": "^29.7.0",
47
+ "smartquotes": "2.3.2",
48
+ "smartypants": "0.2.2",
49
+ "tipograph": "0.7.4",
47
50
  "ts-jest": "^29.1.2",
48
51
  "typescript": "^5.3.3",
49
52
  "typescript-eslint": "^8.54.0"