@drghaliasri/butex 5.3.0 → 5.3.2

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.
@@ -35,9 +35,11 @@ function formatDigits(value, digitForm = "western") {
35
35
  }
36
36
 
37
37
  // src/document2/articleMeta.ts
38
- var BUTEX_BASMALA_LINE1 = "\u0628\u0650\u0633\u0652\u0645\u0650 \u0627\u0644\u0644\u064E\u0651\u0647\u0650 \u0627\u0644\u0631\u064E\u0651\u062D\u0652\u0645\u064E\u0670\u0646\u0650 \u0627\u0644\u0631\u064E\u0651\u062D\u0650\u064A\u0645\u0650";
39
- var BUTEX_BASMALA_SALAWAT = "\u0635\u064E\u0644\u064E\u0651\u0649 \u0627\u0644\u0644\u064E\u0651\u0647\u064F \u0639\u064E\u0644\u064E\u064A\u0652\u0647\u0650 \u0648\u064E\u0633\u064E\u0644\u064E\u0651\u0645\u064E";
38
+ var BUTEX_BASMALA_LINE1 = "\u0628\u0650\u0633\u0652\u0645\u0650 \u0671\u0644\u0644\u064E\u0651\u0670\u0647\u0650 \u0671\u0644\u0631\u064E\u0651\u062D\u0652\u0645\u064E\u0670\u0646\u0650 \u0671\u0644\u0631\u064E\u0651\u062D\u0650\u064A\u0645\u0650";
39
+ var BUTEX_BASMALA_LINE2 = "\u0648\u064E\u0671\u0644\u0635\u064E\u0651\u0644\u064E\u0627\u0629\u064F \u0648\u064E\u0671\u0644\u0633\u064E\u0651\u0644\u064E\u0627\u0645\u064F \u0639\u064E\u0644\u064E\u0649\u0670 \u0631\u064E\u0633\u064F\u0648\u0644\u0650 \u0671\u0644\u0644\u064E\u0651\u0670\u0647\u0650";
40
+ var BUTEX_BASMALA_SALAWAT = "\u0635\u064E\u0644\u064E\u0651\u0649 \u0671\u0644\u0644\u064E\u0651\u0647\u064F \u0639\u064E\u0644\u064E\u064A\u0652\u0647\u0650 \u0648\u064E\u0633\u064E\u0644\u064E\u0651\u0645\u064E";
40
41
  var BUTEX_BASMALA = `${BUTEX_BASMALA_LINE1}
42
+ ${BUTEX_BASMALA_LINE2}
41
43
  ${BUTEX_BASMALA_SALAWAT}`;
42
44
  var BUTEX_CLOSING_HAMDALA = "\u0627\u0644\u0652\u062D\u064E\u0645\u0652\u062F\u064F \u0644\u0650\u0644\u064E\u0651\u0647\u0650 \u0646\u064E\u0641\u064E\u0639\u064E\u0646\u064E\u0627 \u0628\u0650\u0639\u0650\u0644\u0652\u0645\u0650\u0647\u0650";
43
45
  function escapeButexTextArg(text) {
@@ -51,26 +53,60 @@ function butexDiwaniDisplayLatex(text) {
51
53
  ${butexDiwaniDisplayTex(text)}
52
54
  \\]`;
53
55
  }
56
+ var BASMALA_LINES = [BUTEX_BASMALA_LINE1, BUTEX_BASMALA_LINE2, BUTEX_BASMALA_SALAWAT];
54
57
  function butexBasmalaDisplayTex() {
55
- return `${butexDiwaniDisplayTex(BUTEX_BASMALA_LINE1)} \\\\ ${butexDiwaniDisplayTex(BUTEX_BASMALA_SALAWAT)}`;
58
+ return BASMALA_LINES.map((line) => butexDiwaniDisplayTex(line)).join(" \\\\ ");
56
59
  }
57
60
  function butexBasmalaDisplayLatex() {
58
61
  return `\\[
59
62
  ${butexBasmalaDisplayTex()}
60
63
  \\]`;
61
64
  }
62
- function butexBasmalaTitlingPreamble() {
63
- return [
65
+ function butexInColumnMaketitleHook() {
66
+ return String.raw`\makeatletter
67
+ \renewcommand{\maketitle}{%
68
+ \par
69
+ \begingroup
70
+ \renewcommand\thefootnote{\@fnsymbol\c@footnote}%
71
+ \def\@makefnmark{\rlap{\@textsuperscript{\normalfont\@thefnmark}}}%
72
+ \long\def\@makefntext##1{\parindent 1em\noindent
73
+ \hb@xt@1.8em{\hss\@textsuperscript{\normalfont\@thefnmark}}##1}%
74
+ \@maketitle
75
+ \thispagestyle{plain}\@thanks
76
+ \endgroup
77
+ \setcounter{footnote}{0}%
78
+ \global\let\thanks\relax
79
+ \global\let\maketitle\relax
80
+ \global\let\@maketitle\relax
81
+ \global\let\@thanks\@empty
82
+ \global\let\@author\@empty
83
+ \global\let\@date\@empty
84
+ \global\let\@title\@empty
85
+ \global\let\title\relax
86
+ \global\let\author\relax
87
+ \global\let\date\relax
88
+ \global\let\and\relax
89
+ }
90
+ \makeatother`;
91
+ }
92
+ function butexBasmalaTitlingPreamble(options = {}) {
93
+ const lines = [
64
94
  "\\usepackage{titling}",
65
95
  "\\pretitle{%",
66
96
  " \\begin{center}",
67
- ` ${butexDiwaniDisplayTex(BUTEX_BASMALA_LINE1)}\\\\`,
68
- ` ${butexDiwaniDisplayTex(BUTEX_BASMALA_SALAWAT)}`,
97
+ ...BASMALA_LINES.map((line, index) => {
98
+ const suffix = index < BASMALA_LINES.length - 1 ? "\\\\" : "";
99
+ return ` ${butexDiwaniDisplayTex(line)}${suffix}`;
100
+ }),
69
101
  " \\par\\vspace{1.5em}",
70
102
  " \\LARGE",
71
103
  "}",
72
104
  "\\posttitle{\\par\\end{center}}"
73
- ].join("\n");
105
+ ];
106
+ if (options.twocolumn) {
107
+ lines.push(butexInColumnMaketitleHook());
108
+ }
109
+ return lines.join("\n");
74
110
  }
75
111
  var HIJRI_YEAR_MIN = 1400;
76
112
  var HIJRI_YEAR_MAX = 1500;
@@ -232,6 +268,10 @@ function cloneDocument2Meta(meta) {
232
268
  }
233
269
 
234
270
  // src/document2/citations.ts
271
+ var DEFAULT_REFERENCE_FIELD_SEPARATOR = "\u060C";
272
+ function normalizeReferenceFieldSeparator(value) {
273
+ return value === "," ? "," : DEFAULT_REFERENCE_FIELD_SEPARATOR;
274
+ }
235
275
  function referenceNumberMap(references) {
236
276
  const map = /* @__PURE__ */ new Map();
237
277
  references.forEach((reference, index) => {
@@ -277,7 +317,8 @@ function referenceFromJson(json) {
277
317
  title: typeof json.title === "string" ? json.title : "",
278
318
  year: typeof json.year === "string" ? json.year : "",
279
319
  url: typeof json.url === "string" ? json.url : "",
280
- venue: typeof json.venue === "string" ? json.venue : ""
320
+ venue: typeof json.venue === "string" ? json.venue : "",
321
+ fieldSeparator: normalizeReferenceFieldSeparator(json.field_separator)
281
322
  };
282
323
  }
283
324
  function createEmptyReference2(partial = {}) {
@@ -287,15 +328,33 @@ function createEmptyReference2(partial = {}) {
287
328
  title: partial.title,
288
329
  year: partial.year,
289
330
  url: partial.url,
290
- venue: partial.venue
331
+ venue: partial.venue,
332
+ field_separator: partial.field_separator
291
333
  });
292
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
+ }
293
340
  function bibliographyEntryLatex(reference) {
294
- const parts = [reference.authors, reference.title, reference.venue, reference.year].filter((part) => part.trim().length > 0);
295
- const body = parts.join(", ");
341
+ const body = bibliographyEntryBody(reference);
296
342
  const url = reference.url.trim().length > 0 ? ` \\url{${reference.url}}` : "";
297
343
  return `\\bibitem{${reference.key}} ${body}${url}`.trim();
298
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
+ }
299
358
 
300
359
  // src/ast/commands/index.ts
301
360
  function renderCommandCore(context) {
@@ -780,6 +839,23 @@ function labelNumberMap(document2) {
780
839
  }
781
840
  return map;
782
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
+ }
783
859
  function formatRefLabel(keys, document2, refCommand, options = {}) {
784
860
  const documentDirection = options.documentDirection ?? "rtl";
785
861
  const digitForm = options.digitForm ?? (documentDirection === "rtl" ? "arabicIndic" : "western");
@@ -1050,7 +1126,8 @@ function parseReferences(json) {
1050
1126
  title: typeof entry.title === "string" ? entry.title : void 0,
1051
1127
  year: typeof entry.year === "string" ? entry.year : void 0,
1052
1128
  url: typeof entry.url === "string" ? entry.url : void 0,
1053
- 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
1054
1131
  })
1055
1132
  );
1056
1133
  }
@@ -3947,7 +4024,7 @@ function addDocument2ImageBlock(document2, src = "", afterBlockId) {
3947
4024
  kind: "image",
3948
4025
  command: "\\includegraphics",
3949
4026
  value: src,
3950
- options: { width: "0.8\\textwidth" },
4027
+ options: { width: "0.8\\columnwidth" },
3951
4028
  ...defaultFloatMeta()
3952
4029
  };
3953
4030
  return insertDocument2BlockAfter(document2, afterBlockId, block);
@@ -4232,6 +4309,9 @@ function updateDocument2Reference(document2, referenceId, patch) {
4232
4309
  if (typeof patch.venue === "string") {
4233
4310
  reference.venue = patch.venue;
4234
4311
  }
4312
+ if (patch.field_separator === "," || patch.field_separator === "\u060C") {
4313
+ reference.fieldSeparator = patch.field_separator;
4314
+ }
4235
4315
  return next;
4236
4316
  }
4237
4317
  function removeDocument2Reference(document2, referenceId) {
@@ -4270,6 +4350,52 @@ function updateDocument2Meta(document2, patch) {
4270
4350
  return next;
4271
4351
  }
4272
4352
 
4353
+ // src/document2/keys.ts
4354
+ var DOCUMENT2_KEY_PATTERN = /^[\p{L}\p{M}0-9:._-]+$/u;
4355
+ function normalizeDocument2Key(key) {
4356
+ return key.normalize("NFC").trim();
4357
+ }
4358
+ function isValidDocument2Key(key) {
4359
+ const normalized = normalizeDocument2Key(key);
4360
+ return normalized.length > 0 && DOCUMENT2_KEY_PATTERN.test(normalized);
4361
+ }
4362
+ function isDuplicateDocument2Key(key, namespace) {
4363
+ const normalized = normalizeDocument2Key(key);
4364
+ if (normalized.length === 0) {
4365
+ return false;
4366
+ }
4367
+ for (const reference of namespace.references ?? []) {
4368
+ if (namespace.excludeReferenceId && reference.id === namespace.excludeReferenceId) {
4369
+ continue;
4370
+ }
4371
+ if (normalizeDocument2Key(reference.key) === normalized) {
4372
+ return true;
4373
+ }
4374
+ }
4375
+ for (const label of namespace.labels ?? []) {
4376
+ if (namespace.excludeOwnerId && label.ownerId === namespace.excludeOwnerId) {
4377
+ continue;
4378
+ }
4379
+ if (normalizeDocument2Key(label.key) === normalized) {
4380
+ return true;
4381
+ }
4382
+ }
4383
+ return false;
4384
+ }
4385
+ function document2KeyError(key, namespace = {}) {
4386
+ const normalized = normalizeDocument2Key(key);
4387
+ if (normalized.length === 0) {
4388
+ return "empty";
4389
+ }
4390
+ if (!DOCUMENT2_KEY_PATTERN.test(normalized)) {
4391
+ return "invalid";
4392
+ }
4393
+ if (isDuplicateDocument2Key(normalized, namespace)) {
4394
+ return "duplicate";
4395
+ }
4396
+ return null;
4397
+ }
4398
+
4273
4399
  // src/document2/arabicPreamble.ts
4274
4400
  function arabicXeLatexPreamblePkg(twocolumn = false) {
4275
4401
  const classOptions = twocolumn ? "12pt,a4paper,notitlepage,twocolumn" : "12pt,a4paper,notitlepage";
@@ -4552,8 +4678,16 @@ function tableBlockLatex(block) {
4552
4678
  lines.push("\\end{table}");
4553
4679
  return lines.join("\n");
4554
4680
  }
4555
- function imageOptionsLatex(block) {
4556
- const entries = Object.entries(block.options);
4681
+ function remapImageWidthForColumns(value) {
4682
+ return value.replace(/\\textwidth\b/g, "\\columnwidth");
4683
+ }
4684
+ function imageOptionsLatex(block, constrainToColumn) {
4685
+ const entries = Object.entries(block.options).map(([key, value]) => {
4686
+ if (constrainToColumn && key === "width") {
4687
+ return [key, remapImageWidthForColumns(value)];
4688
+ }
4689
+ return [key, value];
4690
+ });
4557
4691
  if (entries.length === 0) {
4558
4692
  return "";
4559
4693
  }
@@ -4564,7 +4698,7 @@ function imageBlockLatex(block) {
4564
4698
  if (block.centered) {
4565
4699
  lines.push(" \\centering");
4566
4700
  }
4567
- lines.push(` ${block.command}${imageOptionsLatex(block)}{${block.value}}`);
4701
+ lines.push(` ${block.command}${imageOptionsLatex(block, true)}{${block.value}}`);
4568
4702
  lines.push(...floatCaptionLabelLines(block));
4569
4703
  lines.push("\\end{figure}");
4570
4704
  return lines.join("\n");
@@ -4594,11 +4728,11 @@ ${block.closing}`;
4594
4728
  function authorLatex(authors) {
4595
4729
  return authors.split(/\n+/).map((line) => line.trim()).filter((line) => line.length > 0).join(" \\\\ ");
4596
4730
  }
4597
- function articleMaketitlePreamble(meta) {
4731
+ function articleMaketitlePreamble(meta, twocolumn = false) {
4598
4732
  if (!document2HasMaketitle(meta)) {
4599
4733
  return "";
4600
4734
  }
4601
- const parts = [butexBasmalaTitlingPreamble()];
4735
+ const parts = [butexBasmalaTitlingPreamble({ twocolumn })];
4602
4736
  if (meta.title.trim().length > 0) {
4603
4737
  parts.push(`\\title{${meta.title.trim()}}`);
4604
4738
  }
@@ -4624,21 +4758,22 @@ ${meta.abstract.trim()}
4624
4758
  }
4625
4759
  function document2Latex(document2, options = {}) {
4626
4760
  const meta = document2.meta ?? emptyDocument2Meta();
4761
+ const twocolumn = options.twocolumn === true;
4627
4762
  const front = articleFrontMatterLatex(meta);
4628
4763
  const bodyBlocks = document2.blocks.map((block) => blockLatex(block, document2.references));
4629
4764
  const closing = butexDiwaniDisplayLatex(BUTEX_CLOSING_HAMDALA);
4630
4765
  const body = [...front, ...bodyBlocks, closing].filter((part) => part.length > 0).join("\n\n");
4631
4766
  const wrapDocument = options.wrapDocument !== false;
4632
4767
  if (!wrapDocument) {
4633
- const metaPreamble = articleMaketitlePreamble(meta);
4768
+ const metaPreamble = articleMaketitlePreamble(meta, twocolumn);
4634
4769
  return metaPreamble.length > 0 ? `${metaPreamble}
4635
4770
 
4636
4771
  ${body}` : body;
4637
4772
  }
4638
4773
  const preamble = getArabicXeLatexPreamble({
4639
4774
  digitsMapping: options.digitsMapping ?? "arabicdigits",
4640
- twocolumn: options.twocolumn === true
4641
- }) + "\n" + articleMaketitlePreamble(meta);
4775
+ twocolumn
4776
+ }) + "\n" + articleMaketitlePreamble(meta, twocolumn);
4642
4777
  return `${preamble}
4643
4778
  \\begin{document}
4644
4779
 
@@ -4811,13 +4946,11 @@ function floatNumberLabel(document2, key, previewOptions) {
4811
4946
  if (!hit || hit.kind !== "fig" && hit.kind !== "tab") {
4812
4947
  return void 0;
4813
4948
  }
4814
- const locale = previewOptions.uiLocale ?? "ar";
4815
- const kindWord = hit.kind === "fig" ? locale === "ar" ? "\u0627\u0644\u0634\u0643\u0644" : "Figure" : locale === "ar" ? "\u0627\u0644\u062C\u062F\u0648\u0644" : "Table";
4816
- const digits = formatBibliographyNumber(hit.number, {
4949
+ return formatFloatCaptionTitle(hit.kind, hit.number, {
4950
+ uiLocale: previewOptions.uiLocale ?? "ar",
4817
4951
  documentDirection: previewOptions.documentDirection,
4818
4952
  digitForm: previewOptions.digitForm
4819
4953
  });
4820
- return `${kindWord} ${digits}`;
4821
4954
  }
4822
4955
  function blockPreview(block, islands, output, equationSide, document2, previewOptions) {
4823
4956
  if (block.kind === "textBlock") {
@@ -4872,7 +5005,8 @@ function blockPreview(block, islands, output, equationSide, document2, previewOp
4872
5005
  title: reference.title,
4873
5006
  year: reference.year,
4874
5007
  url: reference.url,
4875
- venue: reference.venue
5008
+ venue: reference.venue,
5009
+ fieldSeparator: reference.fieldSeparator
4876
5010
  }))
4877
5011
  };
4878
5012
  }
@@ -4920,13 +5054,16 @@ function document2Preview(document2, output = "svg", equationSide = "arabic", pr
4920
5054
  export {
4921
5055
  BUTEX_BASMALA,
4922
5056
  BUTEX_BASMALA_LINE1,
5057
+ BUTEX_BASMALA_LINE2,
4923
5058
  BUTEX_BASMALA_SALAWAT,
4924
5059
  BUTEX_CLOSING_HAMDALA,
4925
5060
  DEFAULT_DOCUMENT2_HISTORY_MAX_DEPTH,
4926
5061
  DEFAULT_HIJRI_DATE,
5062
+ DEFAULT_REFERENCE_FIELD_SEPARATOR,
4927
5063
  HIJRI_MONTH_IDS,
4928
5064
  HIJRI_YEAR_MAX,
4929
5065
  HIJRI_YEAR_MIN,
5066
+ absoluteHttpHref,
4930
5067
  addDocument2ImageBlock,
4931
5068
  addDocument2ListBlock,
4932
5069
  addDocument2ListItem,
@@ -4937,12 +5074,14 @@ export {
4937
5074
  arabicXeLatexPreambleCmd,
4938
5075
  arabicXeLatexPreambleFont,
4939
5076
  arabicXeLatexPreamblePkg,
5077
+ bibliographyEntryBody,
4940
5078
  bibliographyEntryLatex,
4941
5079
  butexBasmalaDisplayLatex,
4942
5080
  butexBasmalaDisplayTex,
4943
5081
  butexBasmalaTitlingPreamble,
4944
5082
  butexDiwaniDisplayLatex,
4945
5083
  butexDiwaniDisplayTex,
5084
+ butexInColumnMaketitleHook,
4946
5085
  citeTokenLatex,
4947
5086
  cloneDocument2Meta,
4948
5087
  cloneDocument2Node,
@@ -4961,6 +5100,7 @@ export {
4961
5100
  document2HasTitleStack,
4962
5101
  document2HistoryCanRedo,
4963
5102
  document2HistoryCanUndo,
5103
+ document2KeyError,
4964
5104
  document2Latex,
4965
5105
  document2Preview,
4966
5106
  emptyBlockSelection,
@@ -4971,6 +5111,8 @@ export {
4971
5111
  findFirstInlineField,
4972
5112
  formatBibliographyNumber,
4973
5113
  formatCiteLabel,
5114
+ formatFloatCaptionPreview,
5115
+ formatFloatCaptionTitle,
4974
5116
  formatHijriDate,
4975
5117
  formatRefLabel,
4976
5118
  fromDocumentJson2,
@@ -4982,6 +5124,8 @@ export {
4982
5124
  insertMathToken,
4983
5125
  insertMathTokenAtCaret,
4984
5126
  insertRefTokenAtCaret,
5127
+ isDuplicateDocument2Key,
5128
+ isValidDocument2Key,
4985
5129
  labelNumberMap,
4986
5130
  mathNodeFromArabicSession,
4987
5131
  mathNodeFromSession,
@@ -4996,7 +5140,9 @@ export {
4996
5140
  moveDocument2Reference,
4997
5141
  normalizeBlockSelection,
4998
5142
  normalizeDocument2HijriDate,
5143
+ normalizeDocument2Key,
4999
5144
  normalizeDocument2Meta,
5145
+ normalizeReferenceFieldSeparator,
5000
5146
  parseCiteKeys,
5001
5147
  parseFloatMetaFromJson,
5002
5148
  parseRefKeys,