punctilio 0.1.0 → 0.2.0
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 +126 -7
- package/dist/index.d.ts +33 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +32 -7
- package/dist/index.js.map +1 -1
- package/dist/symbols.d.ts +183 -0
- package/dist/symbols.d.ts.map +1 -0
- package/dist/symbols.js +296 -0
- package/dist/symbols.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,6 +10,14 @@ Smart typography transformations for JavaScript/TypeScript. Converts ASCII punct
|
|
|
10
10
|
- **Em dashes**: `word - word` or `word--word` → `word—word`
|
|
11
11
|
- **En dashes**: `1-5` → `1–5` (number ranges), `January-March` → `January–March` (date ranges)
|
|
12
12
|
- **Minus signs**: `-5` → `−5` (proper Unicode minus)
|
|
13
|
+
- **Ellipsis**: `...` → `…`
|
|
14
|
+
- **Multiplication**: `5x5` → `5×5`, `3*4` → `3×4`
|
|
15
|
+
- **Math symbols**: `!=` → `≠`, `+-` → `±`, `<=` → `≤`, `>=` → `≥`, `~=` → `≈`
|
|
16
|
+
- **Legal symbols**: `(c)` → `©`, `(r)` → `®`, `(tm)` → `™`
|
|
17
|
+
- **Arrows**: `->` → `→`, `<-` → `←`, `<->` → `↔`
|
|
18
|
+
- **Prime marks**: `5'10"` → `5′10″` (feet/inches, arcminutes/arcseconds)
|
|
19
|
+
- **Fractions** (optional): `1/2` → `½`, `3/4` → `¾`
|
|
20
|
+
- **Degrees** (optional): `20 C` → `20 °C`
|
|
13
21
|
- **Handles edge cases**: contractions, possessives, nested quotes, year abbreviations ('99), "rock 'n' roll"
|
|
14
22
|
|
|
15
23
|
## Why another typography library?
|
|
@@ -41,6 +49,10 @@ import { transform, niceQuotes, hyphenReplace } from 'punctilio'
|
|
|
41
49
|
transform('"Hello," she said - "it\'s pages 1-5."')
|
|
42
50
|
// → "Hello," she said—"it's pages 1–5."
|
|
43
51
|
|
|
52
|
+
// Symbol transforms are included by default
|
|
53
|
+
transform('Wait... 5x5 != 25 (c) 2024')
|
|
54
|
+
// → Wait… 5×5 ≠ 25 © 2024
|
|
55
|
+
|
|
44
56
|
// Or use individual functions
|
|
45
57
|
niceQuotes('"Hello", she said.')
|
|
46
58
|
// → "Hello", she said.
|
|
@@ -49,6 +61,23 @@ hyphenReplace('word - word')
|
|
|
49
61
|
// → word—word
|
|
50
62
|
```
|
|
51
63
|
|
|
64
|
+
### Transform Options
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
import { transform } from 'punctilio'
|
|
68
|
+
|
|
69
|
+
// Enable optional transforms
|
|
70
|
+
transform('Add 1/2 cup at 20 C', {
|
|
71
|
+
fractions: true, // 1/2 → ½
|
|
72
|
+
degrees: true // 20 C → 20 °C
|
|
73
|
+
})
|
|
74
|
+
// → Add ½ cup at 20 °C
|
|
75
|
+
|
|
76
|
+
// Disable symbol transforms if you only want quotes/dashes
|
|
77
|
+
transform('5x5 = 25', { symbols: false })
|
|
78
|
+
// → 5x5 = 25 (unchanged)
|
|
79
|
+
```
|
|
80
|
+
|
|
52
81
|
### With HTML Element Boundaries
|
|
53
82
|
|
|
54
83
|
When processing text that spans multiple HTML elements, use a separator character to mark boundaries:
|
|
@@ -65,15 +94,21 @@ const result = transform(text, { separator: DEFAULT_SEPARATOR })
|
|
|
65
94
|
// The separator is preserved; split on it to restore to your elements
|
|
66
95
|
```
|
|
67
96
|
|
|
68
|
-
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).
|
|
97
|
+
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).
|
|
69
98
|
|
|
70
99
|
## API
|
|
71
100
|
|
|
72
101
|
### `transform(text, options?)`
|
|
73
102
|
|
|
74
|
-
Applies all typography transformations
|
|
103
|
+
Applies all typography transformations. Options:
|
|
104
|
+
- `separator`: Boundary marker for HTML elements (default: `"\uE000"`)
|
|
105
|
+
- `symbols`: Include symbol transforms (default: `true`)
|
|
106
|
+
- `fractions`: Convert common fractions like 1/2 → ½ (default: `false`)
|
|
107
|
+
- `degrees`: Convert temperature notation like 20 C → 20 °C (default: `false`)
|
|
108
|
+
|
|
109
|
+
### Quote Functions
|
|
75
110
|
|
|
76
|
-
|
|
111
|
+
#### `niceQuotes(text, options?)`
|
|
77
112
|
|
|
78
113
|
Converts straight quotes to curly quotes. Handles:
|
|
79
114
|
- Opening/closing double quotes: `"` → `"` or `"`
|
|
@@ -83,7 +118,9 @@ Converts straight quotes to curly quotes. Handles:
|
|
|
83
118
|
- Year abbreviations: `'99` → `'99`
|
|
84
119
|
- Special cases: `'n'` in "rock 'n' roll"
|
|
85
120
|
|
|
86
|
-
###
|
|
121
|
+
### Dash Functions
|
|
122
|
+
|
|
123
|
+
#### `hyphenReplace(text, options?)`
|
|
87
124
|
|
|
88
125
|
Converts hyphens to proper dashes. Handles:
|
|
89
126
|
- Em dashes: `word - word` → `word—word`
|
|
@@ -92,18 +129,100 @@ Converts hyphens to proper dashes. Handles:
|
|
|
92
129
|
- Minus signs: `-5` → `−5`
|
|
93
130
|
- Preserves: horizontal rules (`---`), compound words (`well-known`)
|
|
94
131
|
|
|
95
|
-
|
|
132
|
+
#### `enDashNumberRange(text, options?)`
|
|
96
133
|
|
|
97
134
|
Converts number ranges only: `pages 10-20` → `pages 10–20`
|
|
98
135
|
|
|
99
|
-
|
|
136
|
+
#### `enDashDateRange(text, options?)`
|
|
100
137
|
|
|
101
138
|
Converts month ranges only: `January-March` → `January–March`
|
|
102
139
|
|
|
103
|
-
|
|
140
|
+
#### `minusReplace(text, options?)`
|
|
104
141
|
|
|
105
142
|
Converts hyphens to minus signs in numerical contexts: `-5` → `−5`
|
|
106
143
|
|
|
144
|
+
### Symbol Functions
|
|
145
|
+
|
|
146
|
+
#### `ellipsis(text, options?)`
|
|
147
|
+
|
|
148
|
+
Converts three periods to ellipsis: `...` → `…`
|
|
149
|
+
|
|
150
|
+
#### `multiplication(text, options?)`
|
|
151
|
+
|
|
152
|
+
Converts multiplication patterns: `5x5` → `5×5`, `3*4` → `3×4`
|
|
153
|
+
|
|
154
|
+
#### `mathSymbols(text)`
|
|
155
|
+
|
|
156
|
+
Converts math operators:
|
|
157
|
+
- `!=` → `≠`
|
|
158
|
+
- `+-` or `+/-` → `±`
|
|
159
|
+
- `<=` → `≤`
|
|
160
|
+
- `>=` → `≥`
|
|
161
|
+
- `~=` or `=~` → `≈`
|
|
162
|
+
|
|
163
|
+
#### `legalSymbols(text)`
|
|
164
|
+
|
|
165
|
+
Converts legal symbols:
|
|
166
|
+
- `(c)` → `©`
|
|
167
|
+
- `(r)` → `®`
|
|
168
|
+
- `(tm)` → `™`
|
|
169
|
+
|
|
170
|
+
#### `arrows(text, options?)`
|
|
171
|
+
|
|
172
|
+
Converts arrow patterns:
|
|
173
|
+
- `->` or `-->` → `→`
|
|
174
|
+
- `<-` or `<--` → `←`
|
|
175
|
+
- `<->` or `<-->` → `↔`
|
|
176
|
+
|
|
177
|
+
#### `primeMarks(text, options?)`
|
|
178
|
+
|
|
179
|
+
Converts straight quotes after numbers to prime marks:
|
|
180
|
+
- `5'10"` → `5′10″` (feet and inches)
|
|
181
|
+
- `45° 30' 15"` → `45° 30′ 15″` (coordinates)
|
|
182
|
+
|
|
183
|
+
#### `fractions(text)`
|
|
184
|
+
|
|
185
|
+
Converts common fractions: `1/2` → `½`, `1/4` → `¼`, `3/4` → `¾`, etc.
|
|
186
|
+
|
|
187
|
+
#### `degrees(text)`
|
|
188
|
+
|
|
189
|
+
Converts temperature notation: `20 C` → `20 °C`, `68 F` → `68 °F`
|
|
190
|
+
|
|
191
|
+
#### `symbolTransform(text, options?)`
|
|
192
|
+
|
|
193
|
+
Applies all symbol transforms except fractions and degrees.
|
|
194
|
+
|
|
195
|
+
### Constants
|
|
196
|
+
|
|
197
|
+
- `DEFAULT_SEPARATOR`: The default separator character (`"\uE000"`)
|
|
198
|
+
- `months`: Regex-ready string of month names for date range detection
|
|
199
|
+
|
|
200
|
+
## Character Reference
|
|
201
|
+
|
|
202
|
+
| Input | Output | Unicode | Name |
|
|
203
|
+
|-------|--------|---------|------|
|
|
204
|
+
| `"` | `"` | U+201C | Left double quotation mark |
|
|
205
|
+
| `"` | `"` | U+201D | Right double quotation mark |
|
|
206
|
+
| `'` | `'` | U+2018 | Left single quotation mark |
|
|
207
|
+
| `'` | `'` | U+2019 | Right single quotation mark (apostrophe) |
|
|
208
|
+
| `--` | `—` | U+2014 | Em dash |
|
|
209
|
+
| `-` (range) | `–` | U+2013 | En dash |
|
|
210
|
+
| `-` (negative) | `−` | U+2212 | Minus sign |
|
|
211
|
+
| `...` | `…` | U+2026 | Ellipsis |
|
|
212
|
+
| `x` (multiply) | `×` | U+00D7 | Multiplication sign |
|
|
213
|
+
| `!=` | `≠` | U+2260 | Not equal |
|
|
214
|
+
| `+-` | `±` | U+00B1 | Plus-minus |
|
|
215
|
+
| `<=` | `≤` | U+2264 | Less than or equal |
|
|
216
|
+
| `>=` | `≥` | U+2265 | Greater than or equal |
|
|
217
|
+
| `(c)` | `©` | U+00A9 | Copyright |
|
|
218
|
+
| `(r)` | `®` | U+00AE | Registered |
|
|
219
|
+
| `(tm)` | `™` | U+2122 | Trademark |
|
|
220
|
+
| `->` | `→` | U+2192 | Right arrow |
|
|
221
|
+
| `<-` | `←` | U+2190 | Left arrow |
|
|
222
|
+
| `<->` | `↔` | U+2194 | Left-right arrow |
|
|
223
|
+
| `'` (after digit) | `′` | U+2032 | Prime (feet, arcminutes) |
|
|
224
|
+
| `"` (after digit) | `″` | U+2033 | Double prime (inches, arcseconds) |
|
|
225
|
+
|
|
107
226
|
## License
|
|
108
227
|
|
|
109
228
|
MIT © Alexander Turner
|
package/dist/index.d.ts
CHANGED
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
*
|
|
4
4
|
* A library for converting plain ASCII punctuation into typographically
|
|
5
5
|
* correct Unicode characters. Handles smart quotes, em-dashes, en-dashes,
|
|
6
|
-
* minus signs, and more.
|
|
6
|
+
* minus signs, ellipses, multiplication signs, and more.
|
|
7
7
|
*
|
|
8
8
|
* @packageDocumentation
|
|
9
9
|
*/
|
|
10
10
|
export { niceQuotes, type QuoteOptions } from "./quotes.js";
|
|
11
11
|
export { hyphenReplace, enDashNumberRange, enDashDateRange, minusReplace, months, type DashOptions, } from "./dashes.js";
|
|
12
|
+
export { ellipsis, multiplication, mathSymbols, legalSymbols, arrows, degrees, fractions, primeMarks, symbolTransform, type SymbolOptions, } from "./symbols.js";
|
|
12
13
|
export interface TransformOptions {
|
|
13
14
|
/**
|
|
14
15
|
* A boundary marker character used when transforming text that spans
|
|
@@ -19,12 +20,33 @@ export interface TransformOptions {
|
|
|
19
20
|
* Default: "\uE000" (Unicode Private Use Area)
|
|
20
21
|
*/
|
|
21
22
|
separator?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Whether to include symbol transforms (ellipsis, multiplication, etc.)
|
|
25
|
+
* Default: true
|
|
26
|
+
*/
|
|
27
|
+
symbols?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Whether to include fraction transforms (1/2 → ½)
|
|
30
|
+
* Default: false (can be aggressive)
|
|
31
|
+
*/
|
|
32
|
+
fractions?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Whether to include degree symbol transforms (20 C → 20 °C)
|
|
35
|
+
* Default: false (can be aggressive)
|
|
36
|
+
*/
|
|
37
|
+
degrees?: boolean;
|
|
22
38
|
}
|
|
23
39
|
/**
|
|
24
|
-
* Applies all typography transformations: smart quotes
|
|
40
|
+
* Applies all typography transformations: smart quotes, proper dashes,
|
|
41
|
+
* and symbol improvements.
|
|
25
42
|
*
|
|
26
|
-
* This is a convenience function that applies
|
|
27
|
-
*
|
|
43
|
+
* This is a convenience function that applies transformations in sequence:
|
|
44
|
+
* 1. hyphenReplace (em-dashes, en-dashes, minus signs)
|
|
45
|
+
* 2. primeMarks (feet/inches, arcminutes/arcseconds)
|
|
46
|
+
* 3. niceQuotes (smart quotes)
|
|
47
|
+
* 4. symbolTransform (ellipses, multiplication, math symbols, legal symbols, arrows)
|
|
48
|
+
* 5. fractions (optional, disabled by default)
|
|
49
|
+
* 6. degrees (optional, disabled by default)
|
|
28
50
|
*
|
|
29
51
|
* @param text - The text to transform
|
|
30
52
|
* @param options - Configuration options
|
|
@@ -32,10 +54,16 @@ export interface TransformOptions {
|
|
|
32
54
|
*
|
|
33
55
|
* @example
|
|
34
56
|
* ```ts
|
|
35
|
-
* import { transform } from '
|
|
57
|
+
* import { transform } from 'punctilio'
|
|
36
58
|
*
|
|
37
59
|
* transform('"Hello," she said - "it\'s pages 1-5."')
|
|
38
60
|
* // → '"Hello," she said—"it's pages 1–5."'
|
|
61
|
+
*
|
|
62
|
+
* transform('Wait... 5x5 != 25 (c) 2024')
|
|
63
|
+
* // → 'Wait… 5×5 ≠ 25 © 2024'
|
|
64
|
+
*
|
|
65
|
+
* transform('Add 1/2 cup', { fractions: true })
|
|
66
|
+
* // → 'Add ½ cup'
|
|
39
67
|
* ```
|
|
40
68
|
*/
|
|
41
69
|
export declare function transform(text: string, options?: TransformOptions): string;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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,MAAM,aAAa,CAAA;AAC3D,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,MAAM,EACN,KAAK,WAAW,GACjB,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAA;AAC3D,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,MAAM,EACN,KAAK,WAAW,GACjB,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,QAAQ,EACR,cAAc,EACd,WAAW,EACX,YAAY,EACZ,MAAM,EACN,OAAO,EACP,SAAS,EACT,UAAU,EACV,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;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IAEnB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,MAAM,CAoB9E;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,WAAW,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -3,19 +3,27 @@
|
|
|
3
3
|
*
|
|
4
4
|
* A library for converting plain ASCII punctuation into typographically
|
|
5
5
|
* correct Unicode characters. Handles smart quotes, em-dashes, en-dashes,
|
|
6
|
-
* minus signs, and more.
|
|
6
|
+
* minus signs, ellipses, multiplication signs, and more.
|
|
7
7
|
*
|
|
8
8
|
* @packageDocumentation
|
|
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, symbolTransform, } from "./symbols.js";
|
|
12
13
|
import { niceQuotes } from "./quotes.js";
|
|
13
14
|
import { hyphenReplace } from "./dashes.js";
|
|
15
|
+
import { symbolTransform, fractions as fractionsTransform, degrees as degreesTransform, primeMarks } from "./symbols.js";
|
|
14
16
|
/**
|
|
15
|
-
* Applies all typography transformations: smart quotes
|
|
17
|
+
* Applies all typography transformations: smart quotes, proper dashes,
|
|
18
|
+
* and symbol improvements.
|
|
16
19
|
*
|
|
17
|
-
* This is a convenience function that applies
|
|
18
|
-
*
|
|
20
|
+
* This is a convenience function that applies transformations in sequence:
|
|
21
|
+
* 1. hyphenReplace (em-dashes, en-dashes, minus signs)
|
|
22
|
+
* 2. primeMarks (feet/inches, arcminutes/arcseconds)
|
|
23
|
+
* 3. niceQuotes (smart quotes)
|
|
24
|
+
* 4. symbolTransform (ellipses, multiplication, math symbols, legal symbols, arrows)
|
|
25
|
+
* 5. fractions (optional, disabled by default)
|
|
26
|
+
* 6. degrees (optional, disabled by default)
|
|
19
27
|
*
|
|
20
28
|
* @param text - The text to transform
|
|
21
29
|
* @param options - Configuration options
|
|
@@ -23,15 +31,32 @@ import { hyphenReplace } from "./dashes.js";
|
|
|
23
31
|
*
|
|
24
32
|
* @example
|
|
25
33
|
* ```ts
|
|
26
|
-
* import { transform } from '
|
|
34
|
+
* import { transform } from 'punctilio'
|
|
27
35
|
*
|
|
28
36
|
* transform('"Hello," she said - "it\'s pages 1-5."')
|
|
29
37
|
* // → '"Hello," she said—"it's pages 1–5."'
|
|
38
|
+
*
|
|
39
|
+
* transform('Wait... 5x5 != 25 (c) 2024')
|
|
40
|
+
* // → 'Wait… 5×5 ≠ 25 © 2024'
|
|
41
|
+
*
|
|
42
|
+
* transform('Add 1/2 cup', { fractions: true })
|
|
43
|
+
* // → 'Add ½ cup'
|
|
30
44
|
* ```
|
|
31
45
|
*/
|
|
32
46
|
export function transform(text, options = {}) {
|
|
33
|
-
|
|
34
|
-
text =
|
|
47
|
+
const { symbols = true, fractions = false, degrees = false, ...separatorOpts } = options;
|
|
48
|
+
text = hyphenReplace(text, separatorOpts);
|
|
49
|
+
text = primeMarks(text, separatorOpts);
|
|
50
|
+
text = niceQuotes(text, separatorOpts);
|
|
51
|
+
if (symbols) {
|
|
52
|
+
text = symbolTransform(text, separatorOpts);
|
|
53
|
+
}
|
|
54
|
+
if (fractions) {
|
|
55
|
+
text = fractionsTransform(text);
|
|
56
|
+
}
|
|
57
|
+
if (degrees) {
|
|
58
|
+
text = degreesTransform(text);
|
|
59
|
+
}
|
|
35
60
|
return text;
|
|
36
61
|
}
|
|
37
62
|
/**
|
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,EAAqB,MAAM,aAAa,CAAA;AAC3D,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,MAAM,GAEP,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAqB,MAAM,aAAa,CAAA;AAC3D,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,MAAM,GAEP,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,QAAQ,EACR,cAAc,EACd,WAAW,EACX,YAAY,EACZ,MAAM,EACN,OAAO,EACP,SAAS,EACT,UAAU,EACV,eAAe,GAEhB,MAAM,cAAc,CAAA;AAgCrB,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,MAAM,cAAc,CAAA;AAExH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,UAA4B,EAAE;IACpE,MAAM,EAAE,OAAO,GAAG,IAAI,EAAE,SAAS,GAAG,KAAK,EAAE,OAAO,GAAG,KAAK,EAAE,GAAG,aAAa,EAAE,GAAG,OAAO,CAAA;IAExF,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,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,QAAQ,CAAA"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Symbol and character transformations for common typography improvements.
|
|
3
|
+
*
|
|
4
|
+
* Handles ellipses, multiplication signs, mathematical symbols, and
|
|
5
|
+
* common character sequences that should use proper Unicode glyphs.
|
|
6
|
+
*
|
|
7
|
+
* @module symbols
|
|
8
|
+
*/
|
|
9
|
+
export interface SymbolOptions {
|
|
10
|
+
/**
|
|
11
|
+
* Boundary marker character for text spanning HTML elements.
|
|
12
|
+
* Default: "\uE000" (Unicode Private Use Area)
|
|
13
|
+
*/
|
|
14
|
+
separator?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Converts three periods to a proper ellipsis character.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* ellipsis("Wait for it...")
|
|
22
|
+
* // → "Wait for it…"
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare function ellipsis(text: string, options?: SymbolOptions): string;
|
|
26
|
+
/**
|
|
27
|
+
* Converts ASCII multiplication patterns to proper multiplication sign (×).
|
|
28
|
+
*
|
|
29
|
+
* Handles:
|
|
30
|
+
* - Dimensions: "5x5" → "5×5"
|
|
31
|
+
* - Trailing multiplier: "5x" → "5×" (when followed by word boundary)
|
|
32
|
+
* - Asterisk multiplication: "5*3" → "5×3" (when between numbers)
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* multiplication("The room is 10x12 feet")
|
|
37
|
+
* // → "The room is 10×12 feet"
|
|
38
|
+
*
|
|
39
|
+
* multiplication("2x speed")
|
|
40
|
+
* // → "2× speed"
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export declare function multiplication(text: string, options?: SymbolOptions): string;
|
|
44
|
+
/**
|
|
45
|
+
* Converts ASCII mathematical symbols to proper Unicode equivalents.
|
|
46
|
+
*
|
|
47
|
+
* Handles:
|
|
48
|
+
* - "!=" → "≠"
|
|
49
|
+
* - "+-" or "+/-" → "±"
|
|
50
|
+
* - "<=" → "≤"
|
|
51
|
+
* - ">=" → "≥"
|
|
52
|
+
* - "~=" or "=~" → "≈"
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts
|
|
56
|
+
* mathSymbols("x != y and a <= b")
|
|
57
|
+
* // → "x ≠ y and a ≤ b"
|
|
58
|
+
*
|
|
59
|
+
* mathSymbols("The answer is +- 5%")
|
|
60
|
+
* // → "The answer is ± 5%"
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export declare function mathSymbols(text: string): string;
|
|
64
|
+
/**
|
|
65
|
+
* Converts ASCII representations of copyright, registered, and trademark
|
|
66
|
+
* symbols to proper Unicode characters.
|
|
67
|
+
*
|
|
68
|
+
* Handles:
|
|
69
|
+
* - "(c)" or "(C)" → "©"
|
|
70
|
+
* - "(r)" or "(R)" → "®"
|
|
71
|
+
* - "(tm)" or "(TM)" → "™"
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```ts
|
|
75
|
+
* legalSymbols("Copyright (c) 2024 Acme Inc.")
|
|
76
|
+
* // → "Copyright © 2024 Acme Inc."
|
|
77
|
+
*
|
|
78
|
+
* legalSymbols("Brand Name(tm)")
|
|
79
|
+
* // → "Brand Name™"
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export declare function legalSymbols(text: string): string;
|
|
83
|
+
/**
|
|
84
|
+
* Converts arrow character sequences to Unicode arrows.
|
|
85
|
+
*
|
|
86
|
+
* Handles:
|
|
87
|
+
* - "->" or "-->" → "→"
|
|
88
|
+
* - "<-" or "<--" → "←"
|
|
89
|
+
* - "<->" or "<-->" → "↔"
|
|
90
|
+
*
|
|
91
|
+
* Note: Only converts when surrounded by spaces or at word boundaries
|
|
92
|
+
* to avoid false matches in code or URLs.
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```ts
|
|
96
|
+
* arrows("A -> B -> C")
|
|
97
|
+
* // → "A → B → C"
|
|
98
|
+
*
|
|
99
|
+
* arrows("left <-> right")
|
|
100
|
+
* // → "left ↔ right"
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
export declare function arrows(text: string, options?: SymbolOptions): string;
|
|
104
|
+
/**
|
|
105
|
+
* Adds degree symbol in temperature contexts.
|
|
106
|
+
*
|
|
107
|
+
* Handles:
|
|
108
|
+
* - "20 C" or "20C" → "20 °C" (Celsius)
|
|
109
|
+
* - "68 F" or "68F" → "68 °F" (Fahrenheit)
|
|
110
|
+
*
|
|
111
|
+
* Only matches when followed by C or F (case insensitive) to avoid
|
|
112
|
+
* false positives.
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```ts
|
|
116
|
+
* degrees("The temperature is 20 C")
|
|
117
|
+
* // → "The temperature is 20 °C"
|
|
118
|
+
*
|
|
119
|
+
* degrees("Water boils at 212F")
|
|
120
|
+
* // → "Water boils at 212 °F"
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
export declare function degrees(text: string): string;
|
|
124
|
+
/**
|
|
125
|
+
* Converts straight quotes after numbers to prime marks.
|
|
126
|
+
*
|
|
127
|
+
* Prime marks are used for:
|
|
128
|
+
* - Feet and inches: 5'10" → 5′10″
|
|
129
|
+
* - Arcminutes and arcseconds: 45° 30' 15" → 45° 30′ 15″
|
|
130
|
+
*
|
|
131
|
+
* This should be called BEFORE smart quote transformations to prevent
|
|
132
|
+
* quotes in measurements from being curled.
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```ts
|
|
136
|
+
* primeMarks("He's 5'10\" tall")
|
|
137
|
+
* // → "He's 5′10″ tall"
|
|
138
|
+
*
|
|
139
|
+
* primeMarks("Location: 45° 30' 15\"")
|
|
140
|
+
* // → "Location: 45° 30′ 15″"
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
export declare function primeMarks(text: string, options?: SymbolOptions): string;
|
|
144
|
+
/**
|
|
145
|
+
* Converts common fractions to Unicode fraction characters.
|
|
146
|
+
*
|
|
147
|
+
* Handles: 1/4, 1/2, 3/4, 1/3, 2/3, 1/5, 2/5, 3/5, 4/5,
|
|
148
|
+
* 1/6, 5/6, 1/8, 3/8, 5/8, 7/8
|
|
149
|
+
*
|
|
150
|
+
* Only converts when the fraction is surrounded by word boundaries
|
|
151
|
+
* to avoid breaking URLs, file paths, or dates.
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* ```ts
|
|
155
|
+
* fractions("Add 1/2 cup of flour")
|
|
156
|
+
* // → "Add ½ cup of flour"
|
|
157
|
+
*
|
|
158
|
+
* fractions("About 3/4 complete")
|
|
159
|
+
* // → "About ¾ complete"
|
|
160
|
+
* ```
|
|
161
|
+
*/
|
|
162
|
+
export declare function fractions(text: string): string;
|
|
163
|
+
/**
|
|
164
|
+
* Applies all symbol transformations.
|
|
165
|
+
*
|
|
166
|
+
* Runs in order:
|
|
167
|
+
* 1. ellipsis
|
|
168
|
+
* 2. multiplication
|
|
169
|
+
* 3. mathSymbols
|
|
170
|
+
* 4. legalSymbols
|
|
171
|
+
* 5. arrows
|
|
172
|
+
*
|
|
173
|
+
* Note: `degrees` and `fractions` are not included by default as they
|
|
174
|
+
* may be too aggressive for some use cases. Call them explicitly if needed.
|
|
175
|
+
*
|
|
176
|
+
* @example
|
|
177
|
+
* ```ts
|
|
178
|
+
* symbolTransform("Wait... 5x5 != 20 (c) 2024")
|
|
179
|
+
* // → "Wait… 5×5 ≠ 20 © 2024"
|
|
180
|
+
* ```
|
|
181
|
+
*/
|
|
182
|
+
export declare function symbolTransform(text: string, options?: SymbolOptions): string;
|
|
183
|
+
//# sourceMappingURL=symbols.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"symbols.d.ts","sourceRoot":"","sources":["../src/symbols.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AA6BD;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAW1E;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAYhF;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAmBhD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAWjD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAaxE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAO5C;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAiB5E;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA0B9C;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAOjF"}
|
package/dist/symbols.js
ADDED
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Symbol and character transformations for common typography improvements.
|
|
3
|
+
*
|
|
4
|
+
* Handles ellipses, multiplication signs, mathematical symbols, and
|
|
5
|
+
* common character sequences that should use proper Unicode glyphs.
|
|
6
|
+
*
|
|
7
|
+
* @module symbols
|
|
8
|
+
*/
|
|
9
|
+
const DEFAULT_SEPARATOR = "\uE000";
|
|
10
|
+
/**
|
|
11
|
+
* Escapes special regex characters in a string.
|
|
12
|
+
*/
|
|
13
|
+
function escapeRegex(str) {
|
|
14
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
15
|
+
}
|
|
16
|
+
// Unicode characters
|
|
17
|
+
const ELLIPSIS = "\u2026"; // …
|
|
18
|
+
const MULTIPLICATION = "\u00D7"; // ×
|
|
19
|
+
const NOT_EQUAL = "\u2260"; // ≠
|
|
20
|
+
const PLUS_MINUS = "\u00B1"; // ±
|
|
21
|
+
const COPYRIGHT = "\u00A9"; // ©
|
|
22
|
+
const REGISTERED = "\u00AE"; // ®
|
|
23
|
+
const TRADEMARK = "\u2122"; // ™
|
|
24
|
+
const DEGREE = "\u00B0"; // °
|
|
25
|
+
const ARROW_RIGHT = "\u2192"; // →
|
|
26
|
+
const ARROW_LEFT = "\u2190"; // ←
|
|
27
|
+
const ARROW_LEFT_RIGHT = "\u2194"; // ↔
|
|
28
|
+
const APPROXIMATE = "\u2248"; // ≈
|
|
29
|
+
const LESS_EQUAL = "\u2264"; // ≤
|
|
30
|
+
const GREATER_EQUAL = "\u2265"; // ≥
|
|
31
|
+
const PRIME = "\u2032"; // ′
|
|
32
|
+
const DOUBLE_PRIME = "\u2033"; // ″
|
|
33
|
+
/**
|
|
34
|
+
* Converts three periods to a proper ellipsis character.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* ellipsis("Wait for it...")
|
|
39
|
+
* // → "Wait for it…"
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export function ellipsis(text, options = {}) {
|
|
43
|
+
const chr = escapeRegex(options.separator ?? DEFAULT_SEPARATOR);
|
|
44
|
+
// Replace three periods with ellipsis, allowing for separator chars between
|
|
45
|
+
const pattern = new RegExp(`\\.${chr}?\\.${chr}?\\.`, "g");
|
|
46
|
+
text = text.replace(pattern, ELLIPSIS);
|
|
47
|
+
// Add space after ellipsis when followed by a word character
|
|
48
|
+
text = text.replace(new RegExp(`${ELLIPSIS}(?=\\w)`, "gu"), `${ELLIPSIS} `);
|
|
49
|
+
return text;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Converts ASCII multiplication patterns to proper multiplication sign (×).
|
|
53
|
+
*
|
|
54
|
+
* Handles:
|
|
55
|
+
* - Dimensions: "5x5" → "5×5"
|
|
56
|
+
* - Trailing multiplier: "5x" → "5×" (when followed by word boundary)
|
|
57
|
+
* - Asterisk multiplication: "5*3" → "5×3" (when between numbers)
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* multiplication("The room is 10x12 feet")
|
|
62
|
+
* // → "The room is 10×12 feet"
|
|
63
|
+
*
|
|
64
|
+
* multiplication("2x speed")
|
|
65
|
+
* // → "2× speed"
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export function multiplication(text, options = {}) {
|
|
69
|
+
const chr = escapeRegex(options.separator ?? DEFAULT_SEPARATOR);
|
|
70
|
+
// Dimensions: 5x5, 10 x 20, etc.
|
|
71
|
+
const dimensionPattern = new RegExp(`(\\d${chr}?) ?[xX*] ?(${chr}?\\d)`, "g");
|
|
72
|
+
text = text.replace(dimensionPattern, `$1${MULTIPLICATION}$2`);
|
|
73
|
+
// Trailing multiplier: 5x (followed by space or end, not letters or numbers)
|
|
74
|
+
const trailingPattern = new RegExp(`(\\d${chr}?)[xX*](?=${chr}?(?:\\s|$))`, "g");
|
|
75
|
+
text = text.replace(trailingPattern, `$1${MULTIPLICATION}`);
|
|
76
|
+
return text;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Converts ASCII mathematical symbols to proper Unicode equivalents.
|
|
80
|
+
*
|
|
81
|
+
* Handles:
|
|
82
|
+
* - "!=" → "≠"
|
|
83
|
+
* - "+-" or "+/-" → "±"
|
|
84
|
+
* - "<=" → "≤"
|
|
85
|
+
* - ">=" → "≥"
|
|
86
|
+
* - "~=" or "=~" → "≈"
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```ts
|
|
90
|
+
* mathSymbols("x != y and a <= b")
|
|
91
|
+
* // → "x ≠ y and a ≤ b"
|
|
92
|
+
*
|
|
93
|
+
* mathSymbols("The answer is +- 5%")
|
|
94
|
+
* // → "The answer is ± 5%"
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
export function mathSymbols(text) {
|
|
98
|
+
// Not equal
|
|
99
|
+
text = text.replace(/!=/g, NOT_EQUAL);
|
|
100
|
+
// Plus/minus
|
|
101
|
+
text = text.replace(/\+\/-/g, PLUS_MINUS);
|
|
102
|
+
text = text.replace(/\+-/g, PLUS_MINUS);
|
|
103
|
+
// Less than or equal
|
|
104
|
+
text = text.replace(/<=/g, LESS_EQUAL);
|
|
105
|
+
// Greater than or equal
|
|
106
|
+
text = text.replace(/>=/g, GREATER_EQUAL);
|
|
107
|
+
// Approximately equal
|
|
108
|
+
text = text.replace(/~=/g, APPROXIMATE);
|
|
109
|
+
text = text.replace(/=~/g, APPROXIMATE);
|
|
110
|
+
return text;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Converts ASCII representations of copyright, registered, and trademark
|
|
114
|
+
* symbols to proper Unicode characters.
|
|
115
|
+
*
|
|
116
|
+
* Handles:
|
|
117
|
+
* - "(c)" or "(C)" → "©"
|
|
118
|
+
* - "(r)" or "(R)" → "®"
|
|
119
|
+
* - "(tm)" or "(TM)" → "™"
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```ts
|
|
123
|
+
* legalSymbols("Copyright (c) 2024 Acme Inc.")
|
|
124
|
+
* // → "Copyright © 2024 Acme Inc."
|
|
125
|
+
*
|
|
126
|
+
* legalSymbols("Brand Name(tm)")
|
|
127
|
+
* // → "Brand Name™"
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
export function legalSymbols(text) {
|
|
131
|
+
// Copyright - must be surrounded by word boundaries or spaces to avoid false matches
|
|
132
|
+
text = text.replace(/\(c\)/gi, COPYRIGHT);
|
|
133
|
+
// Registered trademark
|
|
134
|
+
text = text.replace(/\(r\)/gi, REGISTERED);
|
|
135
|
+
// Trademark
|
|
136
|
+
text = text.replace(/\(tm\)/gi, TRADEMARK);
|
|
137
|
+
return text;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Converts arrow character sequences to Unicode arrows.
|
|
141
|
+
*
|
|
142
|
+
* Handles:
|
|
143
|
+
* - "->" or "-->" → "→"
|
|
144
|
+
* - "<-" or "<--" → "←"
|
|
145
|
+
* - "<->" or "<-->" → "↔"
|
|
146
|
+
*
|
|
147
|
+
* Note: Only converts when surrounded by spaces or at word boundaries
|
|
148
|
+
* to avoid false matches in code or URLs.
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* ```ts
|
|
152
|
+
* arrows("A -> B -> C")
|
|
153
|
+
* // → "A → B → C"
|
|
154
|
+
*
|
|
155
|
+
* arrows("left <-> right")
|
|
156
|
+
* // → "left ↔ right"
|
|
157
|
+
* ```
|
|
158
|
+
*/
|
|
159
|
+
export function arrows(text, options = {}) {
|
|
160
|
+
const chr = escapeRegex(options.separator ?? DEFAULT_SEPARATOR);
|
|
161
|
+
// Bidirectional arrow first (to avoid partial matches)
|
|
162
|
+
text = text.replace(new RegExp(`<-{1,2}${chr}?>`, "g"), ARROW_LEFT_RIGHT);
|
|
163
|
+
// Right arrow
|
|
164
|
+
text = text.replace(new RegExp(`(?<=[\\s${chr}]|^)-{1,2}>(?=[\\s${chr}]|$)`, "g"), ARROW_RIGHT);
|
|
165
|
+
// Left arrow
|
|
166
|
+
text = text.replace(new RegExp(`(?<=[\\s${chr}]|^)<-{1,2}(?=[\\s${chr}]|$)`, "g"), ARROW_LEFT);
|
|
167
|
+
return text;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Adds degree symbol in temperature contexts.
|
|
171
|
+
*
|
|
172
|
+
* Handles:
|
|
173
|
+
* - "20 C" or "20C" → "20 °C" (Celsius)
|
|
174
|
+
* - "68 F" or "68F" → "68 °F" (Fahrenheit)
|
|
175
|
+
*
|
|
176
|
+
* Only matches when followed by C or F (case insensitive) to avoid
|
|
177
|
+
* false positives.
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* ```ts
|
|
181
|
+
* degrees("The temperature is 20 C")
|
|
182
|
+
* // → "The temperature is 20 °C"
|
|
183
|
+
*
|
|
184
|
+
* degrees("Water boils at 212F")
|
|
185
|
+
* // → "Water boils at 212 °F"
|
|
186
|
+
* ```
|
|
187
|
+
*/
|
|
188
|
+
export function degrees(text) {
|
|
189
|
+
// Temperature with optional space before C or F
|
|
190
|
+
text = text.replace(/(\d+) ?([CF])\b/gi, (_, num, unit) => {
|
|
191
|
+
return `${num} ${DEGREE}${unit.toUpperCase()}`;
|
|
192
|
+
});
|
|
193
|
+
return text;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Converts straight quotes after numbers to prime marks.
|
|
197
|
+
*
|
|
198
|
+
* Prime marks are used for:
|
|
199
|
+
* - Feet and inches: 5'10" → 5′10″
|
|
200
|
+
* - Arcminutes and arcseconds: 45° 30' 15" → 45° 30′ 15″
|
|
201
|
+
*
|
|
202
|
+
* This should be called BEFORE smart quote transformations to prevent
|
|
203
|
+
* quotes in measurements from being curled.
|
|
204
|
+
*
|
|
205
|
+
* @example
|
|
206
|
+
* ```ts
|
|
207
|
+
* primeMarks("He's 5'10\" tall")
|
|
208
|
+
* // → "He's 5′10″ tall"
|
|
209
|
+
*
|
|
210
|
+
* primeMarks("Location: 45° 30' 15\"")
|
|
211
|
+
* // → "Location: 45° 30′ 15″"
|
|
212
|
+
* ```
|
|
213
|
+
*/
|
|
214
|
+
export function primeMarks(text, options = {}) {
|
|
215
|
+
const chr = escapeRegex(options.separator ?? DEFAULT_SEPARATOR);
|
|
216
|
+
// Single prime: digit followed by ' and then either digit, ", or end/space/punctuation
|
|
217
|
+
// This handles feet (5') and arcminutes (30')
|
|
218
|
+
const singlePrimePattern = new RegExp(`(\\d${chr}?)'(?=${chr}?(?:\\d|"|$|[\\s.,;:!?)]))`, "g");
|
|
219
|
+
text = text.replace(singlePrimePattern, `$1${PRIME}`);
|
|
220
|
+
// Double prime: digit followed by "
|
|
221
|
+
// This handles inches (10") and arcseconds (15")
|
|
222
|
+
const doublePrimePattern = new RegExp(`(\\d${chr}?)"`, "g");
|
|
223
|
+
text = text.replace(doublePrimePattern, `$1${DOUBLE_PRIME}`);
|
|
224
|
+
return text;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Converts common fractions to Unicode fraction characters.
|
|
228
|
+
*
|
|
229
|
+
* Handles: 1/4, 1/2, 3/4, 1/3, 2/3, 1/5, 2/5, 3/5, 4/5,
|
|
230
|
+
* 1/6, 5/6, 1/8, 3/8, 5/8, 7/8
|
|
231
|
+
*
|
|
232
|
+
* Only converts when the fraction is surrounded by word boundaries
|
|
233
|
+
* to avoid breaking URLs, file paths, or dates.
|
|
234
|
+
*
|
|
235
|
+
* @example
|
|
236
|
+
* ```ts
|
|
237
|
+
* fractions("Add 1/2 cup of flour")
|
|
238
|
+
* // → "Add ½ cup of flour"
|
|
239
|
+
*
|
|
240
|
+
* fractions("About 3/4 complete")
|
|
241
|
+
* // → "About ¾ complete"
|
|
242
|
+
* ```
|
|
243
|
+
*/
|
|
244
|
+
export function fractions(text) {
|
|
245
|
+
const fractionMap = {
|
|
246
|
+
"1/4": "\u00BC", // ¼
|
|
247
|
+
"1/2": "\u00BD", // ½
|
|
248
|
+
"3/4": "\u00BE", // ¾
|
|
249
|
+
"1/3": "\u2153", // ⅓
|
|
250
|
+
"2/3": "\u2154", // ⅔
|
|
251
|
+
"1/5": "\u2155", // ⅕
|
|
252
|
+
"2/5": "\u2156", // ⅖
|
|
253
|
+
"3/5": "\u2157", // ⅗
|
|
254
|
+
"4/5": "\u2158", // ⅘
|
|
255
|
+
"1/6": "\u2159", // ⅙
|
|
256
|
+
"5/6": "\u215A", // ⅚
|
|
257
|
+
"1/8": "\u215B", // ⅛
|
|
258
|
+
"3/8": "\u215C", // ⅜
|
|
259
|
+
"5/8": "\u215D", // ⅝
|
|
260
|
+
"7/8": "\u215E", // ⅞
|
|
261
|
+
};
|
|
262
|
+
for (const [ascii, unicode] of Object.entries(fractionMap)) {
|
|
263
|
+
// Match fraction at word boundaries, not inside numbers like "21/4"
|
|
264
|
+
const pattern = new RegExp(`(?<!\\d)${ascii.replace("/", "\\/")}(?!\\d)`, "g");
|
|
265
|
+
text = text.replace(pattern, unicode);
|
|
266
|
+
}
|
|
267
|
+
return text;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Applies all symbol transformations.
|
|
271
|
+
*
|
|
272
|
+
* Runs in order:
|
|
273
|
+
* 1. ellipsis
|
|
274
|
+
* 2. multiplication
|
|
275
|
+
* 3. mathSymbols
|
|
276
|
+
* 4. legalSymbols
|
|
277
|
+
* 5. arrows
|
|
278
|
+
*
|
|
279
|
+
* Note: `degrees` and `fractions` are not included by default as they
|
|
280
|
+
* may be too aggressive for some use cases. Call them explicitly if needed.
|
|
281
|
+
*
|
|
282
|
+
* @example
|
|
283
|
+
* ```ts
|
|
284
|
+
* symbolTransform("Wait... 5x5 != 20 (c) 2024")
|
|
285
|
+
* // → "Wait… 5×5 ≠ 20 © 2024"
|
|
286
|
+
* ```
|
|
287
|
+
*/
|
|
288
|
+
export function symbolTransform(text, options = {}) {
|
|
289
|
+
text = ellipsis(text, options);
|
|
290
|
+
text = multiplication(text, options);
|
|
291
|
+
text = mathSymbols(text);
|
|
292
|
+
text = legalSymbols(text);
|
|
293
|
+
text = arrows(text, options);
|
|
294
|
+
return text;
|
|
295
|
+
}
|
|
296
|
+
//# sourceMappingURL=symbols.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"symbols.js","sourceRoot":"","sources":["../src/symbols.ts"],"names":[],"mappings":"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"}
|