@spintax/core 0.10.0 → 0.12.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.
- package/CHANGELOG.md +80 -0
- package/README.md +3 -3
- package/dist/index.cjs +60 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +60 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -206,8 +206,8 @@ interface Analysis extends ExtractResult {
|
|
|
206
206
|
*/
|
|
207
207
|
declare function normalizeBaseLang(locale?: string | null): string;
|
|
208
208
|
/**
|
|
209
|
-
* How many `{plural …}` forms this locale takes —
|
|
210
|
-
* family (ru/uk/be + sr/hr/bs), 2 for everything else.
|
|
209
|
+
* How many `{plural …}` forms this locale takes — 6 for Arabic (zero/one/two/few/many/other),
|
|
210
|
+
* 3 for the Slavic one/few/other family (ru/uk/be + sr/hr/bs), 2 for everything else.
|
|
211
211
|
*
|
|
212
212
|
* Takes a RAW locale and normalizes internally, unlike the internal helper of the
|
|
213
213
|
* same name: a public function that silently answered 2 for `sr-Latn` would be a
|
package/dist/index.d.ts
CHANGED
|
@@ -206,8 +206,8 @@ interface Analysis extends ExtractResult {
|
|
|
206
206
|
*/
|
|
207
207
|
declare function normalizeBaseLang(locale?: string | null): string;
|
|
208
208
|
/**
|
|
209
|
-
* How many `{plural …}` forms this locale takes —
|
|
210
|
-
* family (ru/uk/be + sr/hr/bs), 2 for everything else.
|
|
209
|
+
* How many `{plural …}` forms this locale takes — 6 for Arabic (zero/one/two/few/many/other),
|
|
210
|
+
* 3 for the Slavic one/few/other family (ru/uk/be + sr/hr/bs), 2 for everything else.
|
|
211
211
|
*
|
|
212
212
|
* Takes a RAW locale and normalizes internally, unlike the internal helper of the
|
|
213
213
|
* same name: a public function that silently answered 2 for `sr-Latn` would be a
|
package/dist/index.js
CHANGED
|
@@ -742,6 +742,8 @@ function normalizeBaseLang(locale) {
|
|
|
742
742
|
}
|
|
743
743
|
function pluralArity(baseLang) {
|
|
744
744
|
switch (baseLang) {
|
|
745
|
+
case "ar":
|
|
746
|
+
return 6;
|
|
745
747
|
case "ru":
|
|
746
748
|
case "uk":
|
|
747
749
|
case "be":
|
|
@@ -759,6 +761,13 @@ function pluralFor(baseLang, n, forms) {
|
|
|
759
761
|
const mod10 = abs % 10;
|
|
760
762
|
const mod100 = abs % 100;
|
|
761
763
|
switch (baseLang) {
|
|
764
|
+
case "ar":
|
|
765
|
+
if (abs === 0) return forms[0] ?? "";
|
|
766
|
+
if (abs === 1) return forms[1] ?? "";
|
|
767
|
+
if (abs === 2) return forms[2] ?? "";
|
|
768
|
+
if (mod100 >= 3 && mod100 <= 10) return forms[3] ?? "";
|
|
769
|
+
if (mod100 >= 11) return forms[4] ?? "";
|
|
770
|
+
return forms[5] ?? "";
|
|
762
771
|
case "ru":
|
|
763
772
|
case "uk":
|
|
764
773
|
case "be":
|
|
@@ -1378,6 +1387,37 @@ function trimFragment(fragment) {
|
|
|
1378
1387
|
if (fragment.lead === 0 && fragment.trail === 0) return fragment;
|
|
1379
1388
|
return new Window(fragment, fragment.lead, fragment.length - fragment.trail);
|
|
1380
1389
|
}
|
|
1390
|
+
function firstCodePointOf(fragment) {
|
|
1391
|
+
const hi = charCodeAtOf(fragment, 0);
|
|
1392
|
+
if (hi >= 55296 && hi <= 56319) {
|
|
1393
|
+
const lo = charCodeAtOf(fragment, 1);
|
|
1394
|
+
if (lo >= 56320 && lo <= 57343) return (hi - 55296) * 1024 + (lo - 56320) + 65536;
|
|
1395
|
+
}
|
|
1396
|
+
return hi;
|
|
1397
|
+
}
|
|
1398
|
+
function charCodeAtOf(fragment, index) {
|
|
1399
|
+
let piece = fragment;
|
|
1400
|
+
let at = index;
|
|
1401
|
+
for (; ; ) {
|
|
1402
|
+
if (at < 0 || at >= lengthOf(piece)) return -1;
|
|
1403
|
+
if (typeof piece === "string") return piece.charCodeAt(at);
|
|
1404
|
+
if (piece instanceof Window) {
|
|
1405
|
+
at += piece.from;
|
|
1406
|
+
piece = piece.base;
|
|
1407
|
+
continue;
|
|
1408
|
+
}
|
|
1409
|
+
let offset = 0;
|
|
1410
|
+
for (const child of piece.pieces) {
|
|
1411
|
+
const length = lengthOf(child);
|
|
1412
|
+
if (at < offset + length) {
|
|
1413
|
+
piece = child;
|
|
1414
|
+
at -= offset;
|
|
1415
|
+
break;
|
|
1416
|
+
}
|
|
1417
|
+
offset += length;
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
}
|
|
1381
1421
|
function flatten(fragment) {
|
|
1382
1422
|
if (typeof fragment === "string") return fragment;
|
|
1383
1423
|
const out = [];
|
|
@@ -1771,7 +1811,12 @@ function assemblePermutation(node, rendered, opts) {
|
|
|
1771
1811
|
max = Math.max(min, Math.min(max, total));
|
|
1772
1812
|
const pick = randomInt(opts.rng, min, max);
|
|
1773
1813
|
shuffle(elements, opts.rng);
|
|
1774
|
-
return joinWithSeparators(
|
|
1814
|
+
return joinWithSeparators(
|
|
1815
|
+
elements.slice(0, pick),
|
|
1816
|
+
config.sep,
|
|
1817
|
+
config.lastsep ?? config.sep,
|
|
1818
|
+
normalizeBaseLang(opts.locale)
|
|
1819
|
+
);
|
|
1775
1820
|
}
|
|
1776
1821
|
function shuffle(arr, rng) {
|
|
1777
1822
|
for (let i = arr.length - 1; i > 0; i -= 1) {
|
|
@@ -1781,7 +1826,7 @@ function shuffle(arr, rng) {
|
|
|
1781
1826
|
arr[j] = tmp;
|
|
1782
1827
|
}
|
|
1783
1828
|
}
|
|
1784
|
-
function joinWithSeparators(elements, globalSep, globalLastsep) {
|
|
1829
|
+
function joinWithSeparators(elements, globalSep, globalLastsep, lang) {
|
|
1785
1830
|
const count = elements.length;
|
|
1786
1831
|
if (count === 0) return "";
|
|
1787
1832
|
if (count === 1) return elements[0].text;
|
|
@@ -1789,14 +1834,24 @@ function joinWithSeparators(elements, globalSep, globalLastsep) {
|
|
|
1789
1834
|
for (let i = 1; i < count; i += 1) {
|
|
1790
1835
|
const el = elements[i];
|
|
1791
1836
|
const sep = el.sep ?? (i === count - 1 ? globalLastsep : globalSep);
|
|
1792
|
-
pieces.push(padSeparator(sep), el.text);
|
|
1837
|
+
pieces.push(padSeparator(sep, lang, el.text), el.text);
|
|
1793
1838
|
}
|
|
1794
1839
|
return joinFragments(pieces);
|
|
1795
1840
|
}
|
|
1796
|
-
|
|
1841
|
+
var UNSPACED_SCRIPT_RE = /^[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}ーー\p{Script=Thai}\p{Script=Lao}\p{Script=Khmer}\p{Script=Myanmar}]+$/u;
|
|
1842
|
+
var PROCLITICS = /* @__PURE__ */ new Map([
|
|
1843
|
+
["ar", { words: /* @__PURE__ */ new Set(["\u0648", "\u0641"]), letter: /^(?=\p{L})\p{Script=Arabic}$/u }],
|
|
1844
|
+
["he", { words: /* @__PURE__ */ new Set(["\u05D5"]), letter: /^(?=\p{L})\p{Script=Hebrew}$/u }]
|
|
1845
|
+
]);
|
|
1846
|
+
function padSeparator(sep, lang, next) {
|
|
1797
1847
|
const trimmed = phpTrim(sep);
|
|
1798
1848
|
if (trimmed === "") return sep;
|
|
1799
|
-
|
|
1849
|
+
const proclitic = PROCLITICS.get(lang);
|
|
1850
|
+
if (proclitic !== void 0 && proclitic.words.has(trimmed)) {
|
|
1851
|
+
const first = firstCodePointOf(next);
|
|
1852
|
+
return first >= 0 && proclitic.letter.test(String.fromCodePoint(first)) ? ` ${trimmed}` : ` ${trimmed} `;
|
|
1853
|
+
}
|
|
1854
|
+
if (/^\p{L}+$/u.test(trimmed) && !UNSPACED_SCRIPT_RE.test(trimmed)) return ` ${trimmed} `;
|
|
1800
1855
|
return sep;
|
|
1801
1856
|
}
|
|
1802
1857
|
|