punctilio 3.5.0 → 3.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;CACpC;AAyQD,+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"}
1
+ {"version":3,"file":"quotes.d.ts","sourceRoot":"","sources":["../src/quotes.ts"],"names":[],"mappings":"AAAA;;GAEG;AAyBH,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAA;AAEpF,MAAM,WAAW,YAAY;IAC3B,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;CACpC;AAySD,+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
@@ -6,6 +6,13 @@ import { UNICODE_SYMBOLS, DEFAULT_SEPARATOR, LATIN_LETTERS, TERMINAL_PUNCTUATION
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
+ /**
10
+ * Maximum consecutive closing quotes the punctuation-placement regexes will
11
+ * traverse in a single match (e.g., '". for two-deep nesting). Bounded to keep
12
+ * the regex linear on pathological inputs that contain many closing quotes
13
+ * without any following period or comma.
14
+ */
15
+ const MAX_NESTED_QUOTES = 4;
9
16
  /** Convert straight single quotes to curly quotes and apostrophes */
10
17
  function convertSingleQuotes(text, sep) {
11
18
  const escapedSep = getEscapedSeparator({ separator: sep });
@@ -107,16 +114,47 @@ function convertDoubleQuotes(text, sep) {
107
114
  text = text.replace(cachedRegExp(`'(?=${RIGHT_DOUBLE_QUOTE})`, "gu"), RIGHT_SINGLE_QUOTE);
108
115
  return text;
109
116
  }
117
+ /**
118
+ * Build a regex that matches a punctuation mark sitting OUTSIDE one or more
119
+ * consecutive closing quotes, for American-style inside-the-quotes placement.
120
+ *
121
+ * Shape: `<non-terminal>(sepBefore)(quotes)(sepAfter)<punctuation>`
122
+ *
123
+ * - The lookbehind ensures the char just before the match isn't already terminal
124
+ * punctuation (so we don't rewrite, e.g., "Stop!".).
125
+ * - `quotes` matches 1 to MAX_NESTED_QUOTES closing quotes (possibly separated
126
+ * by element-boundary markers). The bound keeps the regex linear on
127
+ * pathological inputs — unbounded `*` causes catastrophic backtracking when
128
+ * many closing quotes appear with no following punctuation.
129
+ * - `punctuationPattern` is the trailing pattern (e.g. `,` or `(?!\.\.\.)\.`).
130
+ */
131
+ function buildOutsidePunctuationRegex(escapedSep, punctuationPattern) {
132
+ const closingQuoteClass = `[${RIGHT_SINGLE_QUOTE}${RIGHT_DOUBLE_QUOTE}]`;
133
+ const additionalQuotes = `(?:${escapedSep}?${closingQuoteClass}){0,${MAX_NESTED_QUOTES - 1}}`;
134
+ const nonTerminalLookbehind = `(?<![${TERMINAL_PUNCTUATION_CLASS}])`;
135
+ const pattern = `${nonTerminalLookbehind}` +
136
+ `(?<sepBefore>${escapedSep}?)` +
137
+ `(?<quotes>${closingQuoteClass}${additionalQuotes})` +
138
+ `(?<sepAfter>${escapedSep}?)` +
139
+ punctuationPattern;
140
+ return cachedRegExp(pattern, "g");
141
+ }
142
+ /**
143
+ * Move a punctuation mark sitting outside one or more consecutive closing
144
+ * quotes to the inside (American style): `Hello'".` → `Hello.'"`.
145
+ */
146
+ function moveOutsideToInside(text, escapedSep, replacementChar, punctuationPattern) {
147
+ const regex = buildOutsidePunctuationRegex(escapedSep, punctuationPattern);
148
+ return text.replace(regex, `$<sepBefore>${replacementChar}$<quotes>$<sepAfter>`);
149
+ }
110
150
  /** Apply American or British punctuation style */
111
151
  function applyPunctuationStyle(text, sep, style) {
112
152
  const escapedSep = getEscapedSeparator({ separator: sep });
113
153
  if (style === "american") {
114
- // Period outside → inside: "Hello". → "Hello."
115
- const periodOutsideRegex = cachedRegExp(`(?<![${TERMINAL_PUNCTUATION_CLASS}])(?<sepBefore>${escapedSep}?)(?<quote>[${RIGHT_SINGLE_QUOTE}${RIGHT_DOUBLE_QUOTE}])(?<sepAfter>${escapedSep}?)(?!\\.\\.\\.)\\.`, "g");
116
- text = text.replace(periodOutsideRegex, "$<sepBefore>.$<quote>$<sepAfter>");
117
- // Comma outside → inside: "Hello", → "Hello,"
118
- const commaOutsideRegex = cachedRegExp(`(?<![${TERMINAL_PUNCTUATION_CLASS}])(?<sepBefore>${escapedSep}?)(?<quote>[${RIGHT_SINGLE_QUOTE}${RIGHT_DOUBLE_QUOTE}])(?<sepAfter>${escapedSep}?),`, "g");
119
- text = text.replace(commaOutsideRegex, "$<sepBefore>,$<quote>$<sepAfter>");
154
+ // Period outside → inside: Hello". → Hello." (and Hello'". → Hello.'")
155
+ text = moveOutsideToInside(text, escapedSep, ".", `(?!\\.\\.\\.)\\.`);
156
+ // Comma outside → inside: Hello", → Hello,"
157
+ text = moveOutsideToInside(text, escapedSep, ",", `,`);
120
158
  }
121
159
  else if (style === "british" || style === "german" || style === "french") {
122
160
  // Period inside → outside: "Hello." → "Hello".
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "punctilio",
3
- "version": "3.5.0",
3
+ "version": "3.6.0",
4
4
  "description": "Smart typography transformations: curly quotes, em-dashes, en-dashes, and more",
5
5
  "type": "module",
6
6
  "sideEffects": false,
package/src/quotes.ts CHANGED
@@ -17,6 +17,14 @@ const {
17
17
  /** Joined string of all terminal punctuation characters for use in regex character classes. */
18
18
  const TERMINAL_PUNCTUATION_CLASS = TERMINAL_PUNCTUATION.join("")
19
19
 
20
+ /**
21
+ * Maximum consecutive closing quotes the punctuation-placement regexes will
22
+ * traverse in a single match (e.g., '". for two-deep nesting). Bounded to keep
23
+ * the regex linear on pathological inputs that contain many closing quotes
24
+ * without any following period or comma.
25
+ */
26
+ const MAX_NESTED_QUOTES = 4
27
+
20
28
  export type PunctuationStyle = "american" | "british" | "german" | "french" | "none"
21
29
 
22
30
  export interface QuoteOptions {
@@ -156,24 +164,56 @@ function convertDoubleQuotes(text: string, sep: string): string {
156
164
  return text
157
165
  }
158
166
 
167
+ /**
168
+ * Build a regex that matches a punctuation mark sitting OUTSIDE one or more
169
+ * consecutive closing quotes, for American-style inside-the-quotes placement.
170
+ *
171
+ * Shape: `<non-terminal>(sepBefore)(quotes)(sepAfter)<punctuation>`
172
+ *
173
+ * - The lookbehind ensures the char just before the match isn't already terminal
174
+ * punctuation (so we don't rewrite, e.g., "Stop!".).
175
+ * - `quotes` matches 1 to MAX_NESTED_QUOTES closing quotes (possibly separated
176
+ * by element-boundary markers). The bound keeps the regex linear on
177
+ * pathological inputs — unbounded `*` causes catastrophic backtracking when
178
+ * many closing quotes appear with no following punctuation.
179
+ * - `punctuationPattern` is the trailing pattern (e.g. `,` or `(?!\.\.\.)\.`).
180
+ */
181
+ function buildOutsidePunctuationRegex(escapedSep: string, punctuationPattern: string): RegExp {
182
+ const closingQuoteClass = `[${RIGHT_SINGLE_QUOTE}${RIGHT_DOUBLE_QUOTE}]`
183
+ const additionalQuotes = `(?:${escapedSep}?${closingQuoteClass}){0,${MAX_NESTED_QUOTES - 1}}`
184
+ const nonTerminalLookbehind = `(?<![${TERMINAL_PUNCTUATION_CLASS}])`
185
+ const pattern =
186
+ `${nonTerminalLookbehind}` +
187
+ `(?<sepBefore>${escapedSep}?)` +
188
+ `(?<quotes>${closingQuoteClass}${additionalQuotes})` +
189
+ `(?<sepAfter>${escapedSep}?)` +
190
+ punctuationPattern
191
+ return cachedRegExp(pattern, "g")
192
+ }
193
+
194
+ /**
195
+ * Move a punctuation mark sitting outside one or more consecutive closing
196
+ * quotes to the inside (American style): `Hello'".` → `Hello.'"`.
197
+ */
198
+ function moveOutsideToInside(
199
+ text: string,
200
+ escapedSep: string,
201
+ replacementChar: string,
202
+ punctuationPattern: string,
203
+ ): string {
204
+ const regex = buildOutsidePunctuationRegex(escapedSep, punctuationPattern)
205
+ return text.replace(regex, `$<sepBefore>${replacementChar}$<quotes>$<sepAfter>`)
206
+ }
207
+
159
208
  /** Apply American or British punctuation style */
160
209
  function applyPunctuationStyle(text: string, sep: string, style: PunctuationStyle): string {
161
210
  const escapedSep = getEscapedSeparator({ separator: sep })
162
211
 
163
212
  if (style === "american") {
164
- // Period outside → inside: "Hello". → "Hello."
165
- const periodOutsideRegex = cachedRegExp(
166
- `(?<![${TERMINAL_PUNCTUATION_CLASS}])(?<sepBefore>${escapedSep}?)(?<quote>[${RIGHT_SINGLE_QUOTE}${RIGHT_DOUBLE_QUOTE}])(?<sepAfter>${escapedSep}?)(?!\\.\\.\\.)\\.`,
167
- "g"
168
- )
169
- text = text.replace(periodOutsideRegex, "$<sepBefore>.$<quote>$<sepAfter>")
170
-
171
- // Comma outside → inside: "Hello", → "Hello,"
172
- const commaOutsideRegex = cachedRegExp(
173
- `(?<![${TERMINAL_PUNCTUATION_CLASS}])(?<sepBefore>${escapedSep}?)(?<quote>[${RIGHT_SINGLE_QUOTE}${RIGHT_DOUBLE_QUOTE}])(?<sepAfter>${escapedSep}?),`,
174
- "g"
175
- )
176
- text = text.replace(commaOutsideRegex, "$<sepBefore>,$<quote>$<sepAfter>")
213
+ // Period outside → inside: Hello". → Hello." (and Hello'". → Hello.'")
214
+ text = moveOutsideToInside(text, escapedSep, ".", `(?!\\.\\.\\.)\\.`)
215
+ // Comma outside → inside: Hello", → Hello,"
216
+ text = moveOutsideToInside(text, escapedSep, ",", `,`)
177
217
  } else if (style === "british" || style === "german" || style === "french") {
178
218
  // Period inside → outside: "Hello." → "Hello".
179
219
  // No terminal punctuation guard — "Stop!." inside is always wrong; move the period out.
@@ -719,6 +719,23 @@ describe("niceQuotes", () => {
719
719
  const first = niceQuotes(`"He said, 'Hello.'"`, { punctuationStyle: style })
720
720
  expect(niceQuotes(first, { punctuationStyle: style })).toBe(first)
721
721
  })
722
+
723
+ it.each([
724
+ // Period moves past all closing quotes in one pass
725
+ [
726
+ `${LEFT_DOUBLE_QUOTE}He said, ${LEFT_SINGLE_QUOTE}Hello${RIGHT_SINGLE_QUOTE}${RIGHT_DOUBLE_QUOTE}.`,
727
+ `${LEFT_DOUBLE_QUOTE}He said, ${LEFT_SINGLE_QUOTE}Hello.${RIGHT_SINGLE_QUOTE}${RIGHT_DOUBLE_QUOTE}`,
728
+ ],
729
+ // Comma moves past all closing quotes in one pass
730
+ [
731
+ `${LEFT_DOUBLE_QUOTE}He said, ${LEFT_SINGLE_QUOTE}Hello${RIGHT_SINGLE_QUOTE}${RIGHT_DOUBLE_QUOTE}, she replied.`,
732
+ `${LEFT_DOUBLE_QUOTE}He said, ${LEFT_SINGLE_QUOTE}Hello,${RIGHT_SINGLE_QUOTE}${RIGHT_DOUBLE_QUOTE} she replied.`,
733
+ ],
734
+ ])("american moves past all closing quotes: %s → %s", (input, expected) => {
735
+ const result = niceQuotes(input, { punctuationStyle: "american" })
736
+ expect(result).toBe(expected)
737
+ expect(niceQuotes(result, { punctuationStyle: "american" })).toBe(result)
738
+ })
722
739
  })
723
740
 
724
741
  describe("pathological inputs", () => {