@spintax/core 0.11.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/dist/index.js CHANGED
@@ -1387,6 +1387,37 @@ function trimFragment(fragment) {
1387
1387
  if (fragment.lead === 0 && fragment.trail === 0) return fragment;
1388
1388
  return new Window(fragment, fragment.lead, fragment.length - fragment.trail);
1389
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
+ }
1390
1421
  function flatten(fragment) {
1391
1422
  if (typeof fragment === "string") return fragment;
1392
1423
  const out = [];
@@ -1780,7 +1811,12 @@ function assemblePermutation(node, rendered, opts) {
1780
1811
  max = Math.max(min, Math.min(max, total));
1781
1812
  const pick = randomInt(opts.rng, min, max);
1782
1813
  shuffle(elements, opts.rng);
1783
- return joinWithSeparators(elements.slice(0, pick), config.sep, config.lastsep ?? config.sep);
1814
+ return joinWithSeparators(
1815
+ elements.slice(0, pick),
1816
+ config.sep,
1817
+ config.lastsep ?? config.sep,
1818
+ normalizeBaseLang(opts.locale)
1819
+ );
1784
1820
  }
1785
1821
  function shuffle(arr, rng) {
1786
1822
  for (let i = arr.length - 1; i > 0; i -= 1) {
@@ -1790,7 +1826,7 @@ function shuffle(arr, rng) {
1790
1826
  arr[j] = tmp;
1791
1827
  }
1792
1828
  }
1793
- function joinWithSeparators(elements, globalSep, globalLastsep) {
1829
+ function joinWithSeparators(elements, globalSep, globalLastsep, lang) {
1794
1830
  const count = elements.length;
1795
1831
  if (count === 0) return "";
1796
1832
  if (count === 1) return elements[0].text;
@@ -1798,14 +1834,23 @@ function joinWithSeparators(elements, globalSep, globalLastsep) {
1798
1834
  for (let i = 1; i < count; i += 1) {
1799
1835
  const el = elements[i];
1800
1836
  const sep = el.sep ?? (i === count - 1 ? globalLastsep : globalSep);
1801
- pieces.push(padSeparator(sep), el.text);
1837
+ pieces.push(padSeparator(sep, lang, el.text), el.text);
1802
1838
  }
1803
1839
  return joinFragments(pieces);
1804
1840
  }
1805
- var UNSPACED_SCRIPT_RE = /^[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}ーー]+$/u;
1806
- function padSeparator(sep) {
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) {
1807
1847
  const trimmed = phpTrim(sep);
1808
1848
  if (trimmed === "") return sep;
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
+ }
1809
1854
  if (/^\p{L}+$/u.test(trimmed) && !UNSPACED_SCRIPT_RE.test(trimmed)) return ` ${trimmed} `;
1810
1855
  return sep;
1811
1856
  }