punctilio 1.1.2 → 1.2.2
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 +43 -21
- package/dist/constants.d.ts +21 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +25 -0
- package/dist/constants.js.map +1 -1
- package/dist/symbols.d.ts +1 -1
- package/dist/symbols.d.ts.map +1 -1
- package/dist/symbols.js +77 -46
- package/dist/symbols.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -36,17 +36,17 @@ My [`benchmark.mjs`](./benchmark.mjs) measures how well libraries handle a [wide
|
|
|
36
36
|
|
|
37
37
|
| Package | Score |
|
|
38
38
|
|--------:|:------|
|
|
39
|
-
| `punctilio` |
|
|
40
|
-
| `tipograph` |
|
|
41
|
-
| `typograf` |
|
|
42
|
-
| `smartquotes` |
|
|
43
|
-
| `smartypants` |
|
|
44
|
-
| `retext-smartypants` |
|
|
39
|
+
| `punctilio` | 106/109 (97%) |
|
|
40
|
+
| `tipograph` | 70/109 (64%) |
|
|
41
|
+
| `typograf` | 58/109 (53%) |
|
|
42
|
+
| `smartquotes` | 51/109 (47%) |
|
|
43
|
+
| `smartypants` | 49/109 (45%) |
|
|
44
|
+
| `retext-smartypants` | 47/109 (43%) |
|
|
45
45
|
|
|
46
46
|
| Feature | Example | `smartypants` | `tipograph` | `smartquotes` | `typograf` | `punctilio` |
|
|
47
47
|
|--------:|:-------:|:-------:|:-------:|:-------:|:-------:|:-------:|
|
|
48
|
-
| Smart quotes | "hello" →
|
|
49
|
-
| Leading apostrophe | 'Twas →
|
|
48
|
+
| Smart quotes | "hello" → “hello” | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
49
|
+
| Leading apostrophe | 'Twas → ’Twas | ✗ | ✗ | ✓ | ✗ | ✓ |
|
|
50
50
|
| Em dash | -- → — | ✓ | ✗ | ✗ | ✓ | ✓ |
|
|
51
51
|
| En dash (ranges) | 1-5 → 1–5 | ✗ | ✓ | ✗ | ✗ | ✓ |
|
|
52
52
|
| Minus sign | -5 → −5 | ✗ | ✓ | ✗ | ✗ | ✓ |
|
|
@@ -61,14 +61,37 @@ My [`benchmark.mjs`](./benchmark.mjs) measures how well libraries handle a [wide
|
|
|
61
61
|
| Superscripts | 1st → 1ˢᵗ | ✗ | ✗ | ✗ | ✗ | ✓ |
|
|
62
62
|
| Localization | American/British | ✗ | ✗ | ✗ | ✗ | ✓ |
|
|
63
63
|
| Ligatures | ?? → ⁇ | ✗ | ✓ | ✗ | ✗ | ✓ |
|
|
64
|
-
| Non-English quotes | „Hallo
|
|
64
|
+
| Non-English quotes | „Hallo” (German) | ✗ | ✓ | ✗ | ✓ | ✗ |
|
|
65
65
|
| Non-breaking spaces | Chapter 1 | ✗ | ✗ | ✗ | ✓ | ✗ |
|
|
66
66
|
|
|
67
|
-
`typograf` uniquely inserts non-breaking spaces to prevent bad line breaks (e.g. before numbers, after colons). I might add this to `punctilio` in the future. `punctilio
|
|
67
|
+
`typograf` uniquely inserts non-breaking spaces to prevent bad line breaks (e.g. before numbers, after colons). I might add this to `punctilio` in the future. `punctilio`’s other missing feature is non-English quote support—feel free to make a pull request!
|
|
68
|
+
|
|
69
|
+
### Known limitations of `punctilio`
|
|
70
|
+
|
|
71
|
+
| Pattern | Behavior | Notes |
|
|
72
|
+
|:--------|:---------|:------|
|
|
73
|
+
| `—'Hi'—` | Opening `'` not converted | Single quote after em-dash at start is ambiguous |
|
|
74
|
+
| `"Hello"--"second"` | `--` not converted | Unspaced dashes between quotes need word boundaries |
|
|
75
|
+
| `10' x 12'` | Second `'` not converted | Quote balancing prevents double prime conversion |
|
|
76
|
+
| `€5-€10` | Not converted to en-dash | Only `$` currency prefix supported for ranges |
|
|
77
|
+
| `2-3pm` | Not converted to en-dash | Suffix letters prevent number range detection |
|
|
78
|
+
| `. . .` (spaced) | Not converted to ellipsis | Only consecutive dots (`...`) are converted |
|
|
79
|
+
| `No. 3` | Doesn’t replace normal space with a non-breaking one | Requires major new feature |
|
|
80
|
+
| German/French quotes | Not supported | `« Bonjour »` requires language detection |
|
|
81
|
+
|
|
82
|
+
## Test suite
|
|
83
|
+
|
|
84
|
+
Setting aside the benchmark, `punctilio`’s test suite includes 600+ tests at 100% branch coverage, including edge cases derived from competitor libraries ([`smartquotes`](https://github.com/kellym/smartquotes.js), [`retext-smartypants`](https://github.com/retextjs/retext-smartypants), [`typograf`](https://github.com/typograf/typograf)), and the [Standard Ebooks typography manual](https://standardebooks.org/manual/). Key test categories:
|
|
85
|
+
|
|
86
|
+
- _Quote handling_: Unicode text, nested quotes, contractions, Irish names (O’Brien), leading apostrophes (’99, ’twas)
|
|
87
|
+
- _Dash transformations_: Year/page/score ranges, model name preservation (Llama-2-7B, GPT-4), phone numbers, ISBNs
|
|
88
|
+
- _Symbol transforms_: Measurements (6′2″), coordinates (40° 44′ N), temperatures, fractions, math symbols
|
|
89
|
+
- _Idempotency_: All transformations are verified to be stable when applied multiple times
|
|
90
|
+
- _Separator boundaries_: Tests verify HTML DOM integration doesn’t break patterns
|
|
68
91
|
|
|
69
92
|
## Works with HTML DOMs via separation boundaries
|
|
70
93
|
|
|
71
|
-
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,
|
|
94
|
+
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, youve lost track of where `</em>` belonged.
|
|
72
95
|
|
|
73
96
|
`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.
|
|
74
97
|
|
|
@@ -95,7 +118,7 @@ transform(text, {
|
|
|
95
118
|
punctuationStyle: 'american' | 'british' | 'none', // default: 'american'
|
|
96
119
|
dashStyle: 'american' | 'british' | 'none', // default: 'american'
|
|
97
120
|
|
|
98
|
-
symbols: true, // math, legal, arrows
|
|
121
|
+
symbols: true, // math, legal, arrows, primes
|
|
99
122
|
collapseSpaces: true, // normalize whitespace
|
|
100
123
|
fractions: false, // 1/2 → ½
|
|
101
124
|
degrees: false, // 20 C → 20 °C
|
|
@@ -105,12 +128,11 @@ transform(text, {
|
|
|
105
128
|
})
|
|
106
129
|
```
|
|
107
130
|
|
|
108
|
-
|
|
109
|
-
-
|
|
110
|
-
-
|
|
111
|
-
|
|
112
|
-
The `
|
|
113
|
-
-
|
|
114
|
-
-
|
|
115
|
-
|
|
116
|
-
`punctilio` is idempotent by design: `transform(transform(text))` always equals `transform(text)`. If performance is critical, set `checkIdempotency: false` to skip the verification pass.
|
|
131
|
+
- Prime marks (`5'10"` → `5′10″`) require semantic understanding to distinguish from closing quotes (e.g. `"Term 1"` should produce closing quotes). `punctilio` counts quotes to heuristically guess whether the matched number at the end of a quote (if not, it requires a prime mark). Other libraries like `tipograph` 0.7.4 use simpler patterns that make more mistakes. That said, `punctilio` is still not perfect and will sometimes wrongly convert to ending quotation marks: `transform('I said "5" sounds right"')` will wrongly produce a closed double quote after the 5” instead of a double prime (correct).
|
|
132
|
+
- The `american` style follows the [Chicago Manual of Style](https://www.chicagomanualofstyle.org/):
|
|
133
|
+
- Periods and commas go inside quotation marks (“Hello,” she said.)
|
|
134
|
+
- Unspaced em-dashes between words (word—word)
|
|
135
|
+
- The `british` style follows [Oxford style](https://www.ox.ac.uk/sites/files/oxford/Style%20Guide%20quick%20reference%20A-Z.pdf):
|
|
136
|
+
- Periods and commas go outside quotation marks (“Hello”, she said.)
|
|
137
|
+
- Spaced en-dashes between words (word – word)
|
|
138
|
+
- `punctilio` is idempotent by design: `transform(transform(text))` always equals `transform(text)`. If performance is critical, set `checkIdempotency: false` to skip the verification pass.
|
package/dist/constants.d.ts
CHANGED
|
@@ -112,4 +112,25 @@ export declare function wordBoundaryStart(escapedSeparator: string): string;
|
|
|
112
112
|
* // With text "1st\uE000ly": \b would match after t, but wbe won't
|
|
113
113
|
*/
|
|
114
114
|
export declare function wordBoundaryEnd(escapedSeparator: string): string;
|
|
115
|
+
/**
|
|
116
|
+
* Pattern string for space characters (regular space and non-breaking space).
|
|
117
|
+
* Use inside regex character classes: `[${SPACE_CHARS}]`
|
|
118
|
+
*/
|
|
119
|
+
export declare const SPACE_CHARS: string;
|
|
120
|
+
/**
|
|
121
|
+
* Creates a lookbehind pattern that matches after whitespace, separator, or start of string.
|
|
122
|
+
* Used for arrow patterns and other constructs that should appear at word boundaries.
|
|
123
|
+
*
|
|
124
|
+
* @param escapedSeparator - Regex-escaped separator string
|
|
125
|
+
* @returns Pattern string: `(?<=[\\s${sep}]|^)`
|
|
126
|
+
*/
|
|
127
|
+
export declare function spaceBoundaryStart(escapedSeparator: string): string;
|
|
128
|
+
/**
|
|
129
|
+
* Creates a lookahead pattern that matches before whitespace, separator, or end of string.
|
|
130
|
+
* Used for arrow patterns and other constructs that should appear at word boundaries.
|
|
131
|
+
*
|
|
132
|
+
* @param escapedSeparator - Regex-escaped separator string
|
|
133
|
+
* @returns Pattern string: `(?=[\\s${sep}]|$)`
|
|
134
|
+
*/
|
|
135
|
+
export declare function spaceBoundaryEnd(escapedSeparator: string): string;
|
|
115
136
|
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH;;GAEG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkDlB,CAAA;AAEV;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,aAAa,sFAAsF,CAAA;AAEhH;;;GAGG;AACH,eAAO,MAAM,iBAAiB,WAAW,CAAA;AACzC,eAAO,MAAM,yBAAyB,QAAwC,CAAA;AAE9E;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAElE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAEhE"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH;;GAEG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkDlB,CAAA;AAEV;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,aAAa,sFAAsF,CAAA;AAEhH;;;GAGG;AACH,eAAO,MAAM,iBAAiB,WAAW,CAAA;AACzC,eAAO,MAAM,yBAAyB,QAAwC,CAAA;AAE9E;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAElE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED;;;GAGG;AACH,eAAO,MAAM,WAAW,QAA6B,CAAA;AAErD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAEjE"}
|
package/dist/constants.js
CHANGED
|
@@ -119,4 +119,29 @@ export function wordBoundaryStart(escapedSeparator) {
|
|
|
119
119
|
export function wordBoundaryEnd(escapedSeparator) {
|
|
120
120
|
return `\\b(?!${escapedSeparator}*\\w)`;
|
|
121
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* Pattern string for space characters (regular space and non-breaking space).
|
|
124
|
+
* Use inside regex character classes: `[${SPACE_CHARS}]`
|
|
125
|
+
*/
|
|
126
|
+
export const SPACE_CHARS = ` ${UNICODE_SYMBOLS.NBSP}`;
|
|
127
|
+
/**
|
|
128
|
+
* Creates a lookbehind pattern that matches after whitespace, separator, or start of string.
|
|
129
|
+
* Used for arrow patterns and other constructs that should appear at word boundaries.
|
|
130
|
+
*
|
|
131
|
+
* @param escapedSeparator - Regex-escaped separator string
|
|
132
|
+
* @returns Pattern string: `(?<=[\\s${sep}]|^)`
|
|
133
|
+
*/
|
|
134
|
+
export function spaceBoundaryStart(escapedSeparator) {
|
|
135
|
+
return `(?<=[\\s${escapedSeparator}]|^)`;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Creates a lookahead pattern that matches before whitespace, separator, or end of string.
|
|
139
|
+
* Used for arrow patterns and other constructs that should appear at word boundaries.
|
|
140
|
+
*
|
|
141
|
+
* @param escapedSeparator - Regex-escaped separator string
|
|
142
|
+
* @returns Pattern string: `(?=[\\s${sep}]|$)`
|
|
143
|
+
*/
|
|
144
|
+
export function spaceBoundaryEnd(escapedSeparator) {
|
|
145
|
+
return `(?=[\\s${escapedSeparator}]|$)`;
|
|
146
|
+
}
|
|
122
147
|
//# sourceMappingURL=constants.js.map
|
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,kBAAkB,MAAM,sBAAsB,CAAA;AAErD;;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;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,mFAAmF,CAAA;AAEhH;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,QAAQ,CAAA;AACzC,MAAM,CAAC,MAAM,yBAAyB,GAAG,kBAAkB,CAAC,iBAAiB,CAAC,CAAA;AAE9E;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,iBAAiB,CAAC,gBAAwB;IACxD,OAAO,UAAU,gBAAgB,OAAO,CAAA;AAC1C,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,eAAe,CAAC,gBAAwB;IACtD,OAAO,SAAS,gBAAgB,OAAO,CAAA;AACzC,CAAC"}
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,kBAAkB,MAAM,sBAAsB,CAAA;AAErD;;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;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,mFAAmF,CAAA;AAEhH;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,QAAQ,CAAA;AACzC,MAAM,CAAC,MAAM,yBAAyB,GAAG,kBAAkB,CAAC,iBAAiB,CAAC,CAAA;AAE9E;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,iBAAiB,CAAC,gBAAwB;IACxD,OAAO,UAAU,gBAAgB,OAAO,CAAA;AAC1C,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,eAAe,CAAC,gBAAwB;IACtD,OAAO,SAAS,gBAAgB,OAAO,CAAA;AACzC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,eAAe,CAAC,IAAI,EAAE,CAAA;AAErD;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,gBAAwB;IACzD,OAAO,WAAW,gBAAgB,MAAM,CAAA;AAC1C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,gBAAwB;IACvD,OAAO,UAAU,gBAAgB,MAAM,CAAA;AACzC,CAAC"}
|
package/dist/symbols.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ export declare function primeMarks(text: string, options?: SymbolOptions): strin
|
|
|
25
25
|
export declare function fractions(text: string, options?: SymbolOptions): string;
|
|
26
26
|
/** Convert 1st, 2nd, 3rd, 4th to superscript ordinals. */
|
|
27
27
|
export declare function superscriptOrdinal(text: string, options?: SymbolOptions): string;
|
|
28
|
-
/** Collapse multiple spaces to single space. */
|
|
28
|
+
/** Collapse multiple spaces to single space. Prefers nbsp if any nbsp is present. */
|
|
29
29
|
export declare function collapseSpaces(text: string): string;
|
|
30
30
|
/** Convert ?? to ⁇, ?! to ⁈, !? to ⁉. Poor font support, disabled by default. */
|
|
31
31
|
export declare function punctuationLigatures(text: string, options?: SymbolOptions): string;
|
package/dist/symbols.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"symbols.d.ts","sourceRoot":"","sources":["../src/symbols.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,MAAM,WAAW,aAAa;IAC5B,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,uDAAuD;IACvD,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;
|
|
1
|
+
{"version":3,"file":"symbols.d.ts","sourceRoot":"","sources":["../src/symbols.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,MAAM,WAAW,aAAa;IAC5B,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,uDAAuD;IACvD,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AA6BD,4BAA4B;AAC5B,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAe1E;AAED,gDAAgD;AAChD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAmChF;AAaD,0DAA0D;AAC1D,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKhD;AASD,yCAAyC;AACzC,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKjD;AASD,oCAAoC;AACpC,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAcxE;AAED,kFAAkF;AAClF,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAazE;AAED,sEAAsE;AACtE,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAiC5E;AAoBD,2CAA2C;AAC3C,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAoB3E;AASD,0DAA0D;AAC1D,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAkBpF;AAED,qFAAqF;AACrF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKnD;AAcD,iFAAiF;AACjF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAWtF;AAED,gFAAgF;AAChF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CASjF"}
|
package/dist/symbols.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Symbol transformations: ellipses, multiplication, math symbols, arrows.
|
|
3
3
|
*/
|
|
4
4
|
import escapeStringRegexp from "escape-string-regexp";
|
|
5
|
-
import { UNICODE_SYMBOLS, ESCAPED_DEFAULT_SEPARATOR, LATIN_LETTERS, wordBoundaryEnd } from "./constants.js";
|
|
6
|
-
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,
|
|
5
|
+
import { UNICODE_SYMBOLS, ESCAPED_DEFAULT_SEPARATOR, LATIN_LETTERS, wordBoundaryEnd, SPACE_CHARS, spaceBoundaryStart, spaceBoundaryEnd } from "./constants.js";
|
|
6
|
+
const { ELLIPSIS, MULTIPLICATION, NOT_EQUAL, PLUS_MINUS, COPYRIGHT, REGISTERED, TRADEMARK, DEGREE, ARROW_RIGHT, ARROW_LEFT, ARROW_LEFT_RIGHT, APPROXIMATE, LESS_EQUAL, GREATER_EQUAL, NBSP, PRIME, DOUBLE_PRIME, SUPERSCRIPT_ST, SUPERSCRIPT_ND, SUPERSCRIPT_RD, SUPERSCRIPT_TH, DOUBLE_QUESTION, QUESTION_EXCLAMATION, EXCLAMATION_QUESTION, } = UNICODE_SYMBOLS;
|
|
7
7
|
/** Convert "..." to "…". */
|
|
8
8
|
export function ellipsis(text, options = {}) {
|
|
9
9
|
const chr = options.separator
|
|
@@ -51,35 +51,53 @@ export function multiplication(text, options = {}) {
|
|
|
51
51
|
});
|
|
52
52
|
return text;
|
|
53
53
|
}
|
|
54
|
+
/** Math symbol replacement map: ASCII → Unicode */
|
|
55
|
+
const MATH_SYMBOL_MAP = [
|
|
56
|
+
[/!=/g, NOT_EQUAL],
|
|
57
|
+
[/\+\/-/g, PLUS_MINUS],
|
|
58
|
+
[/\+-/g, PLUS_MINUS],
|
|
59
|
+
[/<=/g, LESS_EQUAL],
|
|
60
|
+
[/>=/g, GREATER_EQUAL],
|
|
61
|
+
[/~=/g, APPROXIMATE],
|
|
62
|
+
[/=~/g, APPROXIMATE],
|
|
63
|
+
];
|
|
54
64
|
/** Convert !=, <=, >=, +/-, ~= to Unicode equivalents. */
|
|
55
65
|
export function mathSymbols(text) {
|
|
56
|
-
|
|
57
|
-
.replace(
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
.replace(/<=/g, LESS_EQUAL)
|
|
61
|
-
.replace(/>=/g, GREATER_EQUAL)
|
|
62
|
-
.replace(/~=/g, APPROXIMATE)
|
|
63
|
-
.replace(/=~/g, APPROXIMATE);
|
|
66
|
+
for (const [pattern, replacement] of MATH_SYMBOL_MAP) {
|
|
67
|
+
text = text.replace(pattern, replacement);
|
|
68
|
+
}
|
|
69
|
+
return text;
|
|
64
70
|
}
|
|
71
|
+
/** Legal symbol replacement map: ASCII → Unicode */
|
|
72
|
+
const LEGAL_SYMBOL_MAP = [
|
|
73
|
+
[/\(c\)/gi, COPYRIGHT],
|
|
74
|
+
[/\(r\)/gi, REGISTERED],
|
|
75
|
+
[/\(tm\)/gi, TRADEMARK],
|
|
76
|
+
];
|
|
65
77
|
/** Convert (c), (r), (tm) to ©, ®, ™. */
|
|
66
78
|
export function legalSymbols(text) {
|
|
67
|
-
|
|
68
|
-
.replace(
|
|
69
|
-
|
|
70
|
-
|
|
79
|
+
for (const [pattern, replacement] of LEGAL_SYMBOL_MAP) {
|
|
80
|
+
text = text.replace(pattern, replacement);
|
|
81
|
+
}
|
|
82
|
+
return text;
|
|
71
83
|
}
|
|
84
|
+
/** Arrow pattern map: arrow shape → Unicode symbol */
|
|
85
|
+
const ARROW_MAP = [
|
|
86
|
+
[`<-+${"%CHR%"}?>`, ARROW_LEFT_RIGHT], // Bidirectional: <-> or <-->
|
|
87
|
+
["-+>", ARROW_RIGHT], // Right: -> or -->
|
|
88
|
+
["<-+", ARROW_LEFT], // Left: <- or <--
|
|
89
|
+
];
|
|
72
90
|
/** Convert -> and <-> to arrows. */
|
|
73
91
|
export function arrows(text, options = {}) {
|
|
74
92
|
const chr = options.separator
|
|
75
93
|
? escapeStringRegexp(options.separator)
|
|
76
94
|
: ESCAPED_DEFAULT_SEPARATOR;
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
95
|
+
const start = spaceBoundaryStart(chr);
|
|
96
|
+
const end = spaceBoundaryEnd(chr);
|
|
97
|
+
for (const [arrowPattern, replacement] of ARROW_MAP) {
|
|
98
|
+
const pattern = new RegExp(`${start}${arrowPattern.replace("%CHR%", chr)}${end}`, "g");
|
|
99
|
+
text = text.replace(pattern, replacement);
|
|
100
|
+
}
|
|
83
101
|
return text;
|
|
84
102
|
}
|
|
85
103
|
/** Convert "20 C" or "20 F" to "20 °C" or "20 °F". Only matches uppercase C/F. */
|
|
@@ -98,22 +116,27 @@ export function primeMarks(text, options = {}) {
|
|
|
98
116
|
const chr = options.separator
|
|
99
117
|
? escapeStringRegexp(options.separator)
|
|
100
118
|
: ESCAPED_DEFAULT_SEPARATOR;
|
|
101
|
-
//
|
|
102
|
-
//
|
|
103
|
-
// Examples: 5'
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
119
|
+
// Convert quotes to primes using quote balancing
|
|
120
|
+
// Only convert if quotes are balanced (even count before) to avoid converting closing quotes
|
|
121
|
+
// Examples: 5' → 5′ ✓, 12" → 12″ ✓, 'Term 1' → 'Term 1' ✓, "Term 1" → "Term 1" ✓
|
|
122
|
+
const quotePrimePairs = [
|
|
123
|
+
["'", PRIME],
|
|
124
|
+
['"', DOUBLE_PRIME],
|
|
125
|
+
];
|
|
126
|
+
for (const [quote, prime] of quotePrimePairs) {
|
|
127
|
+
const pattern = new RegExp(`(?<digit>\\d)(?<sep>${chr}?)${quote}(?<afterSep>${chr}?)(?![${LATIN_LETTERS}])`, "g");
|
|
128
|
+
text = text.replace(pattern, (match, digit, sep, afterSep, offset) => {
|
|
129
|
+
const textBefore = text.slice(0, offset);
|
|
130
|
+
const quoteCount = (textBefore.match(new RegExp(quote, "g")) || []).length;
|
|
131
|
+
if (quoteCount % 2 === 0) {
|
|
132
|
+
return `${digit}${sep}${prime}${afterSep}`;
|
|
133
|
+
}
|
|
134
|
+
return match;
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
// Feet-inches pattern: convert " after ′ + digit (e.g., 5′10" → 5′10″)
|
|
109
138
|
const feetInchesPattern = new RegExp(`(?<primeAndNum>${PRIME}${chr}?\\d${chr}?)"`, "g");
|
|
110
139
|
text = text.replace(feetInchesPattern, `$<primeAndNum>${DOUBLE_PRIME}`);
|
|
111
|
-
// Double prime Pattern 2: Standalone inches
|
|
112
|
-
// Negative lookbehind: ensures no opening quote within 20 chars before the digit
|
|
113
|
-
// Negative lookahead: ensures not followed by word characters
|
|
114
|
-
// Matches: 12" wide ✓, but not: "Term 1" ✗
|
|
115
|
-
const standaloneInchesPattern = new RegExp(`(?<!["${LEFT_DOUBLE_QUOTE}]${chr}?[^"${chr}]{0,20})(?<numWithSep>\\d${chr}?)"(?!${chr}?[${LATIN_LETTERS}\\d_])`, "g");
|
|
116
|
-
text = text.replace(standaloneInchesPattern, `$<numWithSep>${DOUBLE_PRIME}`);
|
|
117
140
|
return text;
|
|
118
141
|
}
|
|
119
142
|
const FRACTION_MAP = {
|
|
@@ -171,25 +194,33 @@ export function superscriptOrdinal(text, options = {}) {
|
|
|
171
194
|
return num + superscriptSuffix;
|
|
172
195
|
});
|
|
173
196
|
}
|
|
174
|
-
/** Collapse multiple spaces to single space. */
|
|
197
|
+
/** Collapse multiple spaces to single space. Prefers nbsp if any nbsp is present. */
|
|
175
198
|
export function collapseSpaces(text) {
|
|
176
|
-
return text.replace(new RegExp(`
|
|
199
|
+
return text.replace(new RegExp(`[${SPACE_CHARS}]{2,}`, "g"), (match) => {
|
|
200
|
+
// If any nbsp is present, prefer nbsp (more likely to be intentional)
|
|
201
|
+
return match.includes(NBSP) ? NBSP : " ";
|
|
202
|
+
});
|
|
177
203
|
}
|
|
204
|
+
/**
|
|
205
|
+
* Punctuation ligature map: [first char, repeated char, replacement]
|
|
206
|
+
* Pattern: first(sep)?repeated(?:sep?repeated)* → replacement
|
|
207
|
+
* Order matters: handle mixed punctuation first, then repeated
|
|
208
|
+
*/
|
|
209
|
+
const PUNCTUATION_LIGATURE_MAP = [
|
|
210
|
+
["\\?", "!", QUESTION_EXCLAMATION], // ?!+ → ⁈
|
|
211
|
+
["!", "\\?", EXCLAMATION_QUESTION], // !?+ → ⁉
|
|
212
|
+
["\\?", "\\?", DOUBLE_QUESTION], // ??+ → ⁇
|
|
213
|
+
["!", "!", "!"], // !!+ → ! (normalize)
|
|
214
|
+
];
|
|
178
215
|
/** Convert ?? to ⁇, ?! to ⁈, !? to ⁉. Poor font support, disabled by default. */
|
|
179
216
|
export function punctuationLigatures(text, options = {}) {
|
|
180
217
|
const chr = options.separator
|
|
181
218
|
? escapeStringRegexp(options.separator)
|
|
182
219
|
: ESCAPED_DEFAULT_SEPARATOR;
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
// !?+ → ⁉ (exclamation followed by one or more question marks)
|
|
188
|
-
text = text.replace(new RegExp(`!(${chr})?\\?(?:${chr}?\\?)*`, "g"), (_match, sep) => EXCLAMATION_QUESTION + (sep || ""));
|
|
189
|
-
// ??+ → ⁇ (two or more question marks squashed to ligature)
|
|
190
|
-
text = text.replace(new RegExp(`\\?(${chr})?\\?(?:${chr}?\\?)*`, "g"), (_match, sep) => DOUBLE_QUESTION + (sep || ""));
|
|
191
|
-
// !!+ → ! (two or more exclamation marks squashed to single)
|
|
192
|
-
text = text.replace(new RegExp(`!(${chr})?!(?:${chr}?!)*`, "g"), (_match, sep) => "!" + (sep || ""));
|
|
220
|
+
for (const [first, repeated, replacement] of PUNCTUATION_LIGATURE_MAP) {
|
|
221
|
+
const pattern = new RegExp(`${first}(${chr})?${repeated}(?:${chr}?${repeated})*`, "g");
|
|
222
|
+
text = text.replace(pattern, (_match, sep) => replacement + (sep || ""));
|
|
223
|
+
}
|
|
193
224
|
return text;
|
|
194
225
|
}
|
|
195
226
|
/** Apply all symbol transforms. degrees/fractions excluded (too aggressive). */
|
package/dist/symbols.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"symbols.js","sourceRoot":"","sources":["../src/symbols.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,kBAAkB,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,eAAe,EAAE,yBAAyB,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"symbols.js","sourceRoot":"","sources":["../src/symbols.ts"],"names":[],"mappings":"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"}
|