@drghaliasri/butex 5.3.1 → 5.3.3

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.
@@ -268,6 +268,10 @@ function cloneDocument2Meta(meta) {
268
268
  }
269
269
 
270
270
  // src/document2/citations.ts
271
+ var DEFAULT_REFERENCE_FIELD_SEPARATOR = "\u060C";
272
+ function normalizeReferenceFieldSeparator(value) {
273
+ return value === "," ? "," : DEFAULT_REFERENCE_FIELD_SEPARATOR;
274
+ }
271
275
  function referenceNumberMap(references) {
272
276
  const map = /* @__PURE__ */ new Map();
273
277
  references.forEach((reference, index) => {
@@ -313,7 +317,8 @@ function referenceFromJson(json) {
313
317
  title: typeof json.title === "string" ? json.title : "",
314
318
  year: typeof json.year === "string" ? json.year : "",
315
319
  url: typeof json.url === "string" ? json.url : "",
316
- venue: typeof json.venue === "string" ? json.venue : ""
320
+ venue: typeof json.venue === "string" ? json.venue : "",
321
+ fieldSeparator: normalizeReferenceFieldSeparator(json.field_separator)
317
322
  };
318
323
  }
319
324
  function createEmptyReference2(partial = {}) {
@@ -323,15 +328,33 @@ function createEmptyReference2(partial = {}) {
323
328
  title: partial.title,
324
329
  year: partial.year,
325
330
  url: partial.url,
326
- venue: partial.venue
331
+ venue: partial.venue,
332
+ field_separator: partial.field_separator
327
333
  });
328
334
  }
335
+ function bibliographyEntryBody(reference, separator = reference.fieldSeparator, options = {}) {
336
+ const year = options.digitForm !== void 0 ? formatDigits(reference.year, options.digitForm) : reference.year;
337
+ const parts = [reference.authors, reference.title, reference.venue, year].filter((part) => part.trim().length > 0);
338
+ return parts.join(`${separator} `);
339
+ }
329
340
  function bibliographyEntryLatex(reference) {
330
- const parts = [reference.authors, reference.title, reference.venue, reference.year].filter((part) => part.trim().length > 0);
331
- const body = parts.join(", ");
341
+ const body = bibliographyEntryBody(reference);
332
342
  const url = reference.url.trim().length > 0 ? ` \\url{${reference.url}}` : "";
333
343
  return `\\bibitem{${reference.key}} ${body}${url}`.trim();
334
344
  }
345
+ function absoluteHttpHref(url) {
346
+ const trimmed = url.trim();
347
+ if (trimmed.length === 0) {
348
+ return "";
349
+ }
350
+ if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(trimmed)) {
351
+ return trimmed;
352
+ }
353
+ if (trimmed.startsWith("//")) {
354
+ return `https:${trimmed}`;
355
+ }
356
+ return `https://${trimmed}`;
357
+ }
335
358
 
336
359
  // src/ast/commands/index.ts
337
360
  function renderCommandCore(context) {
@@ -816,6 +839,23 @@ function labelNumberMap(document2) {
816
839
  }
817
840
  return map;
818
841
  }
842
+ function formatFloatCaptionTitle(kind, number, options = {}) {
843
+ const locale = options.uiLocale ?? "ar";
844
+ const kindWord = kind === "fig" ? locale === "ar" ? "\u0627\u0644\u0634\u0643\u0644" : "Figure" : kind === "tab" ? locale === "ar" ? "\u0627\u0644\u062C\u062F\u0648\u0644" : "Table" : locale === "ar" ? "\u0627\u0644\u0645\u0639\u0627\u062F\u0644\u0629" : "Equation";
845
+ const digits = formatBibliographyNumber(number, {
846
+ documentDirection: options.documentDirection ?? (locale === "ar" ? "rtl" : "ltr"),
847
+ digitForm: options.digitForm ?? (locale === "ar" ? "arabicIndic" : "western")
848
+ });
849
+ return `${kindWord} ${digits}`;
850
+ }
851
+ function formatFloatCaptionPreview(title, caption, uiLocale = "ar") {
852
+ const trimmed = caption?.trim() ?? "";
853
+ if (trimmed.length === 0) {
854
+ return title;
855
+ }
856
+ const separator = uiLocale === "ar" ? ": " : ". ";
857
+ return `${title}${separator}${trimmed}`;
858
+ }
819
859
  function formatRefLabel(keys, document2, refCommand, options = {}) {
820
860
  const documentDirection = options.documentDirection ?? "rtl";
821
861
  const digitForm = options.digitForm ?? (documentDirection === "rtl" ? "arabicIndic" : "western");
@@ -1086,7 +1126,8 @@ function parseReferences(json) {
1086
1126
  title: typeof entry.title === "string" ? entry.title : void 0,
1087
1127
  year: typeof entry.year === "string" ? entry.year : void 0,
1088
1128
  url: typeof entry.url === "string" ? entry.url : void 0,
1089
- venue: typeof entry.venue === "string" ? entry.venue : void 0
1129
+ venue: typeof entry.venue === "string" ? entry.venue : void 0,
1130
+ field_separator: entry.field_separator === "," || entry.field_separator === "\u060C" ? entry.field_separator : void 0
1090
1131
  })
1091
1132
  );
1092
1133
  }
@@ -1726,7 +1767,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1726
1767
  id: "neq",
1727
1768
  category: "operators1",
1728
1769
  Tex: "\\neq",
1729
- mirror: false,
1770
+ mirror: true,
1730
1771
  Label: "\u2260",
1731
1772
  title: "\u0644\u0627 \u064A\u0633\u0627\u0648\u064A",
1732
1773
  svg_path: null
@@ -1736,6 +1777,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1736
1777
  category: "operators1",
1737
1778
  Tex: "\\approx",
1738
1779
  mirror: false,
1780
+ displayMirror: true,
1739
1781
  Label: "\u2248",
1740
1782
  title: "\u062A\u0642\u0631\u064A\u0628\u0627 \u064A\u0633\u0627\u0648\u064A",
1741
1783
  svg_path: null
@@ -1745,6 +1787,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1745
1787
  category: "operators1",
1746
1788
  Tex: "\\sim",
1747
1789
  mirror: false,
1790
+ displayMirror: true,
1748
1791
  Label: "\u223C",
1749
1792
  title: "\u0645\u0634\u0627\u0628\u0647",
1750
1793
  svg_path: null
@@ -1763,6 +1806,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1763
1806
  category: "operators1",
1764
1807
  Tex: "\\leq",
1765
1808
  mirror: true,
1809
+ displayMirror: false,
1766
1810
  Label: "\u2264",
1767
1811
  title: "\u0623\u0635\u063A\u0631 \u0645\u0646 \u0623\u0648 \u064A\u0633\u0627\u0648\u064A",
1768
1812
  svg_path: null
@@ -1772,6 +1816,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1772
1816
  category: "operators1",
1773
1817
  Tex: "\\geq",
1774
1818
  mirror: true,
1819
+ displayMirror: false,
1775
1820
  Label: "\u2265",
1776
1821
  title: "\u0623\u0643\u0628\u0631 \u0645\u0646 \u0623\u0648 \u064A\u0633\u0627\u0648\u064A",
1777
1822
  svg_path: null
@@ -1781,6 +1826,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1781
1826
  category: "operators1",
1782
1827
  Tex: "\\coloneqq",
1783
1828
  mirror: true,
1829
+ displayMirror: false,
1784
1830
  Label: "\u2254",
1785
1831
  title: "\u064A\u0639\u0631\u0641 \u0628\u0623\u0646\u0647 \u064A\u0633\u0627\u0648\u064A",
1786
1832
  svg_path: null
@@ -1790,6 +1836,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1790
1836
  category: "operators1",
1791
1837
  Tex: "\\eqqcolon",
1792
1838
  mirror: true,
1839
+ displayMirror: false,
1793
1840
  Label: "\u2255",
1794
1841
  title: "\u064A\u0633\u0627\u0648\u064A \u0628\u0627\u0644\u062A\u0639\u0631\u064A\u0641",
1795
1842
  svg_path: null
@@ -1800,6 +1847,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1800
1847
  category: "operators2",
1801
1848
  Tex: "\\propto",
1802
1849
  mirror: true,
1850
+ displayMirror: false,
1803
1851
  Label: "\u221D",
1804
1852
  title: "\u064A\u062A\u0646\u0627\u0633\u0628 \u0645\u0639",
1805
1853
  svg_path: null
@@ -1809,6 +1857,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1809
1857
  category: "operators2",
1810
1858
  Tex: "\\in",
1811
1859
  mirror: true,
1860
+ displayMirror: false,
1812
1861
  Label: "\u2208",
1813
1862
  title: "\u064A\u0646\u062A\u0645\u064A \u0625\u0644\u0649",
1814
1863
  svg_path: null
@@ -1818,6 +1867,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1818
1867
  category: "operators2",
1819
1868
  Tex: "\\notin",
1820
1869
  mirror: false,
1870
+ displayMirror: true,
1821
1871
  Label: "\u2209",
1822
1872
  title: "\u0644\u0627 \u064A\u0646\u062A\u0645\u064A \u0625\u0644\u0649",
1823
1873
  svg_path: null
@@ -1827,6 +1877,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1827
1877
  category: "operators2",
1828
1878
  Tex: "\\subset",
1829
1879
  mirror: true,
1880
+ displayMirror: false,
1830
1881
  Label: "\u2282",
1831
1882
  title: "\u0645\u062C\u0645\u0648\u0639\u0629 \u062C\u0632\u0626\u064A\u0629 \u0645\u0646",
1832
1883
  svg_path: null
@@ -1836,6 +1887,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1836
1887
  category: "operators2",
1837
1888
  Tex: "\\supset",
1838
1889
  mirror: true,
1890
+ displayMirror: false,
1839
1891
  Label: "\u2283",
1840
1892
  title: "\u0645\u062C\u0645\u0648\u0639\u0629 \u0634\u0627\u0645\u0644\u0629 \u0644\u0640",
1841
1893
  svg_path: null
@@ -1845,6 +1897,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1845
1897
  category: "operators2",
1846
1898
  Tex: "\\subseteq",
1847
1899
  mirror: true,
1900
+ displayMirror: false,
1848
1901
  Label: "\u2286",
1849
1902
  title: "\u0645\u062C\u0645\u0648\u0639\u0629 \u062C\u0632\u0626\u064A\u0629 \u0623\u0648 \u062A\u0633\u0627\u0648\u064A",
1850
1903
  svg_path: null
@@ -1854,6 +1907,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1854
1907
  category: "operators2",
1855
1908
  Tex: "\\supseteq",
1856
1909
  mirror: true,
1910
+ displayMirror: false,
1857
1911
  Label: "\u2287",
1858
1912
  title: "\u0645\u062C\u0645\u0648\u0639\u0629 \u0634\u0627\u0645\u0644\u0629 \u0623\u0648 \u062A\u0633\u0627\u0648\u064A",
1859
1913
  svg_path: null
@@ -1863,6 +1917,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1863
1917
  category: "operators2",
1864
1918
  Tex: "\\cap",
1865
1919
  mirror: false,
1920
+ displayMirror: true,
1866
1921
  Label: "\u2229",
1867
1922
  title: "\u062A\u0642\u0627\u0637\u0639",
1868
1923
  svg_path: null
@@ -1872,6 +1927,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1872
1927
  category: "operators2",
1873
1928
  Tex: "\\cup",
1874
1929
  mirror: false,
1930
+ displayMirror: true,
1875
1931
  Label: "\u222A",
1876
1932
  title: "\u0627\u062A\u062D\u0627\u062F",
1877
1933
  svg_path: null
@@ -1881,6 +1937,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1881
1937
  category: "operators2",
1882
1938
  Tex: "\\emptyset",
1883
1939
  mirror: false,
1940
+ displayMirror: true,
1884
1941
  Label: "\u2205",
1885
1942
  title: "\u0627\u0644\u0645\u062C\u0645\u0648\u0639\u0629 \u0627\u0644\u062E\u0627\u0644\u064A\u0629",
1886
1943
  svg_path: null
@@ -1890,6 +1947,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1890
1947
  category: "operators2",
1891
1948
  Tex: "\\nsubseteq",
1892
1949
  mirror: true,
1950
+ displayMirror: false,
1893
1951
  Label: "\u2288",
1894
1952
  title: "\u0644\u064A\u0633\u062A \u0645\u062C\u0645\u0648\u0639\u0629 \u062C\u0632\u0626\u064A\u0629 \u0623\u0648 \u062A\u0633\u0627\u0648\u064A",
1895
1953
  svg_path: null
@@ -1899,6 +1957,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
1899
1957
  category: "operators2",
1900
1958
  Tex: "\\nsupseteq",
1901
1959
  mirror: true,
1960
+ displayMirror: false,
1902
1961
  Label: "\u2289",
1903
1962
  title: "\u0644\u064A\u0633\u062A \u0645\u062C\u0645\u0648\u0639\u0629 \u0634\u0627\u0645\u0644\u0629 \u0623\u0648 \u062A\u0633\u0627\u0648\u064A",
1904
1963
  svg_path: null
@@ -2110,6 +2169,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2110
2169
  category: "integrals",
2111
2170
  Tex: "\\iint",
2112
2171
  mirror: true,
2172
+ displayMirror: false,
2113
2173
  Label: "\u222C",
2114
2174
  title: "\u062A\u0643\u0627\u0645\u0644 \u0645\u0632\u062F\u0648\u062C",
2115
2175
  svg_path: null
@@ -2119,6 +2179,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2119
2179
  category: "integrals",
2120
2180
  Tex: "\\iiint",
2121
2181
  mirror: true,
2182
+ displayMirror: false,
2122
2183
  Label: "\u222D",
2123
2184
  title: "\u062A\u0643\u0627\u0645\u0644 \u062B\u0644\u0627\u062B\u064A",
2124
2185
  svg_path: null
@@ -2128,6 +2189,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2128
2189
  category: "integrals",
2129
2190
  Tex: "\\iiiint",
2130
2191
  mirror: true,
2192
+ displayMirror: false,
2131
2193
  Label: "\u2A0C",
2132
2194
  title: "\u062A\u0643\u0627\u0645\u0644 \u0631\u0628\u0627\u0639\u064A",
2133
2195
  svg_path: null
@@ -2137,6 +2199,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2137
2199
  category: "integrals",
2138
2200
  Tex: "\\oint",
2139
2201
  mirror: true,
2202
+ displayMirror: false,
2140
2203
  Label: "\u222E",
2141
2204
  title: "\u062A\u0643\u0627\u0645\u0644 \u0645\u063A\u0644\u0642",
2142
2205
  svg_path: null
@@ -2146,6 +2209,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2146
2209
  category: "integrals",
2147
2210
  Tex: "\\oiint",
2148
2211
  mirror: true,
2212
+ displayMirror: false,
2149
2213
  Label: "\u222F",
2150
2214
  title: "\u062A\u0643\u0627\u0645\u0644 \u0633\u0637\u062D\u064A \u0645\u063A\u0644\u0642",
2151
2215
  svg_path: null
@@ -2155,6 +2219,7 @@ var ATOMIC_OPERATOR_COMMANDS = {
2155
2219
  category: "integrals",
2156
2220
  Tex: "\\oiiint",
2157
2221
  mirror: true,
2222
+ displayMirror: false,
2158
2223
  Label: "\u2230",
2159
2224
  title: "\u062A\u0643\u0627\u0645\u0644 \u062D\u062C\u0645\u064A \u0645\u063A\u0644\u0642",
2160
2225
  svg_path: null
@@ -4268,6 +4333,9 @@ function updateDocument2Reference(document2, referenceId, patch) {
4268
4333
  if (typeof patch.venue === "string") {
4269
4334
  reference.venue = patch.venue;
4270
4335
  }
4336
+ if (patch.field_separator === "," || patch.field_separator === "\u060C") {
4337
+ reference.fieldSeparator = patch.field_separator;
4338
+ }
4271
4339
  return next;
4272
4340
  }
4273
4341
  function removeDocument2Reference(document2, referenceId) {
@@ -4306,6 +4374,52 @@ function updateDocument2Meta(document2, patch) {
4306
4374
  return next;
4307
4375
  }
4308
4376
 
4377
+ // src/document2/keys.ts
4378
+ var DOCUMENT2_KEY_PATTERN = /^[\p{L}\p{M}0-9:._-]+$/u;
4379
+ function normalizeDocument2Key(key) {
4380
+ return key.normalize("NFC").trim();
4381
+ }
4382
+ function isValidDocument2Key(key) {
4383
+ const normalized = normalizeDocument2Key(key);
4384
+ return normalized.length > 0 && DOCUMENT2_KEY_PATTERN.test(normalized);
4385
+ }
4386
+ function isDuplicateDocument2Key(key, namespace) {
4387
+ const normalized = normalizeDocument2Key(key);
4388
+ if (normalized.length === 0) {
4389
+ return false;
4390
+ }
4391
+ for (const reference of namespace.references ?? []) {
4392
+ if (namespace.excludeReferenceId && reference.id === namespace.excludeReferenceId) {
4393
+ continue;
4394
+ }
4395
+ if (normalizeDocument2Key(reference.key) === normalized) {
4396
+ return true;
4397
+ }
4398
+ }
4399
+ for (const label of namespace.labels ?? []) {
4400
+ if (namespace.excludeOwnerId && label.ownerId === namespace.excludeOwnerId) {
4401
+ continue;
4402
+ }
4403
+ if (normalizeDocument2Key(label.key) === normalized) {
4404
+ return true;
4405
+ }
4406
+ }
4407
+ return false;
4408
+ }
4409
+ function document2KeyError(key, namespace = {}) {
4410
+ const normalized = normalizeDocument2Key(key);
4411
+ if (normalized.length === 0) {
4412
+ return "empty";
4413
+ }
4414
+ if (!DOCUMENT2_KEY_PATTERN.test(normalized)) {
4415
+ return "invalid";
4416
+ }
4417
+ if (isDuplicateDocument2Key(normalized, namespace)) {
4418
+ return "duplicate";
4419
+ }
4420
+ return null;
4421
+ }
4422
+
4309
4423
  // src/document2/arabicPreamble.ts
4310
4424
  function arabicXeLatexPreamblePkg(twocolumn = false) {
4311
4425
  const classOptions = twocolumn ? "12pt,a4paper,notitlepage,twocolumn" : "12pt,a4paper,notitlepage";
@@ -4856,13 +4970,11 @@ function floatNumberLabel(document2, key, previewOptions) {
4856
4970
  if (!hit || hit.kind !== "fig" && hit.kind !== "tab") {
4857
4971
  return void 0;
4858
4972
  }
4859
- const locale = previewOptions.uiLocale ?? "ar";
4860
- const kindWord = hit.kind === "fig" ? locale === "ar" ? "\u0627\u0644\u0634\u0643\u0644" : "Figure" : locale === "ar" ? "\u0627\u0644\u062C\u062F\u0648\u0644" : "Table";
4861
- const digits = formatBibliographyNumber(hit.number, {
4973
+ return formatFloatCaptionTitle(hit.kind, hit.number, {
4974
+ uiLocale: previewOptions.uiLocale ?? "ar",
4862
4975
  documentDirection: previewOptions.documentDirection,
4863
4976
  digitForm: previewOptions.digitForm
4864
4977
  });
4865
- return `${kindWord} ${digits}`;
4866
4978
  }
4867
4979
  function blockPreview(block, islands, output, equationSide, document2, previewOptions) {
4868
4980
  if (block.kind === "textBlock") {
@@ -4917,7 +5029,8 @@ function blockPreview(block, islands, output, equationSide, document2, previewOp
4917
5029
  title: reference.title,
4918
5030
  year: reference.year,
4919
5031
  url: reference.url,
4920
- venue: reference.venue
5032
+ venue: reference.venue,
5033
+ fieldSeparator: reference.fieldSeparator
4921
5034
  }))
4922
5035
  };
4923
5036
  }
@@ -4970,9 +5083,11 @@ export {
4970
5083
  BUTEX_CLOSING_HAMDALA,
4971
5084
  DEFAULT_DOCUMENT2_HISTORY_MAX_DEPTH,
4972
5085
  DEFAULT_HIJRI_DATE,
5086
+ DEFAULT_REFERENCE_FIELD_SEPARATOR,
4973
5087
  HIJRI_MONTH_IDS,
4974
5088
  HIJRI_YEAR_MAX,
4975
5089
  HIJRI_YEAR_MIN,
5090
+ absoluteHttpHref,
4976
5091
  addDocument2ImageBlock,
4977
5092
  addDocument2ListBlock,
4978
5093
  addDocument2ListItem,
@@ -4983,6 +5098,7 @@ export {
4983
5098
  arabicXeLatexPreambleCmd,
4984
5099
  arabicXeLatexPreambleFont,
4985
5100
  arabicXeLatexPreamblePkg,
5101
+ bibliographyEntryBody,
4986
5102
  bibliographyEntryLatex,
4987
5103
  butexBasmalaDisplayLatex,
4988
5104
  butexBasmalaDisplayTex,
@@ -5008,6 +5124,7 @@ export {
5008
5124
  document2HasTitleStack,
5009
5125
  document2HistoryCanRedo,
5010
5126
  document2HistoryCanUndo,
5127
+ document2KeyError,
5011
5128
  document2Latex,
5012
5129
  document2Preview,
5013
5130
  emptyBlockSelection,
@@ -5018,6 +5135,8 @@ export {
5018
5135
  findFirstInlineField,
5019
5136
  formatBibliographyNumber,
5020
5137
  formatCiteLabel,
5138
+ formatFloatCaptionPreview,
5139
+ formatFloatCaptionTitle,
5021
5140
  formatHijriDate,
5022
5141
  formatRefLabel,
5023
5142
  fromDocumentJson2,
@@ -5029,6 +5148,8 @@ export {
5029
5148
  insertMathToken,
5030
5149
  insertMathTokenAtCaret,
5031
5150
  insertRefTokenAtCaret,
5151
+ isDuplicateDocument2Key,
5152
+ isValidDocument2Key,
5032
5153
  labelNumberMap,
5033
5154
  mathNodeFromArabicSession,
5034
5155
  mathNodeFromSession,
@@ -5043,7 +5164,9 @@ export {
5043
5164
  moveDocument2Reference,
5044
5165
  normalizeBlockSelection,
5045
5166
  normalizeDocument2HijriDate,
5167
+ normalizeDocument2Key,
5046
5168
  normalizeDocument2Meta,
5169
+ normalizeReferenceFieldSeparator,
5047
5170
  parseCiteKeys,
5048
5171
  parseFloatMetaFromJson,
5049
5172
  parseRefKeys,