punctilio 3.1.0 → 3.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/constants.d.ts +20 -10
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +24 -13
- package/dist/constants.js.map +1 -1
- package/dist/dashes.d.ts.map +1 -1
- package/dist/dashes.js +2 -3
- package/dist/dashes.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -6
- package/dist/index.js.map +1 -1
- package/dist/nbsp.d.ts.map +1 -1
- package/dist/nbsp.js +2 -1
- package/dist/nbsp.js.map +1 -1
- package/dist/quotes.d.ts.map +1 -1
- package/dist/quotes.js +25 -11
- package/dist/quotes.js.map +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +9 -6
- package/dist/utils.js.map +1 -1
- package/package.json +1 -1
- package/src/constants.ts +24 -13
- package/src/dashes.ts +2 -3
- package/src/index.ts +13 -8
- package/src/nbsp.ts +2 -1
- package/src/quotes.ts +23 -10
- package/src/tests/index.test.ts +35 -4
- package/src/tests/quotes.test.ts +32 -0
- package/src/tests/utils.test.ts +2 -2
- package/src/utils.ts +9 -5
package/dist/constants.d.ts
CHANGED
|
@@ -98,17 +98,21 @@ export declare const TERMINAL_PUNCTUATION: readonly ["!", "?", ".", ",", ";", ":
|
|
|
98
98
|
*/
|
|
99
99
|
export declare const LATIN_LETTERS = "A-Za-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u00FF\\u0100-\\u017F\\u0180-\\u024F";
|
|
100
100
|
/**
|
|
101
|
-
* Default separator
|
|
102
|
-
* Uses Unicode Private Use Area
|
|
101
|
+
* Default separator for text spanning HTML elements.
|
|
102
|
+
* Uses a two-character sentinel from the Unicode Private Use Area
|
|
103
|
+
* (U+E000 U+E001) to avoid collisions with CJK fonts, Apple emoji
|
|
104
|
+
* internals, PDF-to-text output, and icon fonts that repurpose U+E000.
|
|
103
105
|
*/
|
|
104
|
-
export declare const DEFAULT_SEPARATOR = "\uE000";
|
|
106
|
+
export declare const DEFAULT_SEPARATOR = "\uE000\uE001";
|
|
105
107
|
export declare const ESCAPED_DEFAULT_SEPARATOR: string;
|
|
106
108
|
/**
|
|
107
|
-
* Returns the regex-escaped separator string for the given options
|
|
108
|
-
*
|
|
109
|
+
* Returns the regex-escaped separator string for the given options,
|
|
110
|
+
* wrapped in a non-capturing group so that quantifiers like `?` and `*`
|
|
111
|
+
* apply to the entire separator sequence (critical for multi-character
|
|
112
|
+
* separators like the default U+E000 U+E001).
|
|
109
113
|
*
|
|
110
114
|
* @param options - Object with an optional `separator` field
|
|
111
|
-
* @returns Regex-escaped separator string
|
|
115
|
+
* @returns Regex-escaped separator string wrapped in `(?:...)`
|
|
112
116
|
*/
|
|
113
117
|
export declare function getEscapedSeparator(options: {
|
|
114
118
|
separator?: string;
|
|
@@ -161,16 +165,22 @@ export declare const SPACE_CHARS: string;
|
|
|
161
165
|
* Creates a lookbehind pattern that matches after whitespace, separator, or start of string.
|
|
162
166
|
* Used for arrow patterns and other constructs that should appear at word boundaries.
|
|
163
167
|
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
168
|
+
* Uses alternation instead of a character class so that multi-character
|
|
169
|
+
* separators are matched as a sequence, not as individual characters.
|
|
170
|
+
*
|
|
171
|
+
* @param escapedSeparator - Regex-escaped separator string (may be grouped)
|
|
172
|
+
* @returns Pattern string: `(?<=\\s|${sep}|^)`
|
|
166
173
|
*/
|
|
167
174
|
export declare function spaceBoundaryStart(escapedSeparator: string): string;
|
|
168
175
|
/**
|
|
169
176
|
* Creates a lookahead pattern that matches before whitespace, separator, or end of string.
|
|
170
177
|
* Used for arrow patterns and other constructs that should appear at word boundaries.
|
|
171
178
|
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
179
|
+
* Uses alternation instead of a character class so that multi-character
|
|
180
|
+
* separators are matched as a sequence, not as individual characters.
|
|
181
|
+
*
|
|
182
|
+
* @param escapedSeparator - Regex-escaped separator string (may be grouped)
|
|
183
|
+
* @returns Pattern string: `(?=\\s|${sep}|$)`
|
|
174
184
|
*/
|
|
175
185
|
export declare function spaceBoundaryEnd(escapedSeparator: string): string;
|
|
176
186
|
/**
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH;;GAEG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuElB,CAAA;AAEV;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,8HAYvB,CAAA;AAEV;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,aAAa,sFAAsF,CAAA;AAEhH
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH;;GAEG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuElB,CAAA;AAEV;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,8HAYvB,CAAA;AAEV;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,aAAa,sFAAsF,CAAA;AAEhH;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,iBAAiB,CAAA;AAC/C,eAAO,MAAM,yBAAyB,QAAwC,CAAA;AAE9E;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAK3E;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,wEAAyE,CAAA;AAEzG;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAElE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED;;;GAGG;AACH,eAAO,MAAM,WAAW,QAA6B,CAAA;AAErD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAEjE;AAUD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAcnE"}
|
package/dist/constants.js
CHANGED
|
@@ -117,22 +117,27 @@ export const TERMINAL_PUNCTUATION = [
|
|
|
117
117
|
*/
|
|
118
118
|
export const LATIN_LETTERS = "A-Za-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u00FF\\u0100-\\u017F\\u0180-\\u024F";
|
|
119
119
|
/**
|
|
120
|
-
* Default separator
|
|
121
|
-
* Uses Unicode Private Use Area
|
|
120
|
+
* Default separator for text spanning HTML elements.
|
|
121
|
+
* Uses a two-character sentinel from the Unicode Private Use Area
|
|
122
|
+
* (U+E000 U+E001) to avoid collisions with CJK fonts, Apple emoji
|
|
123
|
+
* internals, PDF-to-text output, and icon fonts that repurpose U+E000.
|
|
122
124
|
*/
|
|
123
|
-
export const DEFAULT_SEPARATOR = "\uE000";
|
|
125
|
+
export const DEFAULT_SEPARATOR = "\uE000\uE001";
|
|
124
126
|
export const ESCAPED_DEFAULT_SEPARATOR = escapeStringRegexp(DEFAULT_SEPARATOR);
|
|
125
127
|
/**
|
|
126
|
-
* Returns the regex-escaped separator string for the given options
|
|
127
|
-
*
|
|
128
|
+
* Returns the regex-escaped separator string for the given options,
|
|
129
|
+
* wrapped in a non-capturing group so that quantifiers like `?` and `*`
|
|
130
|
+
* apply to the entire separator sequence (critical for multi-character
|
|
131
|
+
* separators like the default U+E000 U+E001).
|
|
128
132
|
*
|
|
129
133
|
* @param options - Object with an optional `separator` field
|
|
130
|
-
* @returns Regex-escaped separator string
|
|
134
|
+
* @returns Regex-escaped separator string wrapped in `(?:...)`
|
|
131
135
|
*/
|
|
132
136
|
export function getEscapedSeparator(options) {
|
|
133
|
-
|
|
137
|
+
const escaped = options.separator
|
|
134
138
|
? escapeStringRegexp(options.separator)
|
|
135
139
|
: ESCAPED_DEFAULT_SEPARATOR;
|
|
140
|
+
return `(?:${escaped})`;
|
|
136
141
|
}
|
|
137
142
|
/**
|
|
138
143
|
* Characters that have special meaning in regular expressions.
|
|
@@ -186,21 +191,27 @@ export const SPACE_CHARS = ` ${UNICODE_SYMBOLS.NBSP}`;
|
|
|
186
191
|
* Creates a lookbehind pattern that matches after whitespace, separator, or start of string.
|
|
187
192
|
* Used for arrow patterns and other constructs that should appear at word boundaries.
|
|
188
193
|
*
|
|
189
|
-
*
|
|
190
|
-
*
|
|
194
|
+
* Uses alternation instead of a character class so that multi-character
|
|
195
|
+
* separators are matched as a sequence, not as individual characters.
|
|
196
|
+
*
|
|
197
|
+
* @param escapedSeparator - Regex-escaped separator string (may be grouped)
|
|
198
|
+
* @returns Pattern string: `(?<=\\s|${sep}|^)`
|
|
191
199
|
*/
|
|
192
200
|
export function spaceBoundaryStart(escapedSeparator) {
|
|
193
|
-
return `(
|
|
201
|
+
return `(?<=\\s|${escapedSeparator}|^)`;
|
|
194
202
|
}
|
|
195
203
|
/**
|
|
196
204
|
* Creates a lookahead pattern that matches before whitespace, separator, or end of string.
|
|
197
205
|
* Used for arrow patterns and other constructs that should appear at word boundaries.
|
|
198
206
|
*
|
|
199
|
-
*
|
|
200
|
-
*
|
|
207
|
+
* Uses alternation instead of a character class so that multi-character
|
|
208
|
+
* separators are matched as a sequence, not as individual characters.
|
|
209
|
+
*
|
|
210
|
+
* @param escapedSeparator - Regex-escaped separator string (may be grouped)
|
|
211
|
+
* @returns Pattern string: `(?=\\s|${sep}|$)`
|
|
201
212
|
*/
|
|
202
213
|
export function spaceBoundaryEnd(escapedSeparator) {
|
|
203
|
-
return `(
|
|
214
|
+
return `(?=\\s|${escapedSeparator}|$)`;
|
|
204
215
|
}
|
|
205
216
|
/**
|
|
206
217
|
* Cache for compiled RegExp objects keyed by `pattern + '\0' + flags`.
|
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"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"}
|
package/dist/dashes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashes.d.ts","sourceRoot":"","sources":["../src/dashes.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"dashes.d.ts","sourceRoot":"","sources":["../src/dashes.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,MAAM,CAAA;AAEvD,MAAM,WAAW,WAAW;IAC1B,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,mFAAmF;IACnF,SAAS,CAAC,EAAE,SAAS,CAAA;CACtB;AAID;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,+BAA0C,CAAA;AAEpF,eAAO,MAAM,MAAM,QAKR,CAAA;AAEX,8DAA8D;AAC9D,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAuDjF;AAED,iFAAiF;AACjF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAe/E;AAED,8EAA8E;AAC9E,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAkC5E;AA0ED,gCAAgC;AAChC,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAU7E"}
|
package/dist/dashes.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Dash transformation: hyphens → em-dashes, en-dashes, minus signs.
|
|
3
3
|
*/
|
|
4
|
-
import escapeStringRegexp from "escape-string-regexp";
|
|
5
4
|
import { UNICODE_SYMBOLS, DEFAULT_SEPARATOR, LATIN_LETTERS, wordBoundaryStart, wordBoundaryEnd, getEscapedSeparator, cachedRegExp } from "./constants.js";
|
|
6
5
|
const { EN_DASH, EM_DASH, MINUS, LEFT_DOUBLE_QUOTE, RIGHT_DOUBLE_QUOTE, LEFT_SINGLE_QUOTE, RIGHT_SINGLE_QUOTE } = UNICODE_SYMBOLS;
|
|
7
6
|
/**
|
|
@@ -102,7 +101,7 @@ export function minusReplace(text, options = {}) {
|
|
|
102
101
|
function convertParentheticalDashes(text, sep, style) {
|
|
103
102
|
const localizedDash = style === "british" ? EN_DASH : EM_DASH;
|
|
104
103
|
const maybeSpace = style === "british" ? " " : "";
|
|
105
|
-
const escapedSep =
|
|
104
|
+
const escapedSep = getEscapedSeparator({ separator: sep });
|
|
106
105
|
// Convert spaced dashes: "word - word" or "word — word"
|
|
107
106
|
// When a separator follows the dash, preserve trailing spaces (they belong to the next text segment).
|
|
108
107
|
// A single plain hyphen directly before a word character (through optional separators) is a
|
|
@@ -137,7 +136,7 @@ function convertParentheticalDashes(text, sep, style) {
|
|
|
137
136
|
* allows a space after the dash: "Don't inter— Hey! Who threw that?"
|
|
138
137
|
*/
|
|
139
138
|
function normalizeEmDashSpacing(text, sep) {
|
|
140
|
-
const escapedSep =
|
|
139
|
+
const escapedSep = getEscapedSeparator({ separator: sep });
|
|
141
140
|
// Remove all spaces around em-dashes
|
|
142
141
|
text = text.replace(cachedRegExp(`(?<before>${escapedSep}?)[ ]*${EM_DASH}[ ]*(?<after>${escapedSep}?)`, "g"), `$<before>${EM_DASH}$<after>`);
|
|
143
142
|
// Preserve space after em-dash at start of line (e.g., attribution)
|
package/dist/dashes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashes.js","sourceRoot":"","sources":["../src/dashes.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"dashes.js","sourceRoot":"","sources":["../src/dashes.ts"],"names":[],"mappings":"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"}
|
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,mBAAmB,EAAE,KAAK,YAAY,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAA;AACvG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AACnD,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,MAAM,EACN,6BAA6B,EAC7B,KAAK,WAAW,EAChB,KAAK,SAAS,GACf,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EACL,QAAQ,EACR,cAAc,EACd,WAAW,EACX,YAAY,EACZ,MAAM,EACN,OAAO,EACP,SAAS,EACT,UAAU,EACV,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,eAAe,EACf,KAAK,aAAa,GACnB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,kBAAkB,EAClB,+BAA+B,EAC/B,uBAAuB,EACvB,mBAAmB,EACnB,yBAAyB,EACzB,mBAAmB,EACnB,aAAa,EACb,KAAK,EACL,UAAU,EACV,uBAAuB,EACvB,KAAK,WAAW,GACjB,MAAM,WAAW,CAAA;AAElB,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IAEjB;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IAExB;;;;;;;;;;;;;;;;;OAiBG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IAEnC;;;;;;;;;;;;;OAaG;IACH,SAAS,CAAC,EAAE,SAAS,CAAA;IAErB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IAEnB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IAEjB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IAErB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IAEnB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,OAAO,CAAA;IAEd;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAE3B;AASD,OAAO,EAAE,qBAAqB,EAAE,6BAA6B,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAClG,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AACnE,eAAO,MAAM,0BAA0B,KAA6C,CAAA;AAiDpF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,KAAK,YAAY,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAA;AACvG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AACnD,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,MAAM,EACN,6BAA6B,EAC7B,KAAK,WAAW,EAChB,KAAK,SAAS,GACf,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EACL,QAAQ,EACR,cAAc,EACd,WAAW,EACX,YAAY,EACZ,MAAM,EACN,OAAO,EACP,SAAS,EACT,UAAU,EACV,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,eAAe,EACf,KAAK,aAAa,GACnB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,kBAAkB,EAClB,+BAA+B,EAC/B,uBAAuB,EACvB,mBAAmB,EACnB,yBAAyB,EACzB,mBAAmB,EACnB,aAAa,EACb,KAAK,EACL,UAAU,EACV,uBAAuB,EACvB,KAAK,WAAW,GACjB,MAAM,WAAW,CAAA;AAElB,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IAEjB;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IAExB;;;;;;;;;;;;;;;;;OAiBG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IAEnC;;;;;;;;;;;;;OAaG;IACH,SAAS,CAAC,EAAE,SAAS,CAAA;IAErB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IAEnB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IAEjB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IAErB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IAEnB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,OAAO,CAAA;IAEd;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAE3B;AASD,OAAO,EAAE,qBAAqB,EAAE,6BAA6B,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAClG,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AACnE,eAAO,MAAM,0BAA0B,KAA6C,CAAA;AAiDpF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,MAAM,CAwE9E"}
|
package/dist/index.js
CHANGED
|
@@ -68,12 +68,17 @@ const defaultOpts = {
|
|
|
68
68
|
};
|
|
69
69
|
export function transform(text, options = {}) {
|
|
70
70
|
const separator = options.separator ?? DEFAULT_SEPARATOR;
|
|
71
|
-
// Validate separator: must be
|
|
72
|
-
//
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
71
|
+
// Validate separator: must be non-empty and contain only BMP characters.
|
|
72
|
+
// for...of iterates by code point; surrogate pairs (non-BMP) yield a
|
|
73
|
+
// two-UTF16-unit string, so ch.length > 1 detects them.
|
|
74
|
+
if (separator.length === 0) {
|
|
75
|
+
throw new Error("Invalid separator: must not be empty.");
|
|
76
|
+
}
|
|
77
|
+
for (const ch of separator) {
|
|
78
|
+
if (ch.length > 1) {
|
|
79
|
+
throw new Error(`Invalid separator: must contain only BMP characters (no characters outside the Basic Multilingual Plane). ` +
|
|
80
|
+
`Received "${separator}" which contains a non-BMP character.`);
|
|
81
|
+
}
|
|
77
82
|
}
|
|
78
83
|
const original = text;
|
|
79
84
|
const { symbols, fractions, degrees, superscript, ligatures, nbsp, collapseSpaces, checkIdempotency, ...separatorOpts } = { ...defaultOpts, ...options };
|
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,EAAE,mBAAmB,EAA4C,MAAM,aAAa,CAAA;AAEvG,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,MAAM,EACN,6BAA6B,GAG9B,MAAM,aAAa,CAAA;AAEpB,OAAO,EACL,QAAQ,EACR,cAAc,EACd,WAAW,EACX,YAAY,EACZ,MAAM,EACN,OAAO,EACP,SAAS,EACT,UAAU,EACV,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,eAAe,GAEhB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,kBAAkB,EAClB,+BAA+B,EAC/B,uBAAuB,EACvB,mBAAmB,EACnB,yBAAyB,EACzB,mBAAmB,EACnB,aAAa,EACb,KAAK,EACL,UAAU,EACV,uBAAuB,GAExB,MAAM,WAAW,CAAA;AA+GlB,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,kBAAkB,IAAI,oBAAoB,EAAE,UAAU,EAAE,cAAc,IAAI,uBAAuB,EAAE,oBAAoB,IAAI,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAC3P,OAAO,EAAE,aAAa,IAAI,eAAe,EAAE,MAAM,WAAW,CAAA;AAC5D,OAAO,EAAE,6BAA6B,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAC7E,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAEnE,OAAO,EAAE,qBAAqB,EAAE,6BAA6B,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAClG,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AACnE,MAAM,CAAC,MAAM,0BAA0B,GAAG,eAAe,CAAC,0BAA0B,CAAA;AAEpF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,WAAW,GAAkD;IACjE,OAAO,EAAE,IAAI;IACb,SAAS,EAAE,KAAK;IAChB,OAAO,EAAE,KAAK;IACd,WAAW,EAAE,KAAK;IAClB,SAAS,EAAE,KAAK;IAChB,IAAI,EAAE,IAAI;IACV,cAAc,EAAE,IAAI;IACpB,gBAAgB,EAAE,IAAI;IACtB,gBAAgB,EAAE,UAAU;IAC5B,SAAS,EAAE,UAAU;CACtB,CAAA;AAED,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,UAA4B,EAAE;IACpE,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,iBAAiB,CAAA;IAExD,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAA4C,MAAM,aAAa,CAAA;AAEvG,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,MAAM,EACN,6BAA6B,GAG9B,MAAM,aAAa,CAAA;AAEpB,OAAO,EACL,QAAQ,EACR,cAAc,EACd,WAAW,EACX,YAAY,EACZ,MAAM,EACN,OAAO,EACP,SAAS,EACT,UAAU,EACV,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,eAAe,GAEhB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,kBAAkB,EAClB,+BAA+B,EAC/B,uBAAuB,EACvB,mBAAmB,EACnB,yBAAyB,EACzB,mBAAmB,EACnB,aAAa,EACb,KAAK,EACL,UAAU,EACV,uBAAuB,GAExB,MAAM,WAAW,CAAA;AA+GlB,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,kBAAkB,IAAI,oBAAoB,EAAE,UAAU,EAAE,cAAc,IAAI,uBAAuB,EAAE,oBAAoB,IAAI,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAC3P,OAAO,EAAE,aAAa,IAAI,eAAe,EAAE,MAAM,WAAW,CAAA;AAC5D,OAAO,EAAE,6BAA6B,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAC7E,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAEnE,OAAO,EAAE,qBAAqB,EAAE,6BAA6B,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAClG,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AACnE,MAAM,CAAC,MAAM,0BAA0B,GAAG,eAAe,CAAC,0BAA0B,CAAA;AAEpF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,WAAW,GAAkD;IACjE,OAAO,EAAE,IAAI;IACb,SAAS,EAAE,KAAK;IAChB,OAAO,EAAE,KAAK;IACd,WAAW,EAAE,KAAK;IAClB,SAAS,EAAE,KAAK;IAChB,IAAI,EAAE,IAAI;IACV,cAAc,EAAE,IAAI;IACpB,gBAAgB,EAAE,IAAI;IACtB,gBAAgB,EAAE,UAAU;IAC5B,SAAS,EAAE,UAAU;CACtB,CAAA;AAED,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,UAA4B,EAAE;IACpE,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,iBAAiB,CAAA;IAExD,yEAAyE;IACzE,qEAAqE;IACrE,wDAAwD;IACxD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAA;IAC1D,CAAC;IACD,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;QAC3B,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CACb,4GAA4G;gBAC5G,aAAa,SAAS,uCAAuC,CAC9D,CAAA;QACH,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAA;IACrB,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE,cAAc,EAAE,gBAAgB,EAAE,GAAG,aAAa,EAAE,GAAG,EAAE,GAAG,WAAW,EAAE,GAAG,OAAO,EAAE,CAAA;IAExJ,IAAI,GAAG,aAAa,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;IACzC,IAAI,aAAa,CAAC,gBAAgB,KAAK,MAAM,EAAE,CAAC;QAC9C,IAAI,GAAG,UAAU,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;IACxC,CAAC;IACD,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,EAAE,aAAa,CAAC,CAAA;IAChD,CAAC;IAED,IAAI,OAAO,EAAE,CAAC;QACZ,IAAI,GAAG,gBAAgB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;IAC9C,CAAC;IAED,IAAI,WAAW,EAAE,CAAC;QAChB,IAAI,GAAG,oBAAoB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;IAClD,CAAC;IAED,IAAI,SAAS,EAAE,CAAC;QACd,IAAI,GAAG,kBAAkB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;IAChD,CAAC;IAED,IAAI,cAAc,EAAE,CAAC;QACnB,IAAI,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAA;IACtC,CAAC;IAED,IAAI,IAAI,EAAE,CAAC;QACT,IAAI,GAAG,eAAe,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;IAC7C,CAAC;IAED,6BAA6B,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,CAAC,CAAA;IAErE,IAAI,gBAAgB,EAAE,CAAC;QACrB,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC,CAAA;QAC3E,qEAAqE;QACrE,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CACb,gCAAgC;gBAChC,gBAAgB,iBAAiB,CAAC,IAAI,EAAE,YAAY,CAAC,IAAI;gBACzD,gBAAgB,iBAAiB,CAAC,UAAU,EAAE,aAAa,CAAC,IAAI;gBAChE,4GAA4G;gBAC5G,gDAAgD,CACjD,CAAA;QACH,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC"}
|
package/dist/nbsp.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nbsp.d.ts","sourceRoot":"","sources":["../src/nbsp.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAajD,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,CAAA;AAO1D;;;GAGG;AACH,eAAO,MAAM,KAAK,UA2BjB,CAAA;AAED,eAAO,MAAM,UAAU,UActB,CAAA;AAED,eAAO,MAAM,uBAAuB,UASnC,CAAA;AASD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAOnF;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAQxF;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"nbsp.d.ts","sourceRoot":"","sources":["../src/nbsp.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAajD,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,CAAA;AAO1D;;;GAGG;AACH,eAAO,MAAM,KAAK,UA2BjB,CAAA;AAED,eAAO,MAAM,UAAU,UActB,CAAA;AAED,eAAO,MAAM,uBAAuB,UASnC,CAAA;AASD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAOnF;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAQxF;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAQlF;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAO/F;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAOvF;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAOnF;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAOzF;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAOnF;AAsBD,gEAAgE;AAChE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAK7E"}
|
package/dist/nbsp.js
CHANGED
|
@@ -106,7 +106,8 @@ export function nbspBetweenNumberAndUnit(text, options = {}) {
|
|
|
106
106
|
*/
|
|
107
107
|
export function nbspBeforeLastWord(text, options = {}) {
|
|
108
108
|
const sep = getEscapedSeparator(options);
|
|
109
|
-
|
|
109
|
+
// Use alternation instead of character classes for multi-char separator support
|
|
110
|
+
const pattern = cachedRegExp(`(?<=\\w|${sep})${SPACE}(?<lastWord>(?:(?!\\s)(?!${sep}).){1,10})(?<ending>${sep}?(?:\\n\\n|$))`, "g");
|
|
110
111
|
return text.replace(pattern, `${NBSP}$<lastWord>$<ending>`);
|
|
111
112
|
}
|
|
112
113
|
/**
|
package/dist/nbsp.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nbsp.js","sourceRoot":"","sources":["../src/nbsp.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"nbsp.js","sourceRoot":"","sources":["../src/nbsp.ts"],"names":[],"mappings":"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"}
|
package/dist/quotes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quotes.d.ts","sourceRoot":"","sources":["../src/quotes.ts"],"names":[],"mappings":"AAAA;;GAEG;AAiBH,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAA;AAEpF,MAAM,WAAW,YAAY;IAC3B,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;CACpC;
|
|
1
|
+
{"version":3,"file":"quotes.d.ts","sourceRoot":"","sources":["../src/quotes.ts"],"names":[],"mappings":"AAAA;;GAEG;AAiBH,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAA;AAEpF,MAAM,WAAW,YAAY;IAC3B,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;CACpC;AA+OD,+CAA+C;AAC/C,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,MAAM,CAK3E;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,MAAM,CAEpF"}
|
package/dist/quotes.js
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
* Smart quote transformation: straight quotes → curly quotes.
|
|
3
3
|
*/
|
|
4
4
|
import escapeStringRegexp from "escape-string-regexp";
|
|
5
|
-
import { UNICODE_SYMBOLS, DEFAULT_SEPARATOR, LATIN_LETTERS, TERMINAL_PUNCTUATION, cachedRegExp } from "./constants.js";
|
|
5
|
+
import { UNICODE_SYMBOLS, DEFAULT_SEPARATOR, LATIN_LETTERS, TERMINAL_PUNCTUATION, getEscapedSeparator, cachedRegExp } from "./constants.js";
|
|
6
6
|
const { EM_DASH, LEFT_DOUBLE_QUOTE, RIGHT_DOUBLE_QUOTE, LEFT_SINGLE_QUOTE, RIGHT_SINGLE_QUOTE, MODIFIER_LETTER_APOSTROPHE, } = UNICODE_SYMBOLS;
|
|
7
7
|
/** Joined string of all terminal punctuation characters for use in regex character classes. */
|
|
8
8
|
const TERMINAL_PUNCTUATION_CLASS = TERMINAL_PUNCTUATION.join("");
|
|
9
9
|
/** Convert straight single quotes to curly quotes and apostrophes */
|
|
10
10
|
function convertSingleQuotes(text, sep) {
|
|
11
|
-
const escapedSep =
|
|
11
|
+
const escapedSep = getEscapedSeparator({ separator: sep });
|
|
12
12
|
// Handle empty single quotes '' and whitespace-only quotes ' ' first
|
|
13
13
|
// Only match straight quotes, not already-converted curly quotes
|
|
14
14
|
const singleQuoteChars = `'${LEFT_SINGLE_QUOTE}${RIGHT_SINGLE_QUOTE}${MODIFIER_LETTER_APOSTROPHE}`;
|
|
@@ -60,8 +60,9 @@ function convertUnmatchedPluralPossessives(text, sep) {
|
|
|
60
60
|
return match;
|
|
61
61
|
}
|
|
62
62
|
let i = offset - 1;
|
|
63
|
-
while (i >=
|
|
64
|
-
i
|
|
63
|
+
while (i >= sep.length - 1 && text.startsWith(sep, i - sep.length + 1)) {
|
|
64
|
+
i -= sep.length;
|
|
65
|
+
}
|
|
65
66
|
if (i >= 0 && (text[i] === "s" || text[i] === "S")) {
|
|
66
67
|
return MODIFIER_LETTER_APOSTROPHE;
|
|
67
68
|
}
|
|
@@ -70,13 +71,14 @@ function convertUnmatchedPluralPossessives(text, sep) {
|
|
|
70
71
|
}
|
|
71
72
|
/** Convert straight double quotes to curly quotes */
|
|
72
73
|
function convertDoubleQuotes(text, sep) {
|
|
73
|
-
const
|
|
74
|
+
const rawEscSep = escapeStringRegexp(sep);
|
|
75
|
+
const escapedSep = getEscapedSeparator({ separator: sep });
|
|
74
76
|
// Handle empty quotes "" first - match only when not part of adjacent quotes
|
|
75
77
|
// Require word boundary or start/end of string on at least one side
|
|
76
78
|
text = text.replace(/(?<=^|[\s([{])""(?=$|[\s)\]}.!?,;:])/g, `${LEFT_DOUBLE_QUOTE}${RIGHT_DOUBLE_QUOTE}`);
|
|
77
79
|
// Handle whitespace-only quotes " " - require non-quote chars on both sides
|
|
78
80
|
text = text.replace(/(?<=^|[\s([{])"(?<whitespace>\s+)"(?=$|[\s)\]}.!?,;:])/g, `${LEFT_DOUBLE_QUOTE}$<whitespace>${RIGHT_DOUBLE_QUOTE}`);
|
|
79
|
-
const beginningDouble = cachedRegExp(`(?<=^|[\\s\\(\\/\\[\\{\\-${EM_DASH}
|
|
81
|
+
const beginningDouble = cachedRegExp(`(?<=^|[\\s\\(\\/\\[\\{\\-${EM_DASH}]|${escapedSep})(?<beforeChr>${escapedSep}?)["](?<afterChr>(?<sepWithPunct>${escapedSep}[ .,])|(?=${escapedSep}?\\.{3}|${escapedSep}?[^\\s\\)${EM_DASH},!?;:.\\}${rawEscSep}]))`, "gm");
|
|
80
82
|
text = text.replace(beginningDouble, `$<beforeChr>${LEFT_DOUBLE_QUOTE}$<afterChr>`);
|
|
81
83
|
text = text.replace(cachedRegExp(`(?<=\\{)(?<sepSpace>${escapedSep}? )?["]`, "g"), `$<sepSpace>${LEFT_DOUBLE_QUOTE}`);
|
|
82
84
|
const endingDouble = `(?<beforeQuote>[^\\s\\(])["]((?<sepAfter>${escapedSep})?)(?=${escapedSep}|[\\s/\\).,;${EM_DASH}:\\-\\}!?s]|$)`;
|
|
@@ -87,7 +89,7 @@ function convertDoubleQuotes(text, sep) {
|
|
|
87
89
|
}
|
|
88
90
|
/** Apply American or British punctuation style */
|
|
89
91
|
function applyPunctuationStyle(text, sep, style) {
|
|
90
|
-
const escapedSep =
|
|
92
|
+
const escapedSep = getEscapedSeparator({ separator: sep });
|
|
91
93
|
if (style === "american") {
|
|
92
94
|
// Period outside → inside: "Hello". → "Hello."
|
|
93
95
|
const periodOutsideRegex = cachedRegExp(`(?<![${TERMINAL_PUNCTUATION_CLASS}])(?<sepBefore>${escapedSep}?)(?<quote>[${RIGHT_SINGLE_QUOTE}${RIGHT_DOUBLE_QUOTE}])(?<sepAfter>${escapedSep}?)(?!\\.\\.\\.)\\.`, "g");
|
|
@@ -99,11 +101,13 @@ function applyPunctuationStyle(text, sep, style) {
|
|
|
99
101
|
else if (style === "british" || style === "german" || style === "french") {
|
|
100
102
|
// Period inside → outside: "Hello." → "Hello".
|
|
101
103
|
// No terminal punctuation guard — "Stop!." inside is always wrong; move the period out.
|
|
102
|
-
|
|
103
|
-
|
|
104
|
+
// Match ALL consecutive closing quotes so nested quotes like .'" become '". in one pass.
|
|
105
|
+
const periodInsideRegex = cachedRegExp(`(?<sepBefore>${escapedSep}?)\\.(?<quotes>(?:${escapedSep}?[${RIGHT_SINGLE_QUOTE}${RIGHT_DOUBLE_QUOTE}])+)`, "g");
|
|
106
|
+
text = text.replace(periodInsideRegex, "$<sepBefore>$<quotes>.");
|
|
104
107
|
// Comma inside → outside: "Hello," → "Hello",
|
|
105
|
-
|
|
106
|
-
|
|
108
|
+
// Match ALL consecutive closing quotes so nested quotes like ,'" become '", in one pass.
|
|
109
|
+
const commaInsideRegex = cachedRegExp(`,(?<quotes>(?:${escapedSep}?[${RIGHT_DOUBLE_QUOTE}${RIGHT_SINGLE_QUOTE}])+)`, "g");
|
|
110
|
+
text = text.replace(commaInsideRegex, "$<quotes>,");
|
|
107
111
|
}
|
|
108
112
|
return text;
|
|
109
113
|
}
|
|
@@ -135,6 +139,16 @@ function normalizeGermanQuotes(text) {
|
|
|
135
139
|
result += RIGHT_SINGLE_QUOTE;
|
|
136
140
|
singleDepth--;
|
|
137
141
|
}
|
|
142
|
+
else if (ch === RIGHT_DOUBLE_QUOTE) {
|
|
143
|
+
// RDQ is not used in German typography — normalize to straight quote
|
|
144
|
+
// so the pipeline can re-classify it (e.g., from a previous American pass)
|
|
145
|
+
result += '"';
|
|
146
|
+
}
|
|
147
|
+
else if (ch === RIGHT_SINGLE_QUOTE) {
|
|
148
|
+
// RSQ is not used in German typography — normalize to straight quote
|
|
149
|
+
// so the pipeline can re-classify apostrophes vs closing quotes
|
|
150
|
+
result += "'";
|
|
151
|
+
}
|
|
138
152
|
else {
|
|
139
153
|
result += ch;
|
|
140
154
|
}
|
package/dist/quotes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quotes.js","sourceRoot":"","sources":["../src/quotes.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,kBAAkB,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,aAAa,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"quotes.js","sourceRoot":"","sources":["../src/quotes.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,kBAAkB,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,aAAa,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAE3I,MAAM,EACJ,OAAO,EACP,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,0BAA0B,GAC3B,GAAG,eAAe,CAAA;AAEnB,+FAA+F;AAC/F,MAAM,0BAA0B,GAAG,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AAWhE,qEAAqE;AACrE,SAAS,mBAAmB,CAAC,IAAY,EAAE,GAAW;IACpD,MAAM,UAAU,GAAG,mBAAmB,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAA;IAE1D,qEAAqE;IACrE,iEAAiE;IACjE,MAAM,gBAAgB,GAAG,IAAI,iBAAiB,GAAG,kBAAkB,GAAG,0BAA0B,EAAE,CAAA;IAClG,MAAM,iBAAiB,GAAG,IAAI,gBAAgB,MAAM,CAAA;IACpD,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,iBAAiB,SAAS,iBAAiB,GAAG,EAAE,GAAG,CAAC,EAAE,GAAG,iBAAiB,GAAG,kBAAkB,EAAE,CAAC,CAAA;IAC1I,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,iBAAiB,eAAe,iBAAiB,GAAG,EAAE,GAAG,CAAC,EAAE,GAAG,iBAAiB,KAAK,kBAAkB,EAAE,CAAC,CAAA;IAElJ,MAAM,yBAAyB,GAAG,gBAAgB,OAAO,SAAS,CAAA;IAClE,4EAA4E;IAC5E,MAAM,iBAAiB,GAAG,MAAM,UAAU,QAAQ,UAAU,UAAU,yBAAyB,OAAO,CAAA;IAEtG,2EAA2E;IAC3E,6EAA6E;IAC7E,+EAA+E;IAC/E,mFAAmF;IACnF,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,UAAU,UAAU,QAAQ,kBAAkB,OAAO,kBAAkB,QAAQ,UAAU,OAAO,EAAE,IAAI,CAAC,EAAE,GAAG,0BAA0B,IAAI,0BAA0B,EAAE,CAAC,CAAA;IAExM,mEAAmE;IACnE,MAAM,eAAe,GAAG,MAAM,UAAU,KAAK,UAAU,QAAQ,yBAAyB,OAAO,CAAA;IAC/F,MAAM,gBAAgB,GAAG,YAAY,iBAAiB,QAAQ,kBAAkB,IAAI,eAAe,EAAE,CAAA;IACrG,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,gBAAgB,EAAE,IAAI,CAAC,EAAE,0BAA0B,CAAC,CAAA;IAErF,4DAA4D;IAC5D,MAAM,kBAAkB,GAAG,MAAM,UAAU,QAAQ,yBAAyB,OAAO,CAAA;IACnF,MAAM,aAAa,GAAG,YAAY,iBAAiB,SAAS,kBAAkB,EAAE,CAAA;IAChF,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,aAAa,EAAE,IAAI,CAAC,EAAE,kBAAkB,CAAC,CAAA;IAE1E,MAAM,WAAW,GAAG,QAAQ,aAAa,OAAO,kBAAkB,GAAG,0BAA0B,OAAO,UAAU,KAAK,aAAa,IAAI,CAAA;IACtI,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,0BAA0B,CAAC,CAAA;IAEhF,MAAM,mBAAmB,GAAG,OAAO,0BAA0B,IAAI,CAAA;IACjE,MAAM,sBAAsB,GAAG,MAAM,WAAW,KAAK,kBAAkB,GAAG,0BAA0B,IAAI,iBAAiB,EAAE,CAAA;IAC3H,iGAAiG;IACjG,MAAM,eAAe,GAAG,YAAY,CAClC,oBAAoB,mBAAmB,SAAS,iBAAiB,gBAAgB,sBAAsB,IAAI,EAC3G,IAAI,CACL,CAAA;IACD,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,0BAA0B,CAAC,CAAA;IAEhE,MAAM,eAAe,GAAG,6BAA6B,iBAAiB,GAAG,kBAAkB,GAAG,OAAO,WAAW,UAAU,WAAW,UAAU,OAAO,CAAA;IACtJ,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,eAAe,EAAE,IAAI,CAAC,EAAE,mBAAmB,iBAAiB,EAAE,CAAC,CAAA;IAEhG,IAAI,GAAG,iCAAiC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IAEnD,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;;GAIG;AACH,SAAS,iCAAiC,CAAC,IAAY,EAAE,GAAW;IAClE,IAAI,kBAAkB,GAAG,CAAC,CAAA;IAC1B,OAAO,IAAI,CAAC,OAAO,CACjB,YAAY,CAAC,IAAI,iBAAiB,GAAG,kBAAkB,GAAG,EAAE,GAAG,CAAC,EAChE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;QAChB,IAAI,KAAK,KAAK,iBAAiB,EAAE,CAAC;YAChC,kBAAkB,EAAE,CAAA;YACpB,OAAO,KAAK,CAAA;QACd,CAAC;QACD,IAAI,kBAAkB,GAAG,CAAC,EAAE,CAAC;YAC3B,kBAAkB,EAAE,CAAA;YACpB,OAAO,KAAK,CAAA;QACd,CAAC;QACD,IAAI,CAAC,GAAG,MAAM,GAAG,CAAC,CAAA;QAClB,OAAO,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;YACvE,CAAC,IAAI,GAAG,CAAC,MAAM,CAAA;QACjB,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;YACnD,OAAO,0BAA0B,CAAA;QACnC,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC,CACF,CAAA;AACH,CAAC;AAED,qDAAqD;AACrD,SAAS,mBAAmB,CAAC,IAAY,EAAE,GAAW;IACpD,MAAM,SAAS,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAA;IACzC,MAAM,UAAU,GAAG,mBAAmB,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAA;IAE1D,6EAA6E;IAC7E,oEAAoE;IACpE,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,uCAAuC,EAAE,GAAG,iBAAiB,GAAG,kBAAkB,EAAE,CAAC,CAAA;IACzG,4EAA4E;IAC5E,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,yDAAyD,EAAE,GAAG,iBAAiB,gBAAgB,kBAAkB,EAAE,CAAC,CAAA;IAExI,MAAM,eAAe,GAAG,YAAY,CAClC,4BAA4B,OAAO,KAAK,UAAU,iBAAiB,UAAU,oCAAoC,UAAU,aAAa,UAAU,WAAW,UAAU,YAAY,OAAO,YAAY,SAAS,KAAK,EACpN,IAAI,CACL,CAAA;IACD,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,eAAe,iBAAiB,aAAa,CAAC,CAAA;IAEnF,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,uBAAuB,UAAU,SAAS,EAAE,GAAG,CAAC,EAAE,cAAc,iBAAiB,EAAE,CAAC,CAAA;IAErH,MAAM,YAAY,GAAG,4CAA4C,UAAU,SAAS,UAAU,eAAe,OAAO,gBAAgB,CAAA;IACpI,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,YAAY,EAAE,GAAG,CAAC,EAAE,iBAAiB,kBAAkB,aAAa,CAAC,CAAA;IAEtG,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,gBAAgB,UAAU,KAAK,EAAE,GAAG,CAAC,EAAE,GAAG,kBAAkB,WAAW,CAAC,CAAA;IACzG,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,kBAAkB,GAAG,EAAE,IAAI,CAAC,EAAE,kBAAkB,CAAC,CAAA;IAEzF,OAAO,IAAI,CAAA;AACb,CAAC;AAED,kDAAkD;AAClD,SAAS,qBAAqB,CAAC,IAAY,EAAE,GAAW,EAAE,KAAuB;IAC/E,MAAM,UAAU,GAAG,mBAAmB,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAA;IAE1D,IAAI,KAAK,KAAK,UAAU,EAAE,CAAC;QACzB,+CAA+C;QAC/C,MAAM,kBAAkB,GAAG,YAAY,CACrC,QAAQ,0BAA0B,kBAAkB,UAAU,eAAe,kBAAkB,GAAG,kBAAkB,iBAAiB,UAAU,oBAAoB,EACnK,GAAG,CACJ,CAAA;QACD,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,kCAAkC,CAAC,CAAA;QAE3E,8CAA8C;QAC9C,MAAM,iBAAiB,GAAG,YAAY,CACpC,QAAQ,0BAA0B,kBAAkB,UAAU,eAAe,kBAAkB,GAAG,kBAAkB,iBAAiB,UAAU,KAAK,EACpJ,GAAG,CACJ,CAAA;QACD,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,kCAAkC,CAAC,CAAA;IAC5E,CAAC;SAAM,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC3E,+CAA+C;QAC/C,wFAAwF;QACxF,yFAAyF;QACzF,MAAM,iBAAiB,GAAG,YAAY,CACpC,gBAAgB,UAAU,qBAAqB,UAAU,KAAK,kBAAkB,GAAG,kBAAkB,MAAM,EAC3G,GAAG,CACJ,CAAA;QACD,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,wBAAwB,CAAC,CAAA;QAEhE,8CAA8C;QAC9C,yFAAyF;QACzF,MAAM,gBAAgB,GAAG,YAAY,CACnC,iBAAiB,UAAU,KAAK,kBAAkB,GAAG,kBAAkB,MAAM,EAC7E,GAAG,CACJ,CAAA;QACD,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAA;IACrD,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;;GAIG;AACH,SAAS,qBAAqB,CAAC,IAAY;IACzC,MAAM,GAAG,GAAG,eAAe,CAAC,kBAAkB,CAAA;IAC9C,MAAM,GAAG,GAAG,eAAe,CAAC,kBAAkB,CAAA;IAE9C,IAAI,MAAM,GAAG,EAAE,CAAA;IACf,IAAI,WAAW,GAAG,CAAC,CAAA;IACnB,IAAI,WAAW,GAAG,CAAC,CAAA;IAEnB,KAAK,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;QACtB,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YACf,MAAM,IAAI,iBAAiB,CAAA;YAC3B,WAAW,EAAE,CAAA;QACf,CAAC;aAAM,IAAI,EAAE,KAAK,iBAAiB,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;YACvD,MAAM,IAAI,kBAAkB,CAAA;YAC5B,WAAW,EAAE,CAAA;QACf,CAAC;aAAM,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YACtB,MAAM,IAAI,iBAAiB,CAAA;YAC3B,WAAW,EAAE,CAAA;QACf,CAAC;aAAM,IAAI,EAAE,KAAK,iBAAiB,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;YACvD,MAAM,IAAI,kBAAkB,CAAA;YAC5B,WAAW,EAAE,CAAA;QACf,CAAC;aAAM,IAAI,EAAE,KAAK,kBAAkB,EAAE,CAAC;YACrC,qEAAqE;YACrE,2EAA2E;YAC3E,MAAM,IAAI,GAAG,CAAA;QACf,CAAC;aAAM,IAAI,EAAE,KAAK,kBAAkB,EAAE,CAAC;YACrC,qEAAqE;YACrE,gEAAgE;YAChE,MAAM,IAAI,GAAG,CAAA;QACf,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,EAAE,CAAA;QACd,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAED,+GAA+G;AAC/G,SAAS,iBAAiB,CAAC,IAAY;IACrC,OAAO,IAAI;SACR,UAAU,CAAC,iBAAiB,EAAE,eAAe,CAAC,kBAAkB,CAAC;SACjE,UAAU,CAAC,kBAAkB,EAAE,iBAAiB,CAAC;SACjD,UAAU,CAAC,iBAAiB,EAAE,eAAe,CAAC,kBAAkB,CAAC;SACjE,UAAU,CAAC,kBAAkB,EAAE,iBAAiB,CAAC,CAAA;AACtD,CAAC;AAED,iFAAiF;AACjF,SAAS,qBAAqB,CAAC,IAAY;IACzC,OAAO,IAAI;SACR,OAAO,CAAC,YAAY,CAAC,GAAG,eAAe,CAAC,cAAc,GAAG,eAAe,CAAC,IAAI,GAAG,EAAE,GAAG,CAAC,EAAE,iBAAiB,CAAC;SAC1G,OAAO,CAAC,YAAY,CAAC,GAAG,eAAe,CAAC,IAAI,IAAI,eAAe,CAAC,eAAe,EAAE,EAAE,GAAG,CAAC,EAAE,kBAAkB,CAAC,CAAA;AACjH,CAAC;AAED,iFAAiF;AACjF,SAAS,iBAAiB,CAAC,IAAY;IACrC,OAAO,IAAI;SACR,UAAU,CAAC,iBAAiB,EAAE,GAAG,eAAe,CAAC,cAAc,GAAG,eAAe,CAAC,IAAI,EAAE,CAAC;SACzF,UAAU,CAAC,kBAAkB,EAAE,GAAG,eAAe,CAAC,IAAI,GAAG,eAAe,CAAC,eAAe,EAAE,CAAC,CAAA;AAChG,CAAC;AAED,oFAAoF;AACpF,MAAM,qBAAqB,GAA0G;IACnI,MAAM,EAAE,EAAE,SAAS,EAAE,qBAAqB,EAAE,KAAK,EAAE,iBAAiB,EAAE;IACtE,MAAM,EAAE,EAAE,SAAS,EAAE,qBAAqB,EAAE,KAAK,EAAE,iBAAiB,EAAE;CACvE,CAAA;AAED,+EAA+E;AAC/E,SAAS,aAAa,CAAC,IAAY,EAAE,OAAqB;IACxD,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,IAAI,iBAAiB,CAAA;IAClD,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,IAAI,UAAU,CAAA;IAC/D,IAAI,gBAAgB,KAAK,MAAM;QAAE,OAAO,IAAI,CAAA;IAE5C,MAAM,MAAM,GAAG,qBAAqB,CAAC,gBAAgB,CAAC,CAAA;IACtD,IAAI,MAAM;QAAE,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;IAEzC,IAAI,GAAG,mBAAmB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IACrC,IAAI,GAAG,mBAAmB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IACrC,IAAI,GAAG,qBAAqB,CAAC,IAAI,EAAE,GAAG,EAAE,gBAAgB,CAAC,CAAA;IAEzD,IAAI,MAAM;QAAE,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAErC,OAAO,IAAI,CAAA;AACb,CAAC;AAED,+CAA+C;AAC/C,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,UAAwB,EAAE;IACjE,kEAAkE;IAClE,oEAAoE;IACpE,8DAA8D;IAC9D,OAAO,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,UAAU,CAAC,0BAA0B,EAAE,kBAAkB,CAAC,CAAA;AAChG,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY,EAAE,UAAwB,EAAE;IAC1E,OAAO,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;AACrC,CAAC"}
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAkBxE;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAkBxE;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAanF;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,GAAE,MAA0B,GAAG,MAAM,CAQ3F;AAED;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,SAAS,GAAE,MAA0B,EACrC,aAAa,GAAE,MAAoB,GAClC,IAAI,CAUN"}
|
package/dist/utils.js
CHANGED
|
@@ -41,17 +41,20 @@ export function assertSeparatorAbsent(textValues, separator) {
|
|
|
41
41
|
for (const value of textValues) {
|
|
42
42
|
if (!value.includes(separator))
|
|
43
43
|
continue;
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
const codePoints = [...separator]
|
|
45
|
+
.map(ch => `U+${ch.codePointAt(0).toString(16).toUpperCase().padStart(4, "0")}`)
|
|
46
|
+
.join(" ");
|
|
47
|
+
throw new Error(`Text contains the separator sequence ${codePoints} which is used internally by punctilio ` +
|
|
48
|
+
`to track element boundaries. Pass a different separator via the "separator" option.\n` +
|
|
47
49
|
`Text: ${formatErrorString(value, "input")}`);
|
|
48
50
|
}
|
|
49
51
|
}
|
|
50
52
|
export function countSeparators(text, separator = DEFAULT_SEPARATOR) {
|
|
51
53
|
let count = 0;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
54
|
+
let index = 0;
|
|
55
|
+
while ((index = text.indexOf(separator, index)) !== -1) {
|
|
56
|
+
count++;
|
|
57
|
+
index += separator.length;
|
|
55
58
|
}
|
|
56
59
|
return count;
|
|
57
60
|
}
|
package/dist/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAElD,qEAAqE;AACrE,MAAM,sBAAsB,GAAG,IAAI,CAAA;AAEnC;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAe,EAAE,KAAa;IAC9D,IAAI,OAAO,CAAC,MAAM,IAAI,sBAAsB,EAAE,CAAC;QAC7C,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;IAChC,CAAC;IAED,yDAAyD;IACzD,IAAI,CAAC;QACH,IAAI,OAAO,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,KAAK,UAAU,EAAE,CAAC;YAC5D,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAC7B,gBAAgB,KAAK,kBAAkB,OAAO,CAAC,MAAM,cAAc,OAAO,MAAM,CACjF,CAAA;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,gDAAgD;IAClD,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,sBAAsB,CAAC,CAAA;IAC1D,OAAO,IAAI,KAAK,KAAK,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,OAAO,CAAC,MAAM,gBAAgB,CAAA;AACtF,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CAAC,UAAoB,EAAE,SAAiB;IAC3E,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,SAAQ;QAExC,MAAM,SAAS,GAAG,KAAK,
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAElD,qEAAqE;AACrE,MAAM,sBAAsB,GAAG,IAAI,CAAA;AAEnC;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAe,EAAE,KAAa;IAC9D,IAAI,OAAO,CAAC,MAAM,IAAI,sBAAsB,EAAE,CAAC;QAC7C,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;IAChC,CAAC;IAED,yDAAyD;IACzD,IAAI,CAAC;QACH,IAAI,OAAO,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,KAAK,UAAU,EAAE,CAAC;YAC5D,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAC7B,gBAAgB,KAAK,kBAAkB,OAAO,CAAC,MAAM,cAAc,OAAO,MAAM,CACjF,CAAA;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,gDAAgD;IAClD,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,sBAAsB,CAAC,CAAA;IAC1D,OAAO,IAAI,KAAK,KAAK,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,OAAO,CAAC,MAAM,gBAAgB,CAAA;AACtF,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CAAC,UAAoB,EAAE,SAAiB;IAC3E,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,SAAQ;QAExC,MAAM,UAAU,GAAG,CAAC,GAAG,SAAS,CAAC;aAC9B,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,WAAW,CAAC,CAAC,CAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;aAChF,IAAI,CAAC,GAAG,CAAC,CAAA;QACZ,MAAM,IAAI,KAAK,CACb,wCAAwC,UAAU,yCAAyC;YAC3F,uFAAuF;YACvF,SAAS,iBAAiB,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,CAC7C,CAAA;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,YAAoB,iBAAiB;IACjF,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QACvD,KAAK,EAAE,CAAA;QACP,KAAK,IAAI,SAAS,CAAC,MAAM,CAAA;IAC3B,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,6BAA6B,CAC3C,QAAgB,EAChB,WAAmB,EACnB,YAAoB,iBAAiB,EACrC,gBAAwB,WAAW;IAEnC,MAAM,aAAa,GAAG,eAAe,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAA;IAC1D,MAAM,gBAAgB,GAAG,eAAe,CAAC,WAAW,EAAE,SAAS,CAAC,CAAA;IAChE,IAAI,aAAa,KAAK,gBAAgB,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CACb,GAAG,aAAa,sCAAsC,aAAa,SAAS,gBAAgB,KAAK;YACjG,4GAA4G;YAC5G,gDAAgD,CACjD,CAAA;IACH,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
package/src/constants.ts
CHANGED
|
@@ -122,23 +122,28 @@ export const TERMINAL_PUNCTUATION = [
|
|
|
122
122
|
export const LATIN_LETTERS = "A-Za-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u00FF\\u0100-\\u017F\\u0180-\\u024F"
|
|
123
123
|
|
|
124
124
|
/**
|
|
125
|
-
* Default separator
|
|
126
|
-
* Uses Unicode Private Use Area
|
|
125
|
+
* Default separator for text spanning HTML elements.
|
|
126
|
+
* Uses a two-character sentinel from the Unicode Private Use Area
|
|
127
|
+
* (U+E000 U+E001) to avoid collisions with CJK fonts, Apple emoji
|
|
128
|
+
* internals, PDF-to-text output, and icon fonts that repurpose U+E000.
|
|
127
129
|
*/
|
|
128
|
-
export const DEFAULT_SEPARATOR = "\uE000"
|
|
130
|
+
export const DEFAULT_SEPARATOR = "\uE000\uE001"
|
|
129
131
|
export const ESCAPED_DEFAULT_SEPARATOR = escapeStringRegexp(DEFAULT_SEPARATOR)
|
|
130
132
|
|
|
131
133
|
/**
|
|
132
|
-
* Returns the regex-escaped separator string for the given options
|
|
133
|
-
*
|
|
134
|
+
* Returns the regex-escaped separator string for the given options,
|
|
135
|
+
* wrapped in a non-capturing group so that quantifiers like `?` and `*`
|
|
136
|
+
* apply to the entire separator sequence (critical for multi-character
|
|
137
|
+
* separators like the default U+E000 U+E001).
|
|
134
138
|
*
|
|
135
139
|
* @param options - Object with an optional `separator` field
|
|
136
|
-
* @returns Regex-escaped separator string
|
|
140
|
+
* @returns Regex-escaped separator string wrapped in `(?:...)`
|
|
137
141
|
*/
|
|
138
142
|
export function getEscapedSeparator(options: { separator?: string }): string {
|
|
139
|
-
|
|
143
|
+
const escaped = options.separator
|
|
140
144
|
? escapeStringRegexp(options.separator)
|
|
141
145
|
: ESCAPED_DEFAULT_SEPARATOR
|
|
146
|
+
return `(?:${escaped})`
|
|
142
147
|
}
|
|
143
148
|
|
|
144
149
|
/**
|
|
@@ -197,22 +202,28 @@ export const SPACE_CHARS = ` ${UNICODE_SYMBOLS.NBSP}`
|
|
|
197
202
|
* Creates a lookbehind pattern that matches after whitespace, separator, or start of string.
|
|
198
203
|
* Used for arrow patterns and other constructs that should appear at word boundaries.
|
|
199
204
|
*
|
|
200
|
-
*
|
|
201
|
-
*
|
|
205
|
+
* Uses alternation instead of a character class so that multi-character
|
|
206
|
+
* separators are matched as a sequence, not as individual characters.
|
|
207
|
+
*
|
|
208
|
+
* @param escapedSeparator - Regex-escaped separator string (may be grouped)
|
|
209
|
+
* @returns Pattern string: `(?<=\\s|${sep}|^)`
|
|
202
210
|
*/
|
|
203
211
|
export function spaceBoundaryStart(escapedSeparator: string): string {
|
|
204
|
-
return `(
|
|
212
|
+
return `(?<=\\s|${escapedSeparator}|^)`
|
|
205
213
|
}
|
|
206
214
|
|
|
207
215
|
/**
|
|
208
216
|
* Creates a lookahead pattern that matches before whitespace, separator, or end of string.
|
|
209
217
|
* Used for arrow patterns and other constructs that should appear at word boundaries.
|
|
210
218
|
*
|
|
211
|
-
*
|
|
212
|
-
*
|
|
219
|
+
* Uses alternation instead of a character class so that multi-character
|
|
220
|
+
* separators are matched as a sequence, not as individual characters.
|
|
221
|
+
*
|
|
222
|
+
* @param escapedSeparator - Regex-escaped separator string (may be grouped)
|
|
223
|
+
* @returns Pattern string: `(?=\\s|${sep}|$)`
|
|
213
224
|
*/
|
|
214
225
|
export function spaceBoundaryEnd(escapedSeparator: string): string {
|
|
215
|
-
return `(
|
|
226
|
+
return `(?=\\s|${escapedSeparator}|$)`
|
|
216
227
|
}
|
|
217
228
|
|
|
218
229
|
/**
|
package/src/dashes.ts
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* Dash transformation: hyphens → em-dashes, en-dashes, minus signs.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import escapeStringRegexp from "escape-string-regexp"
|
|
6
5
|
import { UNICODE_SYMBOLS, DEFAULT_SEPARATOR, LATIN_LETTERS, wordBoundaryStart, wordBoundaryEnd, getEscapedSeparator, cachedRegExp } from "./constants.js"
|
|
7
6
|
|
|
8
7
|
export type DashStyle = "american" | "british" | "none"
|
|
@@ -150,7 +149,7 @@ export function minusReplace(text: string, options: DashOptions = {}): string {
|
|
|
150
149
|
function convertParentheticalDashes(text: string, sep: string, style: DashStyle): string {
|
|
151
150
|
const localizedDash = style === "british" ? EN_DASH : EM_DASH
|
|
152
151
|
const maybeSpace = style === "british" ? " " : ""
|
|
153
|
-
const escapedSep =
|
|
152
|
+
const escapedSep = getEscapedSeparator({ separator: sep })
|
|
154
153
|
|
|
155
154
|
// Convert spaced dashes: "word - word" or "word — word"
|
|
156
155
|
// When a separator follows the dash, preserve trailing spaces (they belong to the next text segment).
|
|
@@ -198,7 +197,7 @@ function convertParentheticalDashes(text: string, sep: string, style: DashStyle)
|
|
|
198
197
|
* allows a space after the dash: "Don't inter— Hey! Who threw that?"
|
|
199
198
|
*/
|
|
200
199
|
function normalizeEmDashSpacing(text: string, sep: string): string {
|
|
201
|
-
const escapedSep =
|
|
200
|
+
const escapedSep = getEscapedSeparator({ separator: sep })
|
|
202
201
|
|
|
203
202
|
// Remove all spaces around em-dashes
|
|
204
203
|
text = text.replace(
|
package/src/index.ts
CHANGED
|
@@ -222,14 +222,19 @@ const defaultOpts: Required<Omit<TransformOptions, "separator">> = {
|
|
|
222
222
|
export function transform(text: string, options: TransformOptions = {}): string {
|
|
223
223
|
const separator = options.separator ?? DEFAULT_SEPARATOR
|
|
224
224
|
|
|
225
|
-
// Validate separator: must be
|
|
226
|
-
//
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
)
|
|
225
|
+
// Validate separator: must be non-empty and contain only BMP characters.
|
|
226
|
+
// for...of iterates by code point; surrogate pairs (non-BMP) yield a
|
|
227
|
+
// two-UTF16-unit string, so ch.length > 1 detects them.
|
|
228
|
+
if (separator.length === 0) {
|
|
229
|
+
throw new Error("Invalid separator: must not be empty.")
|
|
230
|
+
}
|
|
231
|
+
for (const ch of separator) {
|
|
232
|
+
if (ch.length > 1) {
|
|
233
|
+
throw new Error(
|
|
234
|
+
`Invalid separator: must contain only BMP characters (no characters outside the Basic Multilingual Plane). ` +
|
|
235
|
+
`Received "${separator}" which contains a non-BMP character.`
|
|
236
|
+
)
|
|
237
|
+
}
|
|
233
238
|
}
|
|
234
239
|
|
|
235
240
|
const original = text
|
package/src/nbsp.ts
CHANGED
|
@@ -135,8 +135,9 @@ export function nbspBetweenNumberAndUnit(text: string, options: NbspOptions = {}
|
|
|
135
135
|
*/
|
|
136
136
|
export function nbspBeforeLastWord(text: string, options: NbspOptions = {}): string {
|
|
137
137
|
const sep = getEscapedSeparator(options)
|
|
138
|
+
// Use alternation instead of character classes for multi-char separator support
|
|
138
139
|
const pattern = cachedRegExp(
|
|
139
|
-
`(
|
|
140
|
+
`(?<=\\w|${sep})${SPACE}(?<lastWord>(?:(?!\\s)(?!${sep}).){1,10})(?<ending>${sep}?(?:\\n\\n|$))`,
|
|
140
141
|
"g"
|
|
141
142
|
)
|
|
142
143
|
return text.replace(pattern, `${NBSP}$<lastWord>$<ending>`)
|
package/src/quotes.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import escapeStringRegexp from "escape-string-regexp"
|
|
6
|
-
import { UNICODE_SYMBOLS, DEFAULT_SEPARATOR, LATIN_LETTERS, TERMINAL_PUNCTUATION, cachedRegExp } from "./constants.js"
|
|
6
|
+
import { UNICODE_SYMBOLS, DEFAULT_SEPARATOR, LATIN_LETTERS, TERMINAL_PUNCTUATION, getEscapedSeparator, cachedRegExp } from "./constants.js"
|
|
7
7
|
|
|
8
8
|
const {
|
|
9
9
|
EM_DASH,
|
|
@@ -28,7 +28,7 @@ export interface QuoteOptions {
|
|
|
28
28
|
|
|
29
29
|
/** Convert straight single quotes to curly quotes and apostrophes */
|
|
30
30
|
function convertSingleQuotes(text: string, sep: string): string {
|
|
31
|
-
const escapedSep =
|
|
31
|
+
const escapedSep = getEscapedSeparator({ separator: sep })
|
|
32
32
|
|
|
33
33
|
// Handle empty single quotes '' and whitespace-only quotes ' ' first
|
|
34
34
|
// Only match straight quotes, not already-converted curly quotes
|
|
@@ -96,7 +96,9 @@ function convertUnmatchedPluralPossessives(text: string, sep: string): string {
|
|
|
96
96
|
return match
|
|
97
97
|
}
|
|
98
98
|
let i = offset - 1
|
|
99
|
-
while (i >=
|
|
99
|
+
while (i >= sep.length - 1 && text.startsWith(sep, i - sep.length + 1)) {
|
|
100
|
+
i -= sep.length
|
|
101
|
+
}
|
|
100
102
|
if (i >= 0 && (text[i] === "s" || text[i] === "S")) {
|
|
101
103
|
return MODIFIER_LETTER_APOSTROPHE
|
|
102
104
|
}
|
|
@@ -107,7 +109,8 @@ function convertUnmatchedPluralPossessives(text: string, sep: string): string {
|
|
|
107
109
|
|
|
108
110
|
/** Convert straight double quotes to curly quotes */
|
|
109
111
|
function convertDoubleQuotes(text: string, sep: string): string {
|
|
110
|
-
const
|
|
112
|
+
const rawEscSep = escapeStringRegexp(sep)
|
|
113
|
+
const escapedSep = getEscapedSeparator({ separator: sep })
|
|
111
114
|
|
|
112
115
|
// Handle empty quotes "" first - match only when not part of adjacent quotes
|
|
113
116
|
// Require word boundary or start/end of string on at least one side
|
|
@@ -116,7 +119,7 @@ function convertDoubleQuotes(text: string, sep: string): string {
|
|
|
116
119
|
text = text.replace(/(?<=^|[\s([{])"(?<whitespace>\s+)"(?=$|[\s)\]}.!?,;:])/g, `${LEFT_DOUBLE_QUOTE}$<whitespace>${RIGHT_DOUBLE_QUOTE}`)
|
|
117
120
|
|
|
118
121
|
const beginningDouble = cachedRegExp(
|
|
119
|
-
`(?<=^|[\\s\\(\\/\\[\\{\\-${EM_DASH}
|
|
122
|
+
`(?<=^|[\\s\\(\\/\\[\\{\\-${EM_DASH}]|${escapedSep})(?<beforeChr>${escapedSep}?)["](?<afterChr>(?<sepWithPunct>${escapedSep}[ .,])|(?=${escapedSep}?\\.{3}|${escapedSep}?[^\\s\\)${EM_DASH},!?;:.\\}${rawEscSep}]))`,
|
|
120
123
|
"gm"
|
|
121
124
|
)
|
|
122
125
|
text = text.replace(beginningDouble, `$<beforeChr>${LEFT_DOUBLE_QUOTE}$<afterChr>`)
|
|
@@ -134,7 +137,7 @@ function convertDoubleQuotes(text: string, sep: string): string {
|
|
|
134
137
|
|
|
135
138
|
/** Apply American or British punctuation style */
|
|
136
139
|
function applyPunctuationStyle(text: string, sep: string, style: PunctuationStyle): string {
|
|
137
|
-
const escapedSep =
|
|
140
|
+
const escapedSep = getEscapedSeparator({ separator: sep })
|
|
138
141
|
|
|
139
142
|
if (style === "american") {
|
|
140
143
|
// Period outside → inside: "Hello". → "Hello."
|
|
@@ -153,18 +156,20 @@ function applyPunctuationStyle(text: string, sep: string, style: PunctuationStyl
|
|
|
153
156
|
} else if (style === "british" || style === "german" || style === "french") {
|
|
154
157
|
// Period inside → outside: "Hello." → "Hello".
|
|
155
158
|
// No terminal punctuation guard — "Stop!." inside is always wrong; move the period out.
|
|
159
|
+
// Match ALL consecutive closing quotes so nested quotes like .'" become '". in one pass.
|
|
156
160
|
const periodInsideRegex = cachedRegExp(
|
|
157
|
-
`(?<sepBefore>${escapedSep}?)\\.(?<
|
|
161
|
+
`(?<sepBefore>${escapedSep}?)\\.(?<quotes>(?:${escapedSep}?[${RIGHT_SINGLE_QUOTE}${RIGHT_DOUBLE_QUOTE}])+)`,
|
|
158
162
|
"g"
|
|
159
163
|
)
|
|
160
|
-
text = text.replace(periodInsideRegex, "$<sepBefore>$<
|
|
164
|
+
text = text.replace(periodInsideRegex, "$<sepBefore>$<quotes>.")
|
|
161
165
|
|
|
162
166
|
// Comma inside → outside: "Hello," → "Hello",
|
|
167
|
+
// Match ALL consecutive closing quotes so nested quotes like ,'" become '", in one pass.
|
|
163
168
|
const commaInsideRegex = cachedRegExp(
|
|
164
|
-
`,(?<
|
|
169
|
+
`,(?<quotes>(?:${escapedSep}?[${RIGHT_DOUBLE_QUOTE}${RIGHT_SINGLE_QUOTE}])+)`,
|
|
165
170
|
"g"
|
|
166
171
|
)
|
|
167
|
-
text = text.replace(commaInsideRegex, "$<
|
|
172
|
+
text = text.replace(commaInsideRegex, "$<quotes>,")
|
|
168
173
|
}
|
|
169
174
|
return text
|
|
170
175
|
}
|
|
@@ -195,6 +200,14 @@ function normalizeGermanQuotes(text: string): string {
|
|
|
195
200
|
} else if (ch === LEFT_SINGLE_QUOTE && singleDepth > 0) {
|
|
196
201
|
result += RIGHT_SINGLE_QUOTE
|
|
197
202
|
singleDepth--
|
|
203
|
+
} else if (ch === RIGHT_DOUBLE_QUOTE) {
|
|
204
|
+
// RDQ is not used in German typography — normalize to straight quote
|
|
205
|
+
// so the pipeline can re-classify it (e.g., from a previous American pass)
|
|
206
|
+
result += '"'
|
|
207
|
+
} else if (ch === RIGHT_SINGLE_QUOTE) {
|
|
208
|
+
// RSQ is not used in German typography — normalize to straight quote
|
|
209
|
+
// so the pipeline can re-classify apostrophes vs closing quotes
|
|
210
|
+
result += "'"
|
|
198
211
|
} else {
|
|
199
212
|
result += ch
|
|
200
213
|
}
|
package/src/tests/index.test.ts
CHANGED
|
@@ -443,6 +443,19 @@ describe("transform", () => {
|
|
|
443
443
|
expect(second).toBe(first)
|
|
444
444
|
})
|
|
445
445
|
|
|
446
|
+
it.each([
|
|
447
|
+
// Nested quotes with period — tests the multi-quote-jump fix
|
|
448
|
+
[`"She said, 'Hello.'"`, "british" as const],
|
|
449
|
+
[`"She said, 'Hello.'"`, "german" as const],
|
|
450
|
+
[`"She said, 'Hello.'"`, "french" as const],
|
|
451
|
+
// Leading apostrophe — tests the German RSQ normalization fix
|
|
452
|
+
[`'Twas the night before Christmas.`, "german" as const],
|
|
453
|
+
])('is idempotent across styles: "%s" [%s]', (input, style) => {
|
|
454
|
+
const first = transform(input, { punctuationStyle: style })
|
|
455
|
+
const second = transform(first, { punctuationStyle: style })
|
|
456
|
+
expect(second).toBe(first)
|
|
457
|
+
})
|
|
458
|
+
|
|
446
459
|
it.each([
|
|
447
460
|
`${LEFT_DOUBLE_QUOTE}Hello${RIGHT_DOUBLE_QUOTE}`,
|
|
448
461
|
`word${EM_DASH}word`,
|
|
@@ -558,18 +571,17 @@ describe("transform", () => {
|
|
|
558
571
|
|
|
559
572
|
describe("separator validation", () => {
|
|
560
573
|
const invalidSeparators = [
|
|
561
|
-
["🎉", "emoji (
|
|
562
|
-
["ab", "multi-character"],
|
|
574
|
+
["🎉", "emoji (non-BMP)"],
|
|
563
575
|
["", "empty string"],
|
|
564
576
|
] as const
|
|
565
577
|
|
|
566
578
|
it.each(invalidSeparators)("rejects %s separator (%s)", (sep) => {
|
|
567
579
|
expect(() => transform('"Hello"', { separator: sep, nbsp: false })).toThrow(
|
|
568
|
-
/Invalid separator
|
|
580
|
+
/Invalid separator/
|
|
569
581
|
)
|
|
570
582
|
})
|
|
571
583
|
|
|
572
|
-
const validSeparators = ["\uE000", "|", "\u2603"] // Default, pipe, snowman
|
|
584
|
+
const validSeparators = ["\uE000\uE001", "\uE000", "|", "\u2603", "ab"] // Default, single PUA, pipe, snowman, multi-char
|
|
573
585
|
|
|
574
586
|
it.each(validSeparators)("accepts '%s' as separator", (sep) => {
|
|
575
587
|
expect(() => transform('"Hello"', { separator: sep, nbsp: false })).not.toThrow()
|
|
@@ -584,6 +596,25 @@ describe("transform", () => {
|
|
|
584
596
|
})
|
|
585
597
|
})
|
|
586
598
|
|
|
599
|
+
describe("multi-character separator behavior", () => {
|
|
600
|
+
const sep = "\uE000\uE001"
|
|
601
|
+
|
|
602
|
+
it.each([
|
|
603
|
+
["quotes with separator at boundary", `${sep}"Hello"`, `${sep}${LEFT_DOUBLE_QUOTE}Hello${RIGHT_DOUBLE_QUOTE}`],
|
|
604
|
+
["em-dash with adjacent separators", `word${sep} - ${sep}word`, `word${sep}${EM_DASH}${sep}word`],
|
|
605
|
+
["ellipsis with separator between dots", `a.${sep}.${sep}.`, `a\u2026${sep}${sep}`],
|
|
606
|
+
["nbsp before last word with trailing separator", `Hello world${sep}`, `Hello${NBSP}world${sep}`],
|
|
607
|
+
])("%s", (_desc, input, expected) => {
|
|
608
|
+
expect(transform(input, { separator: sep, nbsp: true })).toBe(expected)
|
|
609
|
+
})
|
|
610
|
+
|
|
611
|
+
it("preserves separator count through transform", () => {
|
|
612
|
+
const input = `${sep}"Hello"${sep} -- ${sep}world${sep}`
|
|
613
|
+
const result = transform(input, { separator: sep })
|
|
614
|
+
expect(countSeparators(result, sep)).toBe(countSeparators(input, sep))
|
|
615
|
+
})
|
|
616
|
+
})
|
|
617
|
+
|
|
587
618
|
describe("Unicode preservation", () => {
|
|
588
619
|
it.each([
|
|
589
620
|
["emoji", '"Hello 👋 World"', `${LEFT_DOUBLE_QUOTE}Hello 👋 World${RIGHT_DOUBLE_QUOTE}`],
|
package/src/tests/quotes.test.ts
CHANGED
|
@@ -653,6 +653,8 @@ describe("niceQuotes", () => {
|
|
|
653
653
|
[`"She said 'hello'"`, `${DOUBLE_LOW_9_QUOTE}She said ${SINGLE_LOW_9_QUOTE}hello${LEFT_SINGLE_QUOTE}${LEFT_DOUBLE_QUOTE}`, { punctuationStyle: "german" as const }],
|
|
654
654
|
// French punctuation placement
|
|
655
655
|
['"Bonjour," dit-il.', `${LEFT_GUILLEMET}${NBSP}Bonjour${NBSP}${RIGHT_GUILLEMET}, dit-il.`, { punctuationStyle: "french" as const }],
|
|
656
|
+
// German leading apostrophe ('Twas)
|
|
657
|
+
["'Twas the night", `${RIGHT_SINGLE_QUOTE}Twas the night`, { punctuationStyle: "german" as const }],
|
|
656
658
|
])("locale quotes: %s → %s", (input, expected, options) => {
|
|
657
659
|
it("transforms correctly", () => {
|
|
658
660
|
expect(niceQuotes(input, options)).toBe(expected)
|
|
@@ -663,9 +665,39 @@ describe("niceQuotes", () => {
|
|
|
663
665
|
[`${DOUBLE_LOW_9_QUOTE}Guten Tag${LEFT_DOUBLE_QUOTE}`, { punctuationStyle: "german" as const }],
|
|
664
666
|
[`${SINGLE_LOW_9_QUOTE}Hallo${LEFT_SINGLE_QUOTE}`, { punctuationStyle: "german" as const }],
|
|
665
667
|
[`${LEFT_GUILLEMET}${NBSP}Bonjour${NBSP}${RIGHT_GUILLEMET}`, { punctuationStyle: "french" as const }],
|
|
668
|
+
// German apostrophe idempotency — RSQ must not flip to LSQ on re-processing
|
|
669
|
+
[`${RIGHT_SINGLE_QUOTE}Twas the night`, { punctuationStyle: "german" as const }],
|
|
666
670
|
])("locale output is idempotent: %s", (input, options) => {
|
|
667
671
|
expect(niceQuotes(input, options)).toBe(input)
|
|
668
672
|
})
|
|
673
|
+
|
|
674
|
+
it("german normalizer re-classifies pre-existing RDQ", () => {
|
|
675
|
+
// RDQ is not used in German — should become German closing double
|
|
676
|
+
const input = `${LEFT_DOUBLE_QUOTE}Hello${RIGHT_DOUBLE_QUOTE}`
|
|
677
|
+
expect(niceQuotes(input, { punctuationStyle: "german" })).toBe(`${DOUBLE_LOW_9_QUOTE}Hello${LEFT_DOUBLE_QUOTE}`)
|
|
678
|
+
})
|
|
679
|
+
})
|
|
680
|
+
|
|
681
|
+
describe("nested quote punctuation placement", () => {
|
|
682
|
+
it.each([
|
|
683
|
+
// Period moves past all closing quotes in one pass
|
|
684
|
+
[
|
|
685
|
+
`${LEFT_DOUBLE_QUOTE}He said, ${LEFT_SINGLE_QUOTE}Hello.${RIGHT_SINGLE_QUOTE}${RIGHT_DOUBLE_QUOTE}`,
|
|
686
|
+
`${LEFT_DOUBLE_QUOTE}He said, ${LEFT_SINGLE_QUOTE}Hello${RIGHT_SINGLE_QUOTE}${RIGHT_DOUBLE_QUOTE}.`,
|
|
687
|
+
],
|
|
688
|
+
// Comma moves past all closing quotes in one pass
|
|
689
|
+
[
|
|
690
|
+
`${LEFT_DOUBLE_QUOTE}He said, ${LEFT_SINGLE_QUOTE}Hello,${RIGHT_SINGLE_QUOTE}${RIGHT_DOUBLE_QUOTE} she replied.`,
|
|
691
|
+
`${LEFT_DOUBLE_QUOTE}He said, ${LEFT_SINGLE_QUOTE}Hello${RIGHT_SINGLE_QUOTE}${RIGHT_DOUBLE_QUOTE}, she replied.`,
|
|
692
|
+
],
|
|
693
|
+
])("british moves past all closing quotes: %s → %s", (input, expected) => {
|
|
694
|
+
expect(niceQuotes(input, { punctuationStyle: "british" })).toBe(expected)
|
|
695
|
+
})
|
|
696
|
+
|
|
697
|
+
it.each(["british", "german", "french"] as const)("%s nested quote period is idempotent", (style) => {
|
|
698
|
+
const first = niceQuotes(`"He said, 'Hello.'"`, { punctuationStyle: style })
|
|
699
|
+
expect(niceQuotes(first, { punctuationStyle: style })).toBe(first)
|
|
700
|
+
})
|
|
669
701
|
})
|
|
670
702
|
|
|
671
703
|
describe("pathological inputs", () => {
|
package/src/tests/utils.test.ts
CHANGED
|
@@ -10,9 +10,9 @@ describe("assertSeparatorAbsent", () => {
|
|
|
10
10
|
})
|
|
11
11
|
|
|
12
12
|
it.each([
|
|
13
|
-
["default separator", [`hello${DEFAULT_SEPARATOR}world`], DEFAULT_SEPARATOR, /U\+E000/],
|
|
13
|
+
["default separator", [`hello${DEFAULT_SEPARATOR}world`], DEFAULT_SEPARATOR, /U\+E000 U\+E001/],
|
|
14
14
|
["custom separator", ["hello|world"], "|", /U\+007C/],
|
|
15
|
-
["separator in middle element", ["clean", `has${DEFAULT_SEPARATOR}sep`, "also clean"], DEFAULT_SEPARATOR, /separator
|
|
15
|
+
["separator in middle element", ["clean", `has${DEFAULT_SEPARATOR}sep`, "also clean"], DEFAULT_SEPARATOR, /separator sequence/],
|
|
16
16
|
])("throws: %s", (_desc, values, separator, expectedPattern) => {
|
|
17
17
|
expect(() => assertSeparatorAbsent(values, separator)).toThrow(expectedPattern)
|
|
18
18
|
})
|
package/src/utils.ts
CHANGED
|
@@ -48,10 +48,12 @@ export function assertSeparatorAbsent(textValues: string[], separator: string):
|
|
|
48
48
|
for (const value of textValues) {
|
|
49
49
|
if (!value.includes(separator)) continue
|
|
50
50
|
|
|
51
|
-
const
|
|
51
|
+
const codePoints = [...separator]
|
|
52
|
+
.map(ch => `U+${ch.codePointAt(0)!.toString(16).toUpperCase().padStart(4, "0")}`)
|
|
53
|
+
.join(" ")
|
|
52
54
|
throw new Error(
|
|
53
|
-
`Text contains the separator
|
|
54
|
-
`to track element boundaries. Pass a different
|
|
55
|
+
`Text contains the separator sequence ${codePoints} which is used internally by punctilio ` +
|
|
56
|
+
`to track element boundaries. Pass a different separator via the "separator" option.\n` +
|
|
55
57
|
`Text: ${formatErrorString(value, "input")}`
|
|
56
58
|
)
|
|
57
59
|
}
|
|
@@ -59,8 +61,10 @@ export function assertSeparatorAbsent(textValues: string[], separator: string):
|
|
|
59
61
|
|
|
60
62
|
export function countSeparators(text: string, separator: string = DEFAULT_SEPARATOR): number {
|
|
61
63
|
let count = 0
|
|
62
|
-
|
|
63
|
-
|
|
64
|
+
let index = 0
|
|
65
|
+
while ((index = text.indexOf(separator, index)) !== -1) {
|
|
66
|
+
count++
|
|
67
|
+
index += separator.length
|
|
64
68
|
}
|
|
65
69
|
return count
|
|
66
70
|
}
|