punctilio 3.0.8 → 3.0.9

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/src/symbols.ts CHANGED
@@ -2,8 +2,7 @@
2
2
  * Symbol transformations: ellipses, multiplication, math symbols, arrows.
3
3
  */
4
4
 
5
- import escapeStringRegexp from "escape-string-regexp"
6
- import { UNICODE_SYMBOLS, ESCAPED_DEFAULT_SEPARATOR, LATIN_LETTERS, wordBoundaryEnd, SPACE_CHARS, spaceBoundaryStart, spaceBoundaryEnd, cachedRegExp } from "./constants.js"
5
+ import { UNICODE_SYMBOLS, LATIN_LETTERS, wordBoundaryEnd, SPACE_CHARS, spaceBoundaryStart, spaceBoundaryEnd, cachedRegExp, getEscapedSeparator } from "./constants.js"
7
6
 
8
7
  export interface SymbolOptions {
9
8
  /** Boundary marker for HTML element boundaries. Default: "\uE000" */
@@ -41,9 +40,7 @@ const {
41
40
 
42
41
  /** Convert "..." or ". . ." to "…". */
43
42
  export function ellipsis(text: string, options: SymbolOptions = {}): string {
44
- const chr = options.separator
45
- ? escapeStringRegexp(options.separator)
46
- : ESCAPED_DEFAULT_SEPARATOR
43
+ const chr = getEscapedSeparator(options)
47
44
 
48
45
  // Convert consecutive or spaced dots: ... or . . . → …
49
46
  // Captures preserve any separators between dots
@@ -59,9 +56,7 @@ export function ellipsis(text: string, options: SymbolOptions = {}): string {
59
56
 
60
57
  /** Convert "5x5" to "5×5". Skips hex (0x5F). */
61
58
  export function multiplication(text: string, options: SymbolOptions = {}): string {
62
- const chr = options.separator
63
- ? escapeStringRegexp(options.separator)
64
- : ESCAPED_DEFAULT_SEPARATOR
59
+ const chr = getEscapedSeparator(options)
65
60
 
66
61
  // Match entire multiplication chains in one pass: "5 x 5 x 5" or "5x5x5"
67
62
  // Pattern matches: digit(s), then one or more (operator, digit(s)) groups
@@ -113,9 +108,7 @@ const MATH_SYMBOL_MAP: [string, string, string, string][] = [
113
108
 
114
109
  /** Convert !=, <=, >=, +/-, ~= to Unicode equivalents. */
115
110
  export function mathSymbols(text: string, options: SymbolOptions = {}): string {
116
- const chr = options.separator
117
- ? escapeStringRegexp(options.separator)
118
- : ESCAPED_DEFAULT_SEPARATOR
111
+ const chr = getEscapedSeparator(options)
119
112
 
120
113
  for (const [left, right, lookahead, replacement] of MATH_SYMBOL_MAP) {
121
114
  const pattern = cachedRegExp(`${left}${chr}?${right}${lookahead}`, "g")
@@ -168,9 +161,7 @@ const ARROW_MAP: [string, string][] = [
168
161
 
169
162
  /** Convert -> and <-> to arrows. */
170
163
  export function arrows(text: string, options: SymbolOptions = {}): string {
171
- const chr = options.separator
172
- ? escapeStringRegexp(options.separator)
173
- : ESCAPED_DEFAULT_SEPARATOR
164
+ const chr = getEscapedSeparator(options)
174
165
 
175
166
  const start = spaceBoundaryStart(chr)
176
167
  const end = spaceBoundaryEnd(chr)
@@ -185,9 +176,7 @@ export function arrows(text: string, options: SymbolOptions = {}): string {
185
176
 
186
177
  /** Convert "20 C" or "20 F" to "20 °C" or "20 °F". Only matches uppercase C/F. */
187
178
  export function degrees(text: string, options: SymbolOptions = {}): string {
188
- const chr = options.separator
189
- ? escapeStringRegexp(options.separator)
190
- : ESCAPED_DEFAULT_SEPARATOR
179
+ const chr = getEscapedSeparator(options)
191
180
 
192
181
  // Temperature with optional space before C or F (uppercase only)
193
182
  // Handles separator between digit and unit
@@ -288,9 +277,7 @@ function balancedPrimeReplacer(primeChar: string, escapedSeparator: string) {
288
277
 
289
278
  /** Convert 5'10" to 5′10″ (prime marks). Call before smart quotes. */
290
279
  export function primeMarks(text: string, options: SymbolOptions = {}): string {
291
- const escapedSeparator = options.separator
292
- ? escapeStringRegexp(options.separator)
293
- : ESCAPED_DEFAULT_SEPARATOR
280
+ const escapedSeparator = getEscapedSeparator(options)
294
281
 
295
282
  const quotePrimePairs: [string, string][] = [
296
283
  ["'", PRIME],
@@ -298,8 +285,8 @@ export function primeMarks(text: string, options: SymbolOptions = {}): string {
298
285
  ]
299
286
 
300
287
  for (const [quote, primeChar] of quotePrimePairs) {
301
- const escapedQuote = escapeStringRegexp(quote)
302
- const pattern = buildQuoteClassificationPattern(escapedQuote, escapedSeparator)
288
+ // ' and " are not regex-special, so they can be used directly as patterns
289
+ const pattern = buildQuoteClassificationPattern(quote, escapedSeparator)
303
290
  text = text.replace(pattern, balancedPrimeReplacer(primeChar, escapedSeparator))
304
291
  }
305
292
 
@@ -326,9 +313,7 @@ const FRACTION_MAP: Record<string, string> = {
326
313
 
327
314
  /** Convert 1/2, 1/4, etc. to ½, ¼, etc. */
328
315
  export function fractions(text: string, options: SymbolOptions = {}): string {
329
- const chr = options.separator
330
- ? escapeStringRegexp(options.separator)
331
- : ESCAPED_DEFAULT_SEPARATOR
316
+ const chr = getEscapedSeparator(options)
332
317
 
333
318
  for (const [ascii, unicode] of Object.entries(FRACTION_MAP)) {
334
319
  // Negative lookbehind/lookahead: ensures fraction is not part of a larger number or path
@@ -356,9 +341,7 @@ const ORDINAL_MAP: Record<string, string> = {
356
341
 
357
342
  /** Convert 1st, 2nd, 3rd, 4th to superscript ordinals. */
358
343
  export function superscriptOrdinal(text: string, options: SymbolOptions = {}): string {
359
- const chr = options.separator
360
- ? escapeStringRegexp(options.separator)
361
- : ESCAPED_DEFAULT_SEPARATOR
344
+ const chr = getEscapedSeparator(options)
362
345
 
363
346
  // Match number + optional separator + ordinal suffix at word boundary
364
347
  // Use case-insensitive matching for the suffix
@@ -397,9 +380,7 @@ const PUNCTUATION_LIGATURE_MAP: [string, string, string][] = [
397
380
 
398
381
  /** Convert ?? to ⁇, ?! to ⁈, !? to ⁉. Poor font support, disabled by default. */
399
382
  export function punctuationLigatures(text: string, options: SymbolOptions = {}): string {
400
- const chr = options.separator
401
- ? escapeStringRegexp(options.separator)
402
- : ESCAPED_DEFAULT_SEPARATOR
383
+ const chr = getEscapedSeparator(options)
403
384
 
404
385
  for (const [first, repeated, replacement] of PUNCTUATION_LIGATURE_MAP) {
405
386
  const pattern = cachedRegExp(`${first}(${chr})?${repeated}(?:${chr}?${repeated})*`, "g")