@drghaliasri/butex 4.4.0 → 5.2.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/README.md +5 -1
- package/dist/document2.d.mts +390 -80
- package/dist/document2.d.ts +390 -80
- package/dist/document2.js +1585 -112
- package/dist/document2.js.map +1 -1
- package/dist/document2.mjs +1519 -112
- package/dist/document2.mjs.map +1 -1
- package/dist/react-document2.d.mts +257 -87
- package/dist/react-document2.d.ts +257 -87
- package/dist/react-document2.js +5082 -1455
- package/dist/react-document2.js.map +1 -1
- package/dist/react-document2.mjs +5076 -1449
- package/dist/react-document2.mjs.map +1 -1
- package/package.json +1 -1
package/dist/document2.mjs
CHANGED
|
@@ -6,6 +6,273 @@ function document2Id(prefix) {
|
|
|
6
6
|
return id;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
// src/editor/digits.ts
|
|
10
|
+
var WESTERN = "0123456789";
|
|
11
|
+
var ARABIC_INDIC = "\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669";
|
|
12
|
+
var PERSIAN_INDIC = "\u06F0\u06F1\u06F2\u06F3\u06F4\u06F5\u06F6\u06F7\u06F8\u06F9";
|
|
13
|
+
var digitSets = {
|
|
14
|
+
western: WESTERN,
|
|
15
|
+
arabicIndic: ARABIC_INDIC,
|
|
16
|
+
persianIndic: PERSIAN_INDIC
|
|
17
|
+
};
|
|
18
|
+
function digitValue(char) {
|
|
19
|
+
const western = WESTERN.indexOf(char);
|
|
20
|
+
if (western >= 0) {
|
|
21
|
+
return western;
|
|
22
|
+
}
|
|
23
|
+
const arabicIndic = ARABIC_INDIC.indexOf(char);
|
|
24
|
+
if (arabicIndic >= 0) {
|
|
25
|
+
return arabicIndic;
|
|
26
|
+
}
|
|
27
|
+
return PERSIAN_INDIC.indexOf(char);
|
|
28
|
+
}
|
|
29
|
+
function formatDigits(value, digitForm = "western") {
|
|
30
|
+
const target = digitSets[digitForm];
|
|
31
|
+
return Array.from(value, (char) => {
|
|
32
|
+
const value2 = digitValue(char);
|
|
33
|
+
return value2 >= 0 ? target[value2] : char;
|
|
34
|
+
}).join("");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// src/document2/articleMeta.ts
|
|
38
|
+
var BUTEX_BASMALA = "\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 \u0648\u064E\u0627\u0644\u0635\u064E\u0651\u0644\u064E\u0627\u0629\u064F \u0648\u064E\u0627\u0644\u0633\u064E\u0651\u0644\u064E\u0627\u0645\u064F \u0639\u064E\u0644\u064E\u0649\u0670 \u0631\u064E\u0633\u064F\u0648\u0644\u0650 \u0627\u0644\u0644\u064E\u0651\u0647\u0650 \uFDFA";
|
|
39
|
+
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";
|
|
40
|
+
function escapeButexTextArg(text) {
|
|
41
|
+
return text.replace(/\\/g, "\\textbackslash{}").replace(/[{}]/g, "\\$&");
|
|
42
|
+
}
|
|
43
|
+
function butexDiwaniDisplayTex(text) {
|
|
44
|
+
return `\\butexdiwani{${escapeButexTextArg(text)}}`;
|
|
45
|
+
}
|
|
46
|
+
function butexDiwaniDisplayLatex(text) {
|
|
47
|
+
return `\\[
|
|
48
|
+
${butexDiwaniDisplayTex(text)}
|
|
49
|
+
\\]`;
|
|
50
|
+
}
|
|
51
|
+
var HIJRI_YEAR_MIN = 1400;
|
|
52
|
+
var HIJRI_YEAR_MAX = 1500;
|
|
53
|
+
var HIJRI_MONTH_IDS = [
|
|
54
|
+
"\u0645\u062D\u0631\u0645",
|
|
55
|
+
"\u0635\u0641\u0631",
|
|
56
|
+
"\u0631\u0628\u064A\u0639 \u0627\u0644\u0623\u0648\u0644",
|
|
57
|
+
"\u0631\u0628\u064A\u0639 \u0627\u0644\u0622\u062E\u0631",
|
|
58
|
+
"\u062C\u0645\u0627\u062F\u0649 \u0627\u0644\u0623\u0648\u0644\u0649",
|
|
59
|
+
"\u062C\u0645\u0627\u062F\u0649 \u0627\u0644\u0622\u062E\u0631\u0629",
|
|
60
|
+
"\u0631\u062C\u0628",
|
|
61
|
+
"\u0634\u0639\u0628\u0627\u0646",
|
|
62
|
+
"\u0631\u0645\u0636\u0627\u0646",
|
|
63
|
+
"\u0634\u0648\u0627\u0644",
|
|
64
|
+
"\u0630\u0648 \u0627\u0644\u0642\u0639\u062F\u0629",
|
|
65
|
+
"\u0630\u0648 \u0627\u0644\u062D\u062C\u0629"
|
|
66
|
+
];
|
|
67
|
+
var HIJRI_MONTH_LABELS_EN = {
|
|
68
|
+
\u0645\u062D\u0631\u0645: "Muharram",
|
|
69
|
+
\u0635\u0641\u0631: "Safar",
|
|
70
|
+
"\u0631\u0628\u064A\u0639 \u0627\u0644\u0623\u0648\u0644": "Rabi\u02BB I",
|
|
71
|
+
"\u0631\u0628\u064A\u0639 \u0627\u0644\u0622\u062E\u0631": "Rabi\u02BB II",
|
|
72
|
+
"\u062C\u0645\u0627\u062F\u0649 \u0627\u0644\u0623\u0648\u0644\u0649": "Jumada I",
|
|
73
|
+
"\u062C\u0645\u0627\u062F\u0649 \u0627\u0644\u0622\u062E\u0631\u0629": "Jumada II",
|
|
74
|
+
\u0631\u062C\u0628: "Rajab",
|
|
75
|
+
\u0634\u0639\u0628\u0627\u0646: "Sha\u02BBban",
|
|
76
|
+
\u0631\u0645\u0636\u0627\u0646: "Ramadan",
|
|
77
|
+
\u0634\u0648\u0627\u0644: "Shawwal",
|
|
78
|
+
"\u0630\u0648 \u0627\u0644\u0642\u0639\u062F\u0629": "Dhul Qa\u02BBdah",
|
|
79
|
+
"\u0630\u0648 \u0627\u0644\u062D\u062C\u0629": "Dhul Hijjah"
|
|
80
|
+
};
|
|
81
|
+
var LEGACY_LATIN_MONTH = {
|
|
82
|
+
muharram: "\u0645\u062D\u0631\u0645",
|
|
83
|
+
safar: "\u0635\u0641\u0631",
|
|
84
|
+
rabiAwwal: "\u0631\u0628\u064A\u0639 \u0627\u0644\u0623\u0648\u0644",
|
|
85
|
+
rabiThani: "\u0631\u0628\u064A\u0639 \u0627\u0644\u0622\u062E\u0631",
|
|
86
|
+
jumadaAwwal: "\u062C\u0645\u0627\u062F\u0649 \u0627\u0644\u0623\u0648\u0644\u0649",
|
|
87
|
+
jumadaThani: "\u062C\u0645\u0627\u062F\u0649 \u0627\u0644\u0622\u062E\u0631\u0629",
|
|
88
|
+
rajab: "\u0631\u062C\u0628",
|
|
89
|
+
shaban: "\u0634\u0639\u0628\u0627\u0646",
|
|
90
|
+
ramadan: "\u0631\u0645\u0636\u0627\u0646",
|
|
91
|
+
shawwal: "\u0634\u0648\u0627\u0644",
|
|
92
|
+
dhulQadah: "\u0630\u0648 \u0627\u0644\u0642\u0639\u062F\u0629",
|
|
93
|
+
dhulHijjah: "\u0630\u0648 \u0627\u0644\u062D\u062C\u0629"
|
|
94
|
+
};
|
|
95
|
+
var DEFAULT_HIJRI_DATE = {
|
|
96
|
+
day: 1,
|
|
97
|
+
month: "\u0645\u062D\u0631\u0645",
|
|
98
|
+
year: 1448
|
|
99
|
+
};
|
|
100
|
+
function hijriMonthLabel(month, locale = "ar") {
|
|
101
|
+
return locale === "en" ? HIJRI_MONTH_LABELS_EN[month] : month;
|
|
102
|
+
}
|
|
103
|
+
function emptyDocument2Meta() {
|
|
104
|
+
return {
|
|
105
|
+
title: "",
|
|
106
|
+
authors: "",
|
|
107
|
+
date: { ...DEFAULT_HIJRI_DATE },
|
|
108
|
+
abstract: ""
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function clampInt(value, min, max) {
|
|
112
|
+
if (!Number.isFinite(value)) {
|
|
113
|
+
return min;
|
|
114
|
+
}
|
|
115
|
+
return Math.min(max, Math.max(min, Math.trunc(value)));
|
|
116
|
+
}
|
|
117
|
+
function isHijriMonthId(value) {
|
|
118
|
+
return typeof value === "string" && HIJRI_MONTH_IDS.includes(value);
|
|
119
|
+
}
|
|
120
|
+
function resolveHijriMonthId(value) {
|
|
121
|
+
if (isHijriMonthId(value)) {
|
|
122
|
+
return value;
|
|
123
|
+
}
|
|
124
|
+
if (typeof value === "string" && value in LEGACY_LATIN_MONTH) {
|
|
125
|
+
return LEGACY_LATIN_MONTH[value];
|
|
126
|
+
}
|
|
127
|
+
return DEFAULT_HIJRI_DATE.month;
|
|
128
|
+
}
|
|
129
|
+
function normalizeDocument2HijriDate(value) {
|
|
130
|
+
if (typeof value !== "object" || value === null) {
|
|
131
|
+
return { ...DEFAULT_HIJRI_DATE };
|
|
132
|
+
}
|
|
133
|
+
const raw = value;
|
|
134
|
+
const day = clampInt(typeof raw.day === "number" ? raw.day : Number(raw.day), 1, 30);
|
|
135
|
+
const year = clampInt(typeof raw.year === "number" ? raw.year : Number(raw.year), HIJRI_YEAR_MIN, HIJRI_YEAR_MAX);
|
|
136
|
+
const month = resolveHijriMonthId(raw.month);
|
|
137
|
+
return { day, month, year };
|
|
138
|
+
}
|
|
139
|
+
function normalizeDocument2Meta(value) {
|
|
140
|
+
if (typeof value !== "object" || value === null) {
|
|
141
|
+
return emptyDocument2Meta();
|
|
142
|
+
}
|
|
143
|
+
const raw = value;
|
|
144
|
+
return {
|
|
145
|
+
title: typeof raw.title === "string" ? raw.title : "",
|
|
146
|
+
authors: typeof raw.authors === "string" ? raw.authors : "",
|
|
147
|
+
date: normalizeDocument2HijriDate(raw.date),
|
|
148
|
+
abstract: typeof raw.abstract === "string" ? raw.abstract : ""
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
function mergeDocument2Meta(fromJson, fromProp) {
|
|
152
|
+
const fromPropMeta = {
|
|
153
|
+
title: typeof fromProp?.title === "string" ? fromProp.title : "",
|
|
154
|
+
authors: typeof fromProp?.authors === "string" ? fromProp.authors : "",
|
|
155
|
+
abstract: typeof fromProp?.abstract === "string" ? fromProp.abstract : "",
|
|
156
|
+
date: fromProp?.date ? normalizeDocument2HijriDate({ ...DEFAULT_HIJRI_DATE, ...fromProp.date }) : { ...DEFAULT_HIJRI_DATE }
|
|
157
|
+
};
|
|
158
|
+
if (typeof fromJson !== "object" || fromJson === null) {
|
|
159
|
+
return fromPropMeta;
|
|
160
|
+
}
|
|
161
|
+
const json = fromJson;
|
|
162
|
+
return {
|
|
163
|
+
title: "title" in json && typeof json.title === "string" ? json.title : fromPropMeta.title,
|
|
164
|
+
authors: "authors" in json && typeof json.authors === "string" ? json.authors : fromPropMeta.authors,
|
|
165
|
+
abstract: "abstract" in json && typeof json.abstract === "string" ? json.abstract : fromPropMeta.abstract,
|
|
166
|
+
date: "date" in json ? normalizeDocument2HijriDate(json.date) : fromPropMeta.date
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
function fillDocument2MetaGaps(current, fromProp) {
|
|
170
|
+
if (!fromProp) {
|
|
171
|
+
return cloneDocument2Meta(current);
|
|
172
|
+
}
|
|
173
|
+
return {
|
|
174
|
+
title: current.title.trim().length > 0 ? current.title : typeof fromProp.title === "string" ? fromProp.title : current.title,
|
|
175
|
+
authors: current.authors.trim().length > 0 ? current.authors : typeof fromProp.authors === "string" ? fromProp.authors : current.authors,
|
|
176
|
+
abstract: current.abstract.trim().length > 0 ? current.abstract : typeof fromProp.abstract === "string" ? fromProp.abstract : current.abstract,
|
|
177
|
+
date: fromProp.date ? normalizeDocument2HijriDate({ ...current.date, ...fromProp.date }) : { ...current.date }
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
function document2HasMaketitle(meta) {
|
|
181
|
+
return meta.title.trim().length > 0 || meta.authors.trim().length > 0;
|
|
182
|
+
}
|
|
183
|
+
function document2HasAbstract(meta) {
|
|
184
|
+
return meta.abstract.trim().length > 0;
|
|
185
|
+
}
|
|
186
|
+
function document2HasTitleStack(meta) {
|
|
187
|
+
return document2HasMaketitle(meta) || document2HasAbstract(meta);
|
|
188
|
+
}
|
|
189
|
+
function formatHijriDate(date, options = "ar") {
|
|
190
|
+
const opts = typeof options === "string" ? { locale: options } : options;
|
|
191
|
+
const locale = opts.locale ?? "ar";
|
|
192
|
+
const digitForm = opts.digitForm ?? (locale === "en" ? "western" : "arabicIndic");
|
|
193
|
+
const month = hijriMonthLabel(date.month, locale);
|
|
194
|
+
const day = formatDigits(String(date.day), digitForm);
|
|
195
|
+
const year = formatDigits(String(date.year), digitForm);
|
|
196
|
+
if (locale === "en") {
|
|
197
|
+
return `${day} ${month} ${year} AH`;
|
|
198
|
+
}
|
|
199
|
+
return `${day} ${month} ${year}\u0647\u0640`;
|
|
200
|
+
}
|
|
201
|
+
function cloneDocument2Meta(meta) {
|
|
202
|
+
return {
|
|
203
|
+
title: meta.title,
|
|
204
|
+
authors: meta.authors,
|
|
205
|
+
date: { ...meta.date },
|
|
206
|
+
abstract: meta.abstract
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// src/document2/citations.ts
|
|
211
|
+
function referenceNumberMap(references) {
|
|
212
|
+
const map = /* @__PURE__ */ new Map();
|
|
213
|
+
references.forEach((reference, index) => {
|
|
214
|
+
if (!map.has(reference.key)) {
|
|
215
|
+
map.set(reference.key, index + 1);
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
return map;
|
|
219
|
+
}
|
|
220
|
+
function resolveCiteNumbers(keys, references) {
|
|
221
|
+
const map = referenceNumberMap(references);
|
|
222
|
+
return keys.map((key) => map.get(key) ?? null);
|
|
223
|
+
}
|
|
224
|
+
function formatCiteLabel(keys, references, options = {}) {
|
|
225
|
+
const documentDirection = options.documentDirection ?? "rtl";
|
|
226
|
+
const digitForm = options.digitForm ?? (documentDirection === "rtl" ? "arabicIndic" : "western");
|
|
227
|
+
const numbers = resolveCiteNumbers(keys, references).map((value) => value === null ? "?" : String(value));
|
|
228
|
+
const display = documentDirection === "rtl" ? [...numbers].reverse() : numbers;
|
|
229
|
+
const separator = documentDirection === "rtl" ? "\u060C" : ", ";
|
|
230
|
+
const body = display.map((part) => formatDigits(part, digitForm)).join(separator);
|
|
231
|
+
return `[${body}]`;
|
|
232
|
+
}
|
|
233
|
+
function formatBibliographyNumber(index, options = {}) {
|
|
234
|
+
const documentDirection = options.documentDirection ?? "rtl";
|
|
235
|
+
const digitForm = options.digitForm ?? (documentDirection === "rtl" ? "arabicIndic" : "western");
|
|
236
|
+
return formatDigits(String(index), digitForm);
|
|
237
|
+
}
|
|
238
|
+
function parseCiteKeys(source) {
|
|
239
|
+
const match = /^\\cite\{([^}]*)\}$/.exec(source.trim());
|
|
240
|
+
if (!match) {
|
|
241
|
+
return [];
|
|
242
|
+
}
|
|
243
|
+
return (match[1] ?? "").split(",").map((key) => key.trim()).filter((key) => key.length > 0);
|
|
244
|
+
}
|
|
245
|
+
function citeTokenLatex(keys) {
|
|
246
|
+
return `\\cite{${keys.join(",")}}`;
|
|
247
|
+
}
|
|
248
|
+
function referenceFromJson(json) {
|
|
249
|
+
return {
|
|
250
|
+
id: document2Id("ref"),
|
|
251
|
+
key: json.key,
|
|
252
|
+
authors: typeof json.authors === "string" ? json.authors : "",
|
|
253
|
+
title: typeof json.title === "string" ? json.title : "",
|
|
254
|
+
year: typeof json.year === "string" ? json.year : "",
|
|
255
|
+
url: typeof json.url === "string" ? json.url : "",
|
|
256
|
+
venue: typeof json.venue === "string" ? json.venue : ""
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
function createEmptyReference2(partial = {}) {
|
|
260
|
+
return referenceFromJson({
|
|
261
|
+
key: partial.key ?? `ref${String(Date.now()).slice(-4)}`,
|
|
262
|
+
authors: partial.authors,
|
|
263
|
+
title: partial.title,
|
|
264
|
+
year: partial.year,
|
|
265
|
+
url: partial.url,
|
|
266
|
+
venue: partial.venue
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
function bibliographyEntryLatex(reference) {
|
|
270
|
+
const parts = [reference.authors, reference.title, reference.venue, reference.year].filter((part) => part.trim().length > 0);
|
|
271
|
+
const body = parts.join(", ");
|
|
272
|
+
const url = reference.url.trim().length > 0 ? ` \\url{${reference.url}}` : "";
|
|
273
|
+
return `\\bibitem{${reference.key}} ${body}${url}`.trim();
|
|
274
|
+
}
|
|
275
|
+
|
|
9
276
|
// src/ast/commands/index.ts
|
|
10
277
|
function renderCommandCore(context) {
|
|
11
278
|
const optional = context.optionalArgs.map((arg) => `[${context.renderChain(arg)}]`).join("");
|
|
@@ -375,6 +642,168 @@ ${lines.map((line) => ` ${line}`).join(" \\\\\n")}
|
|
|
375
642
|
${math.closing}`;
|
|
376
643
|
}
|
|
377
644
|
|
|
645
|
+
// src/document2/labels.ts
|
|
646
|
+
function defaultFloatMeta() {
|
|
647
|
+
return {
|
|
648
|
+
centered: true,
|
|
649
|
+
captionEnabled: false,
|
|
650
|
+
caption: "",
|
|
651
|
+
labelEnabled: false,
|
|
652
|
+
label: ""
|
|
653
|
+
};
|
|
654
|
+
}
|
|
655
|
+
function parseFloatMetaFromJson(json) {
|
|
656
|
+
const caption = typeof json.caption === "string" ? json.caption : "";
|
|
657
|
+
const label = typeof json.label === "string" ? json.label : "";
|
|
658
|
+
return {
|
|
659
|
+
centered: json.centered !== false,
|
|
660
|
+
captionEnabled: json.caption_enabled === true || typeof json.caption_enabled !== "boolean" && caption.length > 0,
|
|
661
|
+
caption,
|
|
662
|
+
labelEnabled: json.label_enabled === true || typeof json.label_enabled !== "boolean" && label.trim().length > 0,
|
|
663
|
+
label
|
|
664
|
+
};
|
|
665
|
+
}
|
|
666
|
+
function parseRefKeys(source) {
|
|
667
|
+
const eqref = /^\\eqref\{([^}]*)\}$/.exec(source.trim());
|
|
668
|
+
if (eqref) {
|
|
669
|
+
return {
|
|
670
|
+
refCommand: "eqref",
|
|
671
|
+
keys: (eqref[1] ?? "").split(",").map((key) => key.trim()).filter((key) => key.length > 0)
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
const ref = /^\\ref\{([^}]*)\}$/.exec(source.trim());
|
|
675
|
+
if (ref) {
|
|
676
|
+
return {
|
|
677
|
+
refCommand: "ref",
|
|
678
|
+
keys: (ref[1] ?? "").split(",").map((key) => key.trim()).filter((key) => key.length > 0)
|
|
679
|
+
};
|
|
680
|
+
}
|
|
681
|
+
return { keys: [], refCommand: "ref" };
|
|
682
|
+
}
|
|
683
|
+
function refTokenLatex(keys, refCommand) {
|
|
684
|
+
const command = refCommand === "eqref" ? "\\eqref" : "\\ref";
|
|
685
|
+
return `${command}{${keys.join(",")}}`;
|
|
686
|
+
}
|
|
687
|
+
function collectDocument2Labels(document2) {
|
|
688
|
+
const entries = [];
|
|
689
|
+
const counters = { fig: 0, tab: 0, eq: 0 };
|
|
690
|
+
function pushEqFromField(tokens) {
|
|
691
|
+
for (const token of tokens) {
|
|
692
|
+
if (token.kind !== "math") {
|
|
693
|
+
continue;
|
|
694
|
+
}
|
|
695
|
+
if (token.display && token.labelEnabled && token.label && token.label.trim().length > 0) {
|
|
696
|
+
counters.eq += 1;
|
|
697
|
+
entries.push({
|
|
698
|
+
key: token.label.trim(),
|
|
699
|
+
kind: "eq",
|
|
700
|
+
caption: "",
|
|
701
|
+
ownerId: token.id,
|
|
702
|
+
number: counters.eq
|
|
703
|
+
});
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
function walk(blocks) {
|
|
708
|
+
for (const block of blocks) {
|
|
709
|
+
if (block.kind === "image" && block.labelEnabled && block.label.trim().length > 0) {
|
|
710
|
+
counters.fig += 1;
|
|
711
|
+
entries.push({
|
|
712
|
+
key: block.label.trim(),
|
|
713
|
+
kind: "fig",
|
|
714
|
+
caption: block.captionEnabled ? block.caption : "",
|
|
715
|
+
ownerId: block.id,
|
|
716
|
+
number: counters.fig
|
|
717
|
+
});
|
|
718
|
+
}
|
|
719
|
+
if (block.kind === "table") {
|
|
720
|
+
if (block.labelEnabled && block.label.trim().length > 0) {
|
|
721
|
+
counters.tab += 1;
|
|
722
|
+
entries.push({
|
|
723
|
+
key: block.label.trim(),
|
|
724
|
+
kind: "tab",
|
|
725
|
+
caption: block.captionEnabled ? block.caption : "",
|
|
726
|
+
ownerId: block.id,
|
|
727
|
+
number: counters.tab
|
|
728
|
+
});
|
|
729
|
+
}
|
|
730
|
+
for (const row of block.rows) {
|
|
731
|
+
for (const cell of row) {
|
|
732
|
+
pushEqFromField(cell.tokens);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
if (block.kind === "textBlock") {
|
|
737
|
+
pushEqFromField(block.field.tokens);
|
|
738
|
+
}
|
|
739
|
+
if (block.kind === "list") {
|
|
740
|
+
for (const item of block.items) {
|
|
741
|
+
pushEqFromField(item.field.tokens);
|
|
742
|
+
walk(item.blocks);
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
walk(document2.blocks);
|
|
748
|
+
return entries;
|
|
749
|
+
}
|
|
750
|
+
function labelNumberMap(document2) {
|
|
751
|
+
const map = /* @__PURE__ */ new Map();
|
|
752
|
+
for (const entry of collectDocument2Labels(document2)) {
|
|
753
|
+
if (!map.has(entry.key)) {
|
|
754
|
+
map.set(entry.key, { kind: entry.kind, number: entry.number });
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
return map;
|
|
758
|
+
}
|
|
759
|
+
function formatRefLabel(keys, document2, refCommand, options = {}) {
|
|
760
|
+
const documentDirection = options.documentDirection ?? "rtl";
|
|
761
|
+
const digitForm = options.digitForm ?? (documentDirection === "rtl" ? "arabicIndic" : "western");
|
|
762
|
+
const map = labelNumberMap(document2);
|
|
763
|
+
const parts = keys.map((key) => {
|
|
764
|
+
const hit = map.get(key);
|
|
765
|
+
if (!hit) {
|
|
766
|
+
return "?";
|
|
767
|
+
}
|
|
768
|
+
return formatDigits(String(hit.number), digitForm);
|
|
769
|
+
});
|
|
770
|
+
const body = parts.join(documentDirection === "rtl" ? "\u060C" : ", ");
|
|
771
|
+
if (refCommand === "eqref") {
|
|
772
|
+
return `(${body})`;
|
|
773
|
+
}
|
|
774
|
+
return body;
|
|
775
|
+
}
|
|
776
|
+
function stripDisplayMathDelimiters(source) {
|
|
777
|
+
const trimmed = source.trim();
|
|
778
|
+
if (trimmed.startsWith("\\[") && trimmed.endsWith("\\]")) {
|
|
779
|
+
return trimmed.slice(2, -2).trim();
|
|
780
|
+
}
|
|
781
|
+
if (trimmed.startsWith("$$") && trimmed.endsWith("$$")) {
|
|
782
|
+
return trimmed.slice(2, -2).trim();
|
|
783
|
+
}
|
|
784
|
+
if (trimmed.startsWith("\\begin{equation}") && trimmed.endsWith("\\end{equation}")) {
|
|
785
|
+
return trimmed.slice("\\begin{equation}".length, -"\\end{equation}".length).trim();
|
|
786
|
+
}
|
|
787
|
+
return trimmed;
|
|
788
|
+
}
|
|
789
|
+
function applyFloatMetaPatch(block, patch) {
|
|
790
|
+
if (typeof patch.centered === "boolean") {
|
|
791
|
+
block.centered = patch.centered;
|
|
792
|
+
}
|
|
793
|
+
if (typeof patch.captionEnabled === "boolean") {
|
|
794
|
+
block.captionEnabled = patch.captionEnabled;
|
|
795
|
+
}
|
|
796
|
+
if (typeof patch.caption === "string") {
|
|
797
|
+
block.caption = patch.caption;
|
|
798
|
+
}
|
|
799
|
+
if (typeof patch.labelEnabled === "boolean") {
|
|
800
|
+
block.labelEnabled = patch.labelEnabled;
|
|
801
|
+
}
|
|
802
|
+
if (typeof patch.label === "string") {
|
|
803
|
+
block.label = patch.label;
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
|
|
378
807
|
// src/document2/inlineScanner.ts
|
|
379
808
|
var MATH_ENVIRONMENTS = /* @__PURE__ */ new Set([
|
|
380
809
|
"equation",
|
|
@@ -424,53 +853,127 @@ function environmentSpan(value, start) {
|
|
|
424
853
|
const end = closingStart + closing.length;
|
|
425
854
|
return { start, end, source: value.slice(start, end), opening, closing, display: true };
|
|
426
855
|
}
|
|
427
|
-
function
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
856
|
+
function citeSpan(value, start) {
|
|
857
|
+
if (!value.startsWith("\\cite{", start) || isEscaped(value, start)) {
|
|
858
|
+
return null;
|
|
859
|
+
}
|
|
860
|
+
const openBrace = start + "\\cite".length;
|
|
861
|
+
if (value[openBrace] !== "{") {
|
|
862
|
+
return null;
|
|
863
|
+
}
|
|
864
|
+
let depth = 0;
|
|
865
|
+
for (let i = openBrace; i < value.length; i += 1) {
|
|
866
|
+
const char = value[i];
|
|
867
|
+
if (char === "{" && !isEscaped(value, i)) {
|
|
868
|
+
depth += 1;
|
|
869
|
+
continue;
|
|
438
870
|
}
|
|
439
|
-
if (
|
|
440
|
-
|
|
441
|
-
if (
|
|
442
|
-
const end =
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
continue;
|
|
871
|
+
if (char === "}" && !isEscaped(value, i)) {
|
|
872
|
+
depth -= 1;
|
|
873
|
+
if (depth === 0) {
|
|
874
|
+
const end = i + 1;
|
|
875
|
+
const source = value.slice(start, end);
|
|
876
|
+
return { kind: "cite", start, end, source, keys: parseCiteKeys(source) };
|
|
446
877
|
}
|
|
447
878
|
}
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
879
|
+
}
|
|
880
|
+
return null;
|
|
881
|
+
}
|
|
882
|
+
function refSpan(value, start) {
|
|
883
|
+
const eqrefPrefix = "\\eqref{";
|
|
884
|
+
const refPrefix = "\\ref{";
|
|
885
|
+
let refCommand = "ref";
|
|
886
|
+
let prefix = refPrefix;
|
|
887
|
+
if (value.startsWith(eqrefPrefix, start) && !isEscaped(value, start)) {
|
|
888
|
+
refCommand = "eqref";
|
|
889
|
+
prefix = eqrefPrefix;
|
|
890
|
+
} else if (value.startsWith(refPrefix, start) && !isEscaped(value, start)) {
|
|
891
|
+
refCommand = "ref";
|
|
892
|
+
prefix = refPrefix;
|
|
893
|
+
} else {
|
|
894
|
+
return null;
|
|
895
|
+
}
|
|
896
|
+
const openBrace = start + prefix.length - 1;
|
|
897
|
+
if (value[openBrace] !== "{") {
|
|
898
|
+
return null;
|
|
899
|
+
}
|
|
900
|
+
let depth = 0;
|
|
901
|
+
for (let i = openBrace; i < value.length; i += 1) {
|
|
902
|
+
const char = value[i];
|
|
903
|
+
if (char === "{" && !isEscaped(value, i)) {
|
|
904
|
+
depth += 1;
|
|
905
|
+
continue;
|
|
456
906
|
}
|
|
457
|
-
if (
|
|
458
|
-
|
|
459
|
-
if (
|
|
460
|
-
const end =
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
907
|
+
if (char === "}" && !isEscaped(value, i)) {
|
|
908
|
+
depth -= 1;
|
|
909
|
+
if (depth === 0) {
|
|
910
|
+
const end = i + 1;
|
|
911
|
+
const source = value.slice(start, end);
|
|
912
|
+
const parsed = parseRefKeys(source);
|
|
913
|
+
return { kind: "ref", start, end, source, keys: parsed.keys, refCommand };
|
|
464
914
|
}
|
|
465
915
|
}
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
916
|
+
}
|
|
917
|
+
return null;
|
|
918
|
+
}
|
|
919
|
+
function mathSpanAt(value, i) {
|
|
920
|
+
if (value.startsWith("\\begin{", i)) {
|
|
921
|
+
return environmentSpan(value, i);
|
|
922
|
+
}
|
|
923
|
+
if (value.startsWith("\\(", i)) {
|
|
924
|
+
const close = value.indexOf("\\)", i + 2);
|
|
925
|
+
if (close >= 0) {
|
|
926
|
+
const end = close + 2;
|
|
927
|
+
return { start: i, end, source: value.slice(i, end), opening: "\\(", closing: "\\)", display: false };
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
if (value.startsWith("\\[", i)) {
|
|
931
|
+
const close = value.indexOf("\\]", i + 2);
|
|
932
|
+
if (close >= 0) {
|
|
933
|
+
const end = close + 2;
|
|
934
|
+
return { start: i, end, source: value.slice(i, end), opening: "\\[", closing: "\\]", display: true };
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
if (value.startsWith("$$", i) && !isEscaped(value, i)) {
|
|
938
|
+
const close = value.indexOf("$$", i + 2);
|
|
939
|
+
if (close >= 0) {
|
|
940
|
+
const end = close + 2;
|
|
941
|
+
return { start: i, end, source: value.slice(i, end), opening: "$$", closing: "$$", display: true };
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
if (value[i] === "$" && !isEscaped(value, i)) {
|
|
945
|
+
const close = findClosingDollar(value, i + 1);
|
|
946
|
+
if (close >= 0) {
|
|
947
|
+
const end = close + 1;
|
|
948
|
+
return { start: i, end, source: value.slice(i, end), opening: "$", closing: "$", display: false };
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
return null;
|
|
952
|
+
}
|
|
953
|
+
function detectMathSpans2(value) {
|
|
954
|
+
return detectInlineSpans2(value).filter((span) => span.kind === "math").map(({ kind: _kind, ...span }) => span);
|
|
955
|
+
}
|
|
956
|
+
function detectInlineSpans2(value) {
|
|
957
|
+
const spans = [];
|
|
958
|
+
let i = 0;
|
|
959
|
+
while (i < value.length) {
|
|
960
|
+
const cite = citeSpan(value, i);
|
|
961
|
+
if (cite) {
|
|
962
|
+
spans.push(cite);
|
|
963
|
+
i = cite.end;
|
|
964
|
+
continue;
|
|
965
|
+
}
|
|
966
|
+
const ref = refSpan(value, i);
|
|
967
|
+
if (ref) {
|
|
968
|
+
spans.push(ref);
|
|
969
|
+
i = ref.end;
|
|
970
|
+
continue;
|
|
971
|
+
}
|
|
972
|
+
const math = mathSpanAt(value, i);
|
|
973
|
+
if (math) {
|
|
974
|
+
spans.push({ kind: "math", ...math });
|
|
975
|
+
i = math.end;
|
|
976
|
+
continue;
|
|
474
977
|
}
|
|
475
978
|
i += 1;
|
|
476
979
|
}
|
|
@@ -507,19 +1010,63 @@ function pushDiagnostic(diagnostics, options, path, message) {
|
|
|
507
1010
|
}
|
|
508
1011
|
diagnostics.push({ code: "math_alignment", message, path });
|
|
509
1012
|
}
|
|
1013
|
+
function parseReferences(json) {
|
|
1014
|
+
if (!Array.isArray(json)) {
|
|
1015
|
+
return [];
|
|
1016
|
+
}
|
|
1017
|
+
const references = [];
|
|
1018
|
+
for (const entry of json) {
|
|
1019
|
+
if (!isObject2(entry) || typeof entry.key !== "string" || entry.key.trim().length === 0) {
|
|
1020
|
+
continue;
|
|
1021
|
+
}
|
|
1022
|
+
references.push(
|
|
1023
|
+
referenceFromJson({
|
|
1024
|
+
key: entry.key.trim(),
|
|
1025
|
+
authors: typeof entry.authors === "string" ? entry.authors : void 0,
|
|
1026
|
+
title: typeof entry.title === "string" ? entry.title : void 0,
|
|
1027
|
+
year: typeof entry.year === "string" ? entry.year : void 0,
|
|
1028
|
+
url: typeof entry.url === "string" ? entry.url : void 0,
|
|
1029
|
+
venue: typeof entry.venue === "string" ? entry.venue : void 0
|
|
1030
|
+
})
|
|
1031
|
+
);
|
|
1032
|
+
}
|
|
1033
|
+
return references;
|
|
1034
|
+
}
|
|
510
1035
|
function createInlineField2(value = "", mathObjects = [], options = {}, path = "$", diagnostics = []) {
|
|
511
1036
|
const mode = options.mode ?? "english";
|
|
512
|
-
const spans =
|
|
1037
|
+
const spans = detectInlineSpans2(value);
|
|
1038
|
+
const mathSpans = spans.filter((span) => span.kind === "math");
|
|
513
1039
|
const tokens = [];
|
|
514
1040
|
let index = 0;
|
|
515
|
-
|
|
516
|
-
|
|
1041
|
+
let mathObjectIndex = 0;
|
|
1042
|
+
if (mathObjects.length > 0 && mathObjects.length !== mathSpans.length) {
|
|
1043
|
+
pushDiagnostic(diagnostics, options, path, `math_objects count mismatch: detected ${String(mathSpans.length)}, got ${String(mathObjects.length)}`);
|
|
517
1044
|
}
|
|
518
|
-
|
|
1045
|
+
for (const span of spans) {
|
|
519
1046
|
if (span.start > index) {
|
|
520
1047
|
tokens.push({ id: document2Id("text"), kind: "text", text: value.slice(index, span.start) });
|
|
521
1048
|
}
|
|
522
|
-
|
|
1049
|
+
if (span.kind === "cite") {
|
|
1050
|
+
tokens.push({
|
|
1051
|
+
id: document2Id("cite"),
|
|
1052
|
+
kind: "cite",
|
|
1053
|
+
keys: span.keys.length > 0 ? span.keys : []
|
|
1054
|
+
});
|
|
1055
|
+
index = span.end;
|
|
1056
|
+
continue;
|
|
1057
|
+
}
|
|
1058
|
+
if (span.kind === "ref") {
|
|
1059
|
+
tokens.push({
|
|
1060
|
+
id: document2Id("ref"),
|
|
1061
|
+
kind: "ref",
|
|
1062
|
+
keys: span.keys.length > 0 ? span.keys : [],
|
|
1063
|
+
refCommand: span.refCommand
|
|
1064
|
+
});
|
|
1065
|
+
index = span.end;
|
|
1066
|
+
continue;
|
|
1067
|
+
}
|
|
1068
|
+
const mathJson = mathObjects[mathObjectIndex];
|
|
1069
|
+
mathObjectIndex += 1;
|
|
523
1070
|
if (mathJson && (mathJson.math_mode !== span.opening || mathJson.closing !== span.closing)) {
|
|
524
1071
|
pushDiagnostic(diagnostics, options, path, "math_objects order mismatch");
|
|
525
1072
|
}
|
|
@@ -551,7 +1098,7 @@ function createInlineField2(value = "", mathObjects = [], options = {}, path = "
|
|
|
551
1098
|
});
|
|
552
1099
|
}
|
|
553
1100
|
index = span.end;
|
|
554
|
-
}
|
|
1101
|
+
}
|
|
555
1102
|
if (index < value.length || tokens.length === 0) {
|
|
556
1103
|
tokens.push({ id: document2Id("text"), kind: "text", text: value.slice(index) });
|
|
557
1104
|
}
|
|
@@ -566,7 +1113,8 @@ function parseTextBlock(json, options, path, diagnostics) {
|
|
|
566
1113
|
id: document2Id("block"),
|
|
567
1114
|
kind: "textBlock",
|
|
568
1115
|
command: json.command,
|
|
569
|
-
field: createInlineField2(value, json.math_objects ?? [], options, `${path}.value`, diagnostics)
|
|
1116
|
+
field: createInlineField2(value, json.math_objects ?? [], options, `${path}.value`, diagnostics),
|
|
1117
|
+
...json.centered === true ? { centered: true } : {}
|
|
570
1118
|
};
|
|
571
1119
|
}
|
|
572
1120
|
function parseListItem(json, options, path, diagnostics) {
|
|
@@ -619,16 +1167,21 @@ function parseTableBlock(json, options, path, diagnostics) {
|
|
|
619
1167
|
command: "\\begin{tabular}",
|
|
620
1168
|
closing: "\\end{tabular}",
|
|
621
1169
|
columns: typeof json.columns === "string" ? json.columns : "",
|
|
622
|
-
rows
|
|
1170
|
+
rows,
|
|
1171
|
+
...parseFloatMetaFromJson(json)
|
|
623
1172
|
};
|
|
624
1173
|
}
|
|
625
1174
|
function parseImageBlock(json) {
|
|
1175
|
+
const assetId = typeof json.asset_id === "string" && json.asset_id.length > 0 ? json.asset_id : void 0;
|
|
1176
|
+
const value = assetId !== void 0 ? typeof json.value === "string" ? json.value : "" : requireString(json.value, "\\includegraphics requires string value");
|
|
626
1177
|
return {
|
|
627
1178
|
id: document2Id("block"),
|
|
628
1179
|
kind: "image",
|
|
629
1180
|
command: "\\includegraphics",
|
|
630
|
-
value
|
|
631
|
-
|
|
1181
|
+
value,
|
|
1182
|
+
...assetId !== void 0 ? { assetId } : {},
|
|
1183
|
+
options: isRecordOfStrings(json.options) ? json.options : {},
|
|
1184
|
+
...parseFloatMetaFromJson(json)
|
|
632
1185
|
};
|
|
633
1186
|
}
|
|
634
1187
|
function parseRawBlock(json) {
|
|
@@ -639,6 +1192,14 @@ function parseRawBlock(json) {
|
|
|
639
1192
|
value: typeof json.value === "string" ? json.value : ""
|
|
640
1193
|
};
|
|
641
1194
|
}
|
|
1195
|
+
function parseBibliographyBlock() {
|
|
1196
|
+
return {
|
|
1197
|
+
id: document2Id("block"),
|
|
1198
|
+
kind: "bibliography",
|
|
1199
|
+
command: "\\begin{thebibliography}",
|
|
1200
|
+
closing: "\\end{thebibliography}"
|
|
1201
|
+
};
|
|
1202
|
+
}
|
|
642
1203
|
function parseBlock(json, options, path, diagnostics) {
|
|
643
1204
|
if (TEXT_COMMANDS.has(json.command)) {
|
|
644
1205
|
return parseTextBlock(json, options, path, diagnostics);
|
|
@@ -652,6 +1213,9 @@ function parseBlock(json, options, path, diagnostics) {
|
|
|
652
1213
|
if (json.command === "\\includegraphics") {
|
|
653
1214
|
return parseImageBlock(json);
|
|
654
1215
|
}
|
|
1216
|
+
if (json.command === "\\begin{thebibliography}" || json.command === "\\bibliography") {
|
|
1217
|
+
return parseBibliographyBlock();
|
|
1218
|
+
}
|
|
655
1219
|
if (json.command === "\\raw") {
|
|
656
1220
|
return parseRawBlock(json);
|
|
657
1221
|
}
|
|
@@ -672,12 +1236,20 @@ function fromDocumentJson2(json, options = {}) {
|
|
|
672
1236
|
const diagnostics = [];
|
|
673
1237
|
return {
|
|
674
1238
|
nodeType: "DocumentObject",
|
|
1239
|
+
meta: normalizeDocument2Meta(json.meta),
|
|
1240
|
+
references: parseReferences(json.references),
|
|
675
1241
|
blocks: json.blocks.map((block, index) => parseBlock(asBlockJson(block), options, `$.blocks[${String(index)}]`, diagnostics)),
|
|
676
1242
|
diagnostics
|
|
677
1243
|
};
|
|
678
1244
|
}
|
|
679
1245
|
function createEmptyDocument2() {
|
|
680
|
-
return {
|
|
1246
|
+
return {
|
|
1247
|
+
nodeType: "DocumentObject",
|
|
1248
|
+
meta: emptyDocument2Meta(),
|
|
1249
|
+
references: [],
|
|
1250
|
+
blocks: [],
|
|
1251
|
+
diagnostics: []
|
|
1252
|
+
};
|
|
681
1253
|
}
|
|
682
1254
|
|
|
683
1255
|
// src/editor/atomicCommands.ts
|
|
@@ -1700,34 +2272,6 @@ function renderDivideOperatorLatex(side) {
|
|
|
1700
2272
|
return side === "arabic" ? "\\backslash" : DIVIDE_OPERATOR_EN;
|
|
1701
2273
|
}
|
|
1702
2274
|
|
|
1703
|
-
// src/editor/digits.ts
|
|
1704
|
-
var WESTERN = "0123456789";
|
|
1705
|
-
var ARABIC_INDIC = "\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669";
|
|
1706
|
-
var PERSIAN_INDIC = "\u06F0\u06F1\u06F2\u06F3\u06F4\u06F5\u06F6\u06F7\u06F8\u06F9";
|
|
1707
|
-
var digitSets = {
|
|
1708
|
-
western: WESTERN,
|
|
1709
|
-
arabicIndic: ARABIC_INDIC,
|
|
1710
|
-
persianIndic: PERSIAN_INDIC
|
|
1711
|
-
};
|
|
1712
|
-
function digitValue(char) {
|
|
1713
|
-
const western = WESTERN.indexOf(char);
|
|
1714
|
-
if (western >= 0) {
|
|
1715
|
-
return western;
|
|
1716
|
-
}
|
|
1717
|
-
const arabicIndic = ARABIC_INDIC.indexOf(char);
|
|
1718
|
-
if (arabicIndic >= 0) {
|
|
1719
|
-
return arabicIndic;
|
|
1720
|
-
}
|
|
1721
|
-
return PERSIAN_INDIC.indexOf(char);
|
|
1722
|
-
}
|
|
1723
|
-
function formatDigits(value, digitForm = "western") {
|
|
1724
|
-
const target = digitSets[digitForm];
|
|
1725
|
-
return Array.from(value, (char) => {
|
|
1726
|
-
const value2 = digitValue(char);
|
|
1727
|
-
return value2 >= 0 ? target[value2] : char;
|
|
1728
|
-
}).join("");
|
|
1729
|
-
}
|
|
1730
|
-
|
|
1731
2275
|
// src/editor/render.ts
|
|
1732
2276
|
function selectedDigitForm(options) {
|
|
1733
2277
|
return options?.digitForm ?? "western";
|
|
@@ -3060,6 +3604,8 @@ function cloneBlock(block) {
|
|
|
3060
3604
|
function cloneDocument(document2) {
|
|
3061
3605
|
return {
|
|
3062
3606
|
nodeType: "DocumentObject",
|
|
3607
|
+
meta: cloneDocument2Meta(document2.meta ?? emptyDocument2Meta()),
|
|
3608
|
+
references: document2.references.map((reference) => ({ ...reference })),
|
|
3063
3609
|
blocks: document2.blocks.map(cloneBlock),
|
|
3064
3610
|
diagnostics: document2.diagnostics.map((diagnostic) => ({ ...diagnostic }))
|
|
3065
3611
|
};
|
|
@@ -3169,6 +3715,29 @@ function moveDocument2BlockById(document2, blockId, direction) {
|
|
|
3169
3715
|
next.blocks.splice(targetIndex, 0, block);
|
|
3170
3716
|
return next;
|
|
3171
3717
|
}
|
|
3718
|
+
function moveDocument2BlockRange(document2, from, to, direction) {
|
|
3719
|
+
const count = document2.blocks.length;
|
|
3720
|
+
if (from < 0 || to < 0 || from >= count || to >= count || from > to) {
|
|
3721
|
+
return document2;
|
|
3722
|
+
}
|
|
3723
|
+
const insertAt = from + direction;
|
|
3724
|
+
if (insertAt < 0 || to + direction >= count) {
|
|
3725
|
+
return document2;
|
|
3726
|
+
}
|
|
3727
|
+
const next = cloneDocument(document2);
|
|
3728
|
+
const slice = next.blocks.splice(from, to - from + 1);
|
|
3729
|
+
next.blocks.splice(insertAt, 0, ...slice);
|
|
3730
|
+
return next;
|
|
3731
|
+
}
|
|
3732
|
+
function removeDocument2BlockRange(document2, from, to) {
|
|
3733
|
+
const count = document2.blocks.length;
|
|
3734
|
+
if (from < 0 || to < 0 || from >= count || to >= count || from > to) {
|
|
3735
|
+
return document2;
|
|
3736
|
+
}
|
|
3737
|
+
const next = cloneDocument(document2);
|
|
3738
|
+
next.blocks = [...next.blocks.slice(0, from), ...next.blocks.slice(to + 1)];
|
|
3739
|
+
return next;
|
|
3740
|
+
}
|
|
3172
3741
|
function normalizeFieldTokens(tokens) {
|
|
3173
3742
|
if (tokens.length === 0) {
|
|
3174
3743
|
return [{ id: document2Id("text"), kind: "text", text: "" }];
|
|
@@ -3263,16 +3832,50 @@ function replaceMathTokenFromSession(document2, tokenId, session, opening, closi
|
|
|
3263
3832
|
const current = field.tokens[index];
|
|
3264
3833
|
const open = opening ?? current.opening;
|
|
3265
3834
|
const close = closing ?? current.closing;
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3835
|
+
const replaced = mathTokenFromSession(session, open, close, side);
|
|
3836
|
+
replaced.id = current.id;
|
|
3837
|
+
if (current.labelEnabled !== void 0) {
|
|
3838
|
+
replaced.labelEnabled = current.labelEnabled;
|
|
3839
|
+
}
|
|
3840
|
+
if (current.label !== void 0) {
|
|
3841
|
+
replaced.label = current.label;
|
|
3842
|
+
}
|
|
3843
|
+
field.tokens[index] = replaced;
|
|
3844
|
+
return true;
|
|
3269
3845
|
});
|
|
3270
3846
|
return next;
|
|
3271
3847
|
}
|
|
3272
3848
|
function addDocument2TextBlock(document2, command = "\\paragraph", afterBlockId) {
|
|
3273
|
-
const block = {
|
|
3849
|
+
const block = {
|
|
3850
|
+
id: document2Id("block"),
|
|
3851
|
+
kind: "textBlock",
|
|
3852
|
+
command,
|
|
3853
|
+
field: createInlineField2(""),
|
|
3854
|
+
...command === "\\paragraph" ? { centered: false } : {}
|
|
3855
|
+
};
|
|
3274
3856
|
return insertDocument2BlockAfter(document2, afterBlockId, block);
|
|
3275
3857
|
}
|
|
3858
|
+
function updateDocument2TextBlockCentered(document2, blockId, centered) {
|
|
3859
|
+
const next = cloneDocument(document2);
|
|
3860
|
+
function visit(blocks) {
|
|
3861
|
+
for (const block of blocks) {
|
|
3862
|
+
if (block.id === blockId && block.kind === "textBlock" && block.command === "\\paragraph") {
|
|
3863
|
+
block.centered = centered;
|
|
3864
|
+
return true;
|
|
3865
|
+
}
|
|
3866
|
+
if (block.kind === "list") {
|
|
3867
|
+
for (const item of block.items) {
|
|
3868
|
+
if (visit(item.blocks)) {
|
|
3869
|
+
return true;
|
|
3870
|
+
}
|
|
3871
|
+
}
|
|
3872
|
+
}
|
|
3873
|
+
}
|
|
3874
|
+
return false;
|
|
3875
|
+
}
|
|
3876
|
+
visit(next.blocks);
|
|
3877
|
+
return next;
|
|
3878
|
+
}
|
|
3276
3879
|
function removeDocument2BlockById(document2, blockId) {
|
|
3277
3880
|
const next = cloneDocument(document2);
|
|
3278
3881
|
next.blocks = next.blocks.filter((block) => block.id !== blockId);
|
|
@@ -3309,7 +3912,8 @@ function addDocument2TableBlock(document2, columns = "lll", rowCount = 3, colCou
|
|
|
3309
3912
|
command: "\\begin{tabular}",
|
|
3310
3913
|
closing: "\\end{tabular}",
|
|
3311
3914
|
columns: columns || "l".repeat(cols),
|
|
3312
|
-
rows: tableRows
|
|
3915
|
+
rows: tableRows,
|
|
3916
|
+
...defaultFloatMeta()
|
|
3313
3917
|
};
|
|
3314
3918
|
return insertDocument2BlockAfter(document2, afterBlockId, block);
|
|
3315
3919
|
}
|
|
@@ -3319,7 +3923,8 @@ function addDocument2ImageBlock(document2, src = "", afterBlockId) {
|
|
|
3319
3923
|
kind: "image",
|
|
3320
3924
|
command: "\\includegraphics",
|
|
3321
3925
|
value: src,
|
|
3322
|
-
options: {}
|
|
3926
|
+
options: { width: "0.8\\textwidth" },
|
|
3927
|
+
...defaultFloatMeta()
|
|
3323
3928
|
};
|
|
3324
3929
|
return insertDocument2BlockAfter(document2, afterBlockId, block);
|
|
3325
3930
|
}
|
|
@@ -3344,6 +3949,128 @@ function updateDocument2ImageValue(document2, blockId, value) {
|
|
|
3344
3949
|
visit(next.blocks);
|
|
3345
3950
|
return next;
|
|
3346
3951
|
}
|
|
3952
|
+
function updateDocument2ImageMeta(document2, blockId, patch) {
|
|
3953
|
+
const next = cloneDocument(document2);
|
|
3954
|
+
function visit(blocks) {
|
|
3955
|
+
for (const block of blocks) {
|
|
3956
|
+
if (block.id === blockId && block.kind === "image") {
|
|
3957
|
+
applyFloatMetaPatch(block, patch);
|
|
3958
|
+
return true;
|
|
3959
|
+
}
|
|
3960
|
+
if (block.kind === "list") {
|
|
3961
|
+
for (const item of block.items) {
|
|
3962
|
+
if (visit(item.blocks)) {
|
|
3963
|
+
return true;
|
|
3964
|
+
}
|
|
3965
|
+
}
|
|
3966
|
+
}
|
|
3967
|
+
}
|
|
3968
|
+
return false;
|
|
3969
|
+
}
|
|
3970
|
+
visit(next.blocks);
|
|
3971
|
+
return next;
|
|
3972
|
+
}
|
|
3973
|
+
function updateDocument2TableMeta(document2, blockId, patch) {
|
|
3974
|
+
const next = cloneDocument(document2);
|
|
3975
|
+
function visit(blocks) {
|
|
3976
|
+
for (const block of blocks) {
|
|
3977
|
+
if (block.id === blockId && block.kind === "table") {
|
|
3978
|
+
applyFloatMetaPatch(block, patch);
|
|
3979
|
+
return true;
|
|
3980
|
+
}
|
|
3981
|
+
if (block.kind === "list") {
|
|
3982
|
+
for (const item of block.items) {
|
|
3983
|
+
if (visit(item.blocks)) {
|
|
3984
|
+
return true;
|
|
3985
|
+
}
|
|
3986
|
+
}
|
|
3987
|
+
}
|
|
3988
|
+
}
|
|
3989
|
+
return false;
|
|
3990
|
+
}
|
|
3991
|
+
visit(next.blocks);
|
|
3992
|
+
return next;
|
|
3993
|
+
}
|
|
3994
|
+
function updateMathTokenLabel(document2, tokenId, patch) {
|
|
3995
|
+
const next = cloneDocument(document2);
|
|
3996
|
+
visitFields(next.blocks, (field) => {
|
|
3997
|
+
const token = field.tokens.find((entry) => entry.id === tokenId && entry.kind === "math");
|
|
3998
|
+
if (!token) {
|
|
3999
|
+
return false;
|
|
4000
|
+
}
|
|
4001
|
+
if (typeof patch.labelEnabled === "boolean") {
|
|
4002
|
+
token.labelEnabled = patch.labelEnabled;
|
|
4003
|
+
}
|
|
4004
|
+
if (typeof patch.label === "string") {
|
|
4005
|
+
token.label = patch.label;
|
|
4006
|
+
}
|
|
4007
|
+
return true;
|
|
4008
|
+
});
|
|
4009
|
+
return next;
|
|
4010
|
+
}
|
|
4011
|
+
function refTokenFromKeys(keys, refCommand) {
|
|
4012
|
+
return { id: document2Id("ref"), kind: "ref", keys: [...keys], refCommand };
|
|
4013
|
+
}
|
|
4014
|
+
function insertRefTokenAtCaret(document2, fieldId, textTokenId, caretOffset, keys, refCommand = "ref") {
|
|
4015
|
+
if (keys.length === 0) {
|
|
4016
|
+
return document2;
|
|
4017
|
+
}
|
|
4018
|
+
const next = cloneDocument(document2);
|
|
4019
|
+
const refToken = refTokenFromKeys(keys, refCommand);
|
|
4020
|
+
visitFields(next.blocks, (field) => {
|
|
4021
|
+
if (field.id !== fieldId) {
|
|
4022
|
+
return false;
|
|
4023
|
+
}
|
|
4024
|
+
const textIndex = textTokenId ? field.tokens.findIndex((token) => token.id === textTokenId && token.kind === "text") : field.tokens.findIndex((token) => token.kind === "text");
|
|
4025
|
+
if (textIndex < 0) {
|
|
4026
|
+
field.tokens.push(refToken);
|
|
4027
|
+
field.tokens.push({ id: document2Id("text"), kind: "text", text: "" });
|
|
4028
|
+
return true;
|
|
4029
|
+
}
|
|
4030
|
+
const current = field.tokens[textIndex];
|
|
4031
|
+
const [before, after] = splitTextTokenAt(current, caretOffset);
|
|
4032
|
+
const parts = [...field.tokens.slice(0, textIndex)];
|
|
4033
|
+
if (before.text.length > 0) {
|
|
4034
|
+
parts.push(before);
|
|
4035
|
+
}
|
|
4036
|
+
parts.push(refToken);
|
|
4037
|
+
parts.push(after);
|
|
4038
|
+
parts.push(...field.tokens.slice(textIndex + 1));
|
|
4039
|
+
field.tokens = normalizeFieldTokens(parts);
|
|
4040
|
+
return true;
|
|
4041
|
+
});
|
|
4042
|
+
return next;
|
|
4043
|
+
}
|
|
4044
|
+
function updateRefTokenKeys(document2, tokenId, keys, refCommand) {
|
|
4045
|
+
if (keys.length === 0) {
|
|
4046
|
+
return document2;
|
|
4047
|
+
}
|
|
4048
|
+
const next = cloneDocument(document2);
|
|
4049
|
+
visitFields(next.blocks, (field) => {
|
|
4050
|
+
const token = field.tokens.find((entry) => entry.id === tokenId && entry.kind === "ref");
|
|
4051
|
+
if (!token) {
|
|
4052
|
+
return false;
|
|
4053
|
+
}
|
|
4054
|
+
token.keys = [...keys];
|
|
4055
|
+
if (refCommand) {
|
|
4056
|
+
token.refCommand = refCommand;
|
|
4057
|
+
}
|
|
4058
|
+
return true;
|
|
4059
|
+
});
|
|
4060
|
+
return next;
|
|
4061
|
+
}
|
|
4062
|
+
function removeRefTokenById(document2, tokenId) {
|
|
4063
|
+
const next = cloneDocument(document2);
|
|
4064
|
+
visitFields(next.blocks, (field) => {
|
|
4065
|
+
const index = field.tokens.findIndex((token) => token.id === tokenId && token.kind === "ref");
|
|
4066
|
+
if (index < 0) {
|
|
4067
|
+
return false;
|
|
4068
|
+
}
|
|
4069
|
+
field.tokens = normalizeFieldTokens(stitchTextAroundRemovedToken(field.tokens, index));
|
|
4070
|
+
return true;
|
|
4071
|
+
});
|
|
4072
|
+
return next;
|
|
4073
|
+
}
|
|
3347
4074
|
function mutateListBlockById(blocks, listBlockId, mutator) {
|
|
3348
4075
|
for (const block of blocks) {
|
|
3349
4076
|
if (block.id === listBlockId && block.kind === "list") {
|
|
@@ -3380,12 +4107,372 @@ function removeDocument2ListItem(document2, listBlockId, itemId) {
|
|
|
3380
4107
|
});
|
|
3381
4108
|
return next;
|
|
3382
4109
|
}
|
|
4110
|
+
function citeTokenFromKeys(keys) {
|
|
4111
|
+
return { id: document2Id("cite"), kind: "cite", keys: [...keys] };
|
|
4112
|
+
}
|
|
4113
|
+
function insertCiteTokenAtCaret(document2, fieldId, textTokenId, caretOffset, keys) {
|
|
4114
|
+
if (keys.length === 0) {
|
|
4115
|
+
return document2;
|
|
4116
|
+
}
|
|
4117
|
+
const next = cloneDocument(document2);
|
|
4118
|
+
const citeToken = citeTokenFromKeys(keys);
|
|
4119
|
+
visitFields(next.blocks, (field) => {
|
|
4120
|
+
if (field.id !== fieldId) {
|
|
4121
|
+
return false;
|
|
4122
|
+
}
|
|
4123
|
+
const textIndex = textTokenId ? field.tokens.findIndex((token) => token.id === textTokenId && token.kind === "text") : field.tokens.findIndex((token) => token.kind === "text");
|
|
4124
|
+
if (textIndex < 0) {
|
|
4125
|
+
field.tokens.push(citeToken);
|
|
4126
|
+
field.tokens.push({ id: document2Id("text"), kind: "text", text: "" });
|
|
4127
|
+
return true;
|
|
4128
|
+
}
|
|
4129
|
+
const current = field.tokens[textIndex];
|
|
4130
|
+
const [before, after] = splitTextTokenAt(current, caretOffset);
|
|
4131
|
+
const parts = [...field.tokens.slice(0, textIndex)];
|
|
4132
|
+
if (before.text.length > 0) {
|
|
4133
|
+
parts.push(before);
|
|
4134
|
+
}
|
|
4135
|
+
parts.push(citeToken);
|
|
4136
|
+
parts.push(after);
|
|
4137
|
+
parts.push(...field.tokens.slice(textIndex + 1));
|
|
4138
|
+
field.tokens = normalizeFieldTokens(parts);
|
|
4139
|
+
return true;
|
|
4140
|
+
});
|
|
4141
|
+
return next;
|
|
4142
|
+
}
|
|
4143
|
+
function updateCiteTokenKeys(document2, tokenId, keys) {
|
|
4144
|
+
if (keys.length === 0) {
|
|
4145
|
+
return document2;
|
|
4146
|
+
}
|
|
4147
|
+
const next = cloneDocument(document2);
|
|
4148
|
+
visitFields(next.blocks, (field) => {
|
|
4149
|
+
const token = field.tokens.find((entry) => entry.id === tokenId && entry.kind === "cite");
|
|
4150
|
+
if (!token) {
|
|
4151
|
+
return false;
|
|
4152
|
+
}
|
|
4153
|
+
token.keys = [...keys];
|
|
4154
|
+
return true;
|
|
4155
|
+
});
|
|
4156
|
+
return next;
|
|
4157
|
+
}
|
|
4158
|
+
function removeCiteTokenById(document2, tokenId) {
|
|
4159
|
+
const next = cloneDocument(document2);
|
|
4160
|
+
visitFields(next.blocks, (field) => {
|
|
4161
|
+
const index = field.tokens.findIndex((token) => token.id === tokenId && token.kind === "cite");
|
|
4162
|
+
if (index < 0) {
|
|
4163
|
+
return false;
|
|
4164
|
+
}
|
|
4165
|
+
field.tokens = normalizeFieldTokens(stitchTextAroundRemovedToken(field.tokens, index));
|
|
4166
|
+
return true;
|
|
4167
|
+
});
|
|
4168
|
+
return next;
|
|
4169
|
+
}
|
|
4170
|
+
function ensureDocument2BibliographyBlock(document2, afterBlockId) {
|
|
4171
|
+
if (document2.blocks.some((block2) => block2.kind === "bibliography")) {
|
|
4172
|
+
return document2;
|
|
4173
|
+
}
|
|
4174
|
+
const block = {
|
|
4175
|
+
id: document2Id("block"),
|
|
4176
|
+
kind: "bibliography",
|
|
4177
|
+
command: "\\begin{thebibliography}",
|
|
4178
|
+
closing: "\\end{thebibliography}"
|
|
4179
|
+
};
|
|
4180
|
+
return insertDocument2BlockAfter(document2, afterBlockId ?? null, block);
|
|
4181
|
+
}
|
|
4182
|
+
function addDocument2Reference(document2, partial = {}) {
|
|
4183
|
+
const next = cloneDocument(document2);
|
|
4184
|
+
next.references.push(createEmptyReference2(partial));
|
|
4185
|
+
return next;
|
|
4186
|
+
}
|
|
4187
|
+
function updateDocument2Reference(document2, referenceId, patch) {
|
|
4188
|
+
const next = cloneDocument(document2);
|
|
4189
|
+
const reference = next.references.find((entry) => entry.id === referenceId);
|
|
4190
|
+
if (!reference) {
|
|
4191
|
+
return document2;
|
|
4192
|
+
}
|
|
4193
|
+
if (typeof patch.key === "string" && patch.key.trim().length > 0) {
|
|
4194
|
+
reference.key = patch.key.trim();
|
|
4195
|
+
}
|
|
4196
|
+
if (typeof patch.authors === "string") {
|
|
4197
|
+
reference.authors = patch.authors;
|
|
4198
|
+
}
|
|
4199
|
+
if (typeof patch.title === "string") {
|
|
4200
|
+
reference.title = patch.title;
|
|
4201
|
+
}
|
|
4202
|
+
if (typeof patch.year === "string") {
|
|
4203
|
+
reference.year = patch.year;
|
|
4204
|
+
}
|
|
4205
|
+
if (typeof patch.url === "string") {
|
|
4206
|
+
reference.url = patch.url;
|
|
4207
|
+
}
|
|
4208
|
+
if (typeof patch.venue === "string") {
|
|
4209
|
+
reference.venue = patch.venue;
|
|
4210
|
+
}
|
|
4211
|
+
return next;
|
|
4212
|
+
}
|
|
4213
|
+
function removeDocument2Reference(document2, referenceId) {
|
|
4214
|
+
const next = cloneDocument(document2);
|
|
4215
|
+
next.references = next.references.filter((reference) => reference.id !== referenceId);
|
|
4216
|
+
return next;
|
|
4217
|
+
}
|
|
4218
|
+
function moveDocument2Reference(document2, referenceId, direction) {
|
|
4219
|
+
const next = cloneDocument(document2);
|
|
4220
|
+
const index = next.references.findIndex((reference2) => reference2.id === referenceId);
|
|
4221
|
+
const targetIndex = index + direction;
|
|
4222
|
+
if (index < 0 || targetIndex < 0 || targetIndex >= next.references.length) {
|
|
4223
|
+
return document2;
|
|
4224
|
+
}
|
|
4225
|
+
const [reference] = next.references.splice(index, 1);
|
|
4226
|
+
if (!reference) {
|
|
4227
|
+
return document2;
|
|
4228
|
+
}
|
|
4229
|
+
next.references.splice(targetIndex, 0, reference);
|
|
4230
|
+
return next;
|
|
4231
|
+
}
|
|
4232
|
+
function setDocument2References(document2, references) {
|
|
4233
|
+
const next = cloneDocument(document2);
|
|
4234
|
+
next.references = references.map((reference) => ({ ...reference }));
|
|
4235
|
+
return next;
|
|
4236
|
+
}
|
|
4237
|
+
function updateDocument2Meta(document2, patch) {
|
|
4238
|
+
const next = cloneDocument(document2);
|
|
4239
|
+
const current = next.meta ?? emptyDocument2Meta();
|
|
4240
|
+
next.meta = {
|
|
4241
|
+
title: typeof patch.title === "string" ? patch.title : current.title,
|
|
4242
|
+
authors: typeof patch.authors === "string" ? patch.authors : current.authors,
|
|
4243
|
+
abstract: typeof patch.abstract === "string" ? patch.abstract : current.abstract,
|
|
4244
|
+
date: patch.date ? normalizeDocument2HijriDate({ ...current.date, ...patch.date }) : { ...current.date }
|
|
4245
|
+
};
|
|
4246
|
+
return next;
|
|
4247
|
+
}
|
|
4248
|
+
|
|
4249
|
+
// src/document2/arabicPreamble.ts
|
|
4250
|
+
function arabicXeLatexPreamblePkg(twocolumn = false) {
|
|
4251
|
+
const classOptions = twocolumn ? "12pt,a4paper,twocolumn" : "12pt,a4paper";
|
|
4252
|
+
return `
|
|
4253
|
+
\\documentclass[${classOptions}]{article}
|
|
4254
|
+
` + String.raw`\usepackage{amsmath,amsfonts,amssymb,mathrsfs,tikz,fancyhdr, mathtools}
|
|
4255
|
+
\usepackage{fontspec} % For loading OpenType fonts
|
|
4256
|
+
\usepackage{unicode-math} % For setting the math font
|
|
4257
|
+
\usepackage{polyglossia} % For Arabic support
|
|
4258
|
+
\usepackage{array}
|
|
4259
|
+
\usepackage{cancel}
|
|
4260
|
+
\usepackage{bidi} % For bidirectional text handling
|
|
4261
|
+
\usepackage{multirow}
|
|
4262
|
+
\usepackage{booktabs}
|
|
4263
|
+
\usepackage{graphicx} % For \reflectbox
|
|
4264
|
+
\usepackage{xcolor}
|
|
4265
|
+
\usepackage{tikz}
|
|
4266
|
+
\usepackage{tcolorbox} % For tcolorbox environment
|
|
4267
|
+
\usepackage{textcomp} % For \textrightarrow command
|
|
4268
|
+
|
|
4269
|
+
|
|
4270
|
+
% visit : https://www.symbolcopy.com/punctuation-symbol.html
|
|
4271
|
+
% for inversed punctuation
|
|
4272
|
+
|
|
4273
|
+
% save inverted comma for use - copy paste -> ،
|
|
4274
|
+
% save back tick for use - copy paste -> ` + "`";
|
|
4275
|
+
}
|
|
4276
|
+
function arabicXeLatexPreambleFont(digitsMapping = "arabicdigits") {
|
|
4277
|
+
return `
|
|
4278
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4279
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4280
|
+
% Toggle between eastern and western digits by changing the Mapping in the below fonts (inside math font as well) between "arabicdigits" and "digits"
|
|
4281
|
+
\\setdefaultlanguage[calendar=gregorian]{arabic} % from polyglossia
|
|
4282
|
+
\\setmainfont[Script=Arabic , Mapping=${digitsMapping}]{Amiri}
|
|
4283
|
+
\\newfontfamily\\diwani[Script=Arabic,Mapping=${digitsMapping}]{Diwani Letter}
|
|
4284
|
+
\\newfontfamily\\diwanioutlineshaded[Script=Arabic,Mapping=${digitsMapping}]{Diwani Outline Shaded}
|
|
4285
|
+
\\newfontfamily\\takween[Script=Arabic,Mapping=${digitsMapping}]{Takween}
|
|
4286
|
+
\\newfontfamily\\boldarabic[Script=Arabic,Mapping=${digitsMapping}]{Amiri Bold}
|
|
4287
|
+
\\newfontfamily\\italicarabic[Script=Arabic,Mapping=${digitsMapping}]{Amiri Italic}
|
|
4288
|
+
|
|
4289
|
+
% Explicitly set math font to XITS Math
|
|
4290
|
+
% Remove "Script=Arabic" to cancel reflected symbols and other RTL symbols
|
|
4291
|
+
\\setmathfont[Script=Arabic , Mapping=${digitsMapping}]{XITS Math} % Ensure XITS Math is correctly installed and available
|
|
4292
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4293
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4294
|
+
`;
|
|
4295
|
+
}
|
|
4296
|
+
function arabicXeLatexPreambleCmd() {
|
|
4297
|
+
return String.raw`
|
|
4298
|
+
% Run with XeLaTeX compiler
|
|
4299
|
+
\newcommand{\butextakween}[1]{\text{\takween{#1}}}
|
|
4300
|
+
\newcommand{\butexdiwani}[1]{\text{\diwani{#1}}}
|
|
4301
|
+
\newcommand{\butexdiwanioutline}[1]{\text{\diwanioutlineshaded{#1}}}
|
|
4302
|
+
|
|
4303
|
+
\newcommand{\arabN}{\text{\diwanioutlineshaded{ط}}}
|
|
4304
|
+
\newcommand{\arabZ}{\text{\diwanioutlineshaded{ص}}}
|
|
4305
|
+
\newcommand{\arabQ}{\text{\diwanioutlineshaded{ن}}}
|
|
4306
|
+
\newcommand{\arabR}{\text{\diwanioutlineshaded{ح}}}
|
|
4307
|
+
\newcommand{\arabC}{\text{\diwanioutlineshaded{ع}}}
|
|
4308
|
+
\newcommand{\arabH}{\text{\diwanioutlineshaded{ر}}}
|
|
4309
|
+
|
|
4310
|
+
|
|
4311
|
+
\newcommand{\lowerscript}[1]{\raisebox{-4pt}{\scriptsize #1}}
|
|
4312
|
+
\newcommand{\llowerscript}[1]{\raisebox{-8pt}{\scriptsize #1}}
|
|
4313
|
+
\newcommand{\lllowerscript}[2]{\raisebox{#2pt}{\scriptsize #1}}
|
|
4314
|
+
|
|
4315
|
+
\newcommand{\arabdsub}[3]{\prescript{}{#1}{\prescript{}{#2}{#3}}} % arabic double subscript
|
|
4316
|
+
\newcommand{\arabsub}[2]{\prescript{}{#1}{#2}} % arabic single subscript
|
|
4317
|
+
|
|
4318
|
+
|
|
4319
|
+
|
|
4320
|
+
\newcommand{\upperscript}[1]{\raisebox{8pt}{\scriptsize #1}}
|
|
4321
|
+
\newcommand{\uupperscript}[2]{\raisebox{#2pt}{\scriptsize #1}}
|
|
4322
|
+
\newcommand{\vertbar}{\rule[-1ex]{0.5pt}{2.5ex}}
|
|
4323
|
+
\newcommand{\horzbar}{\rule[.5ex]{2.5ex}{0.5pt}}
|
|
4324
|
+
|
|
4325
|
+
\newcommand{\arabsqrt}[2]{\reflectbox{\(\sqrt[\reflectbox{\(#1\)}]{\reflectbox{\(#2\)}}\)}}
|
|
4326
|
+
\newcommand{\arabvec}[1]{\reflectbox{$\vec{\reflectbox{$#1$}}$}}
|
|
4327
|
+
|
|
4328
|
+
\newcommand{\arabexp}[1]{{}^{#1}\!\raisebox{-4.5pt}{\text{\diwani{ه}}}}
|
|
4329
|
+
\newcommand{\arablog}[2]{\left(\text{#2}\right)\!\prescript{}{\text{#1}}{\text{\diwani{لو}}}}
|
|
4330
|
+
\newcommand{\arabnlog}[1]{\left(\text{#1}\right)\!\prescript{}{\text{\diwani{ه}}}{\text{\diwani{لو}}}}
|
|
4331
|
+
|
|
4332
|
+
\newcommand{\arabcos}[1]{\left(#1\right)\!\!\raisebox{-2.5pt}{\text{\diwani{جتا}}}}
|
|
4333
|
+
\newcommand{\arabsin}[1]{\left(#1\right)\!\!\raisebox{-2.5pt}{\text{\diwani{جا}}}}
|
|
4334
|
+
\newcommand{\arabtan}[1]{\left(#1\right)\!\!\raisebox{-2.5pt}{\text{\diwani{ظا}}}}
|
|
4335
|
+
\newcommand{\arabcot}[1]{\left(#1\right)\!\!\raisebox{-2.5pt}{\text{\diwani{ظتا}}}}
|
|
4336
|
+
\newcommand{\arabsec}[1]{\left(#1\right)\!\!\raisebox{-2.5pt}{\text{\diwani{قا}}}}
|
|
4337
|
+
\newcommand{\arabcsc}[1]{\left(#1\right)\!\!\raisebox{-2.5pt}{\text{\diwani{قتا}}}}
|
|
4338
|
+
|
|
4339
|
+
\newcommand{\arabacos}[1]{\left(#1\right)\!\!\raisebox{-2.5pt}{\text{\diwani{قجتا}}}}
|
|
4340
|
+
\newcommand{\arabasin}[1]{\left(#1\right)\!\!\raisebox{-2.5pt}{\text{\diwani{قجا}}}}
|
|
4341
|
+
\newcommand{\arabatan}[1]{\left(#1\right)\!\!\raisebox{-2.5pt}{\text{\diwani{قظا}}}}
|
|
4342
|
+
\newcommand{\arabacot}[1]{\left(#1\right)\!\!\raisebox{-2.5pt}{\text{\diwani{قظتا}}}}
|
|
4343
|
+
\newcommand{\arabasec}[1]{\left(#1\right)\!\!\raisebox{-2.5pt}{\text{\diwani{ققا}}}}
|
|
4344
|
+
\newcommand{\arabacsc}[1]{\left(#1\right)\!\!\raisebox{-2.5pt}{\text{\diwani{ققتا}}}}
|
|
4345
|
+
|
|
4346
|
+
|
|
4347
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4348
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4349
|
+
% summation
|
|
4350
|
+
\newcommand{\arablim}[2]{\underset{#2 \leftarrow #1}{\text{نـــــها}}}
|
|
4351
|
+
\newcommand{\arabsum}[2]{\underset{#1}{\overset{#2}{\text{مجـــ}}}}
|
|
4352
|
+
\newcommand{\arabprod}[2]{\underset{#1}{\overset{#2}{\text{جـــذ}}}}
|
|
4353
|
+
\newcommand{\arabint}[2]{\prescript{#2}{#1\!\!\!}\int}
|
|
4354
|
+
|
|
4355
|
+
|
|
4356
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4357
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4358
|
+
% we define this command to make it ease for change of notation later
|
|
4359
|
+
\newcommand{\ad}[0]{\text{ء}} % "ad" for arabic differentiation or derivative (ء" لإشتقاق")
|
|
4360
|
+
\newcommand{\arpi}[0]{\!\text{\diwani{ط}}}
|
|
4361
|
+
|
|
4362
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4363
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4364
|
+
% differentials
|
|
4365
|
+
|
|
4366
|
+
\newcommand{\arabdiff}[2]{\frac{#1\ad}{#2\ad}} % arabic differential
|
|
4367
|
+
\newcommand{\arabddiff}[2]{\frac{#1{}^{2}\ad}{{}^{2}#2\ad}} % arabic second differential
|
|
4368
|
+
|
|
4369
|
+
\newcommand{\arabode}[2][-5pt]{\stackrel{\raisebox{#1}{$\cdot$}}{\text{#2}}}
|
|
4370
|
+
\newcommand{\arabodde}[2][-5pt]{\stackrel{\raisebox{#1}{$\vcenter{\hbox{$\cdot\!\cdot$}}$}}{\text{#2}}}
|
|
4371
|
+
\newcommand{\araboddde}[2][-5pt]{\stackrel{\raisebox{#1}{$\vcenter{\hbox{$\cdot\!\cdot\!\cdot$}}$}}{\text{#2}}}
|
|
4372
|
+
\newcommand{\arabpde}[1]{\prescript{}{#1\!\!}{\nabla}} % arabic partial differential equation (PDE)
|
|
4373
|
+
|
|
4374
|
+
\newcommand{\arabprime}[0]{\reflectbox{$\prime$}\!} % arabic prime notation
|
|
4375
|
+
\newcommand{\arabpprime}[0]{\reflectbox{$\prime$}\reflectbox{$\prime$}\!} % arabic prime notation
|
|
4376
|
+
\newcommand{\arabppprime}[0]{\reflectbox{$\prime$}\reflectbox{$\prime$}\reflectbox{$\prime$}\!} % arabic prime notation
|
|
4377
|
+
|
|
4378
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4379
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4380
|
+
% probability
|
|
4381
|
+
\newcommand{\ap}[0]{\!\text{\diwani{حـ}}} % arabic Probability - used a lot so short form
|
|
4382
|
+
\newcommand{\arabExpct}[0]{\text{\diwani{توقـ}}} % arabic Expectation
|
|
4383
|
+
\newcommand{\arabVar}[0]{\!\text{\diwani{با}}} % arabic Variance
|
|
4384
|
+
\newcommand{\arabCov}[0]{\!\text{\diwani{ت}}} % arabic Covariance
|
|
4385
|
+
|
|
4386
|
+
|
|
4387
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4388
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4389
|
+
% custom commands specific to lesson
|
|
4390
|
+
\newcommand{\lagrange}[2]{\left(#2\right)\!\prescript{}{#1}{\text{\diwani{لا}}}}
|
|
4391
|
+
\newcommand{\xii}[0]{\left(\prescript{}{\text{يـ}}{\text{س}}\right)\!}
|
|
4392
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4393
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4394
|
+
|
|
4395
|
+
|
|
4396
|
+
\newcommand{\arsqrt}[2][]{\reflectbox{\(\sqrt[\reflectbox{\(#1\)}]{\reflectbox{\(#2\)}}\)}}
|
|
4397
|
+
\newcommand{\arexp}[0]{\!\raisebox{-4.5pt}{\text{\diwani{ه}}}}
|
|
4398
|
+
\newcommand{\arlog}[0]{\!\!\text{\diwani{لو}}}
|
|
4399
|
+
\newcommand{\arln}[0]{\!\!\prescript{}{\text{\diwani{ه}}}{\text{\diwani{لو}}}}
|
|
4400
|
+
\newcommand{\ardet}[0]{\!\!\text{\diwani{محدد}}}
|
|
4401
|
+
|
|
4402
|
+
\newcommand{\arsum}[0]{\text{مجـــ}}
|
|
4403
|
+
\newcommand{\arprod}[0]{\text{جـــذ}}
|
|
4404
|
+
|
|
4405
|
+
\newcommand{\arlim}[0]{\text{نـــــها}}
|
|
4406
|
+
\newcommand{\armax}[0]{\text{أكبر}}
|
|
4407
|
+
\newcommand{\armin}[0]{\text{أصغر}}
|
|
4408
|
+
\newcommand{\arsup}[0]{\text{أعلى}}
|
|
4409
|
+
\newcommand{\arinf}[0]{\text{أدنى}}
|
|
4410
|
+
|
|
4411
|
+
\newcommand{\arsin}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{جا}}}}
|
|
4412
|
+
\newcommand{\arcos}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{جتا}}}}
|
|
4413
|
+
\newcommand{\artan}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{ظا}}}}
|
|
4414
|
+
\newcommand{\arcot}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{ظتا}}}}
|
|
4415
|
+
\newcommand{\arsec}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{قا}}}}
|
|
4416
|
+
\newcommand{\arcsc}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{قتا}}}}
|
|
4417
|
+
|
|
4418
|
+
\newcommand{\arasin}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{قجا}}}}
|
|
4419
|
+
\newcommand{\aracos}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{قجتا}}}}
|
|
4420
|
+
\newcommand{\aratan}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{قظا}}}}
|
|
4421
|
+
\newcommand{\aracot}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{قظتا}}}}
|
|
4422
|
+
\newcommand{\arasec}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{ققا}}}}
|
|
4423
|
+
\newcommand{\aracsc}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{ققتا}}}}
|
|
4424
|
+
|
|
4425
|
+
\newcommand{\arsinh}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{جزا}}}}
|
|
4426
|
+
\newcommand{\arcosh}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{جتزا}}}}
|
|
4427
|
+
\newcommand{\artanh}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{ظزا}}}}
|
|
4428
|
+
\newcommand{\arcoth}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{ظتزا}}}}
|
|
4429
|
+
\newcommand{\arsech}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{قزا}}}}
|
|
4430
|
+
\newcommand{\arcsch}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{قتزا}}}}
|
|
4431
|
+
|
|
4432
|
+
\newcommand{\arasinh}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{قجزا}}}}
|
|
4433
|
+
\newcommand{\aracosh}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{قجتزا}}}}
|
|
4434
|
+
\newcommand{\aratanh}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{قظزا}}}}
|
|
4435
|
+
\newcommand{\aracoth}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{قظتزا}}}}
|
|
4436
|
+
\newcommand{\arasech}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{ققزا}}}}
|
|
4437
|
+
\newcommand{\aracsch}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{ققتزا}}}}
|
|
4438
|
+
|
|
4439
|
+
\newcommand{\unit}[1]{\text{#1}}
|
|
4440
|
+
\newcommand{\idx}[1]{#1}
|
|
4441
|
+
\newcommand{\arbinom}[2]{\left(\begin{array}{c} #1 \\ #2 \end{array} \right)}
|
|
4442
|
+
`;
|
|
4443
|
+
}
|
|
4444
|
+
function getArabicXeLatexPreamble(digitsMappingOrOptions = "arabicdigits") {
|
|
4445
|
+
const options = typeof digitsMappingOrOptions === "string" ? { digitsMapping: digitsMappingOrOptions } : digitsMappingOrOptions;
|
|
4446
|
+
const digitsMapping = options.digitsMapping ?? "arabicdigits";
|
|
4447
|
+
const twocolumn = options.twocolumn === true;
|
|
4448
|
+
return arabicXeLatexPreamblePkg(twocolumn) + arabicXeLatexPreambleFont(digitsMapping) + arabicXeLatexPreambleCmd();
|
|
4449
|
+
}
|
|
3383
4450
|
|
|
3384
4451
|
// src/document2/exportLatex.ts
|
|
4452
|
+
function mathBodyLatex(token) {
|
|
4453
|
+
if (!token.math || token.sourceOwner === "raw" || token.sourceOwner === "editor") {
|
|
4454
|
+
return stripDisplayMathDelimiters(token.source);
|
|
4455
|
+
}
|
|
4456
|
+
const rendered = renderMathNodeLatex(token.math);
|
|
4457
|
+
return stripDisplayMathDelimiters(rendered);
|
|
4458
|
+
}
|
|
3385
4459
|
function tokenLatex(token) {
|
|
3386
4460
|
if (token.kind === "text") {
|
|
3387
4461
|
return token.text;
|
|
3388
4462
|
}
|
|
4463
|
+
if (token.kind === "cite") {
|
|
4464
|
+
return citeTokenLatex(token.keys);
|
|
4465
|
+
}
|
|
4466
|
+
if (token.kind === "ref") {
|
|
4467
|
+
return refTokenLatex(token.keys, token.refCommand);
|
|
4468
|
+
}
|
|
4469
|
+
if (token.display && token.labelEnabled && token.label && token.label.trim().length > 0) {
|
|
4470
|
+
const body = mathBodyLatex(token);
|
|
4471
|
+
return `\\begin{equation}
|
|
4472
|
+
${body}
|
|
4473
|
+
\\label{${token.label.trim()}}
|
|
4474
|
+
\\end{equation}`;
|
|
4475
|
+
}
|
|
3389
4476
|
if (!token.math || token.sourceOwner === "raw" || token.sourceOwner === "editor") {
|
|
3390
4477
|
return token.source;
|
|
3391
4478
|
}
|
|
@@ -3395,26 +4482,52 @@ function inlineFieldLatex(field) {
|
|
|
3395
4482
|
return field.tokens.map((token) => tokenLatex(token)).join("");
|
|
3396
4483
|
}
|
|
3397
4484
|
function textBlockLatex(block) {
|
|
3398
|
-
|
|
4485
|
+
const body = `${block.command}{${inlineFieldLatex(block.field)}}`;
|
|
4486
|
+
if (block.command === "\\paragraph" && block.centered) {
|
|
4487
|
+
return `\\begin{center}
|
|
4488
|
+
${body}
|
|
4489
|
+
\\end{center}`;
|
|
4490
|
+
}
|
|
4491
|
+
return body;
|
|
3399
4492
|
}
|
|
3400
4493
|
function indent(value) {
|
|
3401
4494
|
return value.split("\n").map((line) => ` ${line}`).join("\n");
|
|
3402
4495
|
}
|
|
3403
|
-
function listBlockLatex(block) {
|
|
4496
|
+
function listBlockLatex(block, references) {
|
|
3404
4497
|
const items = block.items.map((item) => {
|
|
3405
|
-
const nested = item.blocks.map((child) => "\n" + indent(blockLatex(child))).join("");
|
|
4498
|
+
const nested = item.blocks.map((child) => "\n" + indent(blockLatex(child, references))).join("");
|
|
3406
4499
|
return ` \\item ${inlineFieldLatex(item.field)}${nested}`;
|
|
3407
4500
|
}).join("\n");
|
|
3408
4501
|
return `${block.command}
|
|
3409
4502
|
${items}
|
|
3410
4503
|
${block.closing}`;
|
|
3411
4504
|
}
|
|
3412
|
-
function
|
|
4505
|
+
function tabularInnerLatex(block) {
|
|
3413
4506
|
const rows = block.rows.map((row) => ` ${row.map((cell) => inlineFieldLatex(cell)).join(" & ")}`).join(" \\\\\n");
|
|
3414
4507
|
return `${block.command}{${block.columns}}
|
|
3415
4508
|
${rows}
|
|
3416
4509
|
${block.closing}`;
|
|
3417
4510
|
}
|
|
4511
|
+
function floatCaptionLabelLines(block) {
|
|
4512
|
+
const lines = [];
|
|
4513
|
+
if (block.captionEnabled && block.caption.trim().length > 0) {
|
|
4514
|
+
lines.push(` \\caption{${block.caption.trim()}}`);
|
|
4515
|
+
}
|
|
4516
|
+
if (block.labelEnabled && block.label.trim().length > 0) {
|
|
4517
|
+
lines.push(` \\label{${block.label.trim()}}`);
|
|
4518
|
+
}
|
|
4519
|
+
return lines;
|
|
4520
|
+
}
|
|
4521
|
+
function tableBlockLatex(block) {
|
|
4522
|
+
const lines = ["\\begin{table}[htbp]"];
|
|
4523
|
+
if (block.centered) {
|
|
4524
|
+
lines.push(" \\centering");
|
|
4525
|
+
}
|
|
4526
|
+
lines.push(...floatCaptionLabelLines(block));
|
|
4527
|
+
lines.push(indent(tabularInnerLatex(block)));
|
|
4528
|
+
lines.push("\\end{table}");
|
|
4529
|
+
return lines.join("\n");
|
|
4530
|
+
}
|
|
3418
4531
|
function imageOptionsLatex(block) {
|
|
3419
4532
|
const entries = Object.entries(block.options);
|
|
3420
4533
|
if (entries.length === 0) {
|
|
@@ -3422,23 +4535,81 @@ function imageOptionsLatex(block) {
|
|
|
3422
4535
|
}
|
|
3423
4536
|
return `[${entries.map(([key, value]) => `${key}=${value}`).join(",")}]`;
|
|
3424
4537
|
}
|
|
3425
|
-
function
|
|
4538
|
+
function imageBlockLatex(block) {
|
|
4539
|
+
const lines = ["\\begin{figure}[htbp]"];
|
|
4540
|
+
if (block.centered) {
|
|
4541
|
+
lines.push(" \\centering");
|
|
4542
|
+
}
|
|
4543
|
+
lines.push(` ${block.command}${imageOptionsLatex(block)}{${block.value}}`);
|
|
4544
|
+
lines.push(...floatCaptionLabelLines(block));
|
|
4545
|
+
lines.push("\\end{figure}");
|
|
4546
|
+
return lines.join("\n");
|
|
4547
|
+
}
|
|
4548
|
+
function blockLatex(block, references) {
|
|
3426
4549
|
if (block.kind === "textBlock") {
|
|
3427
4550
|
return textBlockLatex(block);
|
|
3428
4551
|
}
|
|
3429
4552
|
if (block.kind === "list") {
|
|
3430
|
-
return listBlockLatex(block);
|
|
4553
|
+
return listBlockLatex(block, references);
|
|
3431
4554
|
}
|
|
3432
4555
|
if (block.kind === "table") {
|
|
3433
4556
|
return tableBlockLatex(block);
|
|
3434
4557
|
}
|
|
3435
4558
|
if (block.kind === "image") {
|
|
3436
|
-
return
|
|
4559
|
+
return imageBlockLatex(block);
|
|
4560
|
+
}
|
|
4561
|
+
if (block.kind === "bibliography") {
|
|
4562
|
+
const width = String(Math.max(references.length, 9));
|
|
4563
|
+
const items = references.map((reference) => ` ${bibliographyEntryLatex(reference)}`).join("\n");
|
|
4564
|
+
return `${block.command}{${width}}
|
|
4565
|
+
${items}
|
|
4566
|
+
${block.closing}`;
|
|
3437
4567
|
}
|
|
3438
4568
|
return block.value;
|
|
3439
4569
|
}
|
|
3440
|
-
function
|
|
3441
|
-
return
|
|
4570
|
+
function authorLatex(authors) {
|
|
4571
|
+
return authors.split(/\n+/).map((line) => line.trim()).filter((line) => line.length > 0).join(" \\\\ ");
|
|
4572
|
+
}
|
|
4573
|
+
function articleFrontMatterLatex(meta) {
|
|
4574
|
+
const parts = [butexDiwaniDisplayLatex(BUTEX_BASMALA)];
|
|
4575
|
+
if (document2HasMaketitle(meta)) {
|
|
4576
|
+
if (meta.title.trim().length > 0) {
|
|
4577
|
+
parts.push(`\\title{${meta.title.trim()}}`);
|
|
4578
|
+
}
|
|
4579
|
+
if (meta.authors.trim().length > 0) {
|
|
4580
|
+
parts.push(`\\author{${authorLatex(meta.authors)}}`);
|
|
4581
|
+
}
|
|
4582
|
+
parts.push(`\\date{${formatHijriDate(meta.date, { locale: "ar", digitForm: "arabicIndic" })}}`);
|
|
4583
|
+
parts.push("\\maketitle");
|
|
4584
|
+
}
|
|
4585
|
+
if (document2HasAbstract(meta)) {
|
|
4586
|
+
parts.push(`\\begin{abstract}
|
|
4587
|
+
${meta.abstract.trim()}
|
|
4588
|
+
\\end{abstract}`);
|
|
4589
|
+
}
|
|
4590
|
+
return parts;
|
|
4591
|
+
}
|
|
4592
|
+
function document2Latex(document2, options = {}) {
|
|
4593
|
+
const meta = document2.meta ?? emptyDocument2Meta();
|
|
4594
|
+
const front = articleFrontMatterLatex(meta);
|
|
4595
|
+
const bodyBlocks = document2.blocks.map((block) => blockLatex(block, document2.references));
|
|
4596
|
+
const closing = butexDiwaniDisplayLatex(BUTEX_CLOSING_HAMDALA);
|
|
4597
|
+
const body = [...front, ...bodyBlocks, closing].filter((part) => part.length > 0).join("\n\n");
|
|
4598
|
+
const wrapDocument = options.wrapDocument !== false;
|
|
4599
|
+
if (!wrapDocument) {
|
|
4600
|
+
return body;
|
|
4601
|
+
}
|
|
4602
|
+
const preamble = getArabicXeLatexPreamble({
|
|
4603
|
+
digitsMapping: options.digitsMapping ?? "arabicdigits",
|
|
4604
|
+
twocolumn: options.twocolumn === true
|
|
4605
|
+
});
|
|
4606
|
+
return `${preamble}
|
|
4607
|
+
\\begin{document}
|
|
4608
|
+
|
|
4609
|
+
${body}
|
|
4610
|
+
|
|
4611
|
+
\\end{document}
|
|
4612
|
+
`;
|
|
3442
4613
|
}
|
|
3443
4614
|
|
|
3444
4615
|
// src/document2/history.ts
|
|
@@ -3474,18 +4645,99 @@ function document2HistoryCanRedo(stacks) {
|
|
|
3474
4645
|
return stacks.future.length > 0;
|
|
3475
4646
|
}
|
|
3476
4647
|
|
|
4648
|
+
// src/document2/blockSelection.ts
|
|
4649
|
+
function emptyBlockSelection() {
|
|
4650
|
+
return { selection: null, anchor: null };
|
|
4651
|
+
}
|
|
4652
|
+
function normalizeBlockSelection(selection, blockCount) {
|
|
4653
|
+
if (!selection) {
|
|
4654
|
+
return null;
|
|
4655
|
+
}
|
|
4656
|
+
const { from, to } = selection;
|
|
4657
|
+
if (blockCount <= 0 || from < 0 || to < 0 || from >= blockCount || to >= blockCount || from > to) {
|
|
4658
|
+
return null;
|
|
4659
|
+
}
|
|
4660
|
+
return { from, to };
|
|
4661
|
+
}
|
|
4662
|
+
function inRange(selection, index) {
|
|
4663
|
+
return index >= selection.from && index <= selection.to;
|
|
4664
|
+
}
|
|
4665
|
+
function toggleBlockInSelection(state, index, blockCount) {
|
|
4666
|
+
if (index < 0 || index >= blockCount) {
|
|
4667
|
+
return state;
|
|
4668
|
+
}
|
|
4669
|
+
const selection = normalizeBlockSelection(state.selection, blockCount);
|
|
4670
|
+
if (!selection) {
|
|
4671
|
+
return { selection: { from: index, to: index }, anchor: index };
|
|
4672
|
+
}
|
|
4673
|
+
if (inRange(selection, index)) {
|
|
4674
|
+
if (selection.from === selection.to) {
|
|
4675
|
+
return emptyBlockSelection();
|
|
4676
|
+
}
|
|
4677
|
+
if (index === selection.from) {
|
|
4678
|
+
return { selection: { from: selection.from + 1, to: selection.to }, anchor: state.anchor };
|
|
4679
|
+
}
|
|
4680
|
+
if (index === selection.to) {
|
|
4681
|
+
return { selection: { from: selection.from, to: selection.to - 1 }, anchor: state.anchor };
|
|
4682
|
+
}
|
|
4683
|
+
return emptyBlockSelection();
|
|
4684
|
+
}
|
|
4685
|
+
if (index === selection.from - 1) {
|
|
4686
|
+
return { selection: { from: index, to: selection.to }, anchor: state.anchor ?? index };
|
|
4687
|
+
}
|
|
4688
|
+
if (index === selection.to + 1) {
|
|
4689
|
+
return { selection: { from: selection.from, to: index }, anchor: state.anchor ?? index };
|
|
4690
|
+
}
|
|
4691
|
+
return { selection: { from: index, to: index }, anchor: index };
|
|
4692
|
+
}
|
|
4693
|
+
function extendBlockSelectionFromAnchor(state, index, blockCount) {
|
|
4694
|
+
if (index < 0 || index >= blockCount) {
|
|
4695
|
+
return state;
|
|
4696
|
+
}
|
|
4697
|
+
const anchor = state.anchor ?? index;
|
|
4698
|
+
const from = Math.min(anchor, index);
|
|
4699
|
+
const to = Math.max(anchor, index);
|
|
4700
|
+
return {
|
|
4701
|
+
selection: { from, to },
|
|
4702
|
+
anchor: state.anchor ?? index
|
|
4703
|
+
};
|
|
4704
|
+
}
|
|
4705
|
+
function remapSelectionAfterRangeMove(selection, direction) {
|
|
4706
|
+
return { from: selection.from + direction, to: selection.to + direction };
|
|
4707
|
+
}
|
|
4708
|
+
|
|
3477
4709
|
// src/document2/previewModel.ts
|
|
3478
4710
|
function mathTex(token, equationSide) {
|
|
3479
|
-
if (token.kind === "text") {
|
|
3480
|
-
return token.text;
|
|
3481
|
-
}
|
|
3482
4711
|
return mathTokenSourceForSide(token, equationSide);
|
|
3483
4712
|
}
|
|
3484
|
-
function previewInlines(field, islands, output, equationSide) {
|
|
4713
|
+
function previewInlines(field, islands, output, equationSide, document2, previewOptions) {
|
|
3485
4714
|
return field.tokens.map((token) => {
|
|
3486
4715
|
if (token.kind === "text") {
|
|
3487
4716
|
return { kind: "text", text: token.text };
|
|
3488
4717
|
}
|
|
4718
|
+
if (token.kind === "cite") {
|
|
4719
|
+
return {
|
|
4720
|
+
kind: "cite",
|
|
4721
|
+
id: token.id,
|
|
4722
|
+
keys: [...token.keys],
|
|
4723
|
+
label: formatCiteLabel(token.keys, document2.references, {
|
|
4724
|
+
documentDirection: previewOptions.documentDirection,
|
|
4725
|
+
digitForm: previewOptions.digitForm
|
|
4726
|
+
})
|
|
4727
|
+
};
|
|
4728
|
+
}
|
|
4729
|
+
if (token.kind === "ref") {
|
|
4730
|
+
return {
|
|
4731
|
+
kind: "ref",
|
|
4732
|
+
id: token.id,
|
|
4733
|
+
keys: [...token.keys],
|
|
4734
|
+
refCommand: token.refCommand,
|
|
4735
|
+
label: formatRefLabel(token.keys, document2, token.refCommand, {
|
|
4736
|
+
documentDirection: previewOptions.documentDirection,
|
|
4737
|
+
digitForm: previewOptions.digitForm
|
|
4738
|
+
})
|
|
4739
|
+
};
|
|
4740
|
+
}
|
|
3489
4741
|
const island = {
|
|
3490
4742
|
id: token.id,
|
|
3491
4743
|
tex: mathTex(token, equationSide),
|
|
@@ -3497,21 +4749,43 @@ function previewInlines(field, islands, output, equationSide) {
|
|
|
3497
4749
|
return { kind: "math", ...island };
|
|
3498
4750
|
});
|
|
3499
4751
|
}
|
|
3500
|
-
function textBlockPreview(block, islands, output, equationSide) {
|
|
4752
|
+
function textBlockPreview(block, islands, output, equationSide, document2, previewOptions) {
|
|
4753
|
+
const inlines = previewInlines(block.field, islands, output, equationSide, document2, previewOptions);
|
|
3501
4754
|
if (block.command === "\\section") {
|
|
3502
|
-
return { kind: "heading", id: block.id, level: 1, inlines
|
|
4755
|
+
return { kind: "heading", id: block.id, level: 1, inlines };
|
|
3503
4756
|
}
|
|
3504
4757
|
if (block.command === "\\subsection") {
|
|
3505
|
-
return { kind: "heading", id: block.id, level: 2, inlines
|
|
4758
|
+
return { kind: "heading", id: block.id, level: 2, inlines };
|
|
3506
4759
|
}
|
|
3507
4760
|
if (block.command === "\\subsubsection") {
|
|
3508
|
-
return { kind: "heading", id: block.id, level: 3, inlines
|
|
4761
|
+
return { kind: "heading", id: block.id, level: 3, inlines };
|
|
4762
|
+
}
|
|
4763
|
+
return {
|
|
4764
|
+
kind: "paragraph",
|
|
4765
|
+
id: block.id,
|
|
4766
|
+
inlines,
|
|
4767
|
+
...block.centered ? { centered: true } : {}
|
|
4768
|
+
};
|
|
4769
|
+
}
|
|
4770
|
+
function floatNumberLabel(document2, key, previewOptions) {
|
|
4771
|
+
if (!key || key.trim().length === 0) {
|
|
4772
|
+
return void 0;
|
|
4773
|
+
}
|
|
4774
|
+
const hit = labelNumberMap(document2).get(key.trim());
|
|
4775
|
+
if (!hit || hit.kind !== "fig" && hit.kind !== "tab") {
|
|
4776
|
+
return void 0;
|
|
3509
4777
|
}
|
|
3510
|
-
|
|
4778
|
+
const locale = previewOptions.uiLocale ?? "ar";
|
|
4779
|
+
const kindWord = hit.kind === "fig" ? locale === "ar" ? "\u0627\u0644\u0634\u0643\u0644" : "Figure" : locale === "ar" ? "\u0627\u0644\u062C\u062F\u0648\u0644" : "Table";
|
|
4780
|
+
const digits = formatBibliographyNumber(hit.number, {
|
|
4781
|
+
documentDirection: previewOptions.documentDirection,
|
|
4782
|
+
digitForm: previewOptions.digitForm
|
|
4783
|
+
});
|
|
4784
|
+
return `${kindWord} ${digits}`;
|
|
3511
4785
|
}
|
|
3512
|
-
function blockPreview(block, islands, output, equationSide) {
|
|
4786
|
+
function blockPreview(block, islands, output, equationSide, document2, previewOptions) {
|
|
3513
4787
|
if (block.kind === "textBlock") {
|
|
3514
|
-
return textBlockPreview(block, islands, output, equationSide);
|
|
4788
|
+
return textBlockPreview(block, islands, output, equationSide, document2, previewOptions);
|
|
3515
4789
|
}
|
|
3516
4790
|
if (block.kind === "list") {
|
|
3517
4791
|
return {
|
|
@@ -3520,50 +4794,154 @@ function blockPreview(block, islands, output, equationSide) {
|
|
|
3520
4794
|
ordered: block.command === "\\begin{enumerate}",
|
|
3521
4795
|
items: block.items.map((item) => ({
|
|
3522
4796
|
id: item.id,
|
|
3523
|
-
inlines: previewInlines(item.field, islands, output, equationSide),
|
|
3524
|
-
blocks: item.blocks.map((child) => blockPreview(child, islands, output, equationSide))
|
|
4797
|
+
inlines: previewInlines(item.field, islands, output, equationSide, document2, previewOptions),
|
|
4798
|
+
blocks: item.blocks.map((child) => blockPreview(child, islands, output, equationSide, document2, previewOptions))
|
|
3525
4799
|
}))
|
|
3526
4800
|
};
|
|
3527
4801
|
}
|
|
3528
4802
|
if (block.kind === "table") {
|
|
3529
|
-
|
|
4803
|
+
const label = block.labelEnabled ? block.label.trim() : "";
|
|
4804
|
+
return {
|
|
4805
|
+
kind: "table",
|
|
4806
|
+
id: block.id,
|
|
4807
|
+
rows: block.rows.map((row) => row.map((cell) => previewInlines(cell, islands, output, equationSide, document2, previewOptions))),
|
|
4808
|
+
...block.captionEnabled && block.caption.trim().length > 0 ? { caption: block.caption.trim() } : {},
|
|
4809
|
+
...label.length > 0 ? { label, numberLabel: floatNumberLabel(document2, label, previewOptions) } : {}
|
|
4810
|
+
};
|
|
3530
4811
|
}
|
|
3531
4812
|
if (block.kind === "image") {
|
|
3532
|
-
|
|
4813
|
+
const label = block.labelEnabled ? block.label.trim() : "";
|
|
4814
|
+
return {
|
|
4815
|
+
kind: "image",
|
|
4816
|
+
id: block.id,
|
|
4817
|
+
src: block.value,
|
|
4818
|
+
...block.assetId !== void 0 ? { assetId: block.assetId } : {},
|
|
4819
|
+
options: block.options,
|
|
4820
|
+
...block.captionEnabled && block.caption.trim().length > 0 ? { caption: block.caption.trim() } : {},
|
|
4821
|
+
...label.length > 0 ? { label, numberLabel: floatNumberLabel(document2, label, previewOptions) } : {}
|
|
4822
|
+
};
|
|
4823
|
+
}
|
|
4824
|
+
if (block.kind === "bibliography") {
|
|
4825
|
+
return {
|
|
4826
|
+
kind: "bibliography",
|
|
4827
|
+
id: block.id,
|
|
4828
|
+
items: document2.references.map((reference, index) => ({
|
|
4829
|
+
id: reference.id,
|
|
4830
|
+
numberLabel: formatBibliographyNumber(index + 1, {
|
|
4831
|
+
documentDirection: previewOptions.documentDirection,
|
|
4832
|
+
digitForm: previewOptions.digitForm
|
|
4833
|
+
}),
|
|
4834
|
+
key: reference.key,
|
|
4835
|
+
authors: reference.authors,
|
|
4836
|
+
title: reference.title,
|
|
4837
|
+
year: reference.year,
|
|
4838
|
+
url: reference.url,
|
|
4839
|
+
venue: reference.venue
|
|
4840
|
+
}))
|
|
4841
|
+
};
|
|
3533
4842
|
}
|
|
3534
4843
|
return { kind: "omit", id: block.id };
|
|
3535
4844
|
}
|
|
3536
|
-
function
|
|
4845
|
+
function articleChromePreview(document2, uiLocale, previewOptions) {
|
|
4846
|
+
const meta = document2.meta ?? emptyDocument2Meta();
|
|
4847
|
+
const blocks = [
|
|
4848
|
+
{ kind: "basmala", id: "article-basmala", text: BUTEX_BASMALA, tex: butexDiwaniDisplayTex(BUTEX_BASMALA) }
|
|
4849
|
+
];
|
|
4850
|
+
if (document2HasMaketitle(meta)) {
|
|
4851
|
+
blocks.push({
|
|
4852
|
+
kind: "titleBlock",
|
|
4853
|
+
id: "article-title",
|
|
4854
|
+
...meta.title.trim().length > 0 ? { title: meta.title.trim() } : {},
|
|
4855
|
+
...meta.authors.trim().length > 0 ? { authors: meta.authors.trim() } : {},
|
|
4856
|
+
date: formatHijriDate(meta.date, {
|
|
4857
|
+
locale: uiLocale,
|
|
4858
|
+
digitForm: previewOptions.digitForm
|
|
4859
|
+
})
|
|
4860
|
+
});
|
|
4861
|
+
}
|
|
4862
|
+
if (document2HasAbstract(meta)) {
|
|
4863
|
+
blocks.push({ kind: "abstract", id: "article-abstract", text: meta.abstract.trim() });
|
|
4864
|
+
}
|
|
4865
|
+
return blocks;
|
|
4866
|
+
}
|
|
4867
|
+
function document2Preview(document2, output = "svg", equationSide = "arabic", previewOptions = {}) {
|
|
3537
4868
|
const mathIslands = [];
|
|
4869
|
+
const options = {
|
|
4870
|
+
documentDirection: previewOptions.documentDirection ?? "rtl",
|
|
4871
|
+
digitForm: previewOptions.digitForm ?? (previewOptions.documentDirection === "ltr" ? "western" : "arabicIndic"),
|
|
4872
|
+
uiLocale: previewOptions.uiLocale ?? "ar"
|
|
4873
|
+
};
|
|
4874
|
+
const body = document2.blocks.map((block) => blockPreview(block, mathIslands, output, equationSide, document2, options));
|
|
3538
4875
|
return {
|
|
3539
|
-
blocks:
|
|
4876
|
+
blocks: [
|
|
4877
|
+
...articleChromePreview(document2, options.uiLocale ?? "ar", options),
|
|
4878
|
+
...body,
|
|
4879
|
+
{ kind: "closing", id: "article-closing", text: BUTEX_CLOSING_HAMDALA, tex: butexDiwaniDisplayTex(BUTEX_CLOSING_HAMDALA) }
|
|
4880
|
+
],
|
|
3540
4881
|
mathIslands
|
|
3541
4882
|
};
|
|
3542
4883
|
}
|
|
3543
4884
|
export {
|
|
4885
|
+
BUTEX_BASMALA,
|
|
4886
|
+
BUTEX_CLOSING_HAMDALA,
|
|
3544
4887
|
DEFAULT_DOCUMENT2_HISTORY_MAX_DEPTH,
|
|
4888
|
+
DEFAULT_HIJRI_DATE,
|
|
4889
|
+
HIJRI_MONTH_IDS,
|
|
4890
|
+
HIJRI_YEAR_MAX,
|
|
4891
|
+
HIJRI_YEAR_MIN,
|
|
3545
4892
|
addDocument2ImageBlock,
|
|
3546
4893
|
addDocument2ListBlock,
|
|
3547
4894
|
addDocument2ListItem,
|
|
4895
|
+
addDocument2Reference,
|
|
3548
4896
|
addDocument2TableBlock,
|
|
3549
4897
|
addDocument2TextBlock,
|
|
4898
|
+
applyFloatMetaPatch,
|
|
4899
|
+
arabicXeLatexPreambleCmd,
|
|
4900
|
+
arabicXeLatexPreambleFont,
|
|
4901
|
+
arabicXeLatexPreamblePkg,
|
|
4902
|
+
bibliographyEntryLatex,
|
|
4903
|
+
butexDiwaniDisplayLatex,
|
|
4904
|
+
butexDiwaniDisplayTex,
|
|
4905
|
+
citeTokenLatex,
|
|
4906
|
+
cloneDocument2Meta,
|
|
3550
4907
|
cloneDocument2Node,
|
|
4908
|
+
collectDocument2Labels,
|
|
3551
4909
|
createDocument2History,
|
|
3552
4910
|
createEmptyArabicEquationSession,
|
|
3553
4911
|
createEmptyDocument2,
|
|
3554
4912
|
createEmptyEquationSession,
|
|
4913
|
+
createEmptyReference2,
|
|
3555
4914
|
createInlineField2,
|
|
4915
|
+
defaultFloatMeta,
|
|
4916
|
+
detectInlineSpans2,
|
|
3556
4917
|
detectMathSpans2,
|
|
4918
|
+
document2HasAbstract,
|
|
4919
|
+
document2HasMaketitle,
|
|
4920
|
+
document2HasTitleStack,
|
|
3557
4921
|
document2HistoryCanRedo,
|
|
3558
4922
|
document2HistoryCanUndo,
|
|
3559
4923
|
document2Latex,
|
|
3560
4924
|
document2Preview,
|
|
4925
|
+
emptyBlockSelection,
|
|
4926
|
+
emptyDocument2Meta,
|
|
4927
|
+
ensureDocument2BibliographyBlock,
|
|
4928
|
+
extendBlockSelectionFromAnchor,
|
|
4929
|
+
fillDocument2MetaGaps,
|
|
3561
4930
|
findFirstInlineField,
|
|
4931
|
+
formatBibliographyNumber,
|
|
4932
|
+
formatCiteLabel,
|
|
4933
|
+
formatHijriDate,
|
|
4934
|
+
formatRefLabel,
|
|
3562
4935
|
fromDocumentJson2,
|
|
4936
|
+
getArabicXeLatexPreamble,
|
|
4937
|
+
hijriMonthLabel,
|
|
3563
4938
|
inlineFieldLatex,
|
|
4939
|
+
insertCiteTokenAtCaret,
|
|
3564
4940
|
insertDocument2BlockAfter,
|
|
3565
4941
|
insertMathToken,
|
|
3566
4942
|
insertMathTokenAtCaret,
|
|
4943
|
+
insertRefTokenAtCaret,
|
|
4944
|
+
labelNumberMap,
|
|
3567
4945
|
mathNodeFromArabicSession,
|
|
3568
4946
|
mathNodeFromSession,
|
|
3569
4947
|
mathSourceFromArabicSession,
|
|
@@ -3571,15 +4949,44 @@ export {
|
|
|
3571
4949
|
mathTokenSourceForSide,
|
|
3572
4950
|
mathTokenToArabicEditorSession,
|
|
3573
4951
|
mathTokenToEditorSession,
|
|
4952
|
+
mergeDocument2Meta,
|
|
3574
4953
|
moveDocument2BlockById,
|
|
4954
|
+
moveDocument2BlockRange,
|
|
4955
|
+
moveDocument2Reference,
|
|
4956
|
+
normalizeBlockSelection,
|
|
4957
|
+
normalizeDocument2HijriDate,
|
|
4958
|
+
normalizeDocument2Meta,
|
|
4959
|
+
parseCiteKeys,
|
|
4960
|
+
parseFloatMetaFromJson,
|
|
4961
|
+
parseRefKeys,
|
|
3575
4962
|
pushDocument2Snapshot,
|
|
4963
|
+
refTokenLatex,
|
|
4964
|
+
referenceFromJson,
|
|
4965
|
+
referenceNumberMap,
|
|
4966
|
+
remapSelectionAfterRangeMove,
|
|
4967
|
+
removeCiteTokenById,
|
|
3576
4968
|
removeDocument2BlockById,
|
|
4969
|
+
removeDocument2BlockRange,
|
|
3577
4970
|
removeDocument2ListItem,
|
|
4971
|
+
removeDocument2Reference,
|
|
3578
4972
|
removeMathTokenById,
|
|
4973
|
+
removeRefTokenById,
|
|
3579
4974
|
replaceMathTokenFromSession,
|
|
4975
|
+
resolveCiteNumbers,
|
|
3580
4976
|
restoreDocument2Redo,
|
|
3581
4977
|
restoreDocument2Undo,
|
|
4978
|
+
setDocument2References,
|
|
4979
|
+
stripDisplayMathDelimiters,
|
|
4980
|
+
toggleBlockInSelection,
|
|
4981
|
+
updateCiteTokenKeys,
|
|
4982
|
+
updateDocument2ImageMeta,
|
|
3582
4983
|
updateDocument2ImageValue,
|
|
4984
|
+
updateDocument2Meta,
|
|
4985
|
+
updateDocument2Reference,
|
|
4986
|
+
updateDocument2TableMeta,
|
|
4987
|
+
updateDocument2TextBlockCentered,
|
|
4988
|
+
updateMathTokenLabel,
|
|
4989
|
+
updateRefTokenKeys,
|
|
3583
4990
|
updateTextToken
|
|
3584
4991
|
};
|
|
3585
4992
|
//# sourceMappingURL=document2.mjs.map
|