@storyteller-platform/align 0.1.6 → 0.1.7
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/align/__tests__/align.test.cjs +282 -0
- package/dist/align/__tests__/align.test.d.cts +2 -0
- package/dist/align/__tests__/align.test.d.ts +2 -0
- package/dist/align/__tests__/align.test.js +218 -0
- package/dist/align/__tests__/slugify.test.cjs +64 -0
- package/dist/align/__tests__/slugify.test.d.cts +2 -0
- package/dist/align/__tests__/slugify.test.d.ts +2 -0
- package/dist/align/__tests__/slugify.test.js +41 -0
- package/dist/align/align.cjs +41 -21
- package/dist/align/align.js +41 -21
- package/dist/align/fuzzy.cjs +1 -1
- package/dist/align/fuzzy.js +1 -1
- package/dist/align/getSentenceRanges.cjs +24 -12
- package/dist/align/getSentenceRanges.d.cts +1 -1
- package/dist/align/getSentenceRanges.d.ts +1 -1
- package/dist/align/getSentenceRanges.js +24 -12
- package/dist/align/slugify.cjs +125 -0
- package/dist/align/slugify.d.cts +8 -0
- package/dist/align/slugify.d.ts +8 -0
- package/dist/align/slugify.js +102 -0
- package/package.json +6 -3
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as _storyteller_platform_transliteration from '@storyteller-platform/transliteration';
|
|
2
|
+
|
|
3
|
+
declare function slugify(text: string, locale: Intl.Locale): Promise<{
|
|
4
|
+
result: string;
|
|
5
|
+
mapping: _storyteller_platform_transliteration.Mapping;
|
|
6
|
+
}>;
|
|
7
|
+
|
|
8
|
+
export { slugify };
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import "../chunk-BIEQXUOY.js";
|
|
2
|
+
import { getCurrency } from "locale-currency";
|
|
3
|
+
import { toWords } from "to-words";
|
|
4
|
+
import { slugify as transliterateSlugify } from "@storyteller-platform/transliteration";
|
|
5
|
+
const replacerMap = /* @__PURE__ */ new WeakMap();
|
|
6
|
+
function createReplacers(locale) {
|
|
7
|
+
const maximizedLocale = locale.maximize();
|
|
8
|
+
const demoNumber = 123456.789;
|
|
9
|
+
const currencyFormat = new Intl.NumberFormat(locale, {
|
|
10
|
+
style: "currency",
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
12
|
+
currency: getCurrency(locale.maximize().region)
|
|
13
|
+
});
|
|
14
|
+
const currencyParts = currencyFormat.formatToParts(demoNumber);
|
|
15
|
+
const currencySymbols = currencyParts.reduce(
|
|
16
|
+
(acc, part, index) => {
|
|
17
|
+
if (part.type === "group") {
|
|
18
|
+
return {
|
|
19
|
+
...acc,
|
|
20
|
+
group: part.value
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
if (part.type === "decimal") {
|
|
24
|
+
return {
|
|
25
|
+
...acc,
|
|
26
|
+
decimal: part.value
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
if (part.type === "currency") {
|
|
30
|
+
return {
|
|
31
|
+
...acc,
|
|
32
|
+
currency: part.value,
|
|
33
|
+
currencyLeading: index === 0
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
return acc;
|
|
37
|
+
},
|
|
38
|
+
{ group: "", decimal: "", currency: "", currencyLeading: true }
|
|
39
|
+
);
|
|
40
|
+
const numeralRegexPart = `(\\p{Number}[\\p{Number}${currencySymbols.group}]*(?:[${currencySymbols.decimal}]\\p{Number}*)?)`;
|
|
41
|
+
const currencyRegex = currencySymbols.currencyLeading ? new RegExp(`[${currencySymbols.currency}]\\s?${numeralRegexPart}`, "gu") : new RegExp(`${numeralRegexPart}\\s?[${currencySymbols.currency}]`, "gu");
|
|
42
|
+
function currencyReplacer(match) {
|
|
43
|
+
const numeralMatch = match[1];
|
|
44
|
+
if (!numeralMatch) return match[0];
|
|
45
|
+
const normalizedNumeral = numeralMatch.replaceAll(new RegExp(`\\${currencySymbols.group}`, "g"), "").replace(new RegExp(`\\${currencySymbols.decimal}`), ".");
|
|
46
|
+
const number = parseFloat(normalizedNumeral);
|
|
47
|
+
return toWords(number, {
|
|
48
|
+
localeCode: `${maximizedLocale.language}-${maximizedLocale.region}`,
|
|
49
|
+
currency: true,
|
|
50
|
+
doNotAddOnly: true
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
const numberFormat = new Intl.NumberFormat(locale);
|
|
54
|
+
const numberParts = numberFormat.formatToParts(demoNumber);
|
|
55
|
+
const numberSymbols = numberParts.reduce(
|
|
56
|
+
(acc, part) => {
|
|
57
|
+
if (part.type === "group") {
|
|
58
|
+
return {
|
|
59
|
+
...acc,
|
|
60
|
+
group: part.value
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
if (part.type === "decimal") {
|
|
64
|
+
return {
|
|
65
|
+
...acc,
|
|
66
|
+
decimal: part.value
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
return acc;
|
|
70
|
+
},
|
|
71
|
+
{ group: "", decimal: "" }
|
|
72
|
+
);
|
|
73
|
+
const numberRegex = new RegExp(
|
|
74
|
+
`(\\p{Number}[\\p{Number}${numberSymbols.group}]*(?:[${numberSymbols.decimal}]\\p{Number}*)?)`,
|
|
75
|
+
"gu"
|
|
76
|
+
);
|
|
77
|
+
function numberReplacer(match) {
|
|
78
|
+
const numeralMatch = match[1];
|
|
79
|
+
if (!numeralMatch) return match[0];
|
|
80
|
+
const normalizedNumeral = numeralMatch.replaceAll(new RegExp(`\\${numberSymbols.group}`, "g"), "").replace(new RegExp(`\\${numberSymbols.decimal}`), ".");
|
|
81
|
+
const number = parseFloat(normalizedNumeral);
|
|
82
|
+
return toWords(number, {
|
|
83
|
+
localeCode: `${maximizedLocale.language}-${maximizedLocale.region}`
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
return [
|
|
87
|
+
[currencyRegex, currencyReplacer],
|
|
88
|
+
[numberRegex, numberReplacer]
|
|
89
|
+
];
|
|
90
|
+
}
|
|
91
|
+
async function slugify(text, locale) {
|
|
92
|
+
const replacers = replacerMap.get(locale) ?? createReplacers(locale);
|
|
93
|
+
replacerMap.set(locale, replacers);
|
|
94
|
+
const { result, mapping } = await transliterateSlugify(text, {
|
|
95
|
+
allowedChars: "a-zA-Z0-9",
|
|
96
|
+
replace: replacers
|
|
97
|
+
});
|
|
98
|
+
return { result, mapping };
|
|
99
|
+
}
|
|
100
|
+
export {
|
|
101
|
+
slugify
|
|
102
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@storyteller-platform/align",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "A library and CLI for automatically aligning audiobooks and EPUBs to produce Media Overlays",
|
|
5
5
|
"author": "Shane Friedman",
|
|
6
6
|
"license": "MIT",
|
|
@@ -57,14 +57,17 @@
|
|
|
57
57
|
"@optique/core": "^0.10.7",
|
|
58
58
|
"@optique/run": "^0.10.7",
|
|
59
59
|
"@storyteller-platform/audiobook": "^0.3.8",
|
|
60
|
-
"@storyteller-platform/epub": "^0.4.
|
|
61
|
-
"@storyteller-platform/ghost-story": "^0.1.
|
|
60
|
+
"@storyteller-platform/epub": "^0.4.7",
|
|
61
|
+
"@storyteller-platform/ghost-story": "^0.1.4",
|
|
62
|
+
"@storyteller-platform/transliteration": "^3.1.0",
|
|
62
63
|
"chalk": "^5.4.1",
|
|
63
64
|
"cli-progress": "^3.12.0",
|
|
64
65
|
"esbuild": "^0.27.3",
|
|
66
|
+
"locale-currency": "^1.0.0",
|
|
65
67
|
"memoize": "^10.2.0",
|
|
66
68
|
"pino": "^10.3.1",
|
|
67
69
|
"pino-pretty": "^13.1.3",
|
|
70
|
+
"to-words": "^5.3.0",
|
|
68
71
|
"zod": "^3.24.0"
|
|
69
72
|
},
|
|
70
73
|
"devDependencies": {
|