punctilio 0.2.0 → 0.2.1
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 +58 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +58 -0
- package/dist/constants.js.map +1 -0
- package/dist/dashes.d.ts.map +1 -1
- package/dist/dashes.js +14 -21
- package/dist/dashes.js.map +1 -1
- package/dist/quotes.d.ts.map +1 -1
- package/dist/quotes.js +19 -42
- package/dist/quotes.js.map +1 -1
- package/dist/symbols.d.ts +5 -14
- package/dist/symbols.d.ts.map +1 -1
- package/dist/symbols.js +35 -66
- package/dist/symbols.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Unicode constants used throughout the punctilio package.
|
|
3
|
+
*
|
|
4
|
+
* This module provides a centralized location for all Unicode symbols
|
|
5
|
+
* used in typography transformations, making the codebase more maintainable
|
|
6
|
+
* and self-documenting.
|
|
7
|
+
*
|
|
8
|
+
* @module constants
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Unicode symbols for typography transformations.
|
|
12
|
+
*/
|
|
13
|
+
export declare const UNICODE_SYMBOLS: {
|
|
14
|
+
readonly ELLIPSIS: "…";
|
|
15
|
+
readonly MULTIPLICATION: "×";
|
|
16
|
+
readonly NOT_EQUAL: "≠";
|
|
17
|
+
readonly PLUS_MINUS: "±";
|
|
18
|
+
readonly COPYRIGHT: "©";
|
|
19
|
+
readonly REGISTERED: "®";
|
|
20
|
+
readonly TRADEMARK: "™";
|
|
21
|
+
readonly DEGREE: "°";
|
|
22
|
+
readonly ARROW_RIGHT: "→";
|
|
23
|
+
readonly ARROW_LEFT: "←";
|
|
24
|
+
readonly ARROW_LEFT_RIGHT: "↔";
|
|
25
|
+
readonly APPROXIMATE: "≈";
|
|
26
|
+
readonly LESS_EQUAL: "≤";
|
|
27
|
+
readonly GREATER_EQUAL: "≥";
|
|
28
|
+
readonly PRIME: "′";
|
|
29
|
+
readonly DOUBLE_PRIME: "″";
|
|
30
|
+
readonly FRACTION_1_4: "¼";
|
|
31
|
+
readonly FRACTION_1_2: "½";
|
|
32
|
+
readonly FRACTION_3_4: "¾";
|
|
33
|
+
readonly FRACTION_1_3: "⅓";
|
|
34
|
+
readonly FRACTION_2_3: "⅔";
|
|
35
|
+
readonly FRACTION_1_5: "⅕";
|
|
36
|
+
readonly FRACTION_2_5: "⅖";
|
|
37
|
+
readonly FRACTION_3_5: "⅗";
|
|
38
|
+
readonly FRACTION_4_5: "⅘";
|
|
39
|
+
readonly FRACTION_1_6: "⅙";
|
|
40
|
+
readonly FRACTION_5_6: "⅚";
|
|
41
|
+
readonly FRACTION_1_8: "⅛";
|
|
42
|
+
readonly FRACTION_3_8: "⅜";
|
|
43
|
+
readonly FRACTION_5_8: "⅝";
|
|
44
|
+
readonly FRACTION_7_8: "⅞";
|
|
45
|
+
readonly EM_DASH: "—";
|
|
46
|
+
readonly EN_DASH: "–";
|
|
47
|
+
readonly MINUS: "−";
|
|
48
|
+
readonly LEFT_DOUBLE_QUOTE: "“";
|
|
49
|
+
readonly RIGHT_DOUBLE_QUOTE: "”";
|
|
50
|
+
readonly LEFT_SINGLE_QUOTE: "‘";
|
|
51
|
+
readonly RIGHT_SINGLE_QUOTE: "’";
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Default separator character for text spanning HTML elements.
|
|
55
|
+
* Uses Unicode Private Use Area character U+E000.
|
|
56
|
+
*/
|
|
57
|
+
export declare const DEFAULT_SEPARATOR = "\uE000";
|
|
58
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;GAEG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuClB,CAAA;AAEV;;;GAGG;AACH,eAAO,MAAM,iBAAiB,WAAW,CAAA"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Unicode constants used throughout the punctilio package.
|
|
3
|
+
*
|
|
4
|
+
* This module provides a centralized location for all Unicode symbols
|
|
5
|
+
* used in typography transformations, making the codebase more maintainable
|
|
6
|
+
* and self-documenting.
|
|
7
|
+
*
|
|
8
|
+
* @module constants
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Unicode symbols for typography transformations.
|
|
12
|
+
*/
|
|
13
|
+
export const UNICODE_SYMBOLS = {
|
|
14
|
+
ELLIPSIS: "\u2026",
|
|
15
|
+
MULTIPLICATION: "\u00D7",
|
|
16
|
+
NOT_EQUAL: "\u2260",
|
|
17
|
+
PLUS_MINUS: "\u00B1",
|
|
18
|
+
COPYRIGHT: "\u00A9",
|
|
19
|
+
REGISTERED: "\u00AE",
|
|
20
|
+
TRADEMARK: "\u2122",
|
|
21
|
+
DEGREE: "\u00B0",
|
|
22
|
+
ARROW_RIGHT: "\u2192",
|
|
23
|
+
ARROW_LEFT: "\u2190",
|
|
24
|
+
ARROW_LEFT_RIGHT: "\u2194",
|
|
25
|
+
APPROXIMATE: "\u2248",
|
|
26
|
+
LESS_EQUAL: "\u2264",
|
|
27
|
+
GREATER_EQUAL: "\u2265",
|
|
28
|
+
PRIME: "\u2032",
|
|
29
|
+
DOUBLE_PRIME: "\u2033",
|
|
30
|
+
FRACTION_1_4: "\u00BC",
|
|
31
|
+
FRACTION_1_2: "\u00BD",
|
|
32
|
+
FRACTION_3_4: "\u00BE",
|
|
33
|
+
FRACTION_1_3: "\u2153",
|
|
34
|
+
FRACTION_2_3: "\u2154",
|
|
35
|
+
FRACTION_1_5: "\u2155",
|
|
36
|
+
FRACTION_2_5: "\u2156",
|
|
37
|
+
FRACTION_3_5: "\u2157",
|
|
38
|
+
FRACTION_4_5: "\u2158",
|
|
39
|
+
FRACTION_1_6: "\u2159",
|
|
40
|
+
FRACTION_5_6: "\u215A",
|
|
41
|
+
FRACTION_1_8: "\u215B",
|
|
42
|
+
FRACTION_3_8: "\u215C",
|
|
43
|
+
FRACTION_5_8: "\u215D",
|
|
44
|
+
FRACTION_7_8: "\u215E",
|
|
45
|
+
EM_DASH: "\u2014",
|
|
46
|
+
EN_DASH: "\u2013",
|
|
47
|
+
MINUS: "\u2212",
|
|
48
|
+
LEFT_DOUBLE_QUOTE: "\u201C",
|
|
49
|
+
RIGHT_DOUBLE_QUOTE: "\u201D",
|
|
50
|
+
LEFT_SINGLE_QUOTE: "\u2018",
|
|
51
|
+
RIGHT_SINGLE_QUOTE: "\u2019",
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Default separator character for text spanning HTML elements.
|
|
55
|
+
* Uses Unicode Private Use Area character U+E000.
|
|
56
|
+
*/
|
|
57
|
+
export const DEFAULT_SEPARATOR = "\uE000";
|
|
58
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,QAAQ,EAAE,QAAQ;IAClB,cAAc,EAAE,QAAQ;IACxB,SAAS,EAAE,QAAQ;IACnB,UAAU,EAAE,QAAQ;IACpB,SAAS,EAAE,QAAQ;IACnB,UAAU,EAAE,QAAQ;IACpB,SAAS,EAAE,QAAQ;IACnB,MAAM,EAAE,QAAQ;IAChB,WAAW,EAAE,QAAQ;IACrB,UAAU,EAAE,QAAQ;IACpB,gBAAgB,EAAE,QAAQ;IAC1B,WAAW,EAAE,QAAQ;IACrB,UAAU,EAAE,QAAQ;IACpB,aAAa,EAAE,QAAQ;IACvB,KAAK,EAAE,QAAQ;IACf,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE,QAAQ;IACtB,OAAO,EAAE,QAAQ;IACjB,OAAO,EAAE,QAAQ;IACjB,KAAK,EAAE,QAAQ;IACf,iBAAiB,EAAE,QAAQ;IAC3B,kBAAkB,EAAE,QAAQ;IAC5B,iBAAiB,EAAE,QAAQ;IAC3B,kBAAkB,EAAE,QAAQ;CACpB,CAAA;AAEV;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,QAAQ,CAAA"}
|
package/dist/dashes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashes.d.ts","sourceRoot":"","sources":["../src/dashes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"dashes.d.ts","sourceRoot":"","sources":["../src/dashes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,WAAW,WAAW;IAC1B;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAID;;GAEG;AACH,eAAO,MAAM,MAAM,QAyBR,CAAA;AAEX;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CASjF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAM/E;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAI5E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAwC7E"}
|
package/dist/dashes.js
CHANGED
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
* Converts hyphens and dashes to typographically correct em-dashes,
|
|
5
5
|
* en-dashes, and minus signs based on context.
|
|
6
6
|
*/
|
|
7
|
-
|
|
7
|
+
import { UNICODE_SYMBOLS, DEFAULT_SEPARATOR } from "./constants.js";
|
|
8
|
+
const { EN_DASH, EM_DASH, MINUS } = UNICODE_SYMBOLS;
|
|
8
9
|
/**
|
|
9
10
|
* List of month names (full and abbreviated) for date range detection
|
|
10
11
|
*/
|
|
@@ -59,7 +60,7 @@ export const months = [
|
|
|
59
60
|
*/
|
|
60
61
|
export function enDashNumberRange(text, options = {}) {
|
|
61
62
|
const chr = options.separator ?? DEFAULT_SEPARATOR;
|
|
62
|
-
return text.replace(new RegExp(`\\b(?<![a-zA-Z.])((?:p\\.?|\\$)?\\d[\\d.,]*${chr}?)-(${chr}?\\$?\\d[\\d.,]*)(?!\\.\\d)\\b`, "g"),
|
|
63
|
+
return text.replace(new RegExp(`\\b(?<![a-zA-Z.])((?:p\\.?|\\$)?\\d[\\d.,]*${chr}?)-(${chr}?\\$?\\d[\\d.,]*)(?!\\.\\d)\\b`, "g"), `$1${EN_DASH}$2`);
|
|
63
64
|
}
|
|
64
65
|
/**
|
|
65
66
|
* Replaces hyphens with en-dashes in month/date ranges.
|
|
@@ -80,7 +81,7 @@ export function enDashNumberRange(text, options = {}) {
|
|
|
80
81
|
*/
|
|
81
82
|
export function enDashDateRange(text, options = {}) {
|
|
82
83
|
const chr = options.separator ?? DEFAULT_SEPARATOR;
|
|
83
|
-
return text.replace(new RegExp(`\\b(${months}${chr}?)-(${chr}?(?:${months}))\\b`, "g"),
|
|
84
|
+
return text.replace(new RegExp(`\\b(${months}${chr}?)-(${chr}?(?:${months}))\\b`, "g"), `$1${EN_DASH}$2`);
|
|
84
85
|
}
|
|
85
86
|
/**
|
|
86
87
|
* Replaces hyphens with proper minus signs (−) in numerical contexts.
|
|
@@ -104,7 +105,7 @@ export function enDashDateRange(text, options = {}) {
|
|
|
104
105
|
export function minusReplace(text, options = {}) {
|
|
105
106
|
const chr = options.separator ?? DEFAULT_SEPARATOR;
|
|
106
107
|
const minusRegex = new RegExp(`(^|[\\s\\(${chr}""])-(\\s?\\d*\\.?\\d+)`, "gm");
|
|
107
|
-
return text.replaceAll(minusRegex,
|
|
108
|
+
return text.replaceAll(minusRegex, `$1${MINUS}$2`);
|
|
108
109
|
}
|
|
109
110
|
/**
|
|
110
111
|
* Comprehensive dash replacement for typographic correctness.
|
|
@@ -146,25 +147,17 @@ export function hyphenReplace(text, options = {}) {
|
|
|
146
147
|
// Being right after chr is a sufficient condition for being an em
|
|
147
148
|
// dash, as it indicates the start of a new line
|
|
148
149
|
const preDash = new RegExp(`((?<markerBeforeTwo>${chr}?)[ ]+|(?<markerBeforeThree>${chr}))`);
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
text = text.replace(
|
|
153
|
-
|
|
154
|
-
const
|
|
155
|
-
text = text.replace(
|
|
156
|
-
// Handle dashes at the start of a line
|
|
157
|
-
text = text.replace(new RegExp(`^(${chr})?[-]+ `, "gm"), "$1— ");
|
|
158
|
-
// Create a regex for spaces around em dashes, allowing for optional spaces around the em dash
|
|
159
|
-
const spacesAroundEM = new RegExp(`(?<markerBefore>${chr}?)[ ]*—[ ]*(?<markerAfter>${chr}?)[ ]*`, "g");
|
|
160
|
-
// Remove spaces around em dashes
|
|
161
|
-
text = text.replace(spacesAroundEM, "$<markerBefore>—$<markerAfter>");
|
|
162
|
-
// Handle special case after quotation marks
|
|
150
|
+
const surroundedDash = new RegExp(`(?<=[^\\s>]|^)${preDash.source}[~${EN_DASH}${EM_DASH}-]+[ ]*(?<markerAfter>${chr}?)([ ]+|$)`, "g");
|
|
151
|
+
text = text.replace(surroundedDash, `$<markerBeforeTwo>$<markerBeforeThree>${EM_DASH}$<markerAfter>`);
|
|
152
|
+
const multipleDashInWords = new RegExp(`(?<=[A-Za-z\\d])(?<markerBefore>${chr}?)[~${EN_DASH}${EM_DASH}-]{2,}(?<markerAfter>${chr}?)(?=[A-Za-z\\d ])`, "g");
|
|
153
|
+
text = text.replace(multipleDashInWords, `$<markerBefore>${EM_DASH}$<markerAfter>`);
|
|
154
|
+
text = text.replace(new RegExp(`^(${chr})?[-]+ `, "gm"), `$1${EM_DASH} `);
|
|
155
|
+
const spacesAroundEM = new RegExp(`(?<markerBefore>${chr}?)[ ]*${EM_DASH}[ ]*(?<markerAfter>${chr}?)[ ]*`, "g");
|
|
156
|
+
text = text.replace(spacesAroundEM, `$<markerBefore>${EM_DASH}$<markerAfter>`);
|
|
163
157
|
const postQuote = new RegExp(`(?<quote>[.!?]${chr}?['"'"]${chr}?|…)${spacesAroundEM.source}`, "g");
|
|
164
|
-
text = text.replace(postQuote,
|
|
165
|
-
// Handle em dashes at the start of a line
|
|
158
|
+
text = text.replace(postQuote, `$<quote> $<markerBefore>${EM_DASH}$<markerAfter> `);
|
|
166
159
|
const startOfLine = new RegExp(`^${spacesAroundEM.source}(?<after>[A-Z0-9])`, "gm");
|
|
167
|
-
text = text.replace(startOfLine,
|
|
160
|
+
text = text.replace(startOfLine, `$<markerBefore>${EM_DASH}$<markerAfter> $<after>`);
|
|
168
161
|
text = enDashNumberRange(text, options);
|
|
169
162
|
text = enDashDateRange(text, options);
|
|
170
163
|
return text;
|
package/dist/dashes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashes.js","sourceRoot":"","sources":["../src/dashes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"dashes.js","sourceRoot":"","sources":["../src/dashes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAcnE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,eAAe,CAAA;AAEnD;;GAEG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,SAAS;IACT,UAAU;IACV,OAAO;IACP,OAAO;IACP,KAAK;IACL,MAAM;IACN,MAAM;IACN,QAAQ;IACR,WAAW;IACX,SAAS;IACT,UAAU;IACV,UAAU;IACV,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;CACN,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAEX;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,UAAuB,EAAE;IACvE,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,IAAI,iBAAiB,CAAA;IAClD,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,MAAM,CACR,8CAA8C,GAAG,OAAO,GAAG,gCAAgC,EAC3F,GAAG,CACJ,EACD,KAAK,OAAO,IAAI,CACjB,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,UAAuB,EAAE;IACrE,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,IAAI,iBAAiB,CAAA;IAClD,OAAO,IAAI,CAAC,OAAO,CACjB,IAAI,MAAM,CAAC,OAAO,MAAM,GAAG,GAAG,OAAO,GAAG,OAAO,MAAM,OAAO,EAAE,GAAG,CAAC,EAClE,KAAK,OAAO,IAAI,CACjB,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,UAAuB,EAAE;IAClE,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,IAAI,iBAAiB,CAAA;IAClD,MAAM,UAAU,GAAG,IAAI,MAAM,CAAC,aAAa,GAAG,yBAAyB,EAAE,IAAI,CAAC,CAAA;IAC9E,OAAO,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,KAAK,KAAK,IAAI,CAAC,CAAA;AACpD,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,UAAuB,EAAE;IACnE,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,IAAI,iBAAiB,CAAA;IAElD,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IAElC,oEAAoE;IACpE,mEAAmE;IACnE,iDAAiD;IACjD,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,uBAAuB,GAAG,+BAA+B,GAAG,IAAI,CAAC,CAAA;IAC5F,MAAM,cAAc,GAAG,IAAI,MAAM,CAC/B,iBAAiB,OAAO,CAAC,MAAM,KAAK,OAAO,GAAG,OAAO,yBAAyB,GAAG,YAAY,EAC7F,GAAG,CACJ,CAAA;IAED,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,yCAAyC,OAAO,gBAAgB,CAAC,CAAA;IAErG,MAAM,mBAAmB,GAAG,IAAI,MAAM,CACpC,mCAAmC,GAAG,OAAO,OAAO,GAAG,OAAO,wBAAwB,GAAG,oBAAoB,EAC7G,GAAG,CACJ,CAAA;IACD,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,kBAAkB,OAAO,gBAAgB,CAAC,CAAA;IAEnF,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,KAAK,GAAG,SAAS,EAAE,IAAI,CAAC,EAAE,KAAK,OAAO,GAAG,CAAC,CAAA;IAEzE,MAAM,cAAc,GAAG,IAAI,MAAM,CAC/B,mBAAmB,GAAG,SAAS,OAAO,sBAAsB,GAAG,QAAQ,EACvE,GAAG,CACJ,CAAA;IACD,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,kBAAkB,OAAO,gBAAgB,CAAC,CAAA;IAE9E,MAAM,SAAS,GAAG,IAAI,MAAM,CAAC,iBAAiB,GAAG,UAAU,GAAG,OAAO,cAAc,CAAC,MAAM,EAAE,EAAE,GAAG,CAAC,CAAA;IAClG,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,2BAA2B,OAAO,iBAAiB,CAAC,CAAA;IAEnF,MAAM,WAAW,GAAG,IAAI,MAAM,CAAC,IAAI,cAAc,CAAC,MAAM,oBAAoB,EAAE,IAAI,CAAC,CAAA;IACnF,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,kBAAkB,OAAO,yBAAyB,CAAC,CAAA;IAEpF,IAAI,GAAG,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IACvC,IAAI,GAAG,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IAErC,OAAO,IAAI,CAAA;AACb,CAAC"}
|
package/dist/quotes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quotes.d.ts","sourceRoot":"","sources":["../src/quotes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"quotes.d.ts","sourceRoot":"","sources":["../src/quotes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAaH,MAAM,WAAW,YAAY;IAC3B;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,MAAM,CA8C3E"}
|
package/dist/quotes.js
CHANGED
|
@@ -4,14 +4,8 @@
|
|
|
4
4
|
* Converts straight quotes to typographically correct curly quotes,
|
|
5
5
|
* handling contractions, possessives, and nested quotes.
|
|
6
6
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const EM_DASH = "\u2014"; // —
|
|
10
|
-
const LEFT_DOUBLE = "\u201C"; // "
|
|
11
|
-
const RIGHT_DOUBLE = "\u201D"; // "
|
|
12
|
-
const LEFT_SINGLE = "\u2018"; // '
|
|
13
|
-
const RIGHT_SINGLE = "\u2019"; // '
|
|
14
|
-
const ELLIPSIS = "\u2026"; // …
|
|
7
|
+
import { UNICODE_SYMBOLS, DEFAULT_SEPARATOR } from "./constants.js";
|
|
8
|
+
const { EM_DASH, LEFT_DOUBLE_QUOTE, RIGHT_DOUBLE_QUOTE, LEFT_SINGLE_QUOTE, RIGHT_SINGLE_QUOTE, ELLIPSIS, } = UNICODE_SYMBOLS;
|
|
15
9
|
/**
|
|
16
10
|
* Converts standard quotes to typographic smart quotes.
|
|
17
11
|
*
|
|
@@ -21,45 +15,28 @@ const ELLIPSIS = "\u2026"; // …
|
|
|
21
15
|
*/
|
|
22
16
|
export function niceQuotes(text, options = {}) {
|
|
23
17
|
const chr = options.separator ?? DEFAULT_SEPARATOR;
|
|
24
|
-
// Single quotes //
|
|
25
|
-
// Ending comes first so as to not mess with the open quote
|
|
26
18
|
const afterEndingSinglePatterns = `\\s\\.!?;,\\)${EM_DASH}\\-\\]"`;
|
|
27
19
|
const afterEndingSingle = `(?=${chr}?(?:s${chr}?)?(?:[${afterEndingSinglePatterns}]|$))`;
|
|
28
|
-
const endingSingle = `(?<=[^\\s${
|
|
29
|
-
text = text.replace(new RegExp(endingSingle, "gm"),
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
// Note: The character class uses LEFT_SINGLE and ASCII straight quote (U+0027)
|
|
39
|
-
// NOT RIGHT_SINGLE - this is intentional for the algorithm to work correctly
|
|
40
|
-
const apostropheRegex = new RegExp(`(?<=^|[^\\w])'(${apostropheWhitelist}|(?![^${LEFT_SINGLE}'\\n]*${endQuoteNotContraction}))`, "gm");
|
|
41
|
-
text = text.replace(apostropheRegex, RIGHT_SINGLE);
|
|
42
|
-
// Beginning single quotes
|
|
43
|
-
const beginningSingle = `((?:^|[\\s${LEFT_DOUBLE}${RIGHT_DOUBLE}\\-\\(])${chr}?)['](?=${chr}?\\S)`;
|
|
44
|
-
text = text.replace(new RegExp(beginningSingle, "gm"), `$1${LEFT_SINGLE}`);
|
|
45
|
-
// Double quotes //
|
|
20
|
+
const endingSingle = `(?<=[^\\s${LEFT_DOUBLE_QUOTE}'])[']${afterEndingSingle}`;
|
|
21
|
+
text = text.replace(new RegExp(endingSingle, "gm"), RIGHT_SINGLE_QUOTE);
|
|
22
|
+
const contraction = `(?<=[A-Za-z])['${RIGHT_SINGLE_QUOTE}](?=${chr}?[a-zA-Z])`;
|
|
23
|
+
text = text.replace(new RegExp(contraction, "gm"), RIGHT_SINGLE_QUOTE);
|
|
24
|
+
const apostropheWhitelist = `(?=n${RIGHT_SINGLE_QUOTE} )`;
|
|
25
|
+
const endQuoteNotContraction = `(?!${contraction})${RIGHT_SINGLE_QUOTE}${afterEndingSingle}`;
|
|
26
|
+
const apostropheRegex = new RegExp(`(?<=^|[^\\w])'(${apostropheWhitelist}|(?![^${LEFT_SINGLE_QUOTE}'\\n]*${endQuoteNotContraction}))`, "gm");
|
|
27
|
+
text = text.replace(apostropheRegex, RIGHT_SINGLE_QUOTE);
|
|
28
|
+
const beginningSingle = `((?:^|[\\s${LEFT_DOUBLE_QUOTE}${RIGHT_DOUBLE_QUOTE}\\-\\(])${chr}?)['](?=${chr}?\\S)`;
|
|
29
|
+
text = text.replace(new RegExp(beginningSingle, "gm"), `$1${LEFT_SINGLE_QUOTE}`);
|
|
46
30
|
const beginningDouble = new RegExp(`(?<=^|[\\s\\(\\/\\[\\{\\-${EM_DASH}${chr}])(?<beforeChr>${chr}?)["](?<afterChr>(${chr}[ .,])|(?=${chr}?\\.{3}|${chr}?[^\\s\\)\\${EM_DASH},!?${chr};:.\\}]))`, "gm");
|
|
47
|
-
text = text.replace(beginningDouble, `$<beforeChr>${
|
|
48
|
-
|
|
49
|
-
text = text.replace(new RegExp(`(?<=\\{)(${chr}? )?["]`, "g"), `$1${LEFT_DOUBLE}`);
|
|
50
|
-
// note: Allowing 2 chrs in a row
|
|
31
|
+
text = text.replace(beginningDouble, `$<beforeChr>${LEFT_DOUBLE_QUOTE}$<afterChr>`);
|
|
32
|
+
text = text.replace(new RegExp(`(?<=\\{)(${chr}? )?["]`, "g"), `$1${LEFT_DOUBLE_QUOTE}`);
|
|
51
33
|
const endingDouble = `([^\\s\\(])["](${chr}?)(?=${chr}|[\\s/\\).,;${EM_DASH}:\\-\\}!?s]|$)`;
|
|
52
|
-
text = text.replace(new RegExp(endingDouble, "g"), `$1${
|
|
53
|
-
|
|
54
|
-
text = text.replace(new RegExp(`
|
|
55
|
-
|
|
56
|
-
text = text.replace(new RegExp(`'(?=${RIGHT_DOUBLE})`, "gu"), RIGHT_SINGLE);
|
|
57
|
-
// Punctuation //
|
|
58
|
-
// Periods inside quotes
|
|
59
|
-
const periodRegex = new RegExp(`(?<![!?:\\.${ELLIPSIS}])(${chr}?)([${RIGHT_SINGLE}${RIGHT_DOUBLE}])(${chr}?)(?!\\.\\.\\.)\\.`, "g");
|
|
34
|
+
text = text.replace(new RegExp(endingDouble, "g"), `$1${RIGHT_DOUBLE_QUOTE}$2`);
|
|
35
|
+
text = text.replace(new RegExp(`["](${chr}?)$`, "g"), `${RIGHT_DOUBLE_QUOTE}$1`);
|
|
36
|
+
text = text.replace(new RegExp(`'(?=${RIGHT_DOUBLE_QUOTE})`, "gu"), RIGHT_SINGLE_QUOTE);
|
|
37
|
+
const periodRegex = new RegExp(`(?<![!?:\\.${ELLIPSIS}])(${chr}?)([${RIGHT_SINGLE_QUOTE}${RIGHT_DOUBLE_QUOTE}])(${chr}?)(?!\\.\\.\\.)\\.`, "g");
|
|
60
38
|
text = text.replace(periodRegex, "$1.$2$3");
|
|
61
|
-
|
|
62
|
-
const commaRegex = new RegExp(`(?<![!?]),(${chr}?[${RIGHT_DOUBLE}${RIGHT_SINGLE}])`, "g");
|
|
39
|
+
const commaRegex = new RegExp(`(?<![!?]),(${chr}?[${RIGHT_DOUBLE_QUOTE}${RIGHT_SINGLE_QUOTE}])`, "g");
|
|
63
40
|
text = text.replace(commaRegex, "$1,");
|
|
64
41
|
return text;
|
|
65
42
|
}
|
package/dist/quotes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quotes.js","sourceRoot":"","sources":["../src/quotes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"quotes.js","sourceRoot":"","sources":["../src/quotes.ts"],"names":[],"mappings":"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"}
|
package/dist/symbols.d.ts
CHANGED
|
@@ -12,6 +12,11 @@ export interface SymbolOptions {
|
|
|
12
12
|
* Default: "\uE000" (Unicode Private Use Area)
|
|
13
13
|
*/
|
|
14
14
|
separator?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Whether to include arrow transformations (-> to →, etc.).
|
|
17
|
+
* Default: true
|
|
18
|
+
*/
|
|
19
|
+
includeArrows?: boolean;
|
|
15
20
|
}
|
|
16
21
|
/**
|
|
17
22
|
* Converts three periods to a proper ellipsis character.
|
|
@@ -64,20 +69,6 @@ export declare function mathSymbols(text: string): string;
|
|
|
64
69
|
/**
|
|
65
70
|
* Converts ASCII representations of copyright, registered, and trademark
|
|
66
71
|
* symbols to proper Unicode characters.
|
|
67
|
-
*
|
|
68
|
-
* Handles:
|
|
69
|
-
* - "(c)" or "(C)" → "©"
|
|
70
|
-
* - "(r)" or "(R)" → "®"
|
|
71
|
-
* - "(tm)" or "(TM)" → "™"
|
|
72
|
-
*
|
|
73
|
-
* @example
|
|
74
|
-
* ```ts
|
|
75
|
-
* legalSymbols("Copyright (c) 2024 Acme Inc.")
|
|
76
|
-
* // → "Copyright © 2024 Acme Inc."
|
|
77
|
-
*
|
|
78
|
-
* legalSymbols("Brand Name(tm)")
|
|
79
|
-
* // → "Brand Name™"
|
|
80
|
-
* ```
|
|
81
72
|
*/
|
|
82
73
|
export declare function legalSymbols(text: string): string;
|
|
83
74
|
/**
|
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;
|
|
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;AA4BD;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAS1E;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAgBhF;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAUhD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMjD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAaxE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAO5C;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CA0B5E;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAyB9C;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CASjF"}
|
package/dist/symbols.js
CHANGED
|
@@ -6,30 +6,14 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @module symbols
|
|
8
8
|
*/
|
|
9
|
-
|
|
9
|
+
import { UNICODE_SYMBOLS, DEFAULT_SEPARATOR } from "./constants.js";
|
|
10
10
|
/**
|
|
11
11
|
* Escapes special regex characters in a string.
|
|
12
12
|
*/
|
|
13
13
|
function escapeRegex(str) {
|
|
14
14
|
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
15
15
|
}
|
|
16
|
-
|
|
17
|
-
const ELLIPSIS = "\u2026"; // …
|
|
18
|
-
const MULTIPLICATION = "\u00D7"; // ×
|
|
19
|
-
const NOT_EQUAL = "\u2260"; // ≠
|
|
20
|
-
const PLUS_MINUS = "\u00B1"; // ±
|
|
21
|
-
const COPYRIGHT = "\u00A9"; // ©
|
|
22
|
-
const REGISTERED = "\u00AE"; // ®
|
|
23
|
-
const TRADEMARK = "\u2122"; // ™
|
|
24
|
-
const DEGREE = "\u00B0"; // °
|
|
25
|
-
const ARROW_RIGHT = "\u2192"; // →
|
|
26
|
-
const ARROW_LEFT = "\u2190"; // ←
|
|
27
|
-
const ARROW_LEFT_RIGHT = "\u2194"; // ↔
|
|
28
|
-
const APPROXIMATE = "\u2248"; // ≈
|
|
29
|
-
const LESS_EQUAL = "\u2264"; // ≤
|
|
30
|
-
const GREATER_EQUAL = "\u2265"; // ≥
|
|
31
|
-
const PRIME = "\u2032"; // ′
|
|
32
|
-
const DOUBLE_PRIME = "\u2033"; // ″
|
|
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;
|
|
33
17
|
/**
|
|
34
18
|
* Converts three periods to a proper ellipsis character.
|
|
35
19
|
*
|
|
@@ -41,10 +25,8 @@ const DOUBLE_PRIME = "\u2033"; // ″
|
|
|
41
25
|
*/
|
|
42
26
|
export function ellipsis(text, options = {}) {
|
|
43
27
|
const chr = escapeRegex(options.separator ?? DEFAULT_SEPARATOR);
|
|
44
|
-
// Replace three periods with ellipsis, allowing for separator chars between
|
|
45
28
|
const pattern = new RegExp(`\\.${chr}?\\.${chr}?\\.`, "g");
|
|
46
29
|
text = text.replace(pattern, ELLIPSIS);
|
|
47
|
-
// Add space after ellipsis when followed by a word character
|
|
48
30
|
text = text.replace(new RegExp(`${ELLIPSIS}(?=\\w)`, "gu"), `${ELLIPSIS} `);
|
|
49
31
|
return text;
|
|
50
32
|
}
|
|
@@ -67,9 +49,12 @@ export function ellipsis(text, options = {}) {
|
|
|
67
49
|
*/
|
|
68
50
|
export function multiplication(text, options = {}) {
|
|
69
51
|
const chr = escapeRegex(options.separator ?? DEFAULT_SEPARATOR);
|
|
70
|
-
// Dimensions
|
|
71
|
-
const
|
|
72
|
-
text = text.replace(
|
|
52
|
+
// Dimensions with spaces: preserve spacing
|
|
53
|
+
const loosePattern = new RegExp(`(\\d${chr}?)\\s+[xX*]\\s+(${chr}?\\d)`, "g");
|
|
54
|
+
text = text.replace(loosePattern, `$1 ${MULTIPLICATION} $2`);
|
|
55
|
+
// Dimensions without spaces: keep tight
|
|
56
|
+
const tightPattern = new RegExp(`(\\d${chr}?)[xX*](${chr}?\\d)`, "g");
|
|
57
|
+
text = text.replace(tightPattern, `$1${MULTIPLICATION}$2`);
|
|
73
58
|
// Trailing multiplier: 5x (followed by space or end, not letters or numbers)
|
|
74
59
|
const trailingPattern = new RegExp(`(\\d${chr}?)[xX*](?=${chr}?(?:\\s|$))`, "g");
|
|
75
60
|
text = text.replace(trailingPattern, `$1${MULTIPLICATION}`);
|
|
@@ -95,16 +80,11 @@ export function multiplication(text, options = {}) {
|
|
|
95
80
|
* ```
|
|
96
81
|
*/
|
|
97
82
|
export function mathSymbols(text) {
|
|
98
|
-
// Not equal
|
|
99
83
|
text = text.replace(/!=/g, NOT_EQUAL);
|
|
100
|
-
// Plus/minus
|
|
101
84
|
text = text.replace(/\+\/-/g, PLUS_MINUS);
|
|
102
85
|
text = text.replace(/\+-/g, PLUS_MINUS);
|
|
103
|
-
// Less than or equal
|
|
104
86
|
text = text.replace(/<=/g, LESS_EQUAL);
|
|
105
|
-
// Greater than or equal
|
|
106
87
|
text = text.replace(/>=/g, GREATER_EQUAL);
|
|
107
|
-
// Approximately equal
|
|
108
88
|
text = text.replace(/~=/g, APPROXIMATE);
|
|
109
89
|
text = text.replace(/=~/g, APPROXIMATE);
|
|
110
90
|
return text;
|
|
@@ -112,27 +92,10 @@ export function mathSymbols(text) {
|
|
|
112
92
|
/**
|
|
113
93
|
* Converts ASCII representations of copyright, registered, and trademark
|
|
114
94
|
* symbols to proper Unicode characters.
|
|
115
|
-
*
|
|
116
|
-
* Handles:
|
|
117
|
-
* - "(c)" or "(C)" → "©"
|
|
118
|
-
* - "(r)" or "(R)" → "®"
|
|
119
|
-
* - "(tm)" or "(TM)" → "™"
|
|
120
|
-
*
|
|
121
|
-
* @example
|
|
122
|
-
* ```ts
|
|
123
|
-
* legalSymbols("Copyright (c) 2024 Acme Inc.")
|
|
124
|
-
* // → "Copyright © 2024 Acme Inc."
|
|
125
|
-
*
|
|
126
|
-
* legalSymbols("Brand Name(tm)")
|
|
127
|
-
* // → "Brand Name™"
|
|
128
|
-
* ```
|
|
129
95
|
*/
|
|
130
96
|
export function legalSymbols(text) {
|
|
131
|
-
// Copyright - must be surrounded by word boundaries or spaces to avoid false matches
|
|
132
97
|
text = text.replace(/\(c\)/gi, COPYRIGHT);
|
|
133
|
-
// Registered trademark
|
|
134
98
|
text = text.replace(/\(r\)/gi, REGISTERED);
|
|
135
|
-
// Trademark
|
|
136
99
|
text = text.replace(/\(tm\)/gi, TRADEMARK);
|
|
137
100
|
return text;
|
|
138
101
|
}
|
|
@@ -217,10 +180,15 @@ export function primeMarks(text, options = {}) {
|
|
|
217
180
|
// This handles feet (5') and arcminutes (30')
|
|
218
181
|
const singlePrimePattern = new RegExp(`(\\d${chr}?)'(?=${chr}?(?:\\d|"|$|[\\s.,;:!?)]))`, "g");
|
|
219
182
|
text = text.replace(singlePrimePattern, `$1${PRIME}`);
|
|
220
|
-
// Double prime:
|
|
221
|
-
//
|
|
222
|
-
const
|
|
223
|
-
text = text.replace(
|
|
183
|
+
// Double prime: Only match when it's clearly a measurement context
|
|
184
|
+
// Pattern 1: Feet-inches pattern (5'10" or 5′10")
|
|
185
|
+
const feetInchesPattern = new RegExp(`(${PRIME}${chr}?\\d${chr}?)"`, "g");
|
|
186
|
+
text = text.replace(feetInchesPattern, `$1${DOUBLE_PRIME}`);
|
|
187
|
+
// Pattern 2: Standalone inches - match digit followed by " but NOT when it's a closing quote
|
|
188
|
+
// Use negative lookbehind to ensure there's no opening quote before the number
|
|
189
|
+
// This matches: 12" wide, but not: "Term 1"
|
|
190
|
+
const standaloneInchesPattern = new RegExp(`(?<!["\u201C]${chr}?[^"${chr}]{0,20})(\\d${chr}?)"(?!${chr}?[\\w])`, "g");
|
|
191
|
+
text = text.replace(standaloneInchesPattern, `$1${DOUBLE_PRIME}`);
|
|
224
192
|
return text;
|
|
225
193
|
}
|
|
226
194
|
/**
|
|
@@ -243,24 +211,23 @@ export function primeMarks(text, options = {}) {
|
|
|
243
211
|
*/
|
|
244
212
|
export function fractions(text) {
|
|
245
213
|
const fractionMap = {
|
|
246
|
-
"1/4":
|
|
247
|
-
"1/2":
|
|
248
|
-
"3/4":
|
|
249
|
-
"1/3":
|
|
250
|
-
"2/3":
|
|
251
|
-
"1/5":
|
|
252
|
-
"2/5":
|
|
253
|
-
"3/5":
|
|
254
|
-
"4/5":
|
|
255
|
-
"1/6":
|
|
256
|
-
"5/6":
|
|
257
|
-
"1/8":
|
|
258
|
-
"3/8":
|
|
259
|
-
"5/8":
|
|
260
|
-
"7/8":
|
|
214
|
+
"1/4": UNICODE_SYMBOLS.FRACTION_1_4,
|
|
215
|
+
"1/2": UNICODE_SYMBOLS.FRACTION_1_2,
|
|
216
|
+
"3/4": UNICODE_SYMBOLS.FRACTION_3_4,
|
|
217
|
+
"1/3": UNICODE_SYMBOLS.FRACTION_1_3,
|
|
218
|
+
"2/3": UNICODE_SYMBOLS.FRACTION_2_3,
|
|
219
|
+
"1/5": UNICODE_SYMBOLS.FRACTION_1_5,
|
|
220
|
+
"2/5": UNICODE_SYMBOLS.FRACTION_2_5,
|
|
221
|
+
"3/5": UNICODE_SYMBOLS.FRACTION_3_5,
|
|
222
|
+
"4/5": UNICODE_SYMBOLS.FRACTION_4_5,
|
|
223
|
+
"1/6": UNICODE_SYMBOLS.FRACTION_1_6,
|
|
224
|
+
"5/6": UNICODE_SYMBOLS.FRACTION_5_6,
|
|
225
|
+
"1/8": UNICODE_SYMBOLS.FRACTION_1_8,
|
|
226
|
+
"3/8": UNICODE_SYMBOLS.FRACTION_3_8,
|
|
227
|
+
"5/8": UNICODE_SYMBOLS.FRACTION_5_8,
|
|
228
|
+
"7/8": UNICODE_SYMBOLS.FRACTION_7_8,
|
|
261
229
|
};
|
|
262
230
|
for (const [ascii, unicode] of Object.entries(fractionMap)) {
|
|
263
|
-
// Match fraction at word boundaries, not inside numbers like "21/4"
|
|
264
231
|
const pattern = new RegExp(`(?<!\\d)${ascii.replace("/", "\\/")}(?!\\d)`, "g");
|
|
265
232
|
text = text.replace(pattern, unicode);
|
|
266
233
|
}
|
|
@@ -290,7 +257,9 @@ export function symbolTransform(text, options = {}) {
|
|
|
290
257
|
text = multiplication(text, options);
|
|
291
258
|
text = mathSymbols(text);
|
|
292
259
|
text = legalSymbols(text);
|
|
293
|
-
|
|
260
|
+
if (options.includeArrows !== false) {
|
|
261
|
+
text = arrows(text, options);
|
|
262
|
+
}
|
|
294
263
|
return text;
|
|
295
264
|
}
|
|
296
265
|
//# sourceMappingURL=symbols.js.map
|
package/dist/symbols.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"symbols.js","sourceRoot":"","sources":["../src/symbols.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"symbols.js","sourceRoot":"","sources":["../src/symbols.ts"],"names":[],"mappings":"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"}
|