punctilio 0.2.1 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,19 +6,34 @@ Smart typography transformations for JavaScript/TypeScript. Converts ASCII punct
6
6
 
7
7
  ## Features
8
8
 
9
- - **Smart quotes**: `"straight"` `"curly"` and `'apostrophes'` → `'apostrophes'`
10
- - **Em dashes**: `word - word` or `word--word` → `word—word`
11
- - **En dashes**: `1-5` `1–5` (number ranges), `January-March` → `January–March` (date ranges)
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`
21
- - **Handles edge cases**: contractions, possessives, nested quotes, year abbreviations ('99), "rock 'n' roll"
9
+ | **Feature** | **Before** | **After** |
10
+ |---------|--------|-------|
11
+ | Smart quotes | "straight" | “curly” |
12
+ | | 'apostrophes' | ‘apostrophes’ |
13
+ | Em dashes | wait - why did you | wait—why did you |
14
+ | En dashes | 1-5 | 1–5 |
15
+ | | January-March | January–March |
16
+ | Minus signs | -5 | −5 (proper Unicode minus) |
17
+ | Ellipsis | ... | |
18
+ | Multiplication | 5x5 | 5×5 |
19
+ | | 3*4 | 3×4 |
20
+ | Math symbols | != | |
21
+ | | +- | ± |
22
+ | | <= | ≤ |
23
+ | | >= | ≥ |
24
+ | | ~= | ≈ |
25
+ | Legal symbols | (c) | © |
26
+ | | (r) | ® |
27
+ | | (tm) | ™ |
28
+ | Arrows | -> | → |
29
+ | | <- | ← |
30
+ | | <-> | ↔ |
31
+ | Prime marks | 5'10" | 5′10″ |
32
+ | Fractions (optional) | 1/2 | ½ |
33
+ | | 3/4 | ¾ |
34
+ | Degrees (optional) | 20 C | 20 °C |
35
+
36
+ **Handles edge cases**: contractions, possessives, nested quotes, year abbreviations ('99), "rock 'n' roll"
22
37
 
23
38
  ## Why another typography library?
24
39
 
@@ -76,6 +91,14 @@ transform('Add 1/2 cup at 20 C', {
76
91
  // Disable symbol transforms if you only want quotes/dashes
77
92
  transform('5x5 = 25', { symbols: false })
78
93
  // → 5x5 = 25 (unchanged)
94
+
95
+ // Punctuation style: american (default), british, or none
96
+ transform('"Hello".', { punctuationStyle: 'american' }) // → "Hello."
97
+ transform('"Hello."', { punctuationStyle: 'british' }) // → "Hello".
98
+
99
+ // Dash style: american (default), british, or none
100
+ transform('word - word', { dashStyle: 'american' }) // → word—word
101
+ transform('word - word', { dashStyle: 'british' }) // → word – word
79
102
  ```
80
103
 
81
104
  ### With HTML Element Boundaries
@@ -105,29 +128,24 @@ Applies all typography transformations. Options:
105
128
  - `symbols`: Include symbol transforms (default: `true`)
106
129
  - `fractions`: Convert common fractions like 1/2 → ½ (default: `false`)
107
130
  - `degrees`: Convert temperature notation like 20 C → 20 °C (default: `false`)
131
+ - `punctuationStyle`: `"american"` (default) puts periods/commas inside quotes; `"british"` puts them outside; `"none"` leaves unchanged
132
+ - `dashStyle`: `"american"` (default) uses unspaced em dash (—); `"british"` uses spaced en dash ( – ); `"none"` skips dash conversion
108
133
 
109
134
  ### Quote Functions
110
135
 
111
136
  #### `niceQuotes(text, options?)`
112
137
 
113
- Converts straight quotes to curly quotes. Handles:
114
- - Opening/closing double quotes: `"` → `"` or `"`
115
- - Opening/closing single quotes: `'` `'` or `'`
116
- - Contractions: `don't` → `don't`
117
- - Possessives: `dog's` → `dog's`
118
- - Year abbreviations: `'99` → `'99`
119
- - Special cases: `'n'` in "rock 'n' roll"
138
+ Converts straight quotes to curly quotes. Options: `separator`, `punctuationStyle`.
139
+
140
+ Handles: opening/closing quotes, contractions (`don't`), possessives (`dog's`), year abbreviations (`'99`), special cases (`'n'`).
120
141
 
121
142
  ### Dash Functions
122
143
 
123
144
  #### `hyphenReplace(text, options?)`
124
145
 
125
- Converts hyphens to proper dashes. Handles:
126
- - Em dashes: `word - word` → `word—word`
127
- - En dashes for number ranges: `1-5` → `1–5`
128
- - En dashes for date ranges: `Jan-Mar` → `Jan–Mar`
129
- - Minus signs: `-5` → `−5`
130
- - Preserves: horizontal rules (`---`), compound words (`well-known`)
146
+ Converts hyphens to proper dashes. Options: `separator`, `dashStyle`.
147
+
148
+ Handles: em dashes (`word - word` → `word—word`), en dashes for ranges (`1-5` → `1–5`, `Jan-Mar` → `Jan–Mar`), minus signs (`-5` → `−5`). Preserves horizontal rules and compound words.
131
149
 
132
150
  #### `enDashNumberRange(text, options?)`
133
151
 
@@ -55,4 +55,5 @@ export declare const UNICODE_SYMBOLS: {
55
55
  * Uses Unicode Private Use Area character U+E000.
56
56
  */
57
57
  export declare const DEFAULT_SEPARATOR = "\uE000";
58
+ export declare const ESCAPED_DEFAULT_SEPARATOR: string;
58
59
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +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"}
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;AACzC,eAAO,MAAM,yBAAyB,QAA2D,CAAA"}
package/dist/constants.js CHANGED
@@ -55,4 +55,5 @@ export const UNICODE_SYMBOLS = {
55
55
  * Uses Unicode Private Use Area character U+E000.
56
56
  */
57
57
  export const DEFAULT_SEPARATOR = "\uE000";
58
+ export const ESCAPED_DEFAULT_SEPARATOR = DEFAULT_SEPARATOR.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
58
59
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,QAAQ,EAAE,QAAQ;IAClB,cAAc,EAAE,QAAQ;IACxB,SAAS,EAAE,QAAQ;IACnB,UAAU,EAAE,QAAQ;IACpB,SAAS,EAAE,QAAQ;IACnB,UAAU,EAAE,QAAQ;IACpB,SAAS,EAAE,QAAQ;IACnB,MAAM,EAAE,QAAQ;IAChB,WAAW,EAAE,QAAQ;IACrB,UAAU,EAAE,QAAQ;IACpB,gBAAgB,EAAE,QAAQ;IAC1B,WAAW,EAAE,QAAQ;IACrB,UAAU,EAAE,QAAQ;IACpB,aAAa,EAAE,QAAQ;IACvB,KAAK,EAAE,QAAQ;IACf,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,OAAO,EAAE,QAAQ;IACjB,OAAO,EAAE,QAAQ;IACjB,KAAK,EAAE,QAAQ;IACf,iBAAiB,EAAE,QAAQ;IAC3B,kBAAkB,EAAE,QAAQ;IAC5B,iBAAiB,EAAE,QAAQ;IAC3B,kBAAkB,EAAE,QAAQ;CACpB,CAAA;AAEV;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,QAAQ,CAAA"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,QAAQ,EAAE,QAAQ;IAClB,cAAc,EAAE,QAAQ;IACxB,SAAS,EAAE,QAAQ;IACnB,UAAU,EAAE,QAAQ;IACpB,SAAS,EAAE,QAAQ;IACnB,UAAU,EAAE,QAAQ;IACpB,SAAS,EAAE,QAAQ;IACnB,MAAM,EAAE,QAAQ;IAChB,WAAW,EAAE,QAAQ;IACrB,UAAU,EAAE,QAAQ;IACpB,gBAAgB,EAAE,QAAQ;IAC1B,WAAW,EAAE,QAAQ;IACrB,UAAU,EAAE,QAAQ;IACpB,aAAa,EAAE,QAAQ;IACvB,KAAK,EAAE,QAAQ;IACf,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,OAAO,EAAE,QAAQ;IACjB,OAAO,EAAE,QAAQ;IACjB,KAAK,EAAE,QAAQ;IACf,iBAAiB,EAAE,QAAQ;IAC3B,kBAAkB,EAAE,QAAQ;IAC5B,iBAAiB,EAAE,QAAQ;IAC3B,kBAAkB,EAAE,QAAQ;CACpB,CAAA;AAEV;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,QAAQ,CAAA;AACzC,MAAM,CAAC,MAAM,yBAAyB,GAAG,iBAAiB,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAA"}
package/dist/dashes.d.ts CHANGED
@@ -4,6 +4,7 @@
4
4
  * Converts hyphens and dashes to typographically correct em-dashes,
5
5
  * en-dashes, and minus signs based on context.
6
6
  */
7
+ export type DashStyle = "american" | "british" | "none";
7
8
  export interface DashOptions {
8
9
  /**
9
10
  * A boundary marker character used when transforming text that spans
@@ -14,6 +15,16 @@ export interface DashOptions {
14
15
  * Default: "\uE000" (Unicode Private Use Area)
15
16
  */
16
17
  separator?: string;
18
+ /**
19
+ * How to style parenthetical dashes.
20
+ *
21
+ * - `"american"` (default): Unspaced em dash (word—word)
22
+ * - `"british"`: Spaced en dash (word – word)
23
+ * - `"none"`: Don't convert parenthetical dashes
24
+ *
25
+ * Default: "american"
26
+ */
27
+ dashStyle?: DashStyle;
17
28
  }
18
29
  /**
19
30
  * List of month names (full and abbreviated) for date range detection
@@ -21,98 +32,18 @@ export interface DashOptions {
21
32
  export declare const months: string;
22
33
  /**
23
34
  * Replaces hyphens with en-dashes in number ranges.
24
- *
25
- * Handles:
26
- * - Simple ranges: "1-5" → "1–5"
27
- * - Page numbers: "p.206-207" → "p.206–207"
28
- * - Dollar amounts: "$100-$200" → "$100–$200"
29
- * - Comma-formatted numbers: "1,000-2,000" → "1,000–2,000"
30
- *
31
- * Does NOT replace:
32
- * - Spaced ranges: "1 - 5" (ambiguous, could be subtraction)
33
- * - Version numbers with decimals: "1.5-1.8"
34
- *
35
- * @param text - The text to transform
36
- * @param options - Configuration options
37
- * @returns The text with en-dashes in number ranges
38
- *
39
- * @example
40
- * ```ts
41
- * enDashNumberRange("pages 10-15")
42
- * // → "pages 10–15"
43
- * ```
44
35
  */
45
36
  export declare function enDashNumberRange(text: string, options?: DashOptions): string;
46
37
  /**
47
38
  * Replaces hyphens with en-dashes in month/date ranges.
48
- *
49
- * Handles full and abbreviated month names:
50
- * - "January-March" → "January–March"
51
- * - "Jan-Mar" → "Jan–Mar"
52
- *
53
- * @param text - The text to transform
54
- * @param options - Configuration options
55
- * @returns The text with en-dashes in date ranges
56
- *
57
- * @example
58
- * ```ts
59
- * enDashDateRange("January-March 2024")
60
- * // → "January–March 2024"
61
- * ```
62
39
  */
63
40
  export declare function enDashDateRange(text: string, options?: DashOptions): string;
64
41
  /**
65
42
  * Replaces hyphens with proper minus signs (−) in numerical contexts.
66
- *
67
- * Handles negative numbers at:
68
- * - Start of string/line
69
- * - After whitespace
70
- * - After opening parenthesis
71
- * - After opening quote
72
- *
73
- * @param text - The text to transform
74
- * @param options - Configuration options
75
- * @returns The text with minus signs
76
- *
77
- * @example
78
- * ```ts
79
- * minusReplace("The temperature was -5 degrees")
80
- * // → "The temperature was −5 degrees"
81
- * ```
82
43
  */
83
44
  export declare function minusReplace(text: string, options?: DashOptions): string;
84
45
  /**
85
46
  * Comprehensive dash replacement for typographic correctness.
86
- *
87
- * Applies multiple transformations:
88
- * 1. Converts hyphens to minus signs in numerical contexts
89
- * 2. Converts surrounded dashes (- or --) to em-dashes (—)
90
- * 3. Removes spaces around em-dashes (per modern style)
91
- * 4. Preserves space after em-dash at start of line
92
- * 5. Adds space after em-dash following quotation marks
93
- * 6. Converts number ranges to en-dashes (1-5 → 1–5)
94
- * 7. Converts date ranges to en-dashes (Jan-Mar → Jan–Mar)
95
- *
96
- * Does NOT modify:
97
- * - Horizontal rules (---)
98
- * - Compound modifiers (well-known, browser-specific)
99
- * - Hyphens in quoted blockquotes ("> - item")
100
- *
101
- * @param text - The text to transform
102
- * @param options - Configuration options
103
- * @returns The text with proper dashes
104
- *
105
- * @example
106
- * ```ts
107
- * hyphenReplace("This is a - test")
108
- * // → "This is a—test"
109
- *
110
- * hyphenReplace("Since--as you know")
111
- * // → "Since—as you know"
112
- *
113
- * hyphenReplace("Pages 1-5")
114
- * // → "Pages 1–5"
115
- * ```
116
47
  */
117
48
  export declare function hyphenReplace(text: string, options?: DashOptions): string;
118
49
  //# sourceMappingURL=dashes.d.ts.map
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"dashes.d.ts","sourceRoot":"","sources":["../src/dashes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,MAAM,CAAA;AAEvD,MAAM,WAAW,WAAW;IAC1B;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,SAAS,CAAA;CACtB;AAID;;GAEG;AACH,eAAO,MAAM,MAAM,QAKR,CAAA;AAEX;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CASjF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAM/E;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAI5E;AAuDD;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAe7E"}
package/dist/dashes.js CHANGED
@@ -10,53 +10,13 @@ const { EN_DASH, EM_DASH, MINUS } = UNICODE_SYMBOLS;
10
10
  * List of month names (full and abbreviated) for date range detection
11
11
  */
12
12
  export const months = [
13
- "January",
14
- "February",
15
- "March",
16
- "April",
17
- "May",
18
- "June",
19
- "July",
20
- "August",
21
- "September",
22
- "October",
23
- "November",
24
- "December",
25
- "Jan",
26
- "Feb",
27
- "Mar",
28
- "Apr",
29
- "May",
30
- "Jun",
31
- "Jul",
32
- "Aug",
33
- "Sep",
34
- "Oct",
35
- "Nov",
36
- "Dec",
13
+ "January", "February", "March", "April", "May", "June",
14
+ "July", "August", "September", "October", "November", "December",
15
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
16
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
37
17
  ].join("|");
38
18
  /**
39
19
  * Replaces hyphens with en-dashes in number ranges.
40
- *
41
- * Handles:
42
- * - Simple ranges: "1-5" → "1–5"
43
- * - Page numbers: "p.206-207" → "p.206–207"
44
- * - Dollar amounts: "$100-$200" → "$100–$200"
45
- * - Comma-formatted numbers: "1,000-2,000" → "1,000–2,000"
46
- *
47
- * Does NOT replace:
48
- * - Spaced ranges: "1 - 5" (ambiguous, could be subtraction)
49
- * - Version numbers with decimals: "1.5-1.8"
50
- *
51
- * @param text - The text to transform
52
- * @param options - Configuration options
53
- * @returns The text with en-dashes in number ranges
54
- *
55
- * @example
56
- * ```ts
57
- * enDashNumberRange("pages 10-15")
58
- * // → "pages 10–15"
59
- * ```
60
20
  */
61
21
  export function enDashNumberRange(text, options = {}) {
62
22
  const chr = options.separator ?? DEFAULT_SEPARATOR;
@@ -64,20 +24,6 @@ export function enDashNumberRange(text, options = {}) {
64
24
  }
65
25
  /**
66
26
  * Replaces hyphens with en-dashes in month/date ranges.
67
- *
68
- * Handles full and abbreviated month names:
69
- * - "January-March" → "January–March"
70
- * - "Jan-Mar" → "Jan–Mar"
71
- *
72
- * @param text - The text to transform
73
- * @param options - Configuration options
74
- * @returns The text with en-dashes in date ranges
75
- *
76
- * @example
77
- * ```ts
78
- * enDashDateRange("January-March 2024")
79
- * // → "January–March 2024"
80
- * ```
81
27
  */
82
28
  export function enDashDateRange(text, options = {}) {
83
29
  const chr = options.separator ?? DEFAULT_SEPARATOR;
@@ -85,79 +31,58 @@ export function enDashDateRange(text, options = {}) {
85
31
  }
86
32
  /**
87
33
  * Replaces hyphens with proper minus signs (−) in numerical contexts.
88
- *
89
- * Handles negative numbers at:
90
- * - Start of string/line
91
- * - After whitespace
92
- * - After opening parenthesis
93
- * - After opening quote
94
- *
95
- * @param text - The text to transform
96
- * @param options - Configuration options
97
- * @returns The text with minus signs
98
- *
99
- * @example
100
- * ```ts
101
- * minusReplace("The temperature was -5 degrees")
102
- * // → "The temperature was −5 degrees"
103
- * ```
104
34
  */
105
35
  export function minusReplace(text, options = {}) {
106
36
  const chr = options.separator ?? DEFAULT_SEPARATOR;
107
37
  const minusRegex = new RegExp(`(^|[\\s\\(${chr}""])-(\\s?\\d*\\.?\\d+)`, "gm");
108
38
  return text.replaceAll(minusRegex, `$1${MINUS}$2`);
109
39
  }
40
+ /** Convert surrounded dashes and multiple dashes to em/en dashes */
41
+ function convertParentheticalDashes(text, sep, style) {
42
+ if (style === "none")
43
+ return text;
44
+ const dash = style === "british" ? EN_DASH : EM_DASH;
45
+ const spaced = style === "british";
46
+ // Handle dashes with potential spaces
47
+ const preDash = new RegExp(`((?<markerBeforeTwo>${sep}?)[ ]+|(?<markerBeforeThree>${sep}))`);
48
+ const surroundedDash = new RegExp(`(?<=[^\\s>]|^)${preDash.source}[~${EN_DASH}${EM_DASH}-]+[ ]*(?<markerAfter>${sep}?)([ ]+|$)`, "g");
49
+ const replacement = spaced
50
+ ? `$<markerBeforeTwo>$<markerBeforeThree> ${dash} $<markerAfter>`
51
+ : `$<markerBeforeTwo>$<markerBeforeThree>${dash}$<markerAfter>`;
52
+ text = text.replace(surroundedDash, replacement);
53
+ // Handle multiple dashes within words (e.g., since--as)
54
+ const multipleDashInWords = new RegExp(`(?<=[A-Za-z\\d])(?<markerBefore>${sep}?)[~${EN_DASH}${EM_DASH}-]{2,}(?<markerAfter>${sep}?)(?=[A-Za-z\\d ])`, "g");
55
+ const multiReplacement = spaced
56
+ ? `$<markerBefore> ${dash} $<markerAfter>`
57
+ : `$<markerBefore>${dash}$<markerAfter>`;
58
+ text = text.replace(multipleDashInWords, multiReplacement);
59
+ // Handle dashes at start of line
60
+ text = text.replace(new RegExp(`^(${sep})?[-]+ `, "gm"), `$1${dash} `);
61
+ return text;
62
+ }
63
+ /** Normalize spacing around em dashes for American style */
64
+ function normalizeEmDashSpacing(text, sep) {
65
+ const spacesAroundEM = new RegExp(`(?<markerBefore>${sep}?)[ ]*${EM_DASH}[ ]*(?<markerAfter>${sep}?)[ ]*`, "g");
66
+ text = text.replace(spacesAroundEM, `$<markerBefore>${EM_DASH}$<markerAfter>`);
67
+ // Add space after em dash following quotation marks
68
+ const postQuote = new RegExp(`(?<quote>[.!?]${sep}?['"'"]${sep}?|…)${spacesAroundEM.source}`, "g");
69
+ text = text.replace(postQuote, `$<quote> $<markerBefore>${EM_DASH}$<markerAfter> `);
70
+ // Preserve space after em dash at start of line
71
+ const startOfLine = new RegExp(`^${spacesAroundEM.source}(?<after>[A-Z0-9])`, "gm");
72
+ text = text.replace(startOfLine, `$<markerBefore>${EM_DASH}$<markerAfter> $<after>`);
73
+ return text;
74
+ }
110
75
  /**
111
76
  * Comprehensive dash replacement for typographic correctness.
112
- *
113
- * Applies multiple transformations:
114
- * 1. Converts hyphens to minus signs in numerical contexts
115
- * 2. Converts surrounded dashes (- or --) to em-dashes (—)
116
- * 3. Removes spaces around em-dashes (per modern style)
117
- * 4. Preserves space after em-dash at start of line
118
- * 5. Adds space after em-dash following quotation marks
119
- * 6. Converts number ranges to en-dashes (1-5 → 1–5)
120
- * 7. Converts date ranges to en-dashes (Jan-Mar → Jan–Mar)
121
- *
122
- * Does NOT modify:
123
- * - Horizontal rules (---)
124
- * - Compound modifiers (well-known, browser-specific)
125
- * - Hyphens in quoted blockquotes ("> - item")
126
- *
127
- * @param text - The text to transform
128
- * @param options - Configuration options
129
- * @returns The text with proper dashes
130
- *
131
- * @example
132
- * ```ts
133
- * hyphenReplace("This is a - test")
134
- * // → "This is a—test"
135
- *
136
- * hyphenReplace("Since--as you know")
137
- * // → "Since—as you know"
138
- *
139
- * hyphenReplace("Pages 1-5")
140
- * // → "Pages 1–5"
141
- * ```
142
77
  */
143
78
  export function hyphenReplace(text, options = {}) {
144
- const chr = options.separator ?? DEFAULT_SEPARATOR;
79
+ const sep = options.separator ?? DEFAULT_SEPARATOR;
80
+ const dashStyle = options.dashStyle ?? "american";
145
81
  text = minusReplace(text, options);
146
- // Handle dashes with potential spaces and optional marker character
147
- // Being right after chr is a sufficient condition for being an em
148
- // dash, as it indicates the start of a new line
149
- const preDash = new RegExp(`((?<markerBeforeTwo>${chr}?)[ ]+|(?<markerBeforeThree>${chr}))`);
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>`);
157
- const postQuote = new RegExp(`(?<quote>[.!?]${chr}?['"'"]${chr}?|…)${spacesAroundEM.source}`, "g");
158
- text = text.replace(postQuote, `$<quote> $<markerBefore>${EM_DASH}$<markerAfter> `);
159
- const startOfLine = new RegExp(`^${spacesAroundEM.source}(?<after>[A-Z0-9])`, "gm");
160
- text = text.replace(startOfLine, `$<markerBefore>${EM_DASH}$<markerAfter> $<after>`);
82
+ text = convertParentheticalDashes(text, sep, dashStyle);
83
+ if (dashStyle === "american") {
84
+ text = normalizeEmDashSpacing(text, sep);
85
+ }
161
86
  text = enDashNumberRange(text, options);
162
87
  text = enDashDateRange(text, options);
163
88
  return text;
@@ -1 +1 @@
1
- {"version":3,"file":"dashes.js","sourceRoot":"","sources":["../src/dashes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dashes.js","sourceRoot":"","sources":["../src/dashes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AA2BnE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,eAAe,CAAA;AAEnD;;GAEG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM;IACtD,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU;IAChE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK;IACxC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK;CACzC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAEX;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,UAAuB,EAAE;IACvE,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,IAAI,iBAAiB,CAAA;IAClD,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,MAAM,CACR,8CAA8C,GAAG,OAAO,GAAG,gCAAgC,EAC3F,GAAG,CACJ,EACD,KAAK,OAAO,IAAI,CACjB,CAAA;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,UAAuB,EAAE;IACrE,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,IAAI,iBAAiB,CAAA;IAClD,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,MAAM,CAAC,OAAO,MAAM,GAAG,GAAG,OAAO,GAAG,OAAO,MAAM,OAAO,EAAE,GAAG,CAAC,EAClE,KAAK,OAAO,IAAI,CACjB,CAAA;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,UAAuB,EAAE;IAClE,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,IAAI,iBAAiB,CAAA;IAClD,MAAM,UAAU,GAAG,IAAI,MAAM,CAAC,aAAa,GAAG,yBAAyB,EAAE,IAAI,CAAC,CAAA;IAC9E,OAAO,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,KAAK,KAAK,IAAI,CAAC,CAAA;AACpD,CAAC;AAED,oEAAoE;AACpE,SAAS,0BAA0B,CAAC,IAAY,EAAE,GAAW,EAAE,KAAgB;IAC7E,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO,IAAI,CAAA;IAEjC,MAAM,IAAI,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAA;IACpD,MAAM,MAAM,GAAG,KAAK,KAAK,SAAS,CAAA;IAElC,sCAAsC;IACtC,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,uBAAuB,GAAG,+BAA+B,GAAG,IAAI,CAAC,CAAA;IAC5F,MAAM,cAAc,GAAG,IAAI,MAAM,CAC/B,iBAAiB,OAAO,CAAC,MAAM,KAAK,OAAO,GAAG,OAAO,yBAAyB,GAAG,YAAY,EAC7F,GAAG,CACJ,CAAA;IACD,MAAM,WAAW,GAAG,MAAM;QACxB,CAAC,CAAC,0CAA0C,IAAI,iBAAiB;QACjE,CAAC,CAAC,yCAAyC,IAAI,gBAAgB,CAAA;IACjE,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,WAAW,CAAC,CAAA;IAEhD,wDAAwD;IACxD,MAAM,mBAAmB,GAAG,IAAI,MAAM,CACpC,mCAAmC,GAAG,OAAO,OAAO,GAAG,OAAO,wBAAwB,GAAG,oBAAoB,EAC7G,GAAG,CACJ,CAAA;IACD,MAAM,gBAAgB,GAAG,MAAM;QAC7B,CAAC,CAAC,mBAAmB,IAAI,iBAAiB;QAC1C,CAAC,CAAC,kBAAkB,IAAI,gBAAgB,CAAA;IAC1C,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,gBAAgB,CAAC,CAAA;IAE1D,iCAAiC;IACjC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,KAAK,GAAG,SAAS,EAAE,IAAI,CAAC,EAAE,KAAK,IAAI,GAAG,CAAC,CAAA;IAEtE,OAAO,IAAI,CAAA;AACb,CAAC;AAED,4DAA4D;AAC5D,SAAS,sBAAsB,CAAC,IAAY,EAAE,GAAW;IACvD,MAAM,cAAc,GAAG,IAAI,MAAM,CAC/B,mBAAmB,GAAG,SAAS,OAAO,sBAAsB,GAAG,QAAQ,EACvE,GAAG,CACJ,CAAA;IACD,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,kBAAkB,OAAO,gBAAgB,CAAC,CAAA;IAE9E,oDAAoD;IACpD,MAAM,SAAS,GAAG,IAAI,MAAM,CAAC,iBAAiB,GAAG,UAAU,GAAG,OAAO,cAAc,CAAC,MAAM,EAAE,EAAE,GAAG,CAAC,CAAA;IAClG,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,2BAA2B,OAAO,iBAAiB,CAAC,CAAA;IAEnF,gDAAgD;IAChD,MAAM,WAAW,GAAG,IAAI,MAAM,CAAC,IAAI,cAAc,CAAC,MAAM,oBAAoB,EAAE,IAAI,CAAC,CAAA;IACnF,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,kBAAkB,OAAO,yBAAyB,CAAC,CAAA;IAEpF,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,UAAuB,EAAE;IACnE,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,IAAI,iBAAiB,CAAA;IAClD,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,UAAU,CAAA;IAEjD,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IAClC,IAAI,GAAG,0BAA0B,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,CAAC,CAAA;IAEvD,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;QAC7B,IAAI,GAAG,sBAAsB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IAC1C,CAAC;IAED,IAAI,GAAG,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IACvC,IAAI,GAAG,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IAErC,OAAO,IAAI,CAAA;AACb,CAAC"}
package/dist/index.d.ts CHANGED
@@ -7,8 +7,10 @@
7
7
  *
8
8
  * @packageDocumentation
9
9
  */
10
- export { niceQuotes, type QuoteOptions } from "./quotes.js";
11
- export { hyphenReplace, enDashNumberRange, enDashDateRange, minusReplace, months, type DashOptions, } from "./dashes.js";
10
+ export { niceQuotes, type QuoteOptions, type PunctuationStyle } from "./quotes.js";
11
+ import type { PunctuationStyle } from "./quotes.js";
12
+ export { hyphenReplace, enDashNumberRange, enDashDateRange, minusReplace, months, type DashOptions, type DashStyle, } from "./dashes.js";
13
+ import type { DashStyle } from "./dashes.js";
12
14
  export { ellipsis, multiplication, mathSymbols, legalSymbols, arrows, degrees, fractions, primeMarks, symbolTransform, type SymbolOptions, } from "./symbols.js";
13
15
  export interface TransformOptions {
14
16
  /**
@@ -35,6 +37,28 @@ export interface TransformOptions {
35
37
  * Default: false (can be aggressive)
36
38
  */
37
39
  degrees?: boolean;
40
+ /**
41
+ * How to handle punctuation placement around quotation marks.
42
+ *
43
+ * - `"american"` (default): Periods and commas go inside quotes
44
+ * Example: "Hello." and "Hello,"
45
+ * - `"british"`: Periods and commas go outside quotes
46
+ * Example: "Hello". and "Hello",
47
+ * - `"none"`: Don't modify punctuation placement
48
+ *
49
+ * Default: "american"
50
+ */
51
+ punctuationStyle?: PunctuationStyle;
52
+ /**
53
+ * How to style parenthetical dashes.
54
+ *
55
+ * - `"american"` (default): Unspaced em dash (word—word)
56
+ * - `"british"`: Spaced en dash (word – word)
57
+ * - `"none"`: Don't convert parenthetical dashes
58
+ *
59
+ * Default: "american"
60
+ */
61
+ dashStyle?: DashStyle;
38
62
  }
39
63
  /**
40
64
  * Applies all typography transformations: smart quotes, proper dashes,
@@ -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;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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAE,KAAK,YAAY,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAClF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AACnD,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,MAAM,EACN,KAAK,WAAW,EAChB,KAAK,SAAS,GACf,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EACL,QAAQ,EACR,cAAc,EACd,WAAW,EACX,YAAY,EACZ,MAAM,EACN,OAAO,EACP,SAAS,EACT,UAAU,EACV,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;IAEjB;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IAEnC;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,SAAS,CAAA;CACtB;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.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;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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAA4C,MAAM,aAAa,CAAA;AAElF,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,MAAM,GAGP,MAAM,aAAa,CAAA;AAEpB,OAAO,EACL,QAAQ,EACR,cAAc,EACd,WAAW,EACX,YAAY,EACZ,MAAM,EACN,OAAO,EACP,SAAS,EACT,UAAU,EACV,eAAe,GAEhB,MAAM,cAAc,CAAA;AAwDrB,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 CHANGED
@@ -4,6 +4,7 @@
4
4
  * Converts straight quotes to typographically correct curly quotes,
5
5
  * handling contractions, possessives, and nested quotes.
6
6
  */
7
+ export type PunctuationStyle = "american" | "british" | "none";
7
8
  export interface QuoteOptions {
8
9
  /**
9
10
  * A boundary marker character used when transforming text that spans
@@ -15,6 +16,18 @@ export interface QuoteOptions {
15
16
  * Default: "\uE000" (Unicode Private Use Area)
16
17
  */
17
18
  separator?: string;
19
+ /**
20
+ * How to handle punctuation placement around quotation marks.
21
+ *
22
+ * - `"american"` (default): Periods and commas go inside quotes
23
+ * Example: "Hello." and "Hello,"
24
+ * - `"british"`: Periods and commas go outside quotes
25
+ * Example: "Hello". and "Hello",
26
+ * - `"none"`: Don't modify punctuation placement
27
+ *
28
+ * Default: "american"
29
+ */
30
+ punctuationStyle?: PunctuationStyle;
18
31
  }
19
32
  /**
20
33
  * Converts standard quotes to typographic smart quotes.
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"quotes.d.ts","sourceRoot":"","sources":["../src/quotes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAaH,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,SAAS,GAAG,MAAM,CAAA;AAE9D,MAAM,WAAW,YAAY;IAC3B;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;CACpC;AA+ED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,MAAM,CAS3E"}
package/dist/quotes.js CHANGED
@@ -6,38 +6,66 @@
6
6
  */
7
7
  import { UNICODE_SYMBOLS, DEFAULT_SEPARATOR } from "./constants.js";
8
8
  const { EM_DASH, LEFT_DOUBLE_QUOTE, RIGHT_DOUBLE_QUOTE, LEFT_SINGLE_QUOTE, RIGHT_SINGLE_QUOTE, ELLIPSIS, } = UNICODE_SYMBOLS;
9
- /**
10
- * Converts standard quotes to typographic smart quotes.
11
- *
12
- * @param text - The text to transform
13
- * @param options - Configuration options
14
- * @returns The text with smart quotes
15
- */
16
- export function niceQuotes(text, options = {}) {
17
- const chr = options.separator ?? DEFAULT_SEPARATOR;
9
+ /** Convert straight single quotes to curly quotes and apostrophes */
10
+ function convertSingleQuotes(text, sep) {
18
11
  const afterEndingSinglePatterns = `\\s\\.!?;,\\)${EM_DASH}\\-\\]"`;
19
- const afterEndingSingle = `(?=${chr}?(?:s${chr}?)?(?:[${afterEndingSinglePatterns}]|$))`;
12
+ const afterEndingSingle = `(?=${sep}?(?:s${sep}?)?(?:[${afterEndingSinglePatterns}]|$))`;
20
13
  const endingSingle = `(?<=[^\\s${LEFT_DOUBLE_QUOTE}'])[']${afterEndingSingle}`;
21
14
  text = text.replace(new RegExp(endingSingle, "gm"), RIGHT_SINGLE_QUOTE);
22
- const contraction = `(?<=[A-Za-z])['${RIGHT_SINGLE_QUOTE}](?=${chr}?[a-zA-Z])`;
15
+ const contraction = `(?<=[A-Za-z])['${RIGHT_SINGLE_QUOTE}](?=${sep}?[a-zA-Z])`;
23
16
  text = text.replace(new RegExp(contraction, "gm"), RIGHT_SINGLE_QUOTE);
24
17
  const apostropheWhitelist = `(?=n${RIGHT_SINGLE_QUOTE} )`;
25
18
  const endQuoteNotContraction = `(?!${contraction})${RIGHT_SINGLE_QUOTE}${afterEndingSingle}`;
26
19
  const apostropheRegex = new RegExp(`(?<=^|[^\\w])'(${apostropheWhitelist}|(?![^${LEFT_SINGLE_QUOTE}'\\n]*${endQuoteNotContraction}))`, "gm");
27
20
  text = text.replace(apostropheRegex, RIGHT_SINGLE_QUOTE);
28
- const beginningSingle = `((?:^|[\\s${LEFT_DOUBLE_QUOTE}${RIGHT_DOUBLE_QUOTE}\\-\\(])${chr}?)['](?=${chr}?\\S)`;
21
+ const beginningSingle = `((?:^|[\\s${LEFT_DOUBLE_QUOTE}${RIGHT_DOUBLE_QUOTE}\\-\\(])${sep}?)['](?=${sep}?\\S)`;
29
22
  text = text.replace(new RegExp(beginningSingle, "gm"), `$1${LEFT_SINGLE_QUOTE}`);
30
- const beginningDouble = new RegExp(`(?<=^|[\\s\\(\\/\\[\\{\\-${EM_DASH}${chr}])(?<beforeChr>${chr}?)["](?<afterChr>(${chr}[ .,])|(?=${chr}?\\.{3}|${chr}?[^\\s\\)\\${EM_DASH},!?${chr};:.\\}]))`, "gm");
23
+ return text;
24
+ }
25
+ /** Convert straight double quotes to curly quotes */
26
+ function convertDoubleQuotes(text, sep) {
27
+ const beginningDouble = new RegExp(`(?<=^|[\\s\\(\\/\\[\\{\\-${EM_DASH}${sep}])(?<beforeChr>${sep}?)["](?<afterChr>(${sep}[ .,])|(?=${sep}?\\.{3}|${sep}?[^\\s\\)\\${EM_DASH},!?${sep};:.\\}]))`, "gm");
31
28
  text = text.replace(beginningDouble, `$<beforeChr>${LEFT_DOUBLE_QUOTE}$<afterChr>`);
32
- text = text.replace(new RegExp(`(?<=\\{)(${chr}? )?["]`, "g"), `$1${LEFT_DOUBLE_QUOTE}`);
33
- const endingDouble = `([^\\s\\(])["](${chr}?)(?=${chr}|[\\s/\\).,;${EM_DASH}:\\-\\}!?s]|$)`;
29
+ text = text.replace(new RegExp(`(?<=\\{)(${sep}? )?["]`, "g"), `$1${LEFT_DOUBLE_QUOTE}`);
30
+ const endingDouble = `([^\\s\\(])["](${sep}?)(?=${sep}|[\\s/\\).,;${EM_DASH}:\\-\\}!?s]|$)`;
34
31
  text = text.replace(new RegExp(endingDouble, "g"), `$1${RIGHT_DOUBLE_QUOTE}$2`);
35
- text = text.replace(new RegExp(`["](${chr}?)$`, "g"), `${RIGHT_DOUBLE_QUOTE}$1`);
32
+ text = text.replace(new RegExp(`["](${sep}?)$`, "g"), `${RIGHT_DOUBLE_QUOTE}$1`);
36
33
  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");
38
- text = text.replace(periodRegex, "$1.$2$3");
39
- const commaRegex = new RegExp(`(?<![!?]),(${chr}?[${RIGHT_DOUBLE_QUOTE}${RIGHT_SINGLE_QUOTE}])`, "g");
40
- text = text.replace(commaRegex, "$1,");
34
+ return text;
35
+ }
36
+ /** Apply American or British punctuation style */
37
+ function applyPunctuationStyle(text, sep, style) {
38
+ if (style === "american") {
39
+ // Period outside → inside: "Hello". → "Hello."
40
+ const periodOutsideRegex = new RegExp(`(?<![!?:\\.${ELLIPSIS}])(${sep}?)([${RIGHT_SINGLE_QUOTE}${RIGHT_DOUBLE_QUOTE}])(${sep}?)(?!\\.\\.\\.)\\.`, "g");
41
+ text = text.replace(periodOutsideRegex, "$1.$2$3");
42
+ // Comma outside → inside: "Hello", → "Hello,"
43
+ const commaOutsideRegex = new RegExp(`(${sep}?)([${RIGHT_SINGLE_QUOTE}${RIGHT_DOUBLE_QUOTE}])(${sep}?),`, "g");
44
+ text = text.replace(commaOutsideRegex, "$1,$2$3");
45
+ }
46
+ else if (style === "british") {
47
+ // Period inside → outside: "Hello." → "Hello".
48
+ const periodInsideRegex = new RegExp(`(?<![!?:\\.${ELLIPSIS}])(${sep}?)\\.(${sep}?)([${RIGHT_SINGLE_QUOTE}${RIGHT_DOUBLE_QUOTE}])`, "g");
49
+ text = text.replace(periodInsideRegex, "$1$2$3.");
50
+ // Comma inside → outside: "Hello," → "Hello",
51
+ const commaInsideRegex = new RegExp(`(?<![!?]),(${sep}?[${RIGHT_DOUBLE_QUOTE}${RIGHT_SINGLE_QUOTE}])`, "g");
52
+ text = text.replace(commaInsideRegex, "$1,");
53
+ }
54
+ return text;
55
+ }
56
+ /**
57
+ * Converts standard quotes to typographic smart quotes.
58
+ *
59
+ * @param text - The text to transform
60
+ * @param options - Configuration options
61
+ * @returns The text with smart quotes
62
+ */
63
+ export function niceQuotes(text, options = {}) {
64
+ const sep = options.separator ?? DEFAULT_SEPARATOR;
65
+ const punctuationStyle = options.punctuationStyle ?? "american";
66
+ text = convertSingleQuotes(text, sep);
67
+ text = convertDoubleQuotes(text, sep);
68
+ text = applyPunctuationStyle(text, sep, punctuationStyle);
41
69
  return text;
42
70
  }
43
71
  //# sourceMappingURL=quotes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"quotes.js","sourceRoot":"","sources":["../src/quotes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"quotes.js","sourceRoot":"","sources":["../src/quotes.ts"],"names":[],"mappings":"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"}
package/dist/symbols.d.ts CHANGED
@@ -49,13 +49,6 @@ export declare function multiplication(text: string, options?: SymbolOptions): s
49
49
  /**
50
50
  * Converts ASCII mathematical symbols to proper Unicode equivalents.
51
51
  *
52
- * Handles:
53
- * - "!=" → "≠"
54
- * - "+-" or "+/-" → "±"
55
- * - "<=" → "≤"
56
- * - ">=" → "≥"
57
- * - "~=" or "=~" → "≈"
58
- *
59
52
  * @example
60
53
  * ```ts
61
54
  * mathSymbols("x != y and a <= b")
@@ -111,7 +104,7 @@ export declare function arrows(text: string, options?: SymbolOptions): string;
111
104
  * // → "Water boils at 212 °F"
112
105
  * ```
113
106
  */
114
- export declare function degrees(text: string): string;
107
+ export declare function degrees(text: string, options?: SymbolOptions): string;
115
108
  /**
116
109
  * Converts straight quotes after numbers to prime marks.
117
110
  *
@@ -150,7 +143,7 @@ export declare function primeMarks(text: string, options?: SymbolOptions): strin
150
143
  * // → "About ¾ complete"
151
144
  * ```
152
145
  */
153
- export declare function fractions(text: string): string;
146
+ export declare function fractions(text: string, options?: SymbolOptions): string;
154
147
  /**
155
148
  * Applies all symbol transformations.
156
149
  *
@@ -1 +1 @@
1
- {"version":3,"file":"symbols.d.ts","sourceRoot":"","sources":["../src/symbols.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;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"}
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,CAW1E;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAkBhF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAShD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKjD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAyBxE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAWzE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CA+B5E;AAwBD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAkB3E;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CASjF"}
package/dist/symbols.js CHANGED
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * @module symbols
8
8
  */
9
- import { UNICODE_SYMBOLS, DEFAULT_SEPARATOR } from "./constants.js";
9
+ import { UNICODE_SYMBOLS, ESCAPED_DEFAULT_SEPARATOR } from "./constants.js";
10
10
  /**
11
11
  * Escapes special regex characters in a string.
12
12
  */
@@ -24,7 +24,9 @@ const { ELLIPSIS, MULTIPLICATION, NOT_EQUAL, PLUS_MINUS, COPYRIGHT, REGISTERED,
24
24
  * ```
25
25
  */
26
26
  export function ellipsis(text, options = {}) {
27
- const chr = escapeRegex(options.separator ?? DEFAULT_SEPARATOR);
27
+ const chr = options.separator
28
+ ? escapeRegex(options.separator)
29
+ : ESCAPED_DEFAULT_SEPARATOR;
28
30
  const pattern = new RegExp(`\\.${chr}?\\.${chr}?\\.`, "g");
29
31
  text = text.replace(pattern, ELLIPSIS);
30
32
  text = text.replace(new RegExp(`${ELLIPSIS}(?=\\w)`, "gu"), `${ELLIPSIS} `);
@@ -48,28 +50,23 @@ export function ellipsis(text, options = {}) {
48
50
  * ```
49
51
  */
50
52
  export function multiplication(text, options = {}) {
51
- const chr = escapeRegex(options.separator ?? DEFAULT_SEPARATOR);
53
+ const chr = options.separator
54
+ ? escapeRegex(options.separator)
55
+ : ESCAPED_DEFAULT_SEPARATOR;
52
56
  // Dimensions with spaces: preserve spacing
53
57
  const loosePattern = new RegExp(`(\\d${chr}?)\\s+[xX*]\\s+(${chr}?\\d)`, "g");
54
58
  text = text.replace(loosePattern, `$1 ${MULTIPLICATION} $2`);
55
59
  // Dimensions without spaces: keep tight
56
60
  const tightPattern = new RegExp(`(\\d${chr}?)[xX*](${chr}?\\d)`, "g");
57
61
  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");
62
+ // Trailing multiplier: 5x (followed by word boundary - space, punctuation, etc.)
63
+ const trailingPattern = new RegExp(`(\\d${chr}?)[xX*]\\b`, "g");
60
64
  text = text.replace(trailingPattern, `$1${MULTIPLICATION}`);
61
65
  return text;
62
66
  }
63
67
  /**
64
68
  * Converts ASCII mathematical symbols to proper Unicode equivalents.
65
69
  *
66
- * Handles:
67
- * - "!=" → "≠"
68
- * - "+-" or "+/-" → "±"
69
- * - "<=" → "≤"
70
- * - ">=" → "≥"
71
- * - "~=" or "=~" → "≈"
72
- *
73
70
  * @example
74
71
  * ```ts
75
72
  * mathSymbols("x != y and a <= b")
@@ -80,24 +77,24 @@ export function multiplication(text, options = {}) {
80
77
  * ```
81
78
  */
82
79
  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;
80
+ return text
81
+ .replace(/!=/g, NOT_EQUAL)
82
+ .replace(/\+\/-/g, PLUS_MINUS)
83
+ .replace(/\+-/g, PLUS_MINUS)
84
+ .replace(/<=/g, LESS_EQUAL)
85
+ .replace(/>=/g, GREATER_EQUAL)
86
+ .replace(/~=/g, APPROXIMATE)
87
+ .replace(/=~/g, APPROXIMATE);
91
88
  }
92
89
  /**
93
90
  * Converts ASCII representations of copyright, registered, and trademark
94
91
  * symbols to proper Unicode characters.
95
92
  */
96
93
  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;
94
+ return text
95
+ .replace(/\(c\)/gi, COPYRIGHT)
96
+ .replace(/\(r\)/gi, REGISTERED)
97
+ .replace(/\(tm\)/gi, TRADEMARK);
101
98
  }
102
99
  /**
103
100
  * Converts arrow character sequences to Unicode arrows.
@@ -120,12 +117,15 @@ export function legalSymbols(text) {
120
117
  * ```
121
118
  */
122
119
  export function arrows(text, options = {}) {
123
- const chr = escapeRegex(options.separator ?? DEFAULT_SEPARATOR);
120
+ const chr = options.separator
121
+ ? escapeRegex(options.separator)
122
+ : ESCAPED_DEFAULT_SEPARATOR;
124
123
  // Bidirectional arrow first (to avoid partial matches)
125
- text = text.replace(new RegExp(`<-{1,2}${chr}?>`, "g"), ARROW_LEFT_RIGHT);
126
- // Right arrow
124
+ // Matches <-> or <--> with optional separator, requires boundary context
125
+ text = text.replace(new RegExp(`(?<=[\\s${chr}]|^)<-{1,2}${chr}?>(?=[\\s${chr}]|$)`, "g"), ARROW_LEFT_RIGHT);
126
+ // Right arrow: -> or --> with boundary context
127
127
  text = text.replace(new RegExp(`(?<=[\\s${chr}]|^)-{1,2}>(?=[\\s${chr}]|$)`, "g"), ARROW_RIGHT);
128
- // Left arrow
128
+ // Left arrow: <- or <-- with boundary context
129
129
  text = text.replace(new RegExp(`(?<=[\\s${chr}]|^)<-{1,2}(?=[\\s${chr}]|$)`, "g"), ARROW_LEFT);
130
130
  return text;
131
131
  }
@@ -148,12 +148,13 @@ export function arrows(text, options = {}) {
148
148
  * // → "Water boils at 212 °F"
149
149
  * ```
150
150
  */
151
- export function degrees(text) {
151
+ export function degrees(text, options = {}) {
152
+ const chr = options.separator
153
+ ? escapeRegex(options.separator)
154
+ : ESCAPED_DEFAULT_SEPARATOR;
152
155
  // 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;
156
+ // Handles separator between digit and unit
157
+ return text.replace(new RegExp(`(\\d${chr}?) ?([CF])\\b`, "gi"), (_, num, unit) => `${num} ${DEGREE}${unit.toUpperCase()}`);
157
158
  }
158
159
  /**
159
160
  * Converts straight quotes after numbers to prime marks.
@@ -175,22 +176,48 @@ export function degrees(text) {
175
176
  * ```
176
177
  */
177
178
  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')
179
+ const chr = options.separator
180
+ ? escapeRegex(options.separator)
181
+ : ESCAPED_DEFAULT_SEPARATOR;
182
+ // Single prime: Matches digit + optional separator + apostrophe
183
+ // Lookahead ensures it's followed by: another digit, double quote, end of string, or punctuation
184
+ // Examples: 5' (feet), 30' (arcminutes)
181
185
  const singlePrimePattern = new RegExp(`(\\d${chr}?)'(?=${chr}?(?:\\d|"|$|[\\s.,;:!?)]))`, "g");
182
186
  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")
187
+ // Double prime Pattern 1: Feet-inches pattern
188
+ // Matches: prime symbol + optional separator + digit + optional separator + double quote
189
+ // Examples: 5′10" or 5'10" → 5′10″
185
190
  const feetInchesPattern = new RegExp(`(${PRIME}${chr}?\\d${chr}?)"`, "g");
186
191
  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"
192
+ // Double prime Pattern 2: Standalone inches
193
+ // Negative lookbehind: ensures no opening quote within 20 chars before the digit
194
+ // Negative lookahead: ensures not followed by word characters
195
+ // Matches: 12" wide ✓, but not: "Term 1" ✗
190
196
  const standaloneInchesPattern = new RegExp(`(?<!["\u201C]${chr}?[^"${chr}]{0,20})(\\d${chr}?)"(?!${chr}?[\\w])`, "g");
191
197
  text = text.replace(standaloneInchesPattern, `$1${DOUBLE_PRIME}`);
192
198
  return text;
193
199
  }
200
+ /**
201
+ * Map of ASCII fractions to Unicode fraction characters.
202
+ * Pre-computed to avoid repeated object allocation.
203
+ */
204
+ const FRACTION_MAP = {
205
+ "1/4": UNICODE_SYMBOLS.FRACTION_1_4,
206
+ "1/2": UNICODE_SYMBOLS.FRACTION_1_2,
207
+ "3/4": UNICODE_SYMBOLS.FRACTION_3_4,
208
+ "1/3": UNICODE_SYMBOLS.FRACTION_1_3,
209
+ "2/3": UNICODE_SYMBOLS.FRACTION_2_3,
210
+ "1/5": UNICODE_SYMBOLS.FRACTION_1_5,
211
+ "2/5": UNICODE_SYMBOLS.FRACTION_2_5,
212
+ "3/5": UNICODE_SYMBOLS.FRACTION_3_5,
213
+ "4/5": UNICODE_SYMBOLS.FRACTION_4_5,
214
+ "1/6": UNICODE_SYMBOLS.FRACTION_1_6,
215
+ "5/6": UNICODE_SYMBOLS.FRACTION_5_6,
216
+ "1/8": UNICODE_SYMBOLS.FRACTION_1_8,
217
+ "3/8": UNICODE_SYMBOLS.FRACTION_3_8,
218
+ "5/8": UNICODE_SYMBOLS.FRACTION_5_8,
219
+ "7/8": UNICODE_SYMBOLS.FRACTION_7_8,
220
+ };
194
221
  /**
195
222
  * Converts common fractions to Unicode fraction characters.
196
223
  *
@@ -209,27 +236,17 @@ export function primeMarks(text, options = {}) {
209
236
  * // → "About ¾ complete"
210
237
  * ```
211
238
  */
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);
239
+ export function fractions(text, options = {}) {
240
+ const chr = options.separator
241
+ ? escapeRegex(options.separator)
242
+ : ESCAPED_DEFAULT_SEPARATOR;
243
+ for (const [ascii, unicode] of Object.entries(FRACTION_MAP)) {
244
+ // Negative lookbehind/lookahead: ensures fraction is not part of a larger number
245
+ // Named captures preserve separators before and after the slash
246
+ const [numerator, denominator] = ascii.split("/");
247
+ const pattern = new RegExp(`(?<!\\d)${numerator}(?<sepBefore>${chr}?)/(?<sepAfter>${chr}?)${denominator}(?!\\d)`, "g");
248
+ // Preserve separators around the fraction Unicode character
249
+ text = text.replace(pattern, `$<sepBefore>${unicode}$<sepAfter>`);
233
250
  }
234
251
  return text;
235
252
  }
@@ -1 +1 @@
1
- {"version":3,"file":"symbols.js","sourceRoot":"","sources":["../src/symbols.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"symbols.js","sourceRoot":"","sources":["../src/symbols.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "punctilio",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "Smart typography transformations: curly quotes, em-dashes, en-dashes, and more",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",