punctilio 0.1.1 → 0.2.1
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 +125 -6
- package/dist/constants.d.ts +58 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +58 -0
- package/dist/constants.js.map +1 -0
- package/dist/dashes.d.ts.map +1 -1
- package/dist/dashes.js +14 -21
- package/dist/dashes.js.map +1 -1
- 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/quotes.d.ts.map +1 -1
- package/dist/quotes.js +19 -42
- package/dist/quotes.js.map +1 -1
- package/dist/symbols.d.ts +174 -0
- package/dist/symbols.d.ts.map +1 -0
- package/dist/symbols.js +265 -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:
|
|
@@ -71,9 +100,15 @@ For a complete implementation showing how to use this with a HAST (HTML AST) tre
|
|
|
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
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Unicode constants used throughout the punctilio package.
|
|
3
|
+
*
|
|
4
|
+
* This module provides a centralized location for all Unicode symbols
|
|
5
|
+
* used in typography transformations, making the codebase more maintainable
|
|
6
|
+
* and self-documenting.
|
|
7
|
+
*
|
|
8
|
+
* @module constants
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Unicode symbols for typography transformations.
|
|
12
|
+
*/
|
|
13
|
+
export declare const UNICODE_SYMBOLS: {
|
|
14
|
+
readonly ELLIPSIS: "…";
|
|
15
|
+
readonly MULTIPLICATION: "×";
|
|
16
|
+
readonly NOT_EQUAL: "≠";
|
|
17
|
+
readonly PLUS_MINUS: "±";
|
|
18
|
+
readonly COPYRIGHT: "©";
|
|
19
|
+
readonly REGISTERED: "®";
|
|
20
|
+
readonly TRADEMARK: "™";
|
|
21
|
+
readonly DEGREE: "°";
|
|
22
|
+
readonly ARROW_RIGHT: "→";
|
|
23
|
+
readonly ARROW_LEFT: "←";
|
|
24
|
+
readonly ARROW_LEFT_RIGHT: "↔";
|
|
25
|
+
readonly APPROXIMATE: "≈";
|
|
26
|
+
readonly LESS_EQUAL: "≤";
|
|
27
|
+
readonly GREATER_EQUAL: "≥";
|
|
28
|
+
readonly PRIME: "′";
|
|
29
|
+
readonly DOUBLE_PRIME: "″";
|
|
30
|
+
readonly FRACTION_1_4: "¼";
|
|
31
|
+
readonly FRACTION_1_2: "½";
|
|
32
|
+
readonly FRACTION_3_4: "¾";
|
|
33
|
+
readonly FRACTION_1_3: "⅓";
|
|
34
|
+
readonly FRACTION_2_3: "⅔";
|
|
35
|
+
readonly FRACTION_1_5: "⅕";
|
|
36
|
+
readonly FRACTION_2_5: "⅖";
|
|
37
|
+
readonly FRACTION_3_5: "⅗";
|
|
38
|
+
readonly FRACTION_4_5: "⅘";
|
|
39
|
+
readonly FRACTION_1_6: "⅙";
|
|
40
|
+
readonly FRACTION_5_6: "⅚";
|
|
41
|
+
readonly FRACTION_1_8: "⅛";
|
|
42
|
+
readonly FRACTION_3_8: "⅜";
|
|
43
|
+
readonly FRACTION_5_8: "⅝";
|
|
44
|
+
readonly FRACTION_7_8: "⅞";
|
|
45
|
+
readonly EM_DASH: "—";
|
|
46
|
+
readonly EN_DASH: "–";
|
|
47
|
+
readonly MINUS: "−";
|
|
48
|
+
readonly LEFT_DOUBLE_QUOTE: "“";
|
|
49
|
+
readonly RIGHT_DOUBLE_QUOTE: "”";
|
|
50
|
+
readonly LEFT_SINGLE_QUOTE: "‘";
|
|
51
|
+
readonly RIGHT_SINGLE_QUOTE: "’";
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Default separator character for text spanning HTML elements.
|
|
55
|
+
* Uses Unicode Private Use Area character U+E000.
|
|
56
|
+
*/
|
|
57
|
+
export declare const DEFAULT_SEPARATOR = "\uE000";
|
|
58
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;GAEG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuClB,CAAA;AAEV;;;GAGG;AACH,eAAO,MAAM,iBAAiB,WAAW,CAAA"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Unicode constants used throughout the punctilio package.
|
|
3
|
+
*
|
|
4
|
+
* This module provides a centralized location for all Unicode symbols
|
|
5
|
+
* used in typography transformations, making the codebase more maintainable
|
|
6
|
+
* and self-documenting.
|
|
7
|
+
*
|
|
8
|
+
* @module constants
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Unicode symbols for typography transformations.
|
|
12
|
+
*/
|
|
13
|
+
export const UNICODE_SYMBOLS = {
|
|
14
|
+
ELLIPSIS: "\u2026",
|
|
15
|
+
MULTIPLICATION: "\u00D7",
|
|
16
|
+
NOT_EQUAL: "\u2260",
|
|
17
|
+
PLUS_MINUS: "\u00B1",
|
|
18
|
+
COPYRIGHT: "\u00A9",
|
|
19
|
+
REGISTERED: "\u00AE",
|
|
20
|
+
TRADEMARK: "\u2122",
|
|
21
|
+
DEGREE: "\u00B0",
|
|
22
|
+
ARROW_RIGHT: "\u2192",
|
|
23
|
+
ARROW_LEFT: "\u2190",
|
|
24
|
+
ARROW_LEFT_RIGHT: "\u2194",
|
|
25
|
+
APPROXIMATE: "\u2248",
|
|
26
|
+
LESS_EQUAL: "\u2264",
|
|
27
|
+
GREATER_EQUAL: "\u2265",
|
|
28
|
+
PRIME: "\u2032",
|
|
29
|
+
DOUBLE_PRIME: "\u2033",
|
|
30
|
+
FRACTION_1_4: "\u00BC",
|
|
31
|
+
FRACTION_1_2: "\u00BD",
|
|
32
|
+
FRACTION_3_4: "\u00BE",
|
|
33
|
+
FRACTION_1_3: "\u2153",
|
|
34
|
+
FRACTION_2_3: "\u2154",
|
|
35
|
+
FRACTION_1_5: "\u2155",
|
|
36
|
+
FRACTION_2_5: "\u2156",
|
|
37
|
+
FRACTION_3_5: "\u2157",
|
|
38
|
+
FRACTION_4_5: "\u2158",
|
|
39
|
+
FRACTION_1_6: "\u2159",
|
|
40
|
+
FRACTION_5_6: "\u215A",
|
|
41
|
+
FRACTION_1_8: "\u215B",
|
|
42
|
+
FRACTION_3_8: "\u215C",
|
|
43
|
+
FRACTION_5_8: "\u215D",
|
|
44
|
+
FRACTION_7_8: "\u215E",
|
|
45
|
+
EM_DASH: "\u2014",
|
|
46
|
+
EN_DASH: "\u2013",
|
|
47
|
+
MINUS: "\u2212",
|
|
48
|
+
LEFT_DOUBLE_QUOTE: "\u201C",
|
|
49
|
+
RIGHT_DOUBLE_QUOTE: "\u201D",
|
|
50
|
+
LEFT_SINGLE_QUOTE: "\u2018",
|
|
51
|
+
RIGHT_SINGLE_QUOTE: "\u2019",
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Default separator character for text spanning HTML elements.
|
|
55
|
+
* Uses Unicode Private Use Area character U+E000.
|
|
56
|
+
*/
|
|
57
|
+
export const DEFAULT_SEPARATOR = "\uE000";
|
|
58
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +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;CACpB,CAAA;AAEV;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,QAAQ,CAAA"}
|
package/dist/dashes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashes.d.ts","sourceRoot":"","sources":["../src/dashes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"dashes.d.ts","sourceRoot":"","sources":["../src/dashes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,WAAW,WAAW;IAC1B;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAID;;GAEG;AACH,eAAO,MAAM,MAAM,QAyBR,CAAA;AAEX;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CASjF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAM/E;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAI5E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAwC7E"}
|
package/dist/dashes.js
CHANGED
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
* Converts hyphens and dashes to typographically correct em-dashes,
|
|
5
5
|
* en-dashes, and minus signs based on context.
|
|
6
6
|
*/
|
|
7
|
-
|
|
7
|
+
import { UNICODE_SYMBOLS, DEFAULT_SEPARATOR } from "./constants.js";
|
|
8
|
+
const { EN_DASH, EM_DASH, MINUS } = UNICODE_SYMBOLS;
|
|
8
9
|
/**
|
|
9
10
|
* List of month names (full and abbreviated) for date range detection
|
|
10
11
|
*/
|
|
@@ -59,7 +60,7 @@ export const months = [
|
|
|
59
60
|
*/
|
|
60
61
|
export function enDashNumberRange(text, options = {}) {
|
|
61
62
|
const chr = options.separator ?? DEFAULT_SEPARATOR;
|
|
62
|
-
return text.replace(new RegExp(`\\b(?<![a-zA-Z.])((?:p\\.?|\\$)?\\d[\\d.,]*${chr}?)-(${chr}?\\$?\\d[\\d.,]*)(?!\\.\\d)\\b`, "g"),
|
|
63
|
+
return text.replace(new RegExp(`\\b(?<![a-zA-Z.])((?:p\\.?|\\$)?\\d[\\d.,]*${chr}?)-(${chr}?\\$?\\d[\\d.,]*)(?!\\.\\d)\\b`, "g"), `$1${EN_DASH}$2`);
|
|
63
64
|
}
|
|
64
65
|
/**
|
|
65
66
|
* Replaces hyphens with en-dashes in month/date ranges.
|
|
@@ -80,7 +81,7 @@ export function enDashNumberRange(text, options = {}) {
|
|
|
80
81
|
*/
|
|
81
82
|
export function enDashDateRange(text, options = {}) {
|
|
82
83
|
const chr = options.separator ?? DEFAULT_SEPARATOR;
|
|
83
|
-
return text.replace(new RegExp(`\\b(${months}${chr}?)-(${chr}?(?:${months}))\\b`, "g"),
|
|
84
|
+
return text.replace(new RegExp(`\\b(${months}${chr}?)-(${chr}?(?:${months}))\\b`, "g"), `$1${EN_DASH}$2`);
|
|
84
85
|
}
|
|
85
86
|
/**
|
|
86
87
|
* Replaces hyphens with proper minus signs (−) in numerical contexts.
|
|
@@ -104,7 +105,7 @@ export function enDashDateRange(text, options = {}) {
|
|
|
104
105
|
export function minusReplace(text, options = {}) {
|
|
105
106
|
const chr = options.separator ?? DEFAULT_SEPARATOR;
|
|
106
107
|
const minusRegex = new RegExp(`(^|[\\s\\(${chr}""])-(\\s?\\d*\\.?\\d+)`, "gm");
|
|
107
|
-
return text.replaceAll(minusRegex,
|
|
108
|
+
return text.replaceAll(minusRegex, `$1${MINUS}$2`);
|
|
108
109
|
}
|
|
109
110
|
/**
|
|
110
111
|
* Comprehensive dash replacement for typographic correctness.
|
|
@@ -146,25 +147,17 @@ export function hyphenReplace(text, options = {}) {
|
|
|
146
147
|
// Being right after chr is a sufficient condition for being an em
|
|
147
148
|
// dash, as it indicates the start of a new line
|
|
148
149
|
const preDash = new RegExp(`((?<markerBeforeTwo>${chr}?)[ ]+|(?<markerBeforeThree>${chr}))`);
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
text = text.replace(
|
|
153
|
-
|
|
154
|
-
const
|
|
155
|
-
text = text.replace(
|
|
156
|
-
// Handle dashes at the start of a line
|
|
157
|
-
text = text.replace(new RegExp(`^(${chr})?[-]+ `, "gm"), "$1— ");
|
|
158
|
-
// Create a regex for spaces around em dashes, allowing for optional spaces around the em dash
|
|
159
|
-
const spacesAroundEM = new RegExp(`(?<markerBefore>${chr}?)[ ]*—[ ]*(?<markerAfter>${chr}?)[ ]*`, "g");
|
|
160
|
-
// Remove spaces around em dashes
|
|
161
|
-
text = text.replace(spacesAroundEM, "$<markerBefore>—$<markerAfter>");
|
|
162
|
-
// Handle special case after quotation marks
|
|
150
|
+
const surroundedDash = new RegExp(`(?<=[^\\s>]|^)${preDash.source}[~${EN_DASH}${EM_DASH}-]+[ ]*(?<markerAfter>${chr}?)([ ]+|$)`, "g");
|
|
151
|
+
text = text.replace(surroundedDash, `$<markerBeforeTwo>$<markerBeforeThree>${EM_DASH}$<markerAfter>`);
|
|
152
|
+
const multipleDashInWords = new RegExp(`(?<=[A-Za-z\\d])(?<markerBefore>${chr}?)[~${EN_DASH}${EM_DASH}-]{2,}(?<markerAfter>${chr}?)(?=[A-Za-z\\d ])`, "g");
|
|
153
|
+
text = text.replace(multipleDashInWords, `$<markerBefore>${EM_DASH}$<markerAfter>`);
|
|
154
|
+
text = text.replace(new RegExp(`^(${chr})?[-]+ `, "gm"), `$1${EM_DASH} `);
|
|
155
|
+
const spacesAroundEM = new RegExp(`(?<markerBefore>${chr}?)[ ]*${EM_DASH}[ ]*(?<markerAfter>${chr}?)[ ]*`, "g");
|
|
156
|
+
text = text.replace(spacesAroundEM, `$<markerBefore>${EM_DASH}$<markerAfter>`);
|
|
163
157
|
const postQuote = new RegExp(`(?<quote>[.!?]${chr}?['"'"]${chr}?|…)${spacesAroundEM.source}`, "g");
|
|
164
|
-
text = text.replace(postQuote,
|
|
165
|
-
// Handle em dashes at the start of a line
|
|
158
|
+
text = text.replace(postQuote, `$<quote> $<markerBefore>${EM_DASH}$<markerAfter> `);
|
|
166
159
|
const startOfLine = new RegExp(`^${spacesAroundEM.source}(?<after>[A-Z0-9])`, "gm");
|
|
167
|
-
text = text.replace(startOfLine,
|
|
160
|
+
text = text.replace(startOfLine, `$<markerBefore>${EM_DASH}$<markerAfter> $<after>`);
|
|
168
161
|
text = enDashNumberRange(text, options);
|
|
169
162
|
text = enDashDateRange(text, options);
|
|
170
163
|
return text;
|
package/dist/dashes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashes.js","sourceRoot":"","sources":["../src/dashes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"dashes.js","sourceRoot":"","sources":["../src/dashes.ts"],"names":[],"mappings":"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"}
|
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"}
|
package/dist/quotes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quotes.d.ts","sourceRoot":"","sources":["../src/quotes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"quotes.d.ts","sourceRoot":"","sources":["../src/quotes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAaH,MAAM,WAAW,YAAY;IAC3B;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,MAAM,CA8C3E"}
|
package/dist/quotes.js
CHANGED
|
@@ -4,14 +4,8 @@
|
|
|
4
4
|
* Converts straight quotes to typographically correct curly quotes,
|
|
5
5
|
* handling contractions, possessives, and nested quotes.
|
|
6
6
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const EM_DASH = "\u2014"; // —
|
|
10
|
-
const LEFT_DOUBLE = "\u201C"; // "
|
|
11
|
-
const RIGHT_DOUBLE = "\u201D"; // "
|
|
12
|
-
const LEFT_SINGLE = "\u2018"; // '
|
|
13
|
-
const RIGHT_SINGLE = "\u2019"; // '
|
|
14
|
-
const ELLIPSIS = "\u2026"; // …
|
|
7
|
+
import { UNICODE_SYMBOLS, DEFAULT_SEPARATOR } from "./constants.js";
|
|
8
|
+
const { EM_DASH, LEFT_DOUBLE_QUOTE, RIGHT_DOUBLE_QUOTE, LEFT_SINGLE_QUOTE, RIGHT_SINGLE_QUOTE, ELLIPSIS, } = UNICODE_SYMBOLS;
|
|
15
9
|
/**
|
|
16
10
|
* Converts standard quotes to typographic smart quotes.
|
|
17
11
|
*
|
|
@@ -21,45 +15,28 @@ const ELLIPSIS = "\u2026"; // …
|
|
|
21
15
|
*/
|
|
22
16
|
export function niceQuotes(text, options = {}) {
|
|
23
17
|
const chr = options.separator ?? DEFAULT_SEPARATOR;
|
|
24
|
-
// Single quotes //
|
|
25
|
-
// Ending comes first so as to not mess with the open quote
|
|
26
18
|
const afterEndingSinglePatterns = `\\s\\.!?;,\\)${EM_DASH}\\-\\]"`;
|
|
27
19
|
const afterEndingSingle = `(?=${chr}?(?:s${chr}?)?(?:[${afterEndingSinglePatterns}]|$))`;
|
|
28
|
-
const endingSingle = `(?<=[^\\s${
|
|
29
|
-
text = text.replace(new RegExp(endingSingle, "gm"),
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
// Note: The character class uses LEFT_SINGLE and ASCII straight quote (U+0027)
|
|
39
|
-
// NOT RIGHT_SINGLE - this is intentional for the algorithm to work correctly
|
|
40
|
-
const apostropheRegex = new RegExp(`(?<=^|[^\\w])'(${apostropheWhitelist}|(?![^${LEFT_SINGLE}'\\n]*${endQuoteNotContraction}))`, "gm");
|
|
41
|
-
text = text.replace(apostropheRegex, RIGHT_SINGLE);
|
|
42
|
-
// Beginning single quotes
|
|
43
|
-
const beginningSingle = `((?:^|[\\s${LEFT_DOUBLE}${RIGHT_DOUBLE}\\-\\(])${chr}?)['](?=${chr}?\\S)`;
|
|
44
|
-
text = text.replace(new RegExp(beginningSingle, "gm"), `$1${LEFT_SINGLE}`);
|
|
45
|
-
// Double quotes //
|
|
20
|
+
const endingSingle = `(?<=[^\\s${LEFT_DOUBLE_QUOTE}'])[']${afterEndingSingle}`;
|
|
21
|
+
text = text.replace(new RegExp(endingSingle, "gm"), RIGHT_SINGLE_QUOTE);
|
|
22
|
+
const contraction = `(?<=[A-Za-z])['${RIGHT_SINGLE_QUOTE}](?=${chr}?[a-zA-Z])`;
|
|
23
|
+
text = text.replace(new RegExp(contraction, "gm"), RIGHT_SINGLE_QUOTE);
|
|
24
|
+
const apostropheWhitelist = `(?=n${RIGHT_SINGLE_QUOTE} )`;
|
|
25
|
+
const endQuoteNotContraction = `(?!${contraction})${RIGHT_SINGLE_QUOTE}${afterEndingSingle}`;
|
|
26
|
+
const apostropheRegex = new RegExp(`(?<=^|[^\\w])'(${apostropheWhitelist}|(?![^${LEFT_SINGLE_QUOTE}'\\n]*${endQuoteNotContraction}))`, "gm");
|
|
27
|
+
text = text.replace(apostropheRegex, RIGHT_SINGLE_QUOTE);
|
|
28
|
+
const beginningSingle = `((?:^|[\\s${LEFT_DOUBLE_QUOTE}${RIGHT_DOUBLE_QUOTE}\\-\\(])${chr}?)['](?=${chr}?\\S)`;
|
|
29
|
+
text = text.replace(new RegExp(beginningSingle, "gm"), `$1${LEFT_SINGLE_QUOTE}`);
|
|
46
30
|
const beginningDouble = new RegExp(`(?<=^|[\\s\\(\\/\\[\\{\\-${EM_DASH}${chr}])(?<beforeChr>${chr}?)["](?<afterChr>(${chr}[ .,])|(?=${chr}?\\.{3}|${chr}?[^\\s\\)\\${EM_DASH},!?${chr};:.\\}]))`, "gm");
|
|
47
|
-
text = text.replace(beginningDouble, `$<beforeChr>${
|
|
48
|
-
|
|
49
|
-
text = text.replace(new RegExp(`(?<=\\{)(${chr}? )?["]`, "g"), `$1${LEFT_DOUBLE}`);
|
|
50
|
-
// note: Allowing 2 chrs in a row
|
|
31
|
+
text = text.replace(beginningDouble, `$<beforeChr>${LEFT_DOUBLE_QUOTE}$<afterChr>`);
|
|
32
|
+
text = text.replace(new RegExp(`(?<=\\{)(${chr}? )?["]`, "g"), `$1${LEFT_DOUBLE_QUOTE}`);
|
|
51
33
|
const endingDouble = `([^\\s\\(])["](${chr}?)(?=${chr}|[\\s/\\).,;${EM_DASH}:\\-\\}!?s]|$)`;
|
|
52
|
-
text = text.replace(new RegExp(endingDouble, "g"), `$1${
|
|
53
|
-
|
|
54
|
-
text = text.replace(new RegExp(`
|
|
55
|
-
|
|
56
|
-
text = text.replace(new RegExp(`'(?=${RIGHT_DOUBLE})`, "gu"), RIGHT_SINGLE);
|
|
57
|
-
// Punctuation //
|
|
58
|
-
// Periods inside quotes
|
|
59
|
-
const periodRegex = new RegExp(`(?<![!?:\\.${ELLIPSIS}])(${chr}?)([${RIGHT_SINGLE}${RIGHT_DOUBLE}])(${chr}?)(?!\\.\\.\\.)\\.`, "g");
|
|
34
|
+
text = text.replace(new RegExp(endingDouble, "g"), `$1${RIGHT_DOUBLE_QUOTE}$2`);
|
|
35
|
+
text = text.replace(new RegExp(`["](${chr}?)$`, "g"), `${RIGHT_DOUBLE_QUOTE}$1`);
|
|
36
|
+
text = text.replace(new RegExp(`'(?=${RIGHT_DOUBLE_QUOTE})`, "gu"), RIGHT_SINGLE_QUOTE);
|
|
37
|
+
const periodRegex = new RegExp(`(?<![!?:\\.${ELLIPSIS}])(${chr}?)([${RIGHT_SINGLE_QUOTE}${RIGHT_DOUBLE_QUOTE}])(${chr}?)(?!\\.\\.\\.)\\.`, "g");
|
|
60
38
|
text = text.replace(periodRegex, "$1.$2$3");
|
|
61
|
-
|
|
62
|
-
const commaRegex = new RegExp(`(?<![!?]),(${chr}?[${RIGHT_DOUBLE}${RIGHT_SINGLE}])`, "g");
|
|
39
|
+
const commaRegex = new RegExp(`(?<![!?]),(${chr}?[${RIGHT_DOUBLE_QUOTE}${RIGHT_SINGLE_QUOTE}])`, "g");
|
|
63
40
|
text = text.replace(commaRegex, "$1,");
|
|
64
41
|
return text;
|
|
65
42
|
}
|
package/dist/quotes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quotes.js","sourceRoot":"","sources":["../src/quotes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"quotes.js","sourceRoot":"","sources":["../src/quotes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,174 @@
|
|
|
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
|
+
* Whether to include arrow transformations (-> to →, etc.).
|
|
17
|
+
* Default: true
|
|
18
|
+
*/
|
|
19
|
+
includeArrows?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Converts three periods to a proper ellipsis character.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* ellipsis("Wait for it...")
|
|
27
|
+
* // → "Wait for it…"
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare function ellipsis(text: string, options?: SymbolOptions): string;
|
|
31
|
+
/**
|
|
32
|
+
* Converts ASCII multiplication patterns to proper multiplication sign (×).
|
|
33
|
+
*
|
|
34
|
+
* Handles:
|
|
35
|
+
* - Dimensions: "5x5" → "5×5"
|
|
36
|
+
* - Trailing multiplier: "5x" → "5×" (when followed by word boundary)
|
|
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
|
+
*/
|
|
48
|
+
export declare function multiplication(text: string, options?: SymbolOptions): string;
|
|
49
|
+
/**
|
|
50
|
+
* Converts ASCII mathematical symbols to proper Unicode equivalents.
|
|
51
|
+
*
|
|
52
|
+
* Handles:
|
|
53
|
+
* - "!=" → "≠"
|
|
54
|
+
* - "+-" or "+/-" → "±"
|
|
55
|
+
* - "<=" → "≤"
|
|
56
|
+
* - ">=" → "≥"
|
|
57
|
+
* - "~=" or "=~" → "≈"
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* mathSymbols("x != y and a <= b")
|
|
62
|
+
* // → "x ≠ y and a ≤ b"
|
|
63
|
+
*
|
|
64
|
+
* mathSymbols("The answer is +- 5%")
|
|
65
|
+
* // → "The answer is ± 5%"
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export declare function mathSymbols(text: string): string;
|
|
69
|
+
/**
|
|
70
|
+
* Converts ASCII representations of copyright, registered, and trademark
|
|
71
|
+
* symbols to proper Unicode characters.
|
|
72
|
+
*/
|
|
73
|
+
export declare function legalSymbols(text: string): string;
|
|
74
|
+
/**
|
|
75
|
+
* Converts arrow character sequences to Unicode arrows.
|
|
76
|
+
*
|
|
77
|
+
* Handles:
|
|
78
|
+
* - "->" or "-->" → "→"
|
|
79
|
+
* - "<-" or "<--" → "←"
|
|
80
|
+
* - "<->" or "<-->" → "↔"
|
|
81
|
+
*
|
|
82
|
+
* Note: Only converts when surrounded by spaces or at word boundaries
|
|
83
|
+
* to avoid false matches in code or URLs.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```ts
|
|
87
|
+
* arrows("A -> B -> C")
|
|
88
|
+
* // → "A → B → C"
|
|
89
|
+
*
|
|
90
|
+
* arrows("left <-> right")
|
|
91
|
+
* // → "left ↔ right"
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
export declare function arrows(text: string, options?: SymbolOptions): string;
|
|
95
|
+
/**
|
|
96
|
+
* Adds degree symbol in temperature contexts.
|
|
97
|
+
*
|
|
98
|
+
* Handles:
|
|
99
|
+
* - "20 C" or "20C" → "20 °C" (Celsius)
|
|
100
|
+
* - "68 F" or "68F" → "68 °F" (Fahrenheit)
|
|
101
|
+
*
|
|
102
|
+
* Only matches when followed by C or F (case insensitive) to avoid
|
|
103
|
+
* false positives.
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```ts
|
|
107
|
+
* degrees("The temperature is 20 C")
|
|
108
|
+
* // → "The temperature is 20 °C"
|
|
109
|
+
*
|
|
110
|
+
* degrees("Water boils at 212F")
|
|
111
|
+
* // → "Water boils at 212 °F"
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
export declare function degrees(text: string): string;
|
|
115
|
+
/**
|
|
116
|
+
* Converts straight quotes after numbers to prime marks.
|
|
117
|
+
*
|
|
118
|
+
* Prime marks are used for:
|
|
119
|
+
* - Feet and inches: 5'10" → 5′10″
|
|
120
|
+
* - Arcminutes and arcseconds: 45° 30' 15" → 45° 30′ 15″
|
|
121
|
+
*
|
|
122
|
+
* This should be called BEFORE smart quote transformations to prevent
|
|
123
|
+
* quotes in measurements from being curled.
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```ts
|
|
127
|
+
* primeMarks("He's 5'10\" tall")
|
|
128
|
+
* // → "He's 5′10″ tall"
|
|
129
|
+
*
|
|
130
|
+
* primeMarks("Location: 45° 30' 15\"")
|
|
131
|
+
* // → "Location: 45° 30′ 15″"
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
export declare function primeMarks(text: string, options?: SymbolOptions): string;
|
|
135
|
+
/**
|
|
136
|
+
* Converts common fractions to Unicode fraction characters.
|
|
137
|
+
*
|
|
138
|
+
* Handles: 1/4, 1/2, 3/4, 1/3, 2/3, 1/5, 2/5, 3/5, 4/5,
|
|
139
|
+
* 1/6, 5/6, 1/8, 3/8, 5/8, 7/8
|
|
140
|
+
*
|
|
141
|
+
* Only converts when the fraction is surrounded by word boundaries
|
|
142
|
+
* to avoid breaking URLs, file paths, or dates.
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* ```ts
|
|
146
|
+
* fractions("Add 1/2 cup of flour")
|
|
147
|
+
* // → "Add ½ cup of flour"
|
|
148
|
+
*
|
|
149
|
+
* fractions("About 3/4 complete")
|
|
150
|
+
* // → "About ¾ complete"
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
153
|
+
export declare function fractions(text: string): string;
|
|
154
|
+
/**
|
|
155
|
+
* Applies all symbol transformations.
|
|
156
|
+
*
|
|
157
|
+
* Runs in order:
|
|
158
|
+
* 1. ellipsis
|
|
159
|
+
* 2. multiplication
|
|
160
|
+
* 3. mathSymbols
|
|
161
|
+
* 4. legalSymbols
|
|
162
|
+
* 5. arrows
|
|
163
|
+
*
|
|
164
|
+
* Note: `degrees` and `fractions` are not included by default as they
|
|
165
|
+
* may be too aggressive for some use cases. Call them explicitly if needed.
|
|
166
|
+
*
|
|
167
|
+
* @example
|
|
168
|
+
* ```ts
|
|
169
|
+
* symbolTransform("Wait... 5x5 != 20 (c) 2024")
|
|
170
|
+
* // → "Wait… 5×5 ≠ 20 © 2024"
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
173
|
+
export declare function symbolTransform(text: string, options?: SymbolOptions): string;
|
|
174
|
+
//# sourceMappingURL=symbols.d.ts.map
|
|
@@ -0,0 +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;AA4BD;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAS1E;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAgBhF;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAUhD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMjD;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,CA0B5E;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAyB9C;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CASjF"}
|
package/dist/symbols.js
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
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
|
+
import { UNICODE_SYMBOLS, DEFAULT_SEPARATOR } from "./constants.js";
|
|
10
|
+
/**
|
|
11
|
+
* Escapes special regex characters in a string.
|
|
12
|
+
*/
|
|
13
|
+
function escapeRegex(str) {
|
|
14
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
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, } = UNICODE_SYMBOLS;
|
|
17
|
+
/**
|
|
18
|
+
* Converts three periods to a proper ellipsis character.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* ellipsis("Wait for it...")
|
|
23
|
+
* // → "Wait for it…"
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export function ellipsis(text, options = {}) {
|
|
27
|
+
const chr = escapeRegex(options.separator ?? DEFAULT_SEPARATOR);
|
|
28
|
+
const pattern = new RegExp(`\\.${chr}?\\.${chr}?\\.`, "g");
|
|
29
|
+
text = text.replace(pattern, ELLIPSIS);
|
|
30
|
+
text = text.replace(new RegExp(`${ELLIPSIS}(?=\\w)`, "gu"), `${ELLIPSIS} `);
|
|
31
|
+
return text;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Converts ASCII multiplication patterns to proper multiplication sign (×).
|
|
35
|
+
*
|
|
36
|
+
* Handles:
|
|
37
|
+
* - Dimensions: "5x5" → "5×5"
|
|
38
|
+
* - Trailing multiplier: "5x" → "5×" (when followed by word boundary)
|
|
39
|
+
* - Asterisk multiplication: "5*3" → "5×3" (when between numbers)
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* multiplication("The room is 10x12 feet")
|
|
44
|
+
* // → "The room is 10×12 feet"
|
|
45
|
+
*
|
|
46
|
+
* multiplication("2x speed")
|
|
47
|
+
* // → "2× speed"
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export function multiplication(text, options = {}) {
|
|
51
|
+
const chr = escapeRegex(options.separator ?? DEFAULT_SEPARATOR);
|
|
52
|
+
// Dimensions with spaces: preserve spacing
|
|
53
|
+
const loosePattern = new RegExp(`(\\d${chr}?)\\s+[xX*]\\s+(${chr}?\\d)`, "g");
|
|
54
|
+
text = text.replace(loosePattern, `$1 ${MULTIPLICATION} $2`);
|
|
55
|
+
// Dimensions without spaces: keep tight
|
|
56
|
+
const tightPattern = new RegExp(`(\\d${chr}?)[xX*](${chr}?\\d)`, "g");
|
|
57
|
+
text = text.replace(tightPattern, `$1${MULTIPLICATION}$2`);
|
|
58
|
+
// Trailing multiplier: 5x (followed by space or end, not letters or numbers)
|
|
59
|
+
const trailingPattern = new RegExp(`(\\d${chr}?)[xX*](?=${chr}?(?:\\s|$))`, "g");
|
|
60
|
+
text = text.replace(trailingPattern, `$1${MULTIPLICATION}`);
|
|
61
|
+
return text;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Converts ASCII mathematical symbols to proper Unicode equivalents.
|
|
65
|
+
*
|
|
66
|
+
* Handles:
|
|
67
|
+
* - "!=" → "≠"
|
|
68
|
+
* - "+-" or "+/-" → "±"
|
|
69
|
+
* - "<=" → "≤"
|
|
70
|
+
* - ">=" → "≥"
|
|
71
|
+
* - "~=" or "=~" → "≈"
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```ts
|
|
75
|
+
* mathSymbols("x != y and a <= b")
|
|
76
|
+
* // → "x ≠ y and a ≤ b"
|
|
77
|
+
*
|
|
78
|
+
* mathSymbols("The answer is +- 5%")
|
|
79
|
+
* // → "The answer is ± 5%"
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export function mathSymbols(text) {
|
|
83
|
+
text = text.replace(/!=/g, NOT_EQUAL);
|
|
84
|
+
text = text.replace(/\+\/-/g, PLUS_MINUS);
|
|
85
|
+
text = text.replace(/\+-/g, PLUS_MINUS);
|
|
86
|
+
text = text.replace(/<=/g, LESS_EQUAL);
|
|
87
|
+
text = text.replace(/>=/g, GREATER_EQUAL);
|
|
88
|
+
text = text.replace(/~=/g, APPROXIMATE);
|
|
89
|
+
text = text.replace(/=~/g, APPROXIMATE);
|
|
90
|
+
return text;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Converts ASCII representations of copyright, registered, and trademark
|
|
94
|
+
* symbols to proper Unicode characters.
|
|
95
|
+
*/
|
|
96
|
+
export function legalSymbols(text) {
|
|
97
|
+
text = text.replace(/\(c\)/gi, COPYRIGHT);
|
|
98
|
+
text = text.replace(/\(r\)/gi, REGISTERED);
|
|
99
|
+
text = text.replace(/\(tm\)/gi, TRADEMARK);
|
|
100
|
+
return text;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Converts arrow character sequences to Unicode arrows.
|
|
104
|
+
*
|
|
105
|
+
* Handles:
|
|
106
|
+
* - "->" or "-->" → "→"
|
|
107
|
+
* - "<-" or "<--" → "←"
|
|
108
|
+
* - "<->" or "<-->" → "↔"
|
|
109
|
+
*
|
|
110
|
+
* Note: Only converts when surrounded by spaces or at word boundaries
|
|
111
|
+
* to avoid false matches in code or URLs.
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* ```ts
|
|
115
|
+
* arrows("A -> B -> C")
|
|
116
|
+
* // → "A → B → C"
|
|
117
|
+
*
|
|
118
|
+
* arrows("left <-> right")
|
|
119
|
+
* // → "left ↔ right"
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
export function arrows(text, options = {}) {
|
|
123
|
+
const chr = escapeRegex(options.separator ?? DEFAULT_SEPARATOR);
|
|
124
|
+
// Bidirectional arrow first (to avoid partial matches)
|
|
125
|
+
text = text.replace(new RegExp(`<-{1,2}${chr}?>`, "g"), ARROW_LEFT_RIGHT);
|
|
126
|
+
// Right arrow
|
|
127
|
+
text = text.replace(new RegExp(`(?<=[\\s${chr}]|^)-{1,2}>(?=[\\s${chr}]|$)`, "g"), ARROW_RIGHT);
|
|
128
|
+
// Left arrow
|
|
129
|
+
text = text.replace(new RegExp(`(?<=[\\s${chr}]|^)<-{1,2}(?=[\\s${chr}]|$)`, "g"), ARROW_LEFT);
|
|
130
|
+
return text;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Adds degree symbol in temperature contexts.
|
|
134
|
+
*
|
|
135
|
+
* Handles:
|
|
136
|
+
* - "20 C" or "20C" → "20 °C" (Celsius)
|
|
137
|
+
* - "68 F" or "68F" → "68 °F" (Fahrenheit)
|
|
138
|
+
*
|
|
139
|
+
* Only matches when followed by C or F (case insensitive) to avoid
|
|
140
|
+
* false positives.
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```ts
|
|
144
|
+
* degrees("The temperature is 20 C")
|
|
145
|
+
* // → "The temperature is 20 °C"
|
|
146
|
+
*
|
|
147
|
+
* degrees("Water boils at 212F")
|
|
148
|
+
* // → "Water boils at 212 °F"
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
151
|
+
export function degrees(text) {
|
|
152
|
+
// Temperature with optional space before C or F
|
|
153
|
+
text = text.replace(/(\d+) ?([CF])\b/gi, (_, num, unit) => {
|
|
154
|
+
return `${num} ${DEGREE}${unit.toUpperCase()}`;
|
|
155
|
+
});
|
|
156
|
+
return text;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Converts straight quotes after numbers to prime marks.
|
|
160
|
+
*
|
|
161
|
+
* Prime marks are used for:
|
|
162
|
+
* - Feet and inches: 5'10" → 5′10″
|
|
163
|
+
* - Arcminutes and arcseconds: 45° 30' 15" → 45° 30′ 15″
|
|
164
|
+
*
|
|
165
|
+
* This should be called BEFORE smart quote transformations to prevent
|
|
166
|
+
* quotes in measurements from being curled.
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* ```ts
|
|
170
|
+
* primeMarks("He's 5'10\" tall")
|
|
171
|
+
* // → "He's 5′10″ tall"
|
|
172
|
+
*
|
|
173
|
+
* primeMarks("Location: 45° 30' 15\"")
|
|
174
|
+
* // → "Location: 45° 30′ 15″"
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
|
+
export function primeMarks(text, options = {}) {
|
|
178
|
+
const chr = escapeRegex(options.separator ?? DEFAULT_SEPARATOR);
|
|
179
|
+
// Single prime: digit followed by ' and then either digit, ", or end/space/punctuation
|
|
180
|
+
// This handles feet (5') and arcminutes (30')
|
|
181
|
+
const singlePrimePattern = new RegExp(`(\\d${chr}?)'(?=${chr}?(?:\\d|"|$|[\\s.,;:!?)]))`, "g");
|
|
182
|
+
text = text.replace(singlePrimePattern, `$1${PRIME}`);
|
|
183
|
+
// Double prime: Only match when it's clearly a measurement context
|
|
184
|
+
// Pattern 1: Feet-inches pattern (5'10" or 5′10")
|
|
185
|
+
const feetInchesPattern = new RegExp(`(${PRIME}${chr}?\\d${chr}?)"`, "g");
|
|
186
|
+
text = text.replace(feetInchesPattern, `$1${DOUBLE_PRIME}`);
|
|
187
|
+
// Pattern 2: Standalone inches - match digit followed by " but NOT when it's a closing quote
|
|
188
|
+
// Use negative lookbehind to ensure there's no opening quote before the number
|
|
189
|
+
// This matches: 12" wide, but not: "Term 1"
|
|
190
|
+
const standaloneInchesPattern = new RegExp(`(?<!["\u201C]${chr}?[^"${chr}]{0,20})(\\d${chr}?)"(?!${chr}?[\\w])`, "g");
|
|
191
|
+
text = text.replace(standaloneInchesPattern, `$1${DOUBLE_PRIME}`);
|
|
192
|
+
return text;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Converts common fractions to Unicode fraction characters.
|
|
196
|
+
*
|
|
197
|
+
* Handles: 1/4, 1/2, 3/4, 1/3, 2/3, 1/5, 2/5, 3/5, 4/5,
|
|
198
|
+
* 1/6, 5/6, 1/8, 3/8, 5/8, 7/8
|
|
199
|
+
*
|
|
200
|
+
* Only converts when the fraction is surrounded by word boundaries
|
|
201
|
+
* to avoid breaking URLs, file paths, or dates.
|
|
202
|
+
*
|
|
203
|
+
* @example
|
|
204
|
+
* ```ts
|
|
205
|
+
* fractions("Add 1/2 cup of flour")
|
|
206
|
+
* // → "Add ½ cup of flour"
|
|
207
|
+
*
|
|
208
|
+
* fractions("About 3/4 complete")
|
|
209
|
+
* // → "About ¾ complete"
|
|
210
|
+
* ```
|
|
211
|
+
*/
|
|
212
|
+
export function fractions(text) {
|
|
213
|
+
const fractionMap = {
|
|
214
|
+
"1/4": UNICODE_SYMBOLS.FRACTION_1_4,
|
|
215
|
+
"1/2": UNICODE_SYMBOLS.FRACTION_1_2,
|
|
216
|
+
"3/4": UNICODE_SYMBOLS.FRACTION_3_4,
|
|
217
|
+
"1/3": UNICODE_SYMBOLS.FRACTION_1_3,
|
|
218
|
+
"2/3": UNICODE_SYMBOLS.FRACTION_2_3,
|
|
219
|
+
"1/5": UNICODE_SYMBOLS.FRACTION_1_5,
|
|
220
|
+
"2/5": UNICODE_SYMBOLS.FRACTION_2_5,
|
|
221
|
+
"3/5": UNICODE_SYMBOLS.FRACTION_3_5,
|
|
222
|
+
"4/5": UNICODE_SYMBOLS.FRACTION_4_5,
|
|
223
|
+
"1/6": UNICODE_SYMBOLS.FRACTION_1_6,
|
|
224
|
+
"5/6": UNICODE_SYMBOLS.FRACTION_5_6,
|
|
225
|
+
"1/8": UNICODE_SYMBOLS.FRACTION_1_8,
|
|
226
|
+
"3/8": UNICODE_SYMBOLS.FRACTION_3_8,
|
|
227
|
+
"5/8": UNICODE_SYMBOLS.FRACTION_5_8,
|
|
228
|
+
"7/8": UNICODE_SYMBOLS.FRACTION_7_8,
|
|
229
|
+
};
|
|
230
|
+
for (const [ascii, unicode] of Object.entries(fractionMap)) {
|
|
231
|
+
const pattern = new RegExp(`(?<!\\d)${ascii.replace("/", "\\/")}(?!\\d)`, "g");
|
|
232
|
+
text = text.replace(pattern, unicode);
|
|
233
|
+
}
|
|
234
|
+
return text;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Applies all symbol transformations.
|
|
238
|
+
*
|
|
239
|
+
* Runs in order:
|
|
240
|
+
* 1. ellipsis
|
|
241
|
+
* 2. multiplication
|
|
242
|
+
* 3. mathSymbols
|
|
243
|
+
* 4. legalSymbols
|
|
244
|
+
* 5. arrows
|
|
245
|
+
*
|
|
246
|
+
* Note: `degrees` and `fractions` are not included by default as they
|
|
247
|
+
* may be too aggressive for some use cases. Call them explicitly if needed.
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* ```ts
|
|
251
|
+
* symbolTransform("Wait... 5x5 != 20 (c) 2024")
|
|
252
|
+
* // → "Wait… 5×5 ≠ 20 © 2024"
|
|
253
|
+
* ```
|
|
254
|
+
*/
|
|
255
|
+
export function symbolTransform(text, options = {}) {
|
|
256
|
+
text = ellipsis(text, options);
|
|
257
|
+
text = multiplication(text, options);
|
|
258
|
+
text = mathSymbols(text);
|
|
259
|
+
text = legalSymbols(text);
|
|
260
|
+
if (options.includeArrows !== false) {
|
|
261
|
+
text = arrows(text, options);
|
|
262
|
+
}
|
|
263
|
+
return text;
|
|
264
|
+
}
|
|
265
|
+
//# sourceMappingURL=symbols.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"symbols.js","sourceRoot":"","sources":["../src/symbols.ts"],"names":[],"mappings":"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"}
|