punctilio 4.1.0 → 4.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/README.md +0 -4
- package/dist/quotes.d.ts.map +1 -1
- package/dist/quotes.js +143 -35
- package/dist/quotes.js.map +1 -1
- package/package.json +1 -1
- package/src/quotes.ts +151 -44
package/README.md
CHANGED
|
@@ -74,11 +74,7 @@ _Note on benchmark construction: I assembled the initial cases myself. I then so
|
|
|
74
74
|
| Input | Behavior | Why |
|
|
75
75
|
| :--- | :--- | :--- |
|
|
76
76
|
| `'99 but 5' clearance` | `5'` stays straight | A leading apostrophe and an opening quote are indistinguishable without semantics |
|
|
77
|
-
| Single-quoted passage over 1,000 chars | Opener becomes an apostrophe | The opener-vs-apostrophe test scans only 1,000 characters ahead for the closing quote |
|
|
78
|
-
| `"?"` with a distant closer | Quote stays straight | Quoted-punctuation detection looks only 50 characters ahead for the closing quote |
|
|
79
|
-
| `word’”’”’.` (5+ nested closers) | 5th-level punctuation not moved | Punctuation placement handles at most 4 consecutive closing quotes |
|
|
80
77
|
|
|
81
|
-
Several of these bounds (the 1,000- and 50-character lookaheads, the 4-quote nesting cap) exist to keep the quote regexes provably linear-time; they could be lifted by a single-pass quote scanner.
|
|
82
78
|
|
|
83
79
|
## Test suite
|
|
84
80
|
|
package/dist/quotes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quotes.d.ts","sourceRoot":"","sources":["../src/quotes.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"quotes.d.ts","sourceRoot":"","sources":["../src/quotes.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,kBAAkB,8DAA+D,CAAA;AAC9F,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAA;AAElE,MAAM,WAAW,YAAY;IAC3B,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;CACpC;AAgZD,+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
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { cachedRegExp, DEFAULT_SEPARATOR, escapeStringRegexp, getEscapedSeparator, LATIN_LETTERS, TERMINAL_PUNCTUATION, UNICODE_SYMBOLS } from "./constants.js";
|
|
2
2
|
const { EM_DASH, LEFT_DOUBLE_QUOTE, RIGHT_DOUBLE_QUOTE, LEFT_SINGLE_QUOTE, RIGHT_SINGLE_QUOTE, MODIFIER_LETTER_APOSTROPHE, } = UNICODE_SYMBOLS;
|
|
3
|
-
const TERMINAL_PUNCTUATION_CLASS = TERMINAL_PUNCTUATION.join("");
|
|
4
|
-
// Bounded to keep punctuation-placement regexes linear on pathological inputs.
|
|
5
|
-
const MAX_NESTED_QUOTES = 4;
|
|
6
3
|
export const PUNCTUATION_STYLES = ["american", "british", "german", "french", "none"];
|
|
7
4
|
function convertSingleQuotes(text, sep) {
|
|
8
5
|
const escapedSep = getEscapedSeparator({ separator: sep });
|
|
@@ -13,7 +10,7 @@ function convertSingleQuotes(text, sep) {
|
|
|
13
10
|
text = text.replace(cachedRegExp(`(?<!${singleQuoteOrWord})''(?!${singleQuoteOrWord})`, "g"), `${LEFT_SINGLE_QUOTE}${RIGHT_SINGLE_QUOTE}`);
|
|
14
11
|
text = text.replace(cachedRegExp(`(?<!${singleQuoteOrWord})'(?<ws>\\s+)'(?!${singleQuoteOrWord})`, "g"), `${LEFT_SINGLE_QUOTE}$<ws>${RIGHT_SINGLE_QUOTE}`);
|
|
15
12
|
const afterEndingSinglePatterns = `\\s\\.!?;,\\)${EM_DASH}\\-\\]"`;
|
|
16
|
-
//
|
|
13
|
+
// Ending context with optional 's', for the leading-apostrophe closer scan.
|
|
17
14
|
const afterEndingSingle = `(?=${escapedSep}?(?:s${escapedSep}?)?(?:[${afterEndingSinglePatterns}]|$))`;
|
|
18
15
|
// Handle 'n' abbreviation (Rock 'n' Roll). Before MLA this wasn't needed —
|
|
19
16
|
// the general rules produced LSQ+n+RSQ which was fine. But MLA requires both
|
|
@@ -30,11 +27,8 @@ function convertSingleQuotes(text, sep) {
|
|
|
30
27
|
text = text.replace(cachedRegExp(closingSingle, "gm"), RIGHT_SINGLE_QUOTE);
|
|
31
28
|
const contraction = `(?<=[${LATIN_LETTERS}])['${RIGHT_SINGLE_QUOTE}${MODIFIER_LETTER_APOSTROPHE}](?=${escapedSep}?[${LATIN_LETTERS}])`;
|
|
32
29
|
text = text.replace(cachedRegExp(contraction, "gm"), MODIFIER_LETTER_APOSTROPHE);
|
|
33
|
-
const apostropheWhitelist = `(?=n${MODIFIER_LETTER_APOSTROPHE} )`;
|
|
34
30
|
const endQuoteNotContraction = `(?!${contraction})[${RIGHT_SINGLE_QUOTE}${MODIFIER_LETTER_APOSTROPHE}]${afterEndingSingle}`;
|
|
35
|
-
|
|
36
|
-
const apostropheRegex = cachedRegExp(`(?<=^|[^\\w])['](?:${apostropheWhitelist}|(?![^${LEFT_SINGLE_QUOTE}'\\n]{0,1000}${endQuoteNotContraction}))`, "gm");
|
|
37
|
-
text = text.replace(apostropheRegex, MODIFIER_LETTER_APOSTROPHE);
|
|
31
|
+
text = convertLeadingApostrophes(text, endQuoteNotContraction);
|
|
38
32
|
const beginningSingle = `(?<beforeContext>(?:^|[\\s${LEFT_DOUBLE_QUOTE}${RIGHT_DOUBLE_QUOTE}${EM_DASH}\\-\\(])${escapedSep}?)['](?=${escapedSep}?\\S)`;
|
|
39
33
|
text = text.replace(cachedRegExp(beginningSingle, "gm"), `$<beforeContext>${LEFT_SINGLE_QUOTE}`);
|
|
40
34
|
text = convertUnmatchedPluralPossessives(text, sep);
|
|
@@ -63,22 +57,97 @@ function convertUnmatchedPluralPossessives(text, sep) {
|
|
|
63
57
|
return match;
|
|
64
58
|
});
|
|
65
59
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
60
|
+
// Classifies a leading straight quote (start of line, or after a non-word char)
|
|
61
|
+
// as either an apostrophe/elision (U+02BC) or an opening single quote (left as a
|
|
62
|
+
// straight quote for `beginningSingle` to convert). A left-to-right scan replaces
|
|
63
|
+
// the former distance-bounded lookahead: a leading quote is an apostrophe unless
|
|
64
|
+
// an unbounded forward scan finds a closing single quote (RSQ/MLA in ending
|
|
65
|
+
// context) before reaching a line break or another single-quote opener.
|
|
66
|
+
function convertLeadingApostrophes(text, endQuoteNotContraction) {
|
|
67
|
+
const closerAhead = cachedRegExp(endQuoteNotContraction, "y");
|
|
68
|
+
// `Rock 'n' Roll` already produced `n${MLA} `; a leading quote before it is an
|
|
69
|
+
// apostrophe even though a closing single quote may follow later in the line.
|
|
70
|
+
const nAbbreviationAhead = cachedRegExp(`n${MODIFIER_LETTER_APOSTROPHE} `, "y");
|
|
71
|
+
// High-precision decade elision: a leading quote before two digits (optionally
|
|
72
|
+
// followed by `s`), as in `'90s` or `'99`, is always an apostrophe.
|
|
73
|
+
const decadeElision = cachedRegExp(`\\d\\ds?(?![${LATIN_LETTERS}\\d])`, "y");
|
|
74
|
+
let result = "";
|
|
75
|
+
for (let i = 0; i < text.length; i++) {
|
|
76
|
+
const char = text[i];
|
|
77
|
+
if (char !== "'" || (i > 0 && /\w/.test(text[i - 1]))) {
|
|
78
|
+
result += char;
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
decadeElision.lastIndex = i + 1;
|
|
82
|
+
nAbbreviationAhead.lastIndex = i + 1;
|
|
83
|
+
const isApostrophe = decadeElision.test(text) ||
|
|
84
|
+
nAbbreviationAhead.test(text) ||
|
|
85
|
+
!hasClosingSingleAhead(text, i + 1, closerAhead);
|
|
86
|
+
result += isApostrophe ? MODIFIER_LETTER_APOSTROPHE : char;
|
|
87
|
+
}
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
// Scans forward from `start` for a closing single quote, stopping (no closer) at
|
|
91
|
+
// a line break or another single-quote opener. Separators and other characters
|
|
92
|
+
// are transparent. O(n) amortized: each scan halts at the next single-quote char.
|
|
93
|
+
function hasClosingSingleAhead(text, start, closerAhead) {
|
|
94
|
+
for (let position = start; position < text.length; position++) {
|
|
95
|
+
const char = text[position];
|
|
96
|
+
if (char === "\n" || char === LEFT_SINGLE_QUOTE || char === "'")
|
|
97
|
+
return false;
|
|
98
|
+
closerAhead.lastIndex = position;
|
|
99
|
+
if (closerAhead.test(text))
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
// Matches an opening-position straight double quote: a boundary (start of line,
|
|
105
|
+
// whitespace, bracket, dash, or separator — consumed and re-emitted, since a
|
|
106
|
+
// variable-width alternation lookbehind would be ReDoS-prone) and an optional
|
|
107
|
+
// separator before the quote.
|
|
108
|
+
function doubleOpenerPrefix(escapedSep) {
|
|
69
109
|
const boundary = `(?<boundary>^|[\\s\\(\\/\\[\\{\\-${EM_DASH}]|${escapedSep})`;
|
|
70
110
|
const beforeCapture = `(?<beforeChr>${escapedSep}?)`;
|
|
111
|
+
return `${boundary}${beforeCapture}["]`;
|
|
112
|
+
}
|
|
113
|
+
function buildBeginningDoublePattern(escapedSep, rawEscSep) {
|
|
71
114
|
// Characters that signal an ending-quote position (not valid openers)
|
|
72
115
|
const endingChars = `\\s\\)${EM_DASH},!?;:.\\}${rawEscSep}`;
|
|
73
116
|
const afterConditions = [
|
|
74
117
|
`(?=${escapedSep}[ .,])`,
|
|
75
118
|
`(?=${escapedSep}?\\.{3}|${escapedSep}?[^${endingChars}])`,
|
|
76
|
-
// Lookahead for a closing straight quote within 50 chars — handles
|
|
77
|
-
// quoted punctuation like "?" and "!" where the first char after the
|
|
78
|
-
// opening quote would otherwise look like an ending-quote context
|
|
79
|
-
`(?=[^"]{1,50}")`,
|
|
80
119
|
];
|
|
81
|
-
return `${
|
|
120
|
+
return `${doubleOpenerPrefix(escapedSep)}(?:${afterConditions.join("|")})`;
|
|
121
|
+
}
|
|
122
|
+
// Quoted-punctuation openers like "?" or "!", where the character right after the
|
|
123
|
+
// opening quote looks like an ending-quote context. A left-to-right scan replaces
|
|
124
|
+
// the former 50-char lookahead: a boundary-position straight double quote is an
|
|
125
|
+
// opener when a closing straight double quote appears anywhere ahead, with at
|
|
126
|
+
// least one non-quote character between them.
|
|
127
|
+
function convertQuotedPunctuationOpeners(text, escapedSep) {
|
|
128
|
+
const candidate = cachedRegExp(doubleOpenerPrefix(escapedSep), "gm");
|
|
129
|
+
let result = "";
|
|
130
|
+
let copiedUpTo = 0;
|
|
131
|
+
for (const match of text.matchAll(candidate)) {
|
|
132
|
+
// The boundary and optional separator are left in place; only the straight
|
|
133
|
+
// quote (the final character of the match) is rewritten to an opener.
|
|
134
|
+
const quoteIndex = match.index + match[0].length - 1;
|
|
135
|
+
if (!hasClosingDoubleAhead(text, quoteIndex + 1))
|
|
136
|
+
continue;
|
|
137
|
+
result += text.slice(copiedUpTo, quoteIndex) + LEFT_DOUBLE_QUOTE;
|
|
138
|
+
copiedUpTo = quoteIndex + 1;
|
|
139
|
+
}
|
|
140
|
+
return result + text.slice(copiedUpTo);
|
|
141
|
+
}
|
|
142
|
+
// Scans forward for a closing straight double quote, requiring at least one
|
|
143
|
+
// non-quote character between `start` and it. O(n) amortized: the scan halts at
|
|
144
|
+
// the next double-quote character.
|
|
145
|
+
function hasClosingDoubleAhead(text, start) {
|
|
146
|
+
for (let position = start; position < text.length; position++) {
|
|
147
|
+
if (text[position] === '"')
|
|
148
|
+
return position > start;
|
|
149
|
+
}
|
|
150
|
+
return false;
|
|
82
151
|
}
|
|
83
152
|
function convertDoubleQuotes(text, sep) {
|
|
84
153
|
const rawEscSep = escapeStringRegexp(sep);
|
|
@@ -90,6 +159,7 @@ function convertDoubleQuotes(text, sep) {
|
|
|
90
159
|
text = text.replace(/(?<=^|[\s([{])"(?<whitespace>\s+)"(?=$|[\s)\]}.!?,;:])/g, `${LEFT_DOUBLE_QUOTE}$<whitespace>${RIGHT_DOUBLE_QUOTE}`);
|
|
91
160
|
const beginningDouble = cachedRegExp(buildBeginningDoublePattern(escapedSep, rawEscSep), "gm");
|
|
92
161
|
text = text.replace(beginningDouble, `$<boundary>$<beforeChr>${LEFT_DOUBLE_QUOTE}`);
|
|
162
|
+
text = convertQuotedPunctuationOpeners(text, escapedSep);
|
|
93
163
|
text = text.replace(cachedRegExp(`(?<=\\{)(?<sepSpace>${escapedSep}? )?["]`, "g"), `$<sepSpace>${LEFT_DOUBLE_QUOTE}`);
|
|
94
164
|
const endingDouble = `(?<beforeQuote>[^\\s\\(])["](?<sepAfter>${escapedSep})?(?=${escapedSep}|[\\s/\\).,;${EM_DASH}:\\-\\}!?s]|$)`;
|
|
95
165
|
text = text.replace(cachedRegExp(endingDouble, "g"), `$<beforeQuote>${RIGHT_DOUBLE_QUOTE}$<sepAfter>`);
|
|
@@ -97,32 +167,70 @@ function convertDoubleQuotes(text, sep) {
|
|
|
97
167
|
text = text.replace(cachedRegExp(`'(?=${RIGHT_DOUBLE_QUOTE})`, "gu"), RIGHT_SINGLE_QUOTE);
|
|
98
168
|
return text;
|
|
99
169
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
170
|
+
const CLOSING_QUOTES = new Set([RIGHT_SINGLE_QUOTE, RIGHT_DOUBLE_QUOTE]);
|
|
171
|
+
const TERMINAL_PUNCTUATION_SET = new Set(TERMINAL_PUNCTUATION);
|
|
172
|
+
// Consumes a run of consecutive closing quotes (RSQ/RDQ) of arbitrary depth,
|
|
173
|
+
// each optionally preceded by a separator, starting at `start`. Returns the
|
|
174
|
+
// index just past the last closing quote, or -1 if there is no run.
|
|
175
|
+
function scanClosingQuoteRun(text, start, sep) {
|
|
176
|
+
if (!CLOSING_QUOTES.has(text[start]))
|
|
177
|
+
return -1;
|
|
178
|
+
let runEnd = start + 1;
|
|
179
|
+
for (;;) {
|
|
180
|
+
let next = runEnd;
|
|
181
|
+
if (sep.length > 0 && text.startsWith(sep, next))
|
|
182
|
+
next += sep.length;
|
|
183
|
+
if (!CLOSING_QUOTES.has(text[next]))
|
|
184
|
+
break;
|
|
185
|
+
runEnd = next + 1;
|
|
186
|
+
}
|
|
187
|
+
return runEnd;
|
|
188
|
+
}
|
|
189
|
+
function separatorLengthAt(text, index, sep) {
|
|
190
|
+
return sep.length > 0 && text.startsWith(sep, index) ? sep.length : 0;
|
|
191
|
+
}
|
|
192
|
+
// Moves a period or comma from just after a run of closing quotes to just
|
|
193
|
+
// before it (American style: punctuation inside the quotes). A single
|
|
194
|
+
// left-to-right pass collects each closing-quote run of arbitrary depth — no
|
|
195
|
+
// nesting cap — then relocates an adjacent period/comma, treating separators as
|
|
196
|
+
// transparent (re-emitted in place). The move is skipped when the character
|
|
197
|
+
// before the run is terminal punctuation (`"Stop!".` keeps its period outside).
|
|
198
|
+
function movePunctuationInside(text, sep, isMovablePunctuation) {
|
|
199
|
+
let result = "";
|
|
200
|
+
let position = 0;
|
|
201
|
+
while (position < text.length) {
|
|
202
|
+
const sepBeforeLength = separatorLengthAt(text, position, sep);
|
|
203
|
+
const runStart = position + sepBeforeLength;
|
|
204
|
+
const runEnd = scanClosingQuoteRun(text, runStart, sep);
|
|
205
|
+
const sepAfterLength = runEnd === -1 ? 0 : separatorLengthAt(text, runEnd, sep);
|
|
206
|
+
const punctuationIndex = runEnd + sepAfterLength;
|
|
207
|
+
const precededByTerminal = position > 0 && TERMINAL_PUNCTUATION_SET.has(text[position - 1]);
|
|
208
|
+
if (runEnd === -1 || precededByTerminal || !isMovablePunctuation(text, punctuationIndex)) {
|
|
209
|
+
result += text[position];
|
|
210
|
+
position++;
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
const sepBefore = text.slice(position, runStart);
|
|
214
|
+
const run = text.slice(runStart, runEnd);
|
|
215
|
+
const sepAfter = text.slice(runEnd, punctuationIndex);
|
|
216
|
+
result += sepBefore + text[punctuationIndex] + run + sepAfter;
|
|
217
|
+
position = punctuationIndex + 1;
|
|
218
|
+
}
|
|
219
|
+
return result;
|
|
220
|
+
}
|
|
221
|
+
function isMovablePeriod(text, index) {
|
|
222
|
+
return text[index] === "." && !text.startsWith("...", index);
|
|
114
223
|
}
|
|
115
|
-
function
|
|
116
|
-
|
|
117
|
-
return text.replace(regex, `$<sepBefore>${replacementChar}$<quotes>$<sepAfter>`);
|
|
224
|
+
function isMovableComma(text, index) {
|
|
225
|
+
return text[index] === ",";
|
|
118
226
|
}
|
|
119
227
|
function applyPunctuationStyle(text, sep, style) {
|
|
120
228
|
const escapedSep = getEscapedSeparator({ separator: sep });
|
|
121
229
|
if (style === "american") {
|
|
122
230
|
// Period outside → inside: Hello". → Hello." (and Hello'". → Hello.'")
|
|
123
|
-
text =
|
|
231
|
+
text = movePunctuationInside(text, sep, isMovablePeriod);
|
|
124
232
|
// Comma outside → inside: Hello", → Hello,"
|
|
125
|
-
text =
|
|
233
|
+
text = movePunctuationInside(text, sep, isMovableComma);
|
|
126
234
|
}
|
|
127
235
|
else {
|
|
128
236
|
// Every non-"american" non-"none" style (british/german/french) places
|
package/dist/quotes.js.map
CHANGED
|
@@ -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/package.json
CHANGED
package/src/quotes.ts
CHANGED
|
@@ -9,11 +9,6 @@ const {
|
|
|
9
9
|
MODIFIER_LETTER_APOSTROPHE,
|
|
10
10
|
} = UNICODE_SYMBOLS
|
|
11
11
|
|
|
12
|
-
const TERMINAL_PUNCTUATION_CLASS = TERMINAL_PUNCTUATION.join("")
|
|
13
|
-
|
|
14
|
-
// Bounded to keep punctuation-placement regexes linear on pathological inputs.
|
|
15
|
-
const MAX_NESTED_QUOTES = 4
|
|
16
|
-
|
|
17
12
|
export const PUNCTUATION_STYLES = ["american", "british", "german", "french", "none"] as const
|
|
18
13
|
export type PunctuationStyle = (typeof PUNCTUATION_STYLES)[number]
|
|
19
14
|
|
|
@@ -35,7 +30,7 @@ function convertSingleQuotes(text: string, sep: string): string {
|
|
|
35
30
|
text = text.replace(cachedRegExp(`(?<!${singleQuoteOrWord})'(?<ws>\\s+)'(?!${singleQuoteOrWord})`, "g"), `${LEFT_SINGLE_QUOTE}$<ws>${RIGHT_SINGLE_QUOTE}`)
|
|
36
31
|
|
|
37
32
|
const afterEndingSinglePatterns = `\\s\\.!?;,\\)${EM_DASH}\\-\\]"`
|
|
38
|
-
//
|
|
33
|
+
// Ending context with optional 's', for the leading-apostrophe closer scan.
|
|
39
34
|
const afterEndingSingle = `(?=${escapedSep}?(?:s${escapedSep}?)?(?:[${afterEndingSinglePatterns}]|$))`
|
|
40
35
|
|
|
41
36
|
// Handle 'n' abbreviation (Rock 'n' Roll). Before MLA this wasn't needed —
|
|
@@ -57,14 +52,8 @@ function convertSingleQuotes(text: string, sep: string): string {
|
|
|
57
52
|
const contraction = `(?<=[${LATIN_LETTERS}])['${RIGHT_SINGLE_QUOTE}${MODIFIER_LETTER_APOSTROPHE}](?=${escapedSep}?[${LATIN_LETTERS}])`
|
|
58
53
|
text = text.replace(cachedRegExp(contraction, "gm"), MODIFIER_LETTER_APOSTROPHE)
|
|
59
54
|
|
|
60
|
-
const apostropheWhitelist = `(?=n${MODIFIER_LETTER_APOSTROPHE} )`
|
|
61
55
|
const endQuoteNotContraction = `(?!${contraction})[${RIGHT_SINGLE_QUOTE}${MODIFIER_LETTER_APOSTROPHE}]${afterEndingSingle}`
|
|
62
|
-
|
|
63
|
-
const apostropheRegex = cachedRegExp(
|
|
64
|
-
`(?<=^|[^\\w])['](?:${apostropheWhitelist}|(?![^${LEFT_SINGLE_QUOTE}'\\n]{0,1000}${endQuoteNotContraction}))`,
|
|
65
|
-
"gm"
|
|
66
|
-
)
|
|
67
|
-
text = text.replace(apostropheRegex, MODIFIER_LETTER_APOSTROPHE)
|
|
56
|
+
text = convertLeadingApostrophes(text, endQuoteNotContraction)
|
|
68
57
|
|
|
69
58
|
const beginningSingle = `(?<beforeContext>(?:^|[\\s${LEFT_DOUBLE_QUOTE}${RIGHT_DOUBLE_QUOTE}${EM_DASH}\\-\\(])${escapedSep}?)['](?=${escapedSep}?\\S)`
|
|
70
59
|
text = text.replace(cachedRegExp(beginningSingle, "gm"), `$<beforeContext>${LEFT_SINGLE_QUOTE}`)
|
|
@@ -101,25 +90,102 @@ function convertUnmatchedPluralPossessives(text: string, sep: string): string {
|
|
|
101
90
|
)
|
|
102
91
|
}
|
|
103
92
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
93
|
+
// Classifies a leading straight quote (start of line, or after a non-word char)
|
|
94
|
+
// as either an apostrophe/elision (U+02BC) or an opening single quote (left as a
|
|
95
|
+
// straight quote for `beginningSingle` to convert). A left-to-right scan replaces
|
|
96
|
+
// the former distance-bounded lookahead: a leading quote is an apostrophe unless
|
|
97
|
+
// an unbounded forward scan finds a closing single quote (RSQ/MLA in ending
|
|
98
|
+
// context) before reaching a line break or another single-quote opener.
|
|
99
|
+
function convertLeadingApostrophes(text: string, endQuoteNotContraction: string): string {
|
|
100
|
+
const closerAhead = cachedRegExp(endQuoteNotContraction, "y")
|
|
101
|
+
// `Rock 'n' Roll` already produced `n${MLA} `; a leading quote before it is an
|
|
102
|
+
// apostrophe even though a closing single quote may follow later in the line.
|
|
103
|
+
const nAbbreviationAhead = cachedRegExp(`n${MODIFIER_LETTER_APOSTROPHE} `, "y")
|
|
104
|
+
// High-precision decade elision: a leading quote before two digits (optionally
|
|
105
|
+
// followed by `s`), as in `'90s` or `'99`, is always an apostrophe.
|
|
106
|
+
const decadeElision = cachedRegExp(`\\d\\ds?(?![${LATIN_LETTERS}\\d])`, "y")
|
|
107
|
+
|
|
108
|
+
let result = ""
|
|
109
|
+
for (let i = 0; i < text.length; i++) {
|
|
110
|
+
const char = text[i]
|
|
111
|
+
if (char !== "'" || (i > 0 && /\w/.test(text[i - 1]))) {
|
|
112
|
+
result += char
|
|
113
|
+
continue
|
|
114
|
+
}
|
|
115
|
+
decadeElision.lastIndex = i + 1
|
|
116
|
+
nAbbreviationAhead.lastIndex = i + 1
|
|
117
|
+
const isApostrophe =
|
|
118
|
+
decadeElision.test(text) ||
|
|
119
|
+
nAbbreviationAhead.test(text) ||
|
|
120
|
+
!hasClosingSingleAhead(text, i + 1, closerAhead)
|
|
121
|
+
result += isApostrophe ? MODIFIER_LETTER_APOSTROPHE : char
|
|
122
|
+
}
|
|
123
|
+
return result
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Scans forward from `start` for a closing single quote, stopping (no closer) at
|
|
127
|
+
// a line break or another single-quote opener. Separators and other characters
|
|
128
|
+
// are transparent. O(n) amortized: each scan halts at the next single-quote char.
|
|
129
|
+
function hasClosingSingleAhead(text: string, start: number, closerAhead: RegExp): boolean {
|
|
130
|
+
for (let position = start; position < text.length; position++) {
|
|
131
|
+
const char = text[position]
|
|
132
|
+
if (char === "\n" || char === LEFT_SINGLE_QUOTE || char === "'") return false
|
|
133
|
+
closerAhead.lastIndex = position
|
|
134
|
+
if (closerAhead.test(text)) return true
|
|
135
|
+
}
|
|
136
|
+
return false
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Matches an opening-position straight double quote: a boundary (start of line,
|
|
140
|
+
// whitespace, bracket, dash, or separator — consumed and re-emitted, since a
|
|
141
|
+
// variable-width alternation lookbehind would be ReDoS-prone) and an optional
|
|
142
|
+
// separator before the quote.
|
|
143
|
+
function doubleOpenerPrefix(escapedSep: string): string {
|
|
107
144
|
const boundary = `(?<boundary>^|[\\s\\(\\/\\[\\{\\-${EM_DASH}]|${escapedSep})`
|
|
108
145
|
const beforeCapture = `(?<beforeChr>${escapedSep}?)`
|
|
146
|
+
return `${boundary}${beforeCapture}["]`
|
|
147
|
+
}
|
|
109
148
|
|
|
149
|
+
function buildBeginningDoublePattern(escapedSep: string, rawEscSep: string): string {
|
|
110
150
|
// Characters that signal an ending-quote position (not valid openers)
|
|
111
151
|
const endingChars = `\\s\\)${EM_DASH},!?;:.\\}${rawEscSep}`
|
|
112
152
|
|
|
113
153
|
const afterConditions = [
|
|
114
154
|
`(?=${escapedSep}[ .,])`,
|
|
115
155
|
`(?=${escapedSep}?\\.{3}|${escapedSep}?[^${endingChars}])`,
|
|
116
|
-
// Lookahead for a closing straight quote within 50 chars — handles
|
|
117
|
-
// quoted punctuation like "?" and "!" where the first char after the
|
|
118
|
-
// opening quote would otherwise look like an ending-quote context
|
|
119
|
-
`(?=[^"]{1,50}")`,
|
|
120
156
|
]
|
|
121
157
|
|
|
122
|
-
return `${
|
|
158
|
+
return `${doubleOpenerPrefix(escapedSep)}(?:${afterConditions.join("|")})`
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Quoted-punctuation openers like "?" or "!", where the character right after the
|
|
162
|
+
// opening quote looks like an ending-quote context. A left-to-right scan replaces
|
|
163
|
+
// the former 50-char lookahead: a boundary-position straight double quote is an
|
|
164
|
+
// opener when a closing straight double quote appears anywhere ahead, with at
|
|
165
|
+
// least one non-quote character between them.
|
|
166
|
+
function convertQuotedPunctuationOpeners(text: string, escapedSep: string): string {
|
|
167
|
+
const candidate = cachedRegExp(doubleOpenerPrefix(escapedSep), "gm")
|
|
168
|
+
let result = ""
|
|
169
|
+
let copiedUpTo = 0
|
|
170
|
+
for (const match of text.matchAll(candidate)) {
|
|
171
|
+
// The boundary and optional separator are left in place; only the straight
|
|
172
|
+
// quote (the final character of the match) is rewritten to an opener.
|
|
173
|
+
const quoteIndex = match.index + match[0].length - 1
|
|
174
|
+
if (!hasClosingDoubleAhead(text, quoteIndex + 1)) continue
|
|
175
|
+
result += text.slice(copiedUpTo, quoteIndex) + LEFT_DOUBLE_QUOTE
|
|
176
|
+
copiedUpTo = quoteIndex + 1
|
|
177
|
+
}
|
|
178
|
+
return result + text.slice(copiedUpTo)
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Scans forward for a closing straight double quote, requiring at least one
|
|
182
|
+
// non-quote character between `start` and it. O(n) amortized: the scan halts at
|
|
183
|
+
// the next double-quote character.
|
|
184
|
+
function hasClosingDoubleAhead(text: string, start: number): boolean {
|
|
185
|
+
for (let position = start; position < text.length; position++) {
|
|
186
|
+
if (text[position] === '"') return position > start
|
|
187
|
+
}
|
|
188
|
+
return false
|
|
123
189
|
}
|
|
124
190
|
|
|
125
191
|
function convertDoubleQuotes(text: string, sep: string): string {
|
|
@@ -135,6 +201,8 @@ function convertDoubleQuotes(text: string, sep: string): string {
|
|
|
135
201
|
const beginningDouble = cachedRegExp(buildBeginningDoublePattern(escapedSep, rawEscSep), "gm")
|
|
136
202
|
text = text.replace(beginningDouble, `$<boundary>$<beforeChr>${LEFT_DOUBLE_QUOTE}`)
|
|
137
203
|
|
|
204
|
+
text = convertQuotedPunctuationOpeners(text, escapedSep)
|
|
205
|
+
|
|
138
206
|
text = text.replace(cachedRegExp(`(?<=\\{)(?<sepSpace>${escapedSep}? )?["]`, "g"), `$<sepSpace>${LEFT_DOUBLE_QUOTE}`)
|
|
139
207
|
|
|
140
208
|
const endingDouble = `(?<beforeQuote>[^\\s\\(])["](?<sepAfter>${escapedSep})?(?=${escapedSep}|[\\s/\\).,;${EM_DASH}:\\-\\}!?s]|$)`
|
|
@@ -146,31 +214,70 @@ function convertDoubleQuotes(text: string, sep: string): string {
|
|
|
146
214
|
return text
|
|
147
215
|
}
|
|
148
216
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
217
|
+
const CLOSING_QUOTES = new Set<string>([RIGHT_SINGLE_QUOTE, RIGHT_DOUBLE_QUOTE])
|
|
218
|
+
const TERMINAL_PUNCTUATION_SET = new Set<string>(TERMINAL_PUNCTUATION)
|
|
219
|
+
|
|
220
|
+
// Consumes a run of consecutive closing quotes (RSQ/RDQ) of arbitrary depth,
|
|
221
|
+
// each optionally preceded by a separator, starting at `start`. Returns the
|
|
222
|
+
// index just past the last closing quote, or -1 if there is no run.
|
|
223
|
+
function scanClosingQuoteRun(text: string, start: number, sep: string): number {
|
|
224
|
+
if (!CLOSING_QUOTES.has(text[start])) return -1
|
|
225
|
+
let runEnd = start + 1
|
|
226
|
+
for (;;) {
|
|
227
|
+
let next = runEnd
|
|
228
|
+
if (sep.length > 0 && text.startsWith(sep, next)) next += sep.length
|
|
229
|
+
if (!CLOSING_QUOTES.has(text[next])) break
|
|
230
|
+
runEnd = next + 1
|
|
231
|
+
}
|
|
232
|
+
return runEnd
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function separatorLengthAt(text: string, index: number, sep: string): number {
|
|
236
|
+
return sep.length > 0 && text.startsWith(sep, index) ? sep.length : 0
|
|
164
237
|
}
|
|
165
238
|
|
|
166
|
-
|
|
239
|
+
// Moves a period or comma from just after a run of closing quotes to just
|
|
240
|
+
// before it (American style: punctuation inside the quotes). A single
|
|
241
|
+
// left-to-right pass collects each closing-quote run of arbitrary depth — no
|
|
242
|
+
// nesting cap — then relocates an adjacent period/comma, treating separators as
|
|
243
|
+
// transparent (re-emitted in place). The move is skipped when the character
|
|
244
|
+
// before the run is terminal punctuation (`"Stop!".` keeps its period outside).
|
|
245
|
+
function movePunctuationInside(
|
|
167
246
|
text: string,
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
punctuationPattern: string,
|
|
247
|
+
sep: string,
|
|
248
|
+
isMovablePunctuation: (text: string, index: number) => boolean,
|
|
171
249
|
): string {
|
|
172
|
-
|
|
173
|
-
|
|
250
|
+
let result = ""
|
|
251
|
+
let position = 0
|
|
252
|
+
while (position < text.length) {
|
|
253
|
+
const sepBeforeLength = separatorLengthAt(text, position, sep)
|
|
254
|
+
const runStart = position + sepBeforeLength
|
|
255
|
+
const runEnd = scanClosingQuoteRun(text, runStart, sep)
|
|
256
|
+
const sepAfterLength = runEnd === -1 ? 0 : separatorLengthAt(text, runEnd, sep)
|
|
257
|
+
const punctuationIndex = runEnd + sepAfterLength
|
|
258
|
+
|
|
259
|
+
const precededByTerminal = position > 0 && TERMINAL_PUNCTUATION_SET.has(text[position - 1])
|
|
260
|
+
if (runEnd === -1 || precededByTerminal || !isMovablePunctuation(text, punctuationIndex)) {
|
|
261
|
+
result += text[position]
|
|
262
|
+
position++
|
|
263
|
+
continue
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
const sepBefore = text.slice(position, runStart)
|
|
267
|
+
const run = text.slice(runStart, runEnd)
|
|
268
|
+
const sepAfter = text.slice(runEnd, punctuationIndex)
|
|
269
|
+
result += sepBefore + text[punctuationIndex] + run + sepAfter
|
|
270
|
+
position = punctuationIndex + 1
|
|
271
|
+
}
|
|
272
|
+
return result
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function isMovablePeriod(text: string, index: number): boolean {
|
|
276
|
+
return text[index] === "." && !text.startsWith("...", index)
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function isMovableComma(text: string, index: number): boolean {
|
|
280
|
+
return text[index] === ","
|
|
174
281
|
}
|
|
175
282
|
|
|
176
283
|
function applyPunctuationStyle(text: string, sep: string, style: PunctuationStyle): string {
|
|
@@ -178,9 +285,9 @@ function applyPunctuationStyle(text: string, sep: string, style: PunctuationStyl
|
|
|
178
285
|
|
|
179
286
|
if (style === "american") {
|
|
180
287
|
// Period outside → inside: Hello". → Hello." (and Hello'". → Hello.'")
|
|
181
|
-
text =
|
|
288
|
+
text = movePunctuationInside(text, sep, isMovablePeriod)
|
|
182
289
|
// Comma outside → inside: Hello", → Hello,"
|
|
183
|
-
text =
|
|
290
|
+
text = movePunctuationInside(text, sep, isMovableComma)
|
|
184
291
|
} else {
|
|
185
292
|
// Every non-"american" non-"none" style (british/german/french) places
|
|
186
293
|
// punctuation outside the quotes.
|