punctilio 0.3.0 → 0.4.14
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 +72 -219
- package/dist/constants.d.ts +9 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +11 -0
- package/dist/constants.js.map +1 -1
- package/dist/dashes.d.ts +7 -0
- package/dist/dashes.d.ts.map +1 -1
- package/dist/dashes.js +36 -7
- package/dist/dashes.js.map +1 -1
- package/dist/index.d.ts +38 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -10
- package/dist/index.js.map +1 -1
- package/dist/quotes.js +15 -15
- package/dist/quotes.js.map +1 -1
- package/dist/symbols.d.ts +54 -45
- package/dist/symbols.d.ts.map +1 -1
- package/dist/symbols.js +111 -61
- package/dist/symbols.js.map +1 -1
- package/dist/utils.d.ts +18 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +32 -0
- package/dist/utils.js.map +1 -0
- package/package.json +10 -2
package/dist/index.js
CHANGED
|
@@ -9,10 +9,14 @@
|
|
|
9
9
|
*/
|
|
10
10
|
export { niceQuotes } from "./quotes.js";
|
|
11
11
|
export { hyphenReplace, enDashNumberRange, enDashDateRange, minusReplace, months, } from "./dashes.js";
|
|
12
|
-
export { ellipsis, multiplication, mathSymbols, legalSymbols, arrows, degrees, fractions, primeMarks, symbolTransform, } from "./symbols.js";
|
|
12
|
+
export { ellipsis, multiplication, mathSymbols, legalSymbols, arrows, degrees, fractions, primeMarks, collapseSpaces, superscript, punctuationLigatures, symbolTransform, } from "./symbols.js";
|
|
13
13
|
import { niceQuotes } from "./quotes.js";
|
|
14
14
|
import { hyphenReplace } from "./dashes.js";
|
|
15
|
-
import { symbolTransform, fractions as fractionsTransform, degrees as degreesTransform, primeMarks } from "./symbols.js";
|
|
15
|
+
import { symbolTransform, fractions as fractionsTransform, degrees as degreesTransform, superscript as superscriptTransform, primeMarks, collapseSpaces as collapseSpacesTransform, punctuationLigatures as ligaturesTransform } from "./symbols.js";
|
|
16
|
+
import { assertSeparatorCountPreserved } from "./utils.js";
|
|
17
|
+
import { DEFAULT_SEPARATOR } from "./constants.js";
|
|
18
|
+
export { assertSeparatorCountPreserved, countSeparators } from "./utils.js";
|
|
19
|
+
export { DEFAULT_SEPARATOR } from "./constants.js";
|
|
16
20
|
/**
|
|
17
21
|
* Applies all typography transformations: smart quotes, proper dashes,
|
|
18
22
|
* and symbol improvements.
|
|
@@ -22,8 +26,11 @@ import { symbolTransform, fractions as fractionsTransform, degrees as degreesTra
|
|
|
22
26
|
* 2. primeMarks (feet/inches, arcminutes/arcseconds)
|
|
23
27
|
* 3. niceQuotes (smart quotes)
|
|
24
28
|
* 4. symbolTransform (ellipses, multiplication, math symbols, legal symbols, arrows)
|
|
25
|
-
* 5. fractions (
|
|
26
|
-
* 6. degrees (
|
|
29
|
+
* 5. fractions (disabled by default)
|
|
30
|
+
* 6. degrees (disabled by default)
|
|
31
|
+
* 7. superscript (disabled by default)
|
|
32
|
+
* 8. ligatures (disabled by default)
|
|
33
|
+
* 9. collapseSpaces (collapses multiple spaces into one)
|
|
27
34
|
*
|
|
28
35
|
* @param text - The text to transform
|
|
29
36
|
* @param options - Configuration options
|
|
@@ -44,7 +51,9 @@ import { symbolTransform, fractions as fractionsTransform, degrees as degreesTra
|
|
|
44
51
|
* ```
|
|
45
52
|
*/
|
|
46
53
|
export function transform(text, options = {}) {
|
|
47
|
-
const
|
|
54
|
+
const separator = options.separator ?? DEFAULT_SEPARATOR;
|
|
55
|
+
const original = text;
|
|
56
|
+
const { symbols = true, fractions = false, degrees = false, superscript = false, ligatures = false, collapseSpaces = true, ...separatorOpts } = options;
|
|
48
57
|
text = hyphenReplace(text, separatorOpts);
|
|
49
58
|
text = primeMarks(text, separatorOpts);
|
|
50
59
|
text = niceQuotes(text, separatorOpts);
|
|
@@ -57,11 +66,16 @@ export function transform(text, options = {}) {
|
|
|
57
66
|
if (degrees) {
|
|
58
67
|
text = degreesTransform(text);
|
|
59
68
|
}
|
|
69
|
+
if (superscript) {
|
|
70
|
+
text = superscriptTransform(text, separatorOpts);
|
|
71
|
+
}
|
|
72
|
+
if (ligatures) {
|
|
73
|
+
text = ligaturesTransform(text, separatorOpts);
|
|
74
|
+
}
|
|
75
|
+
if (collapseSpaces) {
|
|
76
|
+
text = collapseSpacesTransform(text);
|
|
77
|
+
}
|
|
78
|
+
assertSeparatorCountPreserved(original, text, separator, "transform");
|
|
60
79
|
return text;
|
|
61
80
|
}
|
|
62
|
-
/**
|
|
63
|
-
* Default separator character for boundary marking.
|
|
64
|
-
* Uses Unicode Private Use Area character U+E000.
|
|
65
|
-
*/
|
|
66
|
-
export const DEFAULT_SEPARATOR = "\uE000";
|
|
67
81
|
//# sourceMappingURL=index.js.map
|
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,EAA4C,MAAM,aAAa,CAAA;AAElF,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,MAAM,GAGP,MAAM,aAAa,CAAA;AAEpB,OAAO,EACL,QAAQ,EACR,cAAc,EACd,WAAW,EACX,YAAY,EACZ,MAAM,EACN,OAAO,EACP,SAAS,EACT,UAAU,EACV,eAAe,GAEhB,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAA4C,MAAM,aAAa,CAAA;AAElF,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,MAAM,GAGP,MAAM,aAAa,CAAA;AAEpB,OAAO,EACL,QAAQ,EACR,cAAc,EACd,WAAW,EACX,YAAY,EACZ,MAAM,EACN,OAAO,EACP,SAAS,EACT,UAAU,EACV,cAAc,EACd,WAAW,EACX,oBAAoB,EACpB,eAAe,GAEhB,MAAM,cAAc,CAAA;AAiFrB,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,WAAW,IAAI,oBAAoB,EAAE,UAAU,EAAE,cAAc,IAAI,uBAAuB,EAAE,oBAAoB,IAAI,kBAAkB,EAAE,MAAM,cAAc,CAAA;AACpP,OAAO,EAAE,6BAA6B,EAAE,MAAM,YAAY,CAAA;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAElD,OAAO,EAAE,6BAA6B,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAC3E,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAElD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,UAA4B,EAAE;IACpE,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,iBAAiB,CAAA;IACxD,MAAM,QAAQ,GAAG,IAAI,CAAA;IACrB,MAAM,EAAE,OAAO,GAAG,IAAI,EAAE,SAAS,GAAG,KAAK,EAAE,OAAO,GAAG,KAAK,EAAE,WAAW,GAAG,KAAK,EAAE,SAAS,GAAG,KAAK,EAAE,cAAc,GAAG,IAAI,EAAE,GAAG,aAAa,EAAE,GAAG,OAAO,CAAA;IAEvJ,IAAI,GAAG,aAAa,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;IACzC,IAAI,GAAG,UAAU,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;IACtC,IAAI,GAAG,UAAU,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;IAEtC,IAAI,OAAO,EAAE,CAAC;QACZ,IAAI,GAAG,eAAe,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;IAC7C,CAAC;IAED,IAAI,SAAS,EAAE,CAAC;QACd,IAAI,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAA;IACjC,CAAC;IAED,IAAI,OAAO,EAAE,CAAC;QACZ,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAA;IAC/B,CAAC;IAED,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,6BAA6B,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,CAAC,CAAA;IAErE,OAAO,IAAI,CAAA;AACb,CAAC"}
|
package/dist/quotes.js
CHANGED
|
@@ -18,18 +18,18 @@ function convertSingleQuotes(text, sep) {
|
|
|
18
18
|
const endQuoteNotContraction = `(?!${contraction})${RIGHT_SINGLE_QUOTE}${afterEndingSingle}`;
|
|
19
19
|
const apostropheRegex = new RegExp(`(?<=^|[^\\w])'(${apostropheWhitelist}|(?![^${LEFT_SINGLE_QUOTE}'\\n]*${endQuoteNotContraction}))`, "gm");
|
|
20
20
|
text = text.replace(apostropheRegex, RIGHT_SINGLE_QUOTE);
|
|
21
|
-
const beginningSingle = `((?:^|[\\s${LEFT_DOUBLE_QUOTE}${RIGHT_DOUBLE_QUOTE}\\-\\(])${sep}?)['](?=${sep}?\\S)`;
|
|
22
|
-
text = text.replace(new RegExp(beginningSingle, "gm"),
|
|
21
|
+
const beginningSingle = `(?<beforeContext>(?:^|[\\s${LEFT_DOUBLE_QUOTE}${RIGHT_DOUBLE_QUOTE}\\-\\(])${sep}?)['](?=${sep}?\\S)`;
|
|
22
|
+
text = text.replace(new RegExp(beginningSingle, "gm"), `$<beforeContext>${LEFT_SINGLE_QUOTE}`);
|
|
23
23
|
return text;
|
|
24
24
|
}
|
|
25
25
|
/** Convert straight double quotes to curly quotes */
|
|
26
26
|
function convertDoubleQuotes(text, sep) {
|
|
27
|
-
const beginningDouble = new RegExp(`(?<=^|[\\s\\(\\/\\[\\{\\-${EM_DASH}${sep}])(?<beforeChr>${sep}?)["](?<afterChr>(
|
|
27
|
+
const beginningDouble = new RegExp(`(?<=^|[\\s\\(\\/\\[\\{\\-${EM_DASH}${sep}])(?<beforeChr>${sep}?)["](?<afterChr>(?<sepWithPunct>${sep}[ .,])|(?=${sep}?\\.{3}|${sep}?[^\\s\\)\\${EM_DASH},!?${sep};:.\\}]))`, "gm");
|
|
28
28
|
text = text.replace(beginningDouble, `$<beforeChr>${LEFT_DOUBLE_QUOTE}$<afterChr>`);
|
|
29
|
-
text = text.replace(new RegExp(`(?<=\\{)(
|
|
30
|
-
const endingDouble = `([^\\s\\(])["](
|
|
31
|
-
text = text.replace(new RegExp(endingDouble, "g"),
|
|
32
|
-
text = text.replace(new RegExp(`["](
|
|
29
|
+
text = text.replace(new RegExp(`(?<=\\{)(?<sepSpace>${sep}? )?["]`, "g"), `$<sepSpace>${LEFT_DOUBLE_QUOTE}`);
|
|
30
|
+
const endingDouble = `(?<beforeQuote>[^\\s\\(])["]((?<sepAfter>${sep})?)(?=${sep}|[\\s/\\).,;${EM_DASH}:\\-\\}!?s]|$)`;
|
|
31
|
+
text = text.replace(new RegExp(endingDouble, "g"), `$<beforeQuote>${RIGHT_DOUBLE_QUOTE}$<sepAfter>`);
|
|
32
|
+
text = text.replace(new RegExp(`["](?<sepEnd>${sep}?)$`, "g"), `${RIGHT_DOUBLE_QUOTE}$<sepEnd>`);
|
|
33
33
|
text = text.replace(new RegExp(`'(?=${RIGHT_DOUBLE_QUOTE})`, "gu"), RIGHT_SINGLE_QUOTE);
|
|
34
34
|
return text;
|
|
35
35
|
}
|
|
@@ -37,19 +37,19 @@ function convertDoubleQuotes(text, sep) {
|
|
|
37
37
|
function applyPunctuationStyle(text, sep, style) {
|
|
38
38
|
if (style === "american") {
|
|
39
39
|
// Period outside → inside: "Hello". → "Hello."
|
|
40
|
-
const periodOutsideRegex = new RegExp(`(?<![!?:\\.${ELLIPSIS}])(
|
|
41
|
-
text = text.replace(periodOutsideRegex, "
|
|
40
|
+
const periodOutsideRegex = new RegExp(`(?<![!?:\\.${ELLIPSIS}])(?<sepBefore>${sep}?)(?<quote>[${RIGHT_SINGLE_QUOTE}${RIGHT_DOUBLE_QUOTE}])(?<sepAfter>${sep}?)(?!\\.\\.\\.)\\.`, "g");
|
|
41
|
+
text = text.replace(periodOutsideRegex, "$<sepBefore>.$<quote>$<sepAfter>");
|
|
42
42
|
// Comma outside → inside: "Hello", → "Hello,"
|
|
43
|
-
const commaOutsideRegex = new RegExp(`(
|
|
44
|
-
text = text.replace(commaOutsideRegex, "
|
|
43
|
+
const commaOutsideRegex = new RegExp(`(?<sepBefore>${sep}?)(?<quote>[${RIGHT_SINGLE_QUOTE}${RIGHT_DOUBLE_QUOTE}])(?<sepAfter>${sep}?),`, "g");
|
|
44
|
+
text = text.replace(commaOutsideRegex, "$<sepBefore>,$<quote>$<sepAfter>");
|
|
45
45
|
}
|
|
46
46
|
else if (style === "british") {
|
|
47
47
|
// Period inside → outside: "Hello." → "Hello".
|
|
48
|
-
const periodInsideRegex = new RegExp(`(?<![!?:\\.${ELLIPSIS}])(
|
|
49
|
-
text = text.replace(periodInsideRegex, "
|
|
48
|
+
const periodInsideRegex = new RegExp(`(?<![!?:\\.${ELLIPSIS}])(?<sepBefore>${sep}?)\\.(?<sepMiddle>${sep}?)(?<quote>[${RIGHT_SINGLE_QUOTE}${RIGHT_DOUBLE_QUOTE}])`, "g");
|
|
49
|
+
text = text.replace(periodInsideRegex, "$<sepBefore>$<sepMiddle>$<quote>.");
|
|
50
50
|
// Comma inside → outside: "Hello," → "Hello",
|
|
51
|
-
const commaInsideRegex = new RegExp(`(?<![!?]),(
|
|
52
|
-
text = text.replace(commaInsideRegex, "
|
|
51
|
+
const commaInsideRegex = new RegExp(`(?<![!?]),(?<sepAndQuote>${sep}?[${RIGHT_DOUBLE_QUOTE}${RIGHT_SINGLE_QUOTE}])`, "g");
|
|
52
|
+
text = text.replace(commaInsideRegex, "$<sepAndQuote>,");
|
|
53
53
|
}
|
|
54
54
|
return text;
|
|
55
55
|
}
|
package/dist/quotes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quotes.js","sourceRoot":"","sources":["../src/quotes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAEnE,MAAM,EACJ,OAAO,EACP,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,GACT,GAAG,eAAe,CAAA;AA8BnB,qEAAqE;AACrE,SAAS,mBAAmB,CAAC,IAAY,EAAE,GAAW;IACpD,MAAM,yBAAyB,GAAG,gBAAgB,OAAO,SAAS,CAAA;IAClE,MAAM,iBAAiB,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,yBAAyB,OAAO,CAAA;IACxF,MAAM,YAAY,GAAG,YAAY,iBAAiB,SAAS,iBAAiB,EAAE,CAAA;IAC9E,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,YAAY,EAAE,IAAI,CAAC,EAAE,kBAAkB,CAAC,CAAA;IAEvE,MAAM,WAAW,GAAG,kBAAkB,kBAAkB,OAAO,GAAG,YAAY,CAAA;IAC9E,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,kBAAkB,CAAC,CAAA;IAEtE,MAAM,mBAAmB,GAAG,OAAO,kBAAkB,IAAI,CAAA;IACzD,MAAM,sBAAsB,GAAG,MAAM,WAAW,IAAI,kBAAkB,GAAG,iBAAiB,EAAE,CAAA;IAC5F,MAAM,eAAe,GAAG,IAAI,MAAM,CAChC,kBAAkB,mBAAmB,SAAS,iBAAiB,SAAS,sBAAsB,IAAI,EAClG,IAAI,CACL,CAAA;IACD,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,kBAAkB,CAAC,CAAA;IAExD,MAAM,eAAe,GAAG,
|
|
1
|
+
{"version":3,"file":"quotes.js","sourceRoot":"","sources":["../src/quotes.ts"],"names":[],"mappings":"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"}
|
package/dist/symbols.d.ts
CHANGED
|
@@ -35,28 +35,10 @@ export declare function ellipsis(text: string, options?: SymbolOptions): string;
|
|
|
35
35
|
* - Dimensions: "5x5" → "5×5"
|
|
36
36
|
* - Trailing multiplier: "5x" → "5×" (when followed by word boundary)
|
|
37
37
|
* - Asterisk multiplication: "5*3" → "5×3" (when between numbers)
|
|
38
|
-
*
|
|
39
|
-
* @example
|
|
40
|
-
* ```ts
|
|
41
|
-
* multiplication("The room is 10x12 feet")
|
|
42
|
-
* // → "The room is 10×12 feet"
|
|
43
|
-
*
|
|
44
|
-
* multiplication("2x speed")
|
|
45
|
-
* // → "2× speed"
|
|
46
|
-
* ```
|
|
47
38
|
*/
|
|
48
39
|
export declare function multiplication(text: string, options?: SymbolOptions): string;
|
|
49
40
|
/**
|
|
50
41
|
* Converts ASCII mathematical symbols to proper Unicode equivalents.
|
|
51
|
-
*
|
|
52
|
-
* @example
|
|
53
|
-
* ```ts
|
|
54
|
-
* mathSymbols("x != y and a <= b")
|
|
55
|
-
* // → "x ≠ y and a ≤ b"
|
|
56
|
-
*
|
|
57
|
-
* mathSymbols("The answer is +- 5%")
|
|
58
|
-
* // → "The answer is ± 5%"
|
|
59
|
-
* ```
|
|
60
42
|
*/
|
|
61
43
|
export declare function mathSymbols(text: string): string;
|
|
62
44
|
/**
|
|
@@ -74,15 +56,6 @@ export declare function legalSymbols(text: string): string;
|
|
|
74
56
|
*
|
|
75
57
|
* Note: Only converts when surrounded by spaces or at word boundaries
|
|
76
58
|
* to avoid false matches in code or URLs.
|
|
77
|
-
*
|
|
78
|
-
* @example
|
|
79
|
-
* ```ts
|
|
80
|
-
* arrows("A -> B -> C")
|
|
81
|
-
* // → "A → B → C"
|
|
82
|
-
*
|
|
83
|
-
* arrows("left <-> right")
|
|
84
|
-
* // → "left ↔ right"
|
|
85
|
-
* ```
|
|
86
59
|
*/
|
|
87
60
|
export declare function arrows(text: string, options?: SymbolOptions): string;
|
|
88
61
|
/**
|
|
@@ -94,15 +67,6 @@ export declare function arrows(text: string, options?: SymbolOptions): string;
|
|
|
94
67
|
*
|
|
95
68
|
* Only matches when followed by C or F (case insensitive) to avoid
|
|
96
69
|
* false positives.
|
|
97
|
-
*
|
|
98
|
-
* @example
|
|
99
|
-
* ```ts
|
|
100
|
-
* degrees("The temperature is 20 C")
|
|
101
|
-
* // → "The temperature is 20 °C"
|
|
102
|
-
*
|
|
103
|
-
* degrees("Water boils at 212F")
|
|
104
|
-
* // → "Water boils at 212 °F"
|
|
105
|
-
* ```
|
|
106
70
|
*/
|
|
107
71
|
export declare function degrees(text: string, options?: SymbolOptions): string;
|
|
108
72
|
/**
|
|
@@ -114,15 +78,6 @@ export declare function degrees(text: string, options?: SymbolOptions): string;
|
|
|
114
78
|
*
|
|
115
79
|
* This should be called BEFORE smart quote transformations to prevent
|
|
116
80
|
* quotes in measurements from being curled.
|
|
117
|
-
*
|
|
118
|
-
* @example
|
|
119
|
-
* ```ts
|
|
120
|
-
* primeMarks("He's 5'10\" tall")
|
|
121
|
-
* // → "He's 5′10″ tall"
|
|
122
|
-
*
|
|
123
|
-
* primeMarks("Location: 45° 30' 15\"")
|
|
124
|
-
* // → "Location: 45° 30′ 15″"
|
|
125
|
-
* ```
|
|
126
81
|
*/
|
|
127
82
|
export declare function primeMarks(text: string, options?: SymbolOptions): string;
|
|
128
83
|
/**
|
|
@@ -144,6 +99,60 @@ export declare function primeMarks(text: string, options?: SymbolOptions): strin
|
|
|
144
99
|
* ```
|
|
145
100
|
*/
|
|
146
101
|
export declare function fractions(text: string, options?: SymbolOptions): string;
|
|
102
|
+
/**
|
|
103
|
+
* Converts ordinal suffixes to Unicode superscript characters.
|
|
104
|
+
*
|
|
105
|
+
* Handles ordinal numbers like:
|
|
106
|
+
* - "1st" → "1ˢᵗ"
|
|
107
|
+
* - "2nd" → "2ⁿᵈ"
|
|
108
|
+
* - "3rd" → "3ʳᵈ"
|
|
109
|
+
* - "4th" → "4ᵗʰ"
|
|
110
|
+
*
|
|
111
|
+
* Works with any number ending in appropriate suffixes (21st, 42nd, 103rd, etc.)
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* ```ts
|
|
115
|
+
* superscript("The 1st place winner")
|
|
116
|
+
* // → "The 1ˢᵗ place winner"
|
|
117
|
+
*
|
|
118
|
+
* superscript("Born on the 30th of June")
|
|
119
|
+
* // → "Born on the 30ᵗʰ of June"
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
export declare function superscript(text: string, options?: SymbolOptions): string;
|
|
123
|
+
/**
|
|
124
|
+
* Collapses multiple consecutive spaces (including non-breaking spaces) into a single space.
|
|
125
|
+
*
|
|
126
|
+
* When multiple spaces or non-breaking spaces appear in sequence, this function
|
|
127
|
+
* keeps only the first space character, preserving its type.
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```ts
|
|
131
|
+
* collapseSpaces("hello world")
|
|
132
|
+
* // → "hello world"
|
|
133
|
+
*
|
|
134
|
+
* collapseSpaces("foo\u00A0\u00A0bar") // two nbsp
|
|
135
|
+
* // → "foo\u00A0bar" // single nbsp
|
|
136
|
+
*
|
|
137
|
+
* collapseSpaces("a \u00A0b") // space followed by nbsp
|
|
138
|
+
* // → "a b" // keeps the first (regular space)
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
export declare function collapseSpaces(text: string): string;
|
|
142
|
+
/**
|
|
143
|
+
* Converts repeated punctuation marks to Unicode ligature characters,
|
|
144
|
+
* squashing multiple marks to a single character.
|
|
145
|
+
*
|
|
146
|
+
* Handles:
|
|
147
|
+
* - "??" or "???" etc → "⁇" (squashed to double question mark ligature)
|
|
148
|
+
* - "?!" or "?!!" etc → "⁈" (question exclamation mark)
|
|
149
|
+
* - "!?" or "!??" etc → "⁉" (exclamation question mark)
|
|
150
|
+
* - "!!" or "!!!" etc → "!" (squashed to single exclamation)
|
|
151
|
+
*
|
|
152
|
+
* Note: These ligatures have poor font support, so this function is
|
|
153
|
+
* disabled by default.
|
|
154
|
+
*/
|
|
155
|
+
export declare function punctuationLigatures(text: string, options?: SymbolOptions): string;
|
|
147
156
|
/**
|
|
148
157
|
* Applies all symbol transformations.
|
|
149
158
|
*
|
package/dist/symbols.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"symbols.d.ts","sourceRoot":"","sources":["../src/symbols.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;
|
|
1
|
+
{"version":3,"file":"symbols.d.ts","sourceRoot":"","sources":["../src/symbols.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAoCD;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAe1E;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAkBhF;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAShD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKjD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAyBxE;AAED;;;;;;;;;GASG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAWzE;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CA+B5E;AAwBD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAkB3E;AAYD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAgB7E;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAiCtF;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CASjF"}
|
package/dist/symbols.js
CHANGED
|
@@ -13,7 +13,7 @@ import { UNICODE_SYMBOLS, ESCAPED_DEFAULT_SEPARATOR } from "./constants.js";
|
|
|
13
13
|
function escapeRegex(str) {
|
|
14
14
|
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
15
15
|
}
|
|
16
|
-
const { ELLIPSIS, MULTIPLICATION, NOT_EQUAL, PLUS_MINUS, COPYRIGHT, REGISTERED, TRADEMARK, DEGREE, ARROW_RIGHT, ARROW_LEFT, ARROW_LEFT_RIGHT, APPROXIMATE, LESS_EQUAL, GREATER_EQUAL, PRIME, DOUBLE_PRIME, } = UNICODE_SYMBOLS;
|
|
16
|
+
const { ELLIPSIS, MULTIPLICATION, NOT_EQUAL, PLUS_MINUS, COPYRIGHT, REGISTERED, TRADEMARK, DEGREE, ARROW_RIGHT, ARROW_LEFT, ARROW_LEFT_RIGHT, APPROXIMATE, LESS_EQUAL, GREATER_EQUAL, PRIME, DOUBLE_PRIME, NBSP, SUPERSCRIPT_ST, SUPERSCRIPT_ND, SUPERSCRIPT_RD, SUPERSCRIPT_TH, DOUBLE_QUESTION, QUESTION_EXCLAMATION, EXCLAMATION_QUESTION } = UNICODE_SYMBOLS;
|
|
17
17
|
/**
|
|
18
18
|
* Converts three periods to a proper ellipsis character.
|
|
19
19
|
*
|
|
@@ -27,8 +27,12 @@ export function ellipsis(text, options = {}) {
|
|
|
27
27
|
const chr = options.separator
|
|
28
28
|
? escapeRegex(options.separator)
|
|
29
29
|
: ESCAPED_DEFAULT_SEPARATOR;
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
// Capture groups preserve separators: .(sep1)?.(sep2)?.
|
|
31
|
+
const pattern = new RegExp(`\\.(${chr})?\\.(${chr})?\\.`, "g");
|
|
32
|
+
text = text.replace(pattern, (_match, sep1, sep2) => {
|
|
33
|
+
// Preserve separators by appending them after the ellipsis
|
|
34
|
+
return ELLIPSIS + (sep1 || "") + (sep2 || "");
|
|
35
|
+
});
|
|
32
36
|
text = text.replace(new RegExp(`${ELLIPSIS}(?=\\w)`, "gu"), `${ELLIPSIS} `);
|
|
33
37
|
return text;
|
|
34
38
|
}
|
|
@@ -39,42 +43,24 @@ export function ellipsis(text, options = {}) {
|
|
|
39
43
|
* - Dimensions: "5x5" → "5×5"
|
|
40
44
|
* - Trailing multiplier: "5x" → "5×" (when followed by word boundary)
|
|
41
45
|
* - Asterisk multiplication: "5*3" → "5×3" (when between numbers)
|
|
42
|
-
*
|
|
43
|
-
* @example
|
|
44
|
-
* ```ts
|
|
45
|
-
* multiplication("The room is 10x12 feet")
|
|
46
|
-
* // → "The room is 10×12 feet"
|
|
47
|
-
*
|
|
48
|
-
* multiplication("2x speed")
|
|
49
|
-
* // → "2× speed"
|
|
50
|
-
* ```
|
|
51
46
|
*/
|
|
52
47
|
export function multiplication(text, options = {}) {
|
|
53
48
|
const chr = options.separator
|
|
54
49
|
? escapeRegex(options.separator)
|
|
55
50
|
: ESCAPED_DEFAULT_SEPARATOR;
|
|
56
51
|
// Dimensions with spaces: preserve spacing
|
|
57
|
-
const loosePattern = new RegExp(`(
|
|
58
|
-
text = text.replace(loosePattern,
|
|
52
|
+
const loosePattern = new RegExp(`(?<leftNum>\\d${chr}?)\\s+[xX*]\\s+(?<rightNum>${chr}?\\d)`, "g");
|
|
53
|
+
text = text.replace(loosePattern, `$<leftNum> ${MULTIPLICATION} $<rightNum>`);
|
|
59
54
|
// Dimensions without spaces: keep tight
|
|
60
|
-
const tightPattern = new RegExp(`(
|
|
61
|
-
text = text.replace(tightPattern,
|
|
55
|
+
const tightPattern = new RegExp(`(?<leftNum>\\d${chr}?)[xX*](?<rightNum>${chr}?\\d)`, "g");
|
|
56
|
+
text = text.replace(tightPattern, `$<leftNum>${MULTIPLICATION}$<rightNum>`);
|
|
62
57
|
// Trailing multiplier: 5x (followed by word boundary - space, punctuation, etc.)
|
|
63
|
-
const trailingPattern = new RegExp(`(
|
|
64
|
-
text = text.replace(trailingPattern,
|
|
58
|
+
const trailingPattern = new RegExp(`(?<num>\\d${chr}?)[xX*]\\b`, "g");
|
|
59
|
+
text = text.replace(trailingPattern, `$<num>${MULTIPLICATION}`);
|
|
65
60
|
return text;
|
|
66
61
|
}
|
|
67
62
|
/**
|
|
68
63
|
* Converts ASCII mathematical symbols to proper Unicode equivalents.
|
|
69
|
-
*
|
|
70
|
-
* @example
|
|
71
|
-
* ```ts
|
|
72
|
-
* mathSymbols("x != y and a <= b")
|
|
73
|
-
* // → "x ≠ y and a ≤ b"
|
|
74
|
-
*
|
|
75
|
-
* mathSymbols("The answer is +- 5%")
|
|
76
|
-
* // → "The answer is ± 5%"
|
|
77
|
-
* ```
|
|
78
64
|
*/
|
|
79
65
|
export function mathSymbols(text) {
|
|
80
66
|
return text
|
|
@@ -106,15 +92,6 @@ export function legalSymbols(text) {
|
|
|
106
92
|
*
|
|
107
93
|
* Note: Only converts when surrounded by spaces or at word boundaries
|
|
108
94
|
* to avoid false matches in code or URLs.
|
|
109
|
-
*
|
|
110
|
-
* @example
|
|
111
|
-
* ```ts
|
|
112
|
-
* arrows("A -> B -> C")
|
|
113
|
-
* // → "A → B → C"
|
|
114
|
-
*
|
|
115
|
-
* arrows("left <-> right")
|
|
116
|
-
* // → "left ↔ right"
|
|
117
|
-
* ```
|
|
118
95
|
*/
|
|
119
96
|
export function arrows(text, options = {}) {
|
|
120
97
|
const chr = options.separator
|
|
@@ -138,15 +115,6 @@ export function arrows(text, options = {}) {
|
|
|
138
115
|
*
|
|
139
116
|
* Only matches when followed by C or F (case insensitive) to avoid
|
|
140
117
|
* false positives.
|
|
141
|
-
*
|
|
142
|
-
* @example
|
|
143
|
-
* ```ts
|
|
144
|
-
* degrees("The temperature is 20 C")
|
|
145
|
-
* // → "The temperature is 20 °C"
|
|
146
|
-
*
|
|
147
|
-
* degrees("Water boils at 212F")
|
|
148
|
-
* // → "Water boils at 212 °F"
|
|
149
|
-
* ```
|
|
150
118
|
*/
|
|
151
119
|
export function degrees(text, options = {}) {
|
|
152
120
|
const chr = options.separator
|
|
@@ -154,7 +122,7 @@ export function degrees(text, options = {}) {
|
|
|
154
122
|
: ESCAPED_DEFAULT_SEPARATOR;
|
|
155
123
|
// Temperature with optional space before C or F
|
|
156
124
|
// Handles separator between digit and unit
|
|
157
|
-
return text.replace(new RegExp(`(
|
|
125
|
+
return text.replace(new RegExp(`(?<num>\\d${chr}?) ?(?<unit>[CF])\\b`, "gi"), (_, num, unit) => `${num} ${DEGREE}${unit.toUpperCase()}`);
|
|
158
126
|
}
|
|
159
127
|
/**
|
|
160
128
|
* Converts straight quotes after numbers to prime marks.
|
|
@@ -165,15 +133,6 @@ export function degrees(text, options = {}) {
|
|
|
165
133
|
*
|
|
166
134
|
* This should be called BEFORE smart quote transformations to prevent
|
|
167
135
|
* quotes in measurements from being curled.
|
|
168
|
-
*
|
|
169
|
-
* @example
|
|
170
|
-
* ```ts
|
|
171
|
-
* primeMarks("He's 5'10\" tall")
|
|
172
|
-
* // → "He's 5′10″ tall"
|
|
173
|
-
*
|
|
174
|
-
* primeMarks("Location: 45° 30' 15\"")
|
|
175
|
-
* // → "Location: 45° 30′ 15″"
|
|
176
|
-
* ```
|
|
177
136
|
*/
|
|
178
137
|
export function primeMarks(text, options = {}) {
|
|
179
138
|
const chr = options.separator
|
|
@@ -182,19 +141,19 @@ export function primeMarks(text, options = {}) {
|
|
|
182
141
|
// Single prime: Matches digit + optional separator + apostrophe
|
|
183
142
|
// Lookahead ensures it's followed by: another digit, double quote, end of string, or punctuation
|
|
184
143
|
// Examples: 5' (feet), 30' (arcminutes)
|
|
185
|
-
const singlePrimePattern = new RegExp(`(
|
|
186
|
-
text = text.replace(singlePrimePattern,
|
|
144
|
+
const singlePrimePattern = new RegExp(`(?<numWithSep>\\d${chr}?)'(?=${chr}?(?:\\d|"|$|[\\s.,;:!?)]))`, "g");
|
|
145
|
+
text = text.replace(singlePrimePattern, `$<numWithSep>${PRIME}`);
|
|
187
146
|
// Double prime Pattern 1: Feet-inches pattern
|
|
188
147
|
// Matches: prime symbol + optional separator + digit + optional separator + double quote
|
|
189
148
|
// Examples: 5′10" or 5'10" → 5′10″
|
|
190
|
-
const feetInchesPattern = new RegExp(`(
|
|
191
|
-
text = text.replace(feetInchesPattern,
|
|
149
|
+
const feetInchesPattern = new RegExp(`(?<primeAndNum>${PRIME}${chr}?\\d${chr}?)"`, "g");
|
|
150
|
+
text = text.replace(feetInchesPattern, `$<primeAndNum>${DOUBLE_PRIME}`);
|
|
192
151
|
// Double prime Pattern 2: Standalone inches
|
|
193
152
|
// Negative lookbehind: ensures no opening quote within 20 chars before the digit
|
|
194
153
|
// Negative lookahead: ensures not followed by word characters
|
|
195
154
|
// Matches: 12" wide ✓, but not: "Term 1" ✗
|
|
196
|
-
const standaloneInchesPattern = new RegExp(`(?<!["\u201C]${chr}?[^"${chr}]{0,20})(
|
|
197
|
-
text = text.replace(standaloneInchesPattern,
|
|
155
|
+
const standaloneInchesPattern = new RegExp(`(?<!["\u201C]${chr}?[^"${chr}]{0,20})(?<numWithSep>\\d${chr}?)"(?!${chr}?[\\w])`, "g");
|
|
156
|
+
text = text.replace(standaloneInchesPattern, `$<numWithSep>${DOUBLE_PRIME}`);
|
|
198
157
|
return text;
|
|
199
158
|
}
|
|
200
159
|
/**
|
|
@@ -250,6 +209,97 @@ export function fractions(text, options = {}) {
|
|
|
250
209
|
}
|
|
251
210
|
return text;
|
|
252
211
|
}
|
|
212
|
+
/**
|
|
213
|
+
* Map of ordinal suffixes to their Unicode superscript equivalents.
|
|
214
|
+
*/
|
|
215
|
+
const ORDINAL_MAP = {
|
|
216
|
+
st: SUPERSCRIPT_ST,
|
|
217
|
+
nd: SUPERSCRIPT_ND,
|
|
218
|
+
rd: SUPERSCRIPT_RD,
|
|
219
|
+
th: SUPERSCRIPT_TH,
|
|
220
|
+
};
|
|
221
|
+
/**
|
|
222
|
+
* Converts ordinal suffixes to Unicode superscript characters.
|
|
223
|
+
*
|
|
224
|
+
* Handles ordinal numbers like:
|
|
225
|
+
* - "1st" → "1ˢᵗ"
|
|
226
|
+
* - "2nd" → "2ⁿᵈ"
|
|
227
|
+
* - "3rd" → "3ʳᵈ"
|
|
228
|
+
* - "4th" → "4ᵗʰ"
|
|
229
|
+
*
|
|
230
|
+
* Works with any number ending in appropriate suffixes (21st, 42nd, 103rd, etc.)
|
|
231
|
+
*
|
|
232
|
+
* @example
|
|
233
|
+
* ```ts
|
|
234
|
+
* superscript("The 1st place winner")
|
|
235
|
+
* // → "The 1ˢᵗ place winner"
|
|
236
|
+
*
|
|
237
|
+
* superscript("Born on the 30th of June")
|
|
238
|
+
* // → "Born on the 30ᵗʰ of June"
|
|
239
|
+
* ```
|
|
240
|
+
*/
|
|
241
|
+
export function superscript(text, options = {}) {
|
|
242
|
+
const chr = options.separator
|
|
243
|
+
? escapeRegex(options.separator)
|
|
244
|
+
: ESCAPED_DEFAULT_SEPARATOR;
|
|
245
|
+
// Match number + optional separator + ordinal suffix at word boundary
|
|
246
|
+
// Use case-insensitive matching for the suffix
|
|
247
|
+
const pattern = new RegExp(`(?<num>\\d${chr}?)(?<suffix>st|nd|rd|th)\\b`, "gi");
|
|
248
|
+
return text.replace(pattern, (_match, num, suffix) => {
|
|
249
|
+
const superscriptSuffix = ORDINAL_MAP[suffix.toLowerCase()];
|
|
250
|
+
return num + superscriptSuffix;
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Collapses multiple consecutive spaces (including non-breaking spaces) into a single space.
|
|
255
|
+
*
|
|
256
|
+
* When multiple spaces or non-breaking spaces appear in sequence, this function
|
|
257
|
+
* keeps only the first space character, preserving its type.
|
|
258
|
+
*
|
|
259
|
+
* @example
|
|
260
|
+
* ```ts
|
|
261
|
+
* collapseSpaces("hello world")
|
|
262
|
+
* // → "hello world"
|
|
263
|
+
*
|
|
264
|
+
* collapseSpaces("foo\u00A0\u00A0bar") // two nbsp
|
|
265
|
+
* // → "foo\u00A0bar" // single nbsp
|
|
266
|
+
*
|
|
267
|
+
* collapseSpaces("a \u00A0b") // space followed by nbsp
|
|
268
|
+
* // → "a b" // keeps the first (regular space)
|
|
269
|
+
* ```
|
|
270
|
+
*/
|
|
271
|
+
export function collapseSpaces(text) {
|
|
272
|
+
return text.replace(new RegExp(`(?<first>[ ${NBSP}])[ ${NBSP}]+`, "g"), "$<first>");
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Converts repeated punctuation marks to Unicode ligature characters,
|
|
276
|
+
* squashing multiple marks to a single character.
|
|
277
|
+
*
|
|
278
|
+
* Handles:
|
|
279
|
+
* - "??" or "???" etc → "⁇" (squashed to double question mark ligature)
|
|
280
|
+
* - "?!" or "?!!" etc → "⁈" (question exclamation mark)
|
|
281
|
+
* - "!?" or "!??" etc → "⁉" (exclamation question mark)
|
|
282
|
+
* - "!!" or "!!!" etc → "!" (squashed to single exclamation)
|
|
283
|
+
*
|
|
284
|
+
* Note: These ligatures have poor font support, so this function is
|
|
285
|
+
* disabled by default.
|
|
286
|
+
*/
|
|
287
|
+
export function punctuationLigatures(text, options = {}) {
|
|
288
|
+
const chr = options.separator
|
|
289
|
+
? escapeRegex(options.separator)
|
|
290
|
+
: ESCAPED_DEFAULT_SEPARATOR;
|
|
291
|
+
// Order matters: handle mixed punctuation first, then repeated
|
|
292
|
+
// Patterns capture separators between characters and preserve them after the ligature
|
|
293
|
+
// ?!+ → ⁈ (question followed by one or more exclamation marks)
|
|
294
|
+
text = text.replace(new RegExp(`\\?(${chr})?!(?:${chr}?!)*`, "g"), (_match, sep) => QUESTION_EXCLAMATION + (sep || ""));
|
|
295
|
+
// !?+ → ⁉ (exclamation followed by one or more question marks)
|
|
296
|
+
text = text.replace(new RegExp(`!(${chr})?\\?(?:${chr}?\\?)*`, "g"), (_match, sep) => EXCLAMATION_QUESTION + (sep || ""));
|
|
297
|
+
// ??+ → ⁇ (two or more question marks squashed to ligature)
|
|
298
|
+
text = text.replace(new RegExp(`\\?(${chr})?\\?(?:${chr}?\\?)*`, "g"), (_match, sep) => DOUBLE_QUESTION + (sep || ""));
|
|
299
|
+
// !!+ → ! (two or more exclamation marks squashed to single)
|
|
300
|
+
text = text.replace(new RegExp(`!(${chr})?!(?:${chr}?!)*`, "g"), (_match, sep) => "!" + (sep || ""));
|
|
301
|
+
return text;
|
|
302
|
+
}
|
|
253
303
|
/**
|
|
254
304
|
* Applies all symbol transformations.
|
|
255
305
|
*
|
package/dist/symbols.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"symbols.js","sourceRoot":"","sources":["../src/symbols.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,eAAe,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAA;AAe3E;;GAEG;AACH,SAAS,WAAW,CAAC,GAAW;IAC9B,OAAO,GAAG,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAA;AACnD,CAAC;AAED,MAAM,EACJ,QAAQ,EACR,cAAc,EACd,SAAS,EACT,UAAU,EACV,SAAS,EACT,UAAU,EACV,SAAS,EACT,MAAM,EACN,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,aAAa,EACb,KAAK,EACL,YAAY,
|
|
1
|
+
{"version":3,"file":"symbols.js","sourceRoot":"","sources":["../src/symbols.ts"],"names":[],"mappings":"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"}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for text transformation validation.
|
|
3
|
+
*
|
|
4
|
+
* @module utils
|
|
5
|
+
*/
|
|
6
|
+
export declare function countSeparators(text: string, separator?: string): number;
|
|
7
|
+
/**
|
|
8
|
+
* Validates that a transformation preserved the separator count.
|
|
9
|
+
* Throws an error if separators were added or removed.
|
|
10
|
+
*
|
|
11
|
+
* @param original - The original text before transformation
|
|
12
|
+
* @param transformed - The text after transformation
|
|
13
|
+
* @param separator - The separator character to check (default: DEFAULT_SEPARATOR)
|
|
14
|
+
* @param transformName - Name of the transform for error messages (default: "transform")
|
|
15
|
+
* @throws Error if separator count changed
|
|
16
|
+
*/
|
|
17
|
+
export declare function assertSeparatorCountPreserved(original: string, transformed: string, separator?: string, transformName?: string): void;
|
|
18
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,GAAE,MAA0B,GAAG,MAAM,CAM3F;AAED;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,SAAS,GAAE,MAA0B,EACrC,aAAa,GAAE,MAAoB,GAClC,IAAI,CAQN"}
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for text transformation validation.
|
|
3
|
+
*
|
|
4
|
+
* @module utils
|
|
5
|
+
*/
|
|
6
|
+
import { DEFAULT_SEPARATOR } from "./constants.js";
|
|
7
|
+
export function countSeparators(text, separator = DEFAULT_SEPARATOR) {
|
|
8
|
+
let count = 0;
|
|
9
|
+
for (const char of text) {
|
|
10
|
+
if (char === separator)
|
|
11
|
+
count++;
|
|
12
|
+
}
|
|
13
|
+
return count;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Validates that a transformation preserved the separator count.
|
|
17
|
+
* Throws an error if separators were added or removed.
|
|
18
|
+
*
|
|
19
|
+
* @param original - The original text before transformation
|
|
20
|
+
* @param transformed - The text after transformation
|
|
21
|
+
* @param separator - The separator character to check (default: DEFAULT_SEPARATOR)
|
|
22
|
+
* @param transformName - Name of the transform for error messages (default: "transform")
|
|
23
|
+
* @throws Error if separator count changed
|
|
24
|
+
*/
|
|
25
|
+
export function assertSeparatorCountPreserved(original, transformed, separator = DEFAULT_SEPARATOR, transformName = "transform") {
|
|
26
|
+
const originalCount = countSeparators(original, separator);
|
|
27
|
+
const transformedCount = countSeparators(transformed, separator);
|
|
28
|
+
if (originalCount !== transformedCount) {
|
|
29
|
+
throw new Error(`${transformName} altered separator count: expected ${originalCount}, got ${transformedCount}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +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,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,YAAoB,iBAAiB;IACjF,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;QACxB,IAAI,IAAI,KAAK,SAAS;YAAE,KAAK,EAAE,CAAA;IACjC,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,EAAE,CAC/F,CAAA;IACH,CAAC;AACH,CAAC"}
|