@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.js
CHANGED
|
@@ -20,29 +20,66 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/document2/index.ts
|
|
21
21
|
var document2_exports = {};
|
|
22
22
|
__export(document2_exports, {
|
|
23
|
+
BUTEX_BASMALA: () => BUTEX_BASMALA,
|
|
24
|
+
BUTEX_CLOSING_HAMDALA: () => BUTEX_CLOSING_HAMDALA,
|
|
23
25
|
DEFAULT_DOCUMENT2_HISTORY_MAX_DEPTH: () => DEFAULT_DOCUMENT2_HISTORY_MAX_DEPTH,
|
|
26
|
+
DEFAULT_HIJRI_DATE: () => DEFAULT_HIJRI_DATE,
|
|
27
|
+
HIJRI_MONTH_IDS: () => HIJRI_MONTH_IDS,
|
|
28
|
+
HIJRI_YEAR_MAX: () => HIJRI_YEAR_MAX,
|
|
29
|
+
HIJRI_YEAR_MIN: () => HIJRI_YEAR_MIN,
|
|
24
30
|
addDocument2ImageBlock: () => addDocument2ImageBlock,
|
|
25
31
|
addDocument2ListBlock: () => addDocument2ListBlock,
|
|
26
32
|
addDocument2ListItem: () => addDocument2ListItem,
|
|
33
|
+
addDocument2Reference: () => addDocument2Reference,
|
|
27
34
|
addDocument2TableBlock: () => addDocument2TableBlock,
|
|
28
35
|
addDocument2TextBlock: () => addDocument2TextBlock,
|
|
36
|
+
applyFloatMetaPatch: () => applyFloatMetaPatch,
|
|
37
|
+
arabicXeLatexPreambleCmd: () => arabicXeLatexPreambleCmd,
|
|
38
|
+
arabicXeLatexPreambleFont: () => arabicXeLatexPreambleFont,
|
|
39
|
+
arabicXeLatexPreamblePkg: () => arabicXeLatexPreamblePkg,
|
|
40
|
+
bibliographyEntryLatex: () => bibliographyEntryLatex,
|
|
41
|
+
butexDiwaniDisplayLatex: () => butexDiwaniDisplayLatex,
|
|
42
|
+
butexDiwaniDisplayTex: () => butexDiwaniDisplayTex,
|
|
43
|
+
citeTokenLatex: () => citeTokenLatex,
|
|
44
|
+
cloneDocument2Meta: () => cloneDocument2Meta,
|
|
29
45
|
cloneDocument2Node: () => cloneDocument2Node,
|
|
46
|
+
collectDocument2Labels: () => collectDocument2Labels,
|
|
30
47
|
createDocument2History: () => createDocument2History,
|
|
31
48
|
createEmptyArabicEquationSession: () => createEmptyArabicEquationSession,
|
|
32
49
|
createEmptyDocument2: () => createEmptyDocument2,
|
|
33
50
|
createEmptyEquationSession: () => createEmptyEquationSession,
|
|
51
|
+
createEmptyReference2: () => createEmptyReference2,
|
|
34
52
|
createInlineField2: () => createInlineField2,
|
|
53
|
+
defaultFloatMeta: () => defaultFloatMeta,
|
|
54
|
+
detectInlineSpans2: () => detectInlineSpans2,
|
|
35
55
|
detectMathSpans2: () => detectMathSpans2,
|
|
56
|
+
document2HasAbstract: () => document2HasAbstract,
|
|
57
|
+
document2HasMaketitle: () => document2HasMaketitle,
|
|
58
|
+
document2HasTitleStack: () => document2HasTitleStack,
|
|
36
59
|
document2HistoryCanRedo: () => document2HistoryCanRedo,
|
|
37
60
|
document2HistoryCanUndo: () => document2HistoryCanUndo,
|
|
38
61
|
document2Latex: () => document2Latex,
|
|
39
62
|
document2Preview: () => document2Preview,
|
|
63
|
+
emptyBlockSelection: () => emptyBlockSelection,
|
|
64
|
+
emptyDocument2Meta: () => emptyDocument2Meta,
|
|
65
|
+
ensureDocument2BibliographyBlock: () => ensureDocument2BibliographyBlock,
|
|
66
|
+
extendBlockSelectionFromAnchor: () => extendBlockSelectionFromAnchor,
|
|
67
|
+
fillDocument2MetaGaps: () => fillDocument2MetaGaps,
|
|
40
68
|
findFirstInlineField: () => findFirstInlineField,
|
|
69
|
+
formatBibliographyNumber: () => formatBibliographyNumber,
|
|
70
|
+
formatCiteLabel: () => formatCiteLabel,
|
|
71
|
+
formatHijriDate: () => formatHijriDate,
|
|
72
|
+
formatRefLabel: () => formatRefLabel,
|
|
41
73
|
fromDocumentJson2: () => fromDocumentJson2,
|
|
74
|
+
getArabicXeLatexPreamble: () => getArabicXeLatexPreamble,
|
|
75
|
+
hijriMonthLabel: () => hijriMonthLabel,
|
|
42
76
|
inlineFieldLatex: () => inlineFieldLatex,
|
|
77
|
+
insertCiteTokenAtCaret: () => insertCiteTokenAtCaret,
|
|
43
78
|
insertDocument2BlockAfter: () => insertDocument2BlockAfter,
|
|
44
79
|
insertMathToken: () => insertMathToken,
|
|
45
80
|
insertMathTokenAtCaret: () => insertMathTokenAtCaret,
|
|
81
|
+
insertRefTokenAtCaret: () => insertRefTokenAtCaret,
|
|
82
|
+
labelNumberMap: () => labelNumberMap,
|
|
46
83
|
mathNodeFromArabicSession: () => mathNodeFromArabicSession,
|
|
47
84
|
mathNodeFromSession: () => mathNodeFromSession,
|
|
48
85
|
mathSourceFromArabicSession: () => mathSourceFromArabicSession,
|
|
@@ -50,15 +87,44 @@ __export(document2_exports, {
|
|
|
50
87
|
mathTokenSourceForSide: () => mathTokenSourceForSide,
|
|
51
88
|
mathTokenToArabicEditorSession: () => mathTokenToArabicEditorSession,
|
|
52
89
|
mathTokenToEditorSession: () => mathTokenToEditorSession,
|
|
90
|
+
mergeDocument2Meta: () => mergeDocument2Meta,
|
|
53
91
|
moveDocument2BlockById: () => moveDocument2BlockById,
|
|
92
|
+
moveDocument2BlockRange: () => moveDocument2BlockRange,
|
|
93
|
+
moveDocument2Reference: () => moveDocument2Reference,
|
|
94
|
+
normalizeBlockSelection: () => normalizeBlockSelection,
|
|
95
|
+
normalizeDocument2HijriDate: () => normalizeDocument2HijriDate,
|
|
96
|
+
normalizeDocument2Meta: () => normalizeDocument2Meta,
|
|
97
|
+
parseCiteKeys: () => parseCiteKeys,
|
|
98
|
+
parseFloatMetaFromJson: () => parseFloatMetaFromJson,
|
|
99
|
+
parseRefKeys: () => parseRefKeys,
|
|
54
100
|
pushDocument2Snapshot: () => pushDocument2Snapshot,
|
|
101
|
+
refTokenLatex: () => refTokenLatex,
|
|
102
|
+
referenceFromJson: () => referenceFromJson,
|
|
103
|
+
referenceNumberMap: () => referenceNumberMap,
|
|
104
|
+
remapSelectionAfterRangeMove: () => remapSelectionAfterRangeMove,
|
|
105
|
+
removeCiteTokenById: () => removeCiteTokenById,
|
|
55
106
|
removeDocument2BlockById: () => removeDocument2BlockById,
|
|
107
|
+
removeDocument2BlockRange: () => removeDocument2BlockRange,
|
|
56
108
|
removeDocument2ListItem: () => removeDocument2ListItem,
|
|
109
|
+
removeDocument2Reference: () => removeDocument2Reference,
|
|
57
110
|
removeMathTokenById: () => removeMathTokenById,
|
|
111
|
+
removeRefTokenById: () => removeRefTokenById,
|
|
58
112
|
replaceMathTokenFromSession: () => replaceMathTokenFromSession,
|
|
113
|
+
resolveCiteNumbers: () => resolveCiteNumbers,
|
|
59
114
|
restoreDocument2Redo: () => restoreDocument2Redo,
|
|
60
115
|
restoreDocument2Undo: () => restoreDocument2Undo,
|
|
116
|
+
setDocument2References: () => setDocument2References,
|
|
117
|
+
stripDisplayMathDelimiters: () => stripDisplayMathDelimiters,
|
|
118
|
+
toggleBlockInSelection: () => toggleBlockInSelection,
|
|
119
|
+
updateCiteTokenKeys: () => updateCiteTokenKeys,
|
|
120
|
+
updateDocument2ImageMeta: () => updateDocument2ImageMeta,
|
|
61
121
|
updateDocument2ImageValue: () => updateDocument2ImageValue,
|
|
122
|
+
updateDocument2Meta: () => updateDocument2Meta,
|
|
123
|
+
updateDocument2Reference: () => updateDocument2Reference,
|
|
124
|
+
updateDocument2TableMeta: () => updateDocument2TableMeta,
|
|
125
|
+
updateDocument2TextBlockCentered: () => updateDocument2TextBlockCentered,
|
|
126
|
+
updateMathTokenLabel: () => updateMathTokenLabel,
|
|
127
|
+
updateRefTokenKeys: () => updateRefTokenKeys,
|
|
62
128
|
updateTextToken: () => updateTextToken
|
|
63
129
|
});
|
|
64
130
|
module.exports = __toCommonJS(document2_exports);
|
|
@@ -71,6 +137,273 @@ function document2Id(prefix) {
|
|
|
71
137
|
return id;
|
|
72
138
|
}
|
|
73
139
|
|
|
140
|
+
// src/editor/digits.ts
|
|
141
|
+
var WESTERN = "0123456789";
|
|
142
|
+
var ARABIC_INDIC = "\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669";
|
|
143
|
+
var PERSIAN_INDIC = "\u06F0\u06F1\u06F2\u06F3\u06F4\u06F5\u06F6\u06F7\u06F8\u06F9";
|
|
144
|
+
var digitSets = {
|
|
145
|
+
western: WESTERN,
|
|
146
|
+
arabicIndic: ARABIC_INDIC,
|
|
147
|
+
persianIndic: PERSIAN_INDIC
|
|
148
|
+
};
|
|
149
|
+
function digitValue(char) {
|
|
150
|
+
const western = WESTERN.indexOf(char);
|
|
151
|
+
if (western >= 0) {
|
|
152
|
+
return western;
|
|
153
|
+
}
|
|
154
|
+
const arabicIndic = ARABIC_INDIC.indexOf(char);
|
|
155
|
+
if (arabicIndic >= 0) {
|
|
156
|
+
return arabicIndic;
|
|
157
|
+
}
|
|
158
|
+
return PERSIAN_INDIC.indexOf(char);
|
|
159
|
+
}
|
|
160
|
+
function formatDigits(value, digitForm = "western") {
|
|
161
|
+
const target = digitSets[digitForm];
|
|
162
|
+
return Array.from(value, (char) => {
|
|
163
|
+
const value2 = digitValue(char);
|
|
164
|
+
return value2 >= 0 ? target[value2] : char;
|
|
165
|
+
}).join("");
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// src/document2/articleMeta.ts
|
|
169
|
+
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";
|
|
170
|
+
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";
|
|
171
|
+
function escapeButexTextArg(text) {
|
|
172
|
+
return text.replace(/\\/g, "\\textbackslash{}").replace(/[{}]/g, "\\$&");
|
|
173
|
+
}
|
|
174
|
+
function butexDiwaniDisplayTex(text) {
|
|
175
|
+
return `\\butexdiwani{${escapeButexTextArg(text)}}`;
|
|
176
|
+
}
|
|
177
|
+
function butexDiwaniDisplayLatex(text) {
|
|
178
|
+
return `\\[
|
|
179
|
+
${butexDiwaniDisplayTex(text)}
|
|
180
|
+
\\]`;
|
|
181
|
+
}
|
|
182
|
+
var HIJRI_YEAR_MIN = 1400;
|
|
183
|
+
var HIJRI_YEAR_MAX = 1500;
|
|
184
|
+
var HIJRI_MONTH_IDS = [
|
|
185
|
+
"\u0645\u062D\u0631\u0645",
|
|
186
|
+
"\u0635\u0641\u0631",
|
|
187
|
+
"\u0631\u0628\u064A\u0639 \u0627\u0644\u0623\u0648\u0644",
|
|
188
|
+
"\u0631\u0628\u064A\u0639 \u0627\u0644\u0622\u062E\u0631",
|
|
189
|
+
"\u062C\u0645\u0627\u062F\u0649 \u0627\u0644\u0623\u0648\u0644\u0649",
|
|
190
|
+
"\u062C\u0645\u0627\u062F\u0649 \u0627\u0644\u0622\u062E\u0631\u0629",
|
|
191
|
+
"\u0631\u062C\u0628",
|
|
192
|
+
"\u0634\u0639\u0628\u0627\u0646",
|
|
193
|
+
"\u0631\u0645\u0636\u0627\u0646",
|
|
194
|
+
"\u0634\u0648\u0627\u0644",
|
|
195
|
+
"\u0630\u0648 \u0627\u0644\u0642\u0639\u062F\u0629",
|
|
196
|
+
"\u0630\u0648 \u0627\u0644\u062D\u062C\u0629"
|
|
197
|
+
];
|
|
198
|
+
var HIJRI_MONTH_LABELS_EN = {
|
|
199
|
+
\u0645\u062D\u0631\u0645: "Muharram",
|
|
200
|
+
\u0635\u0641\u0631: "Safar",
|
|
201
|
+
"\u0631\u0628\u064A\u0639 \u0627\u0644\u0623\u0648\u0644": "Rabi\u02BB I",
|
|
202
|
+
"\u0631\u0628\u064A\u0639 \u0627\u0644\u0622\u062E\u0631": "Rabi\u02BB II",
|
|
203
|
+
"\u062C\u0645\u0627\u062F\u0649 \u0627\u0644\u0623\u0648\u0644\u0649": "Jumada I",
|
|
204
|
+
"\u062C\u0645\u0627\u062F\u0649 \u0627\u0644\u0622\u062E\u0631\u0629": "Jumada II",
|
|
205
|
+
\u0631\u062C\u0628: "Rajab",
|
|
206
|
+
\u0634\u0639\u0628\u0627\u0646: "Sha\u02BBban",
|
|
207
|
+
\u0631\u0645\u0636\u0627\u0646: "Ramadan",
|
|
208
|
+
\u0634\u0648\u0627\u0644: "Shawwal",
|
|
209
|
+
"\u0630\u0648 \u0627\u0644\u0642\u0639\u062F\u0629": "Dhul Qa\u02BBdah",
|
|
210
|
+
"\u0630\u0648 \u0627\u0644\u062D\u062C\u0629": "Dhul Hijjah"
|
|
211
|
+
};
|
|
212
|
+
var LEGACY_LATIN_MONTH = {
|
|
213
|
+
muharram: "\u0645\u062D\u0631\u0645",
|
|
214
|
+
safar: "\u0635\u0641\u0631",
|
|
215
|
+
rabiAwwal: "\u0631\u0628\u064A\u0639 \u0627\u0644\u0623\u0648\u0644",
|
|
216
|
+
rabiThani: "\u0631\u0628\u064A\u0639 \u0627\u0644\u0622\u062E\u0631",
|
|
217
|
+
jumadaAwwal: "\u062C\u0645\u0627\u062F\u0649 \u0627\u0644\u0623\u0648\u0644\u0649",
|
|
218
|
+
jumadaThani: "\u062C\u0645\u0627\u062F\u0649 \u0627\u0644\u0622\u062E\u0631\u0629",
|
|
219
|
+
rajab: "\u0631\u062C\u0628",
|
|
220
|
+
shaban: "\u0634\u0639\u0628\u0627\u0646",
|
|
221
|
+
ramadan: "\u0631\u0645\u0636\u0627\u0646",
|
|
222
|
+
shawwal: "\u0634\u0648\u0627\u0644",
|
|
223
|
+
dhulQadah: "\u0630\u0648 \u0627\u0644\u0642\u0639\u062F\u0629",
|
|
224
|
+
dhulHijjah: "\u0630\u0648 \u0627\u0644\u062D\u062C\u0629"
|
|
225
|
+
};
|
|
226
|
+
var DEFAULT_HIJRI_DATE = {
|
|
227
|
+
day: 1,
|
|
228
|
+
month: "\u0645\u062D\u0631\u0645",
|
|
229
|
+
year: 1448
|
|
230
|
+
};
|
|
231
|
+
function hijriMonthLabel(month, locale = "ar") {
|
|
232
|
+
return locale === "en" ? HIJRI_MONTH_LABELS_EN[month] : month;
|
|
233
|
+
}
|
|
234
|
+
function emptyDocument2Meta() {
|
|
235
|
+
return {
|
|
236
|
+
title: "",
|
|
237
|
+
authors: "",
|
|
238
|
+
date: { ...DEFAULT_HIJRI_DATE },
|
|
239
|
+
abstract: ""
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
function clampInt(value, min, max) {
|
|
243
|
+
if (!Number.isFinite(value)) {
|
|
244
|
+
return min;
|
|
245
|
+
}
|
|
246
|
+
return Math.min(max, Math.max(min, Math.trunc(value)));
|
|
247
|
+
}
|
|
248
|
+
function isHijriMonthId(value) {
|
|
249
|
+
return typeof value === "string" && HIJRI_MONTH_IDS.includes(value);
|
|
250
|
+
}
|
|
251
|
+
function resolveHijriMonthId(value) {
|
|
252
|
+
if (isHijriMonthId(value)) {
|
|
253
|
+
return value;
|
|
254
|
+
}
|
|
255
|
+
if (typeof value === "string" && value in LEGACY_LATIN_MONTH) {
|
|
256
|
+
return LEGACY_LATIN_MONTH[value];
|
|
257
|
+
}
|
|
258
|
+
return DEFAULT_HIJRI_DATE.month;
|
|
259
|
+
}
|
|
260
|
+
function normalizeDocument2HijriDate(value) {
|
|
261
|
+
if (typeof value !== "object" || value === null) {
|
|
262
|
+
return { ...DEFAULT_HIJRI_DATE };
|
|
263
|
+
}
|
|
264
|
+
const raw = value;
|
|
265
|
+
const day = clampInt(typeof raw.day === "number" ? raw.day : Number(raw.day), 1, 30);
|
|
266
|
+
const year = clampInt(typeof raw.year === "number" ? raw.year : Number(raw.year), HIJRI_YEAR_MIN, HIJRI_YEAR_MAX);
|
|
267
|
+
const month = resolveHijriMonthId(raw.month);
|
|
268
|
+
return { day, month, year };
|
|
269
|
+
}
|
|
270
|
+
function normalizeDocument2Meta(value) {
|
|
271
|
+
if (typeof value !== "object" || value === null) {
|
|
272
|
+
return emptyDocument2Meta();
|
|
273
|
+
}
|
|
274
|
+
const raw = value;
|
|
275
|
+
return {
|
|
276
|
+
title: typeof raw.title === "string" ? raw.title : "",
|
|
277
|
+
authors: typeof raw.authors === "string" ? raw.authors : "",
|
|
278
|
+
date: normalizeDocument2HijriDate(raw.date),
|
|
279
|
+
abstract: typeof raw.abstract === "string" ? raw.abstract : ""
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
function mergeDocument2Meta(fromJson, fromProp) {
|
|
283
|
+
const fromPropMeta = {
|
|
284
|
+
title: typeof fromProp?.title === "string" ? fromProp.title : "",
|
|
285
|
+
authors: typeof fromProp?.authors === "string" ? fromProp.authors : "",
|
|
286
|
+
abstract: typeof fromProp?.abstract === "string" ? fromProp.abstract : "",
|
|
287
|
+
date: fromProp?.date ? normalizeDocument2HijriDate({ ...DEFAULT_HIJRI_DATE, ...fromProp.date }) : { ...DEFAULT_HIJRI_DATE }
|
|
288
|
+
};
|
|
289
|
+
if (typeof fromJson !== "object" || fromJson === null) {
|
|
290
|
+
return fromPropMeta;
|
|
291
|
+
}
|
|
292
|
+
const json = fromJson;
|
|
293
|
+
return {
|
|
294
|
+
title: "title" in json && typeof json.title === "string" ? json.title : fromPropMeta.title,
|
|
295
|
+
authors: "authors" in json && typeof json.authors === "string" ? json.authors : fromPropMeta.authors,
|
|
296
|
+
abstract: "abstract" in json && typeof json.abstract === "string" ? json.abstract : fromPropMeta.abstract,
|
|
297
|
+
date: "date" in json ? normalizeDocument2HijriDate(json.date) : fromPropMeta.date
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
function fillDocument2MetaGaps(current, fromProp) {
|
|
301
|
+
if (!fromProp) {
|
|
302
|
+
return cloneDocument2Meta(current);
|
|
303
|
+
}
|
|
304
|
+
return {
|
|
305
|
+
title: current.title.trim().length > 0 ? current.title : typeof fromProp.title === "string" ? fromProp.title : current.title,
|
|
306
|
+
authors: current.authors.trim().length > 0 ? current.authors : typeof fromProp.authors === "string" ? fromProp.authors : current.authors,
|
|
307
|
+
abstract: current.abstract.trim().length > 0 ? current.abstract : typeof fromProp.abstract === "string" ? fromProp.abstract : current.abstract,
|
|
308
|
+
date: fromProp.date ? normalizeDocument2HijriDate({ ...current.date, ...fromProp.date }) : { ...current.date }
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
function document2HasMaketitle(meta) {
|
|
312
|
+
return meta.title.trim().length > 0 || meta.authors.trim().length > 0;
|
|
313
|
+
}
|
|
314
|
+
function document2HasAbstract(meta) {
|
|
315
|
+
return meta.abstract.trim().length > 0;
|
|
316
|
+
}
|
|
317
|
+
function document2HasTitleStack(meta) {
|
|
318
|
+
return document2HasMaketitle(meta) || document2HasAbstract(meta);
|
|
319
|
+
}
|
|
320
|
+
function formatHijriDate(date, options = "ar") {
|
|
321
|
+
const opts = typeof options === "string" ? { locale: options } : options;
|
|
322
|
+
const locale = opts.locale ?? "ar";
|
|
323
|
+
const digitForm = opts.digitForm ?? (locale === "en" ? "western" : "arabicIndic");
|
|
324
|
+
const month = hijriMonthLabel(date.month, locale);
|
|
325
|
+
const day = formatDigits(String(date.day), digitForm);
|
|
326
|
+
const year = formatDigits(String(date.year), digitForm);
|
|
327
|
+
if (locale === "en") {
|
|
328
|
+
return `${day} ${month} ${year} AH`;
|
|
329
|
+
}
|
|
330
|
+
return `${day} ${month} ${year}\u0647\u0640`;
|
|
331
|
+
}
|
|
332
|
+
function cloneDocument2Meta(meta) {
|
|
333
|
+
return {
|
|
334
|
+
title: meta.title,
|
|
335
|
+
authors: meta.authors,
|
|
336
|
+
date: { ...meta.date },
|
|
337
|
+
abstract: meta.abstract
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// src/document2/citations.ts
|
|
342
|
+
function referenceNumberMap(references) {
|
|
343
|
+
const map = /* @__PURE__ */ new Map();
|
|
344
|
+
references.forEach((reference, index) => {
|
|
345
|
+
if (!map.has(reference.key)) {
|
|
346
|
+
map.set(reference.key, index + 1);
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
return map;
|
|
350
|
+
}
|
|
351
|
+
function resolveCiteNumbers(keys, references) {
|
|
352
|
+
const map = referenceNumberMap(references);
|
|
353
|
+
return keys.map((key) => map.get(key) ?? null);
|
|
354
|
+
}
|
|
355
|
+
function formatCiteLabel(keys, references, options = {}) {
|
|
356
|
+
const documentDirection = options.documentDirection ?? "rtl";
|
|
357
|
+
const digitForm = options.digitForm ?? (documentDirection === "rtl" ? "arabicIndic" : "western");
|
|
358
|
+
const numbers = resolveCiteNumbers(keys, references).map((value) => value === null ? "?" : String(value));
|
|
359
|
+
const display = documentDirection === "rtl" ? [...numbers].reverse() : numbers;
|
|
360
|
+
const separator = documentDirection === "rtl" ? "\u060C" : ", ";
|
|
361
|
+
const body = display.map((part) => formatDigits(part, digitForm)).join(separator);
|
|
362
|
+
return `[${body}]`;
|
|
363
|
+
}
|
|
364
|
+
function formatBibliographyNumber(index, options = {}) {
|
|
365
|
+
const documentDirection = options.documentDirection ?? "rtl";
|
|
366
|
+
const digitForm = options.digitForm ?? (documentDirection === "rtl" ? "arabicIndic" : "western");
|
|
367
|
+
return formatDigits(String(index), digitForm);
|
|
368
|
+
}
|
|
369
|
+
function parseCiteKeys(source) {
|
|
370
|
+
const match = /^\\cite\{([^}]*)\}$/.exec(source.trim());
|
|
371
|
+
if (!match) {
|
|
372
|
+
return [];
|
|
373
|
+
}
|
|
374
|
+
return (match[1] ?? "").split(",").map((key) => key.trim()).filter((key) => key.length > 0);
|
|
375
|
+
}
|
|
376
|
+
function citeTokenLatex(keys) {
|
|
377
|
+
return `\\cite{${keys.join(",")}}`;
|
|
378
|
+
}
|
|
379
|
+
function referenceFromJson(json) {
|
|
380
|
+
return {
|
|
381
|
+
id: document2Id("ref"),
|
|
382
|
+
key: json.key,
|
|
383
|
+
authors: typeof json.authors === "string" ? json.authors : "",
|
|
384
|
+
title: typeof json.title === "string" ? json.title : "",
|
|
385
|
+
year: typeof json.year === "string" ? json.year : "",
|
|
386
|
+
url: typeof json.url === "string" ? json.url : "",
|
|
387
|
+
venue: typeof json.venue === "string" ? json.venue : ""
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
function createEmptyReference2(partial = {}) {
|
|
391
|
+
return referenceFromJson({
|
|
392
|
+
key: partial.key ?? `ref${String(Date.now()).slice(-4)}`,
|
|
393
|
+
authors: partial.authors,
|
|
394
|
+
title: partial.title,
|
|
395
|
+
year: partial.year,
|
|
396
|
+
url: partial.url,
|
|
397
|
+
venue: partial.venue
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
function bibliographyEntryLatex(reference) {
|
|
401
|
+
const parts = [reference.authors, reference.title, reference.venue, reference.year].filter((part) => part.trim().length > 0);
|
|
402
|
+
const body = parts.join(", ");
|
|
403
|
+
const url = reference.url.trim().length > 0 ? ` \\url{${reference.url}}` : "";
|
|
404
|
+
return `\\bibitem{${reference.key}} ${body}${url}`.trim();
|
|
405
|
+
}
|
|
406
|
+
|
|
74
407
|
// src/ast/commands/index.ts
|
|
75
408
|
function renderCommandCore(context) {
|
|
76
409
|
const optional = context.optionalArgs.map((arg) => `[${context.renderChain(arg)}]`).join("");
|
|
@@ -440,6 +773,168 @@ ${lines.map((line) => ` ${line}`).join(" \\\\\n")}
|
|
|
440
773
|
${math.closing}`;
|
|
441
774
|
}
|
|
442
775
|
|
|
776
|
+
// src/document2/labels.ts
|
|
777
|
+
function defaultFloatMeta() {
|
|
778
|
+
return {
|
|
779
|
+
centered: true,
|
|
780
|
+
captionEnabled: false,
|
|
781
|
+
caption: "",
|
|
782
|
+
labelEnabled: false,
|
|
783
|
+
label: ""
|
|
784
|
+
};
|
|
785
|
+
}
|
|
786
|
+
function parseFloatMetaFromJson(json) {
|
|
787
|
+
const caption = typeof json.caption === "string" ? json.caption : "";
|
|
788
|
+
const label = typeof json.label === "string" ? json.label : "";
|
|
789
|
+
return {
|
|
790
|
+
centered: json.centered !== false,
|
|
791
|
+
captionEnabled: json.caption_enabled === true || typeof json.caption_enabled !== "boolean" && caption.length > 0,
|
|
792
|
+
caption,
|
|
793
|
+
labelEnabled: json.label_enabled === true || typeof json.label_enabled !== "boolean" && label.trim().length > 0,
|
|
794
|
+
label
|
|
795
|
+
};
|
|
796
|
+
}
|
|
797
|
+
function parseRefKeys(source) {
|
|
798
|
+
const eqref = /^\\eqref\{([^}]*)\}$/.exec(source.trim());
|
|
799
|
+
if (eqref) {
|
|
800
|
+
return {
|
|
801
|
+
refCommand: "eqref",
|
|
802
|
+
keys: (eqref[1] ?? "").split(",").map((key) => key.trim()).filter((key) => key.length > 0)
|
|
803
|
+
};
|
|
804
|
+
}
|
|
805
|
+
const ref = /^\\ref\{([^}]*)\}$/.exec(source.trim());
|
|
806
|
+
if (ref) {
|
|
807
|
+
return {
|
|
808
|
+
refCommand: "ref",
|
|
809
|
+
keys: (ref[1] ?? "").split(",").map((key) => key.trim()).filter((key) => key.length > 0)
|
|
810
|
+
};
|
|
811
|
+
}
|
|
812
|
+
return { keys: [], refCommand: "ref" };
|
|
813
|
+
}
|
|
814
|
+
function refTokenLatex(keys, refCommand) {
|
|
815
|
+
const command = refCommand === "eqref" ? "\\eqref" : "\\ref";
|
|
816
|
+
return `${command}{${keys.join(",")}}`;
|
|
817
|
+
}
|
|
818
|
+
function collectDocument2Labels(document2) {
|
|
819
|
+
const entries = [];
|
|
820
|
+
const counters = { fig: 0, tab: 0, eq: 0 };
|
|
821
|
+
function pushEqFromField(tokens) {
|
|
822
|
+
for (const token of tokens) {
|
|
823
|
+
if (token.kind !== "math") {
|
|
824
|
+
continue;
|
|
825
|
+
}
|
|
826
|
+
if (token.display && token.labelEnabled && token.label && token.label.trim().length > 0) {
|
|
827
|
+
counters.eq += 1;
|
|
828
|
+
entries.push({
|
|
829
|
+
key: token.label.trim(),
|
|
830
|
+
kind: "eq",
|
|
831
|
+
caption: "",
|
|
832
|
+
ownerId: token.id,
|
|
833
|
+
number: counters.eq
|
|
834
|
+
});
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
function walk(blocks) {
|
|
839
|
+
for (const block of blocks) {
|
|
840
|
+
if (block.kind === "image" && block.labelEnabled && block.label.trim().length > 0) {
|
|
841
|
+
counters.fig += 1;
|
|
842
|
+
entries.push({
|
|
843
|
+
key: block.label.trim(),
|
|
844
|
+
kind: "fig",
|
|
845
|
+
caption: block.captionEnabled ? block.caption : "",
|
|
846
|
+
ownerId: block.id,
|
|
847
|
+
number: counters.fig
|
|
848
|
+
});
|
|
849
|
+
}
|
|
850
|
+
if (block.kind === "table") {
|
|
851
|
+
if (block.labelEnabled && block.label.trim().length > 0) {
|
|
852
|
+
counters.tab += 1;
|
|
853
|
+
entries.push({
|
|
854
|
+
key: block.label.trim(),
|
|
855
|
+
kind: "tab",
|
|
856
|
+
caption: block.captionEnabled ? block.caption : "",
|
|
857
|
+
ownerId: block.id,
|
|
858
|
+
number: counters.tab
|
|
859
|
+
});
|
|
860
|
+
}
|
|
861
|
+
for (const row of block.rows) {
|
|
862
|
+
for (const cell of row) {
|
|
863
|
+
pushEqFromField(cell.tokens);
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
if (block.kind === "textBlock") {
|
|
868
|
+
pushEqFromField(block.field.tokens);
|
|
869
|
+
}
|
|
870
|
+
if (block.kind === "list") {
|
|
871
|
+
for (const item of block.items) {
|
|
872
|
+
pushEqFromField(item.field.tokens);
|
|
873
|
+
walk(item.blocks);
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
walk(document2.blocks);
|
|
879
|
+
return entries;
|
|
880
|
+
}
|
|
881
|
+
function labelNumberMap(document2) {
|
|
882
|
+
const map = /* @__PURE__ */ new Map();
|
|
883
|
+
for (const entry of collectDocument2Labels(document2)) {
|
|
884
|
+
if (!map.has(entry.key)) {
|
|
885
|
+
map.set(entry.key, { kind: entry.kind, number: entry.number });
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
return map;
|
|
889
|
+
}
|
|
890
|
+
function formatRefLabel(keys, document2, refCommand, options = {}) {
|
|
891
|
+
const documentDirection = options.documentDirection ?? "rtl";
|
|
892
|
+
const digitForm = options.digitForm ?? (documentDirection === "rtl" ? "arabicIndic" : "western");
|
|
893
|
+
const map = labelNumberMap(document2);
|
|
894
|
+
const parts = keys.map((key) => {
|
|
895
|
+
const hit = map.get(key);
|
|
896
|
+
if (!hit) {
|
|
897
|
+
return "?";
|
|
898
|
+
}
|
|
899
|
+
return formatDigits(String(hit.number), digitForm);
|
|
900
|
+
});
|
|
901
|
+
const body = parts.join(documentDirection === "rtl" ? "\u060C" : ", ");
|
|
902
|
+
if (refCommand === "eqref") {
|
|
903
|
+
return `(${body})`;
|
|
904
|
+
}
|
|
905
|
+
return body;
|
|
906
|
+
}
|
|
907
|
+
function stripDisplayMathDelimiters(source) {
|
|
908
|
+
const trimmed = source.trim();
|
|
909
|
+
if (trimmed.startsWith("\\[") && trimmed.endsWith("\\]")) {
|
|
910
|
+
return trimmed.slice(2, -2).trim();
|
|
911
|
+
}
|
|
912
|
+
if (trimmed.startsWith("$$") && trimmed.endsWith("$$")) {
|
|
913
|
+
return trimmed.slice(2, -2).trim();
|
|
914
|
+
}
|
|
915
|
+
if (trimmed.startsWith("\\begin{equation}") && trimmed.endsWith("\\end{equation}")) {
|
|
916
|
+
return trimmed.slice("\\begin{equation}".length, -"\\end{equation}".length).trim();
|
|
917
|
+
}
|
|
918
|
+
return trimmed;
|
|
919
|
+
}
|
|
920
|
+
function applyFloatMetaPatch(block, patch) {
|
|
921
|
+
if (typeof patch.centered === "boolean") {
|
|
922
|
+
block.centered = patch.centered;
|
|
923
|
+
}
|
|
924
|
+
if (typeof patch.captionEnabled === "boolean") {
|
|
925
|
+
block.captionEnabled = patch.captionEnabled;
|
|
926
|
+
}
|
|
927
|
+
if (typeof patch.caption === "string") {
|
|
928
|
+
block.caption = patch.caption;
|
|
929
|
+
}
|
|
930
|
+
if (typeof patch.labelEnabled === "boolean") {
|
|
931
|
+
block.labelEnabled = patch.labelEnabled;
|
|
932
|
+
}
|
|
933
|
+
if (typeof patch.label === "string") {
|
|
934
|
+
block.label = patch.label;
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
|
|
443
938
|
// src/document2/inlineScanner.ts
|
|
444
939
|
var MATH_ENVIRONMENTS = /* @__PURE__ */ new Set([
|
|
445
940
|
"equation",
|
|
@@ -489,53 +984,127 @@ function environmentSpan(value, start) {
|
|
|
489
984
|
const end = closingStart + closing.length;
|
|
490
985
|
return { start, end, source: value.slice(start, end), opening, closing, display: true };
|
|
491
986
|
}
|
|
492
|
-
function
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
987
|
+
function citeSpan(value, start) {
|
|
988
|
+
if (!value.startsWith("\\cite{", start) || isEscaped(value, start)) {
|
|
989
|
+
return null;
|
|
990
|
+
}
|
|
991
|
+
const openBrace = start + "\\cite".length;
|
|
992
|
+
if (value[openBrace] !== "{") {
|
|
993
|
+
return null;
|
|
994
|
+
}
|
|
995
|
+
let depth = 0;
|
|
996
|
+
for (let i = openBrace; i < value.length; i += 1) {
|
|
997
|
+
const char = value[i];
|
|
998
|
+
if (char === "{" && !isEscaped(value, i)) {
|
|
999
|
+
depth += 1;
|
|
1000
|
+
continue;
|
|
503
1001
|
}
|
|
504
|
-
if (
|
|
505
|
-
|
|
506
|
-
if (
|
|
507
|
-
const end =
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
continue;
|
|
1002
|
+
if (char === "}" && !isEscaped(value, i)) {
|
|
1003
|
+
depth -= 1;
|
|
1004
|
+
if (depth === 0) {
|
|
1005
|
+
const end = i + 1;
|
|
1006
|
+
const source = value.slice(start, end);
|
|
1007
|
+
return { kind: "cite", start, end, source, keys: parseCiteKeys(source) };
|
|
511
1008
|
}
|
|
512
1009
|
}
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
1010
|
+
}
|
|
1011
|
+
return null;
|
|
1012
|
+
}
|
|
1013
|
+
function refSpan(value, start) {
|
|
1014
|
+
const eqrefPrefix = "\\eqref{";
|
|
1015
|
+
const refPrefix = "\\ref{";
|
|
1016
|
+
let refCommand = "ref";
|
|
1017
|
+
let prefix = refPrefix;
|
|
1018
|
+
if (value.startsWith(eqrefPrefix, start) && !isEscaped(value, start)) {
|
|
1019
|
+
refCommand = "eqref";
|
|
1020
|
+
prefix = eqrefPrefix;
|
|
1021
|
+
} else if (value.startsWith(refPrefix, start) && !isEscaped(value, start)) {
|
|
1022
|
+
refCommand = "ref";
|
|
1023
|
+
prefix = refPrefix;
|
|
1024
|
+
} else {
|
|
1025
|
+
return null;
|
|
1026
|
+
}
|
|
1027
|
+
const openBrace = start + prefix.length - 1;
|
|
1028
|
+
if (value[openBrace] !== "{") {
|
|
1029
|
+
return null;
|
|
1030
|
+
}
|
|
1031
|
+
let depth = 0;
|
|
1032
|
+
for (let i = openBrace; i < value.length; i += 1) {
|
|
1033
|
+
const char = value[i];
|
|
1034
|
+
if (char === "{" && !isEscaped(value, i)) {
|
|
1035
|
+
depth += 1;
|
|
1036
|
+
continue;
|
|
521
1037
|
}
|
|
522
|
-
if (
|
|
523
|
-
|
|
524
|
-
if (
|
|
525
|
-
const end =
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
1038
|
+
if (char === "}" && !isEscaped(value, i)) {
|
|
1039
|
+
depth -= 1;
|
|
1040
|
+
if (depth === 0) {
|
|
1041
|
+
const end = i + 1;
|
|
1042
|
+
const source = value.slice(start, end);
|
|
1043
|
+
const parsed = parseRefKeys(source);
|
|
1044
|
+
return { kind: "ref", start, end, source, keys: parsed.keys, refCommand };
|
|
529
1045
|
}
|
|
530
1046
|
}
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
1047
|
+
}
|
|
1048
|
+
return null;
|
|
1049
|
+
}
|
|
1050
|
+
function mathSpanAt(value, i) {
|
|
1051
|
+
if (value.startsWith("\\begin{", i)) {
|
|
1052
|
+
return environmentSpan(value, i);
|
|
1053
|
+
}
|
|
1054
|
+
if (value.startsWith("\\(", i)) {
|
|
1055
|
+
const close = value.indexOf("\\)", i + 2);
|
|
1056
|
+
if (close >= 0) {
|
|
1057
|
+
const end = close + 2;
|
|
1058
|
+
return { start: i, end, source: value.slice(i, end), opening: "\\(", closing: "\\)", display: false };
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
if (value.startsWith("\\[", i)) {
|
|
1062
|
+
const close = value.indexOf("\\]", i + 2);
|
|
1063
|
+
if (close >= 0) {
|
|
1064
|
+
const end = close + 2;
|
|
1065
|
+
return { start: i, end, source: value.slice(i, end), opening: "\\[", closing: "\\]", display: true };
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
if (value.startsWith("$$", i) && !isEscaped(value, i)) {
|
|
1069
|
+
const close = value.indexOf("$$", i + 2);
|
|
1070
|
+
if (close >= 0) {
|
|
1071
|
+
const end = close + 2;
|
|
1072
|
+
return { start: i, end, source: value.slice(i, end), opening: "$$", closing: "$$", display: true };
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
if (value[i] === "$" && !isEscaped(value, i)) {
|
|
1076
|
+
const close = findClosingDollar(value, i + 1);
|
|
1077
|
+
if (close >= 0) {
|
|
1078
|
+
const end = close + 1;
|
|
1079
|
+
return { start: i, end, source: value.slice(i, end), opening: "$", closing: "$", display: false };
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
return null;
|
|
1083
|
+
}
|
|
1084
|
+
function detectMathSpans2(value) {
|
|
1085
|
+
return detectInlineSpans2(value).filter((span) => span.kind === "math").map(({ kind: _kind, ...span }) => span);
|
|
1086
|
+
}
|
|
1087
|
+
function detectInlineSpans2(value) {
|
|
1088
|
+
const spans = [];
|
|
1089
|
+
let i = 0;
|
|
1090
|
+
while (i < value.length) {
|
|
1091
|
+
const cite = citeSpan(value, i);
|
|
1092
|
+
if (cite) {
|
|
1093
|
+
spans.push(cite);
|
|
1094
|
+
i = cite.end;
|
|
1095
|
+
continue;
|
|
1096
|
+
}
|
|
1097
|
+
const ref = refSpan(value, i);
|
|
1098
|
+
if (ref) {
|
|
1099
|
+
spans.push(ref);
|
|
1100
|
+
i = ref.end;
|
|
1101
|
+
continue;
|
|
1102
|
+
}
|
|
1103
|
+
const math = mathSpanAt(value, i);
|
|
1104
|
+
if (math) {
|
|
1105
|
+
spans.push({ kind: "math", ...math });
|
|
1106
|
+
i = math.end;
|
|
1107
|
+
continue;
|
|
539
1108
|
}
|
|
540
1109
|
i += 1;
|
|
541
1110
|
}
|
|
@@ -572,19 +1141,63 @@ function pushDiagnostic(diagnostics, options, path, message) {
|
|
|
572
1141
|
}
|
|
573
1142
|
diagnostics.push({ code: "math_alignment", message, path });
|
|
574
1143
|
}
|
|
1144
|
+
function parseReferences(json) {
|
|
1145
|
+
if (!Array.isArray(json)) {
|
|
1146
|
+
return [];
|
|
1147
|
+
}
|
|
1148
|
+
const references = [];
|
|
1149
|
+
for (const entry of json) {
|
|
1150
|
+
if (!isObject2(entry) || typeof entry.key !== "string" || entry.key.trim().length === 0) {
|
|
1151
|
+
continue;
|
|
1152
|
+
}
|
|
1153
|
+
references.push(
|
|
1154
|
+
referenceFromJson({
|
|
1155
|
+
key: entry.key.trim(),
|
|
1156
|
+
authors: typeof entry.authors === "string" ? entry.authors : void 0,
|
|
1157
|
+
title: typeof entry.title === "string" ? entry.title : void 0,
|
|
1158
|
+
year: typeof entry.year === "string" ? entry.year : void 0,
|
|
1159
|
+
url: typeof entry.url === "string" ? entry.url : void 0,
|
|
1160
|
+
venue: typeof entry.venue === "string" ? entry.venue : void 0
|
|
1161
|
+
})
|
|
1162
|
+
);
|
|
1163
|
+
}
|
|
1164
|
+
return references;
|
|
1165
|
+
}
|
|
575
1166
|
function createInlineField2(value = "", mathObjects = [], options = {}, path = "$", diagnostics = []) {
|
|
576
1167
|
const mode = options.mode ?? "english";
|
|
577
|
-
const spans =
|
|
1168
|
+
const spans = detectInlineSpans2(value);
|
|
1169
|
+
const mathSpans = spans.filter((span) => span.kind === "math");
|
|
578
1170
|
const tokens = [];
|
|
579
1171
|
let index = 0;
|
|
580
|
-
|
|
581
|
-
|
|
1172
|
+
let mathObjectIndex = 0;
|
|
1173
|
+
if (mathObjects.length > 0 && mathObjects.length !== mathSpans.length) {
|
|
1174
|
+
pushDiagnostic(diagnostics, options, path, `math_objects count mismatch: detected ${String(mathSpans.length)}, got ${String(mathObjects.length)}`);
|
|
582
1175
|
}
|
|
583
|
-
|
|
1176
|
+
for (const span of spans) {
|
|
584
1177
|
if (span.start > index) {
|
|
585
1178
|
tokens.push({ id: document2Id("text"), kind: "text", text: value.slice(index, span.start) });
|
|
586
1179
|
}
|
|
587
|
-
|
|
1180
|
+
if (span.kind === "cite") {
|
|
1181
|
+
tokens.push({
|
|
1182
|
+
id: document2Id("cite"),
|
|
1183
|
+
kind: "cite",
|
|
1184
|
+
keys: span.keys.length > 0 ? span.keys : []
|
|
1185
|
+
});
|
|
1186
|
+
index = span.end;
|
|
1187
|
+
continue;
|
|
1188
|
+
}
|
|
1189
|
+
if (span.kind === "ref") {
|
|
1190
|
+
tokens.push({
|
|
1191
|
+
id: document2Id("ref"),
|
|
1192
|
+
kind: "ref",
|
|
1193
|
+
keys: span.keys.length > 0 ? span.keys : [],
|
|
1194
|
+
refCommand: span.refCommand
|
|
1195
|
+
});
|
|
1196
|
+
index = span.end;
|
|
1197
|
+
continue;
|
|
1198
|
+
}
|
|
1199
|
+
const mathJson = mathObjects[mathObjectIndex];
|
|
1200
|
+
mathObjectIndex += 1;
|
|
588
1201
|
if (mathJson && (mathJson.math_mode !== span.opening || mathJson.closing !== span.closing)) {
|
|
589
1202
|
pushDiagnostic(diagnostics, options, path, "math_objects order mismatch");
|
|
590
1203
|
}
|
|
@@ -616,7 +1229,7 @@ function createInlineField2(value = "", mathObjects = [], options = {}, path = "
|
|
|
616
1229
|
});
|
|
617
1230
|
}
|
|
618
1231
|
index = span.end;
|
|
619
|
-
}
|
|
1232
|
+
}
|
|
620
1233
|
if (index < value.length || tokens.length === 0) {
|
|
621
1234
|
tokens.push({ id: document2Id("text"), kind: "text", text: value.slice(index) });
|
|
622
1235
|
}
|
|
@@ -631,7 +1244,8 @@ function parseTextBlock(json, options, path, diagnostics) {
|
|
|
631
1244
|
id: document2Id("block"),
|
|
632
1245
|
kind: "textBlock",
|
|
633
1246
|
command: json.command,
|
|
634
|
-
field: createInlineField2(value, json.math_objects ?? [], options, `${path}.value`, diagnostics)
|
|
1247
|
+
field: createInlineField2(value, json.math_objects ?? [], options, `${path}.value`, diagnostics),
|
|
1248
|
+
...json.centered === true ? { centered: true } : {}
|
|
635
1249
|
};
|
|
636
1250
|
}
|
|
637
1251
|
function parseListItem(json, options, path, diagnostics) {
|
|
@@ -684,16 +1298,21 @@ function parseTableBlock(json, options, path, diagnostics) {
|
|
|
684
1298
|
command: "\\begin{tabular}",
|
|
685
1299
|
closing: "\\end{tabular}",
|
|
686
1300
|
columns: typeof json.columns === "string" ? json.columns : "",
|
|
687
|
-
rows
|
|
1301
|
+
rows,
|
|
1302
|
+
...parseFloatMetaFromJson(json)
|
|
688
1303
|
};
|
|
689
1304
|
}
|
|
690
1305
|
function parseImageBlock(json) {
|
|
1306
|
+
const assetId = typeof json.asset_id === "string" && json.asset_id.length > 0 ? json.asset_id : void 0;
|
|
1307
|
+
const value = assetId !== void 0 ? typeof json.value === "string" ? json.value : "" : requireString(json.value, "\\includegraphics requires string value");
|
|
691
1308
|
return {
|
|
692
1309
|
id: document2Id("block"),
|
|
693
1310
|
kind: "image",
|
|
694
1311
|
command: "\\includegraphics",
|
|
695
|
-
value
|
|
696
|
-
|
|
1312
|
+
value,
|
|
1313
|
+
...assetId !== void 0 ? { assetId } : {},
|
|
1314
|
+
options: isRecordOfStrings(json.options) ? json.options : {},
|
|
1315
|
+
...parseFloatMetaFromJson(json)
|
|
697
1316
|
};
|
|
698
1317
|
}
|
|
699
1318
|
function parseRawBlock(json) {
|
|
@@ -704,6 +1323,14 @@ function parseRawBlock(json) {
|
|
|
704
1323
|
value: typeof json.value === "string" ? json.value : ""
|
|
705
1324
|
};
|
|
706
1325
|
}
|
|
1326
|
+
function parseBibliographyBlock() {
|
|
1327
|
+
return {
|
|
1328
|
+
id: document2Id("block"),
|
|
1329
|
+
kind: "bibliography",
|
|
1330
|
+
command: "\\begin{thebibliography}",
|
|
1331
|
+
closing: "\\end{thebibliography}"
|
|
1332
|
+
};
|
|
1333
|
+
}
|
|
707
1334
|
function parseBlock(json, options, path, diagnostics) {
|
|
708
1335
|
if (TEXT_COMMANDS.has(json.command)) {
|
|
709
1336
|
return parseTextBlock(json, options, path, diagnostics);
|
|
@@ -717,6 +1344,9 @@ function parseBlock(json, options, path, diagnostics) {
|
|
|
717
1344
|
if (json.command === "\\includegraphics") {
|
|
718
1345
|
return parseImageBlock(json);
|
|
719
1346
|
}
|
|
1347
|
+
if (json.command === "\\begin{thebibliography}" || json.command === "\\bibliography") {
|
|
1348
|
+
return parseBibliographyBlock();
|
|
1349
|
+
}
|
|
720
1350
|
if (json.command === "\\raw") {
|
|
721
1351
|
return parseRawBlock(json);
|
|
722
1352
|
}
|
|
@@ -737,12 +1367,20 @@ function fromDocumentJson2(json, options = {}) {
|
|
|
737
1367
|
const diagnostics = [];
|
|
738
1368
|
return {
|
|
739
1369
|
nodeType: "DocumentObject",
|
|
1370
|
+
meta: normalizeDocument2Meta(json.meta),
|
|
1371
|
+
references: parseReferences(json.references),
|
|
740
1372
|
blocks: json.blocks.map((block, index) => parseBlock(asBlockJson(block), options, `$.blocks[${String(index)}]`, diagnostics)),
|
|
741
1373
|
diagnostics
|
|
742
1374
|
};
|
|
743
1375
|
}
|
|
744
1376
|
function createEmptyDocument2() {
|
|
745
|
-
return {
|
|
1377
|
+
return {
|
|
1378
|
+
nodeType: "DocumentObject",
|
|
1379
|
+
meta: emptyDocument2Meta(),
|
|
1380
|
+
references: [],
|
|
1381
|
+
blocks: [],
|
|
1382
|
+
diagnostics: []
|
|
1383
|
+
};
|
|
746
1384
|
}
|
|
747
1385
|
|
|
748
1386
|
// src/editor/atomicCommands.ts
|
|
@@ -1765,34 +2403,6 @@ function renderDivideOperatorLatex(side) {
|
|
|
1765
2403
|
return side === "arabic" ? "\\backslash" : DIVIDE_OPERATOR_EN;
|
|
1766
2404
|
}
|
|
1767
2405
|
|
|
1768
|
-
// src/editor/digits.ts
|
|
1769
|
-
var WESTERN = "0123456789";
|
|
1770
|
-
var ARABIC_INDIC = "\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669";
|
|
1771
|
-
var PERSIAN_INDIC = "\u06F0\u06F1\u06F2\u06F3\u06F4\u06F5\u06F6\u06F7\u06F8\u06F9";
|
|
1772
|
-
var digitSets = {
|
|
1773
|
-
western: WESTERN,
|
|
1774
|
-
arabicIndic: ARABIC_INDIC,
|
|
1775
|
-
persianIndic: PERSIAN_INDIC
|
|
1776
|
-
};
|
|
1777
|
-
function digitValue(char) {
|
|
1778
|
-
const western = WESTERN.indexOf(char);
|
|
1779
|
-
if (western >= 0) {
|
|
1780
|
-
return western;
|
|
1781
|
-
}
|
|
1782
|
-
const arabicIndic = ARABIC_INDIC.indexOf(char);
|
|
1783
|
-
if (arabicIndic >= 0) {
|
|
1784
|
-
return arabicIndic;
|
|
1785
|
-
}
|
|
1786
|
-
return PERSIAN_INDIC.indexOf(char);
|
|
1787
|
-
}
|
|
1788
|
-
function formatDigits(value, digitForm = "western") {
|
|
1789
|
-
const target = digitSets[digitForm];
|
|
1790
|
-
return Array.from(value, (char) => {
|
|
1791
|
-
const value2 = digitValue(char);
|
|
1792
|
-
return value2 >= 0 ? target[value2] : char;
|
|
1793
|
-
}).join("");
|
|
1794
|
-
}
|
|
1795
|
-
|
|
1796
2406
|
// src/editor/render.ts
|
|
1797
2407
|
function selectedDigitForm(options) {
|
|
1798
2408
|
return options?.digitForm ?? "western";
|
|
@@ -3125,6 +3735,8 @@ function cloneBlock(block) {
|
|
|
3125
3735
|
function cloneDocument(document2) {
|
|
3126
3736
|
return {
|
|
3127
3737
|
nodeType: "DocumentObject",
|
|
3738
|
+
meta: cloneDocument2Meta(document2.meta ?? emptyDocument2Meta()),
|
|
3739
|
+
references: document2.references.map((reference) => ({ ...reference })),
|
|
3128
3740
|
blocks: document2.blocks.map(cloneBlock),
|
|
3129
3741
|
diagnostics: document2.diagnostics.map((diagnostic) => ({ ...diagnostic }))
|
|
3130
3742
|
};
|
|
@@ -3234,6 +3846,29 @@ function moveDocument2BlockById(document2, blockId, direction) {
|
|
|
3234
3846
|
next.blocks.splice(targetIndex, 0, block);
|
|
3235
3847
|
return next;
|
|
3236
3848
|
}
|
|
3849
|
+
function moveDocument2BlockRange(document2, from, to, direction) {
|
|
3850
|
+
const count = document2.blocks.length;
|
|
3851
|
+
if (from < 0 || to < 0 || from >= count || to >= count || from > to) {
|
|
3852
|
+
return document2;
|
|
3853
|
+
}
|
|
3854
|
+
const insertAt = from + direction;
|
|
3855
|
+
if (insertAt < 0 || to + direction >= count) {
|
|
3856
|
+
return document2;
|
|
3857
|
+
}
|
|
3858
|
+
const next = cloneDocument(document2);
|
|
3859
|
+
const slice = next.blocks.splice(from, to - from + 1);
|
|
3860
|
+
next.blocks.splice(insertAt, 0, ...slice);
|
|
3861
|
+
return next;
|
|
3862
|
+
}
|
|
3863
|
+
function removeDocument2BlockRange(document2, from, to) {
|
|
3864
|
+
const count = document2.blocks.length;
|
|
3865
|
+
if (from < 0 || to < 0 || from >= count || to >= count || from > to) {
|
|
3866
|
+
return document2;
|
|
3867
|
+
}
|
|
3868
|
+
const next = cloneDocument(document2);
|
|
3869
|
+
next.blocks = [...next.blocks.slice(0, from), ...next.blocks.slice(to + 1)];
|
|
3870
|
+
return next;
|
|
3871
|
+
}
|
|
3237
3872
|
function normalizeFieldTokens(tokens) {
|
|
3238
3873
|
if (tokens.length === 0) {
|
|
3239
3874
|
return [{ id: document2Id("text"), kind: "text", text: "" }];
|
|
@@ -3328,16 +3963,50 @@ function replaceMathTokenFromSession(document2, tokenId, session, opening, closi
|
|
|
3328
3963
|
const current = field.tokens[index];
|
|
3329
3964
|
const open = opening ?? current.opening;
|
|
3330
3965
|
const close = closing ?? current.closing;
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3966
|
+
const replaced = mathTokenFromSession(session, open, close, side);
|
|
3967
|
+
replaced.id = current.id;
|
|
3968
|
+
if (current.labelEnabled !== void 0) {
|
|
3969
|
+
replaced.labelEnabled = current.labelEnabled;
|
|
3970
|
+
}
|
|
3971
|
+
if (current.label !== void 0) {
|
|
3972
|
+
replaced.label = current.label;
|
|
3973
|
+
}
|
|
3974
|
+
field.tokens[index] = replaced;
|
|
3975
|
+
return true;
|
|
3334
3976
|
});
|
|
3335
3977
|
return next;
|
|
3336
3978
|
}
|
|
3337
3979
|
function addDocument2TextBlock(document2, command = "\\paragraph", afterBlockId) {
|
|
3338
|
-
const block = {
|
|
3980
|
+
const block = {
|
|
3981
|
+
id: document2Id("block"),
|
|
3982
|
+
kind: "textBlock",
|
|
3983
|
+
command,
|
|
3984
|
+
field: createInlineField2(""),
|
|
3985
|
+
...command === "\\paragraph" ? { centered: false } : {}
|
|
3986
|
+
};
|
|
3339
3987
|
return insertDocument2BlockAfter(document2, afterBlockId, block);
|
|
3340
3988
|
}
|
|
3989
|
+
function updateDocument2TextBlockCentered(document2, blockId, centered) {
|
|
3990
|
+
const next = cloneDocument(document2);
|
|
3991
|
+
function visit(blocks) {
|
|
3992
|
+
for (const block of blocks) {
|
|
3993
|
+
if (block.id === blockId && block.kind === "textBlock" && block.command === "\\paragraph") {
|
|
3994
|
+
block.centered = centered;
|
|
3995
|
+
return true;
|
|
3996
|
+
}
|
|
3997
|
+
if (block.kind === "list") {
|
|
3998
|
+
for (const item of block.items) {
|
|
3999
|
+
if (visit(item.blocks)) {
|
|
4000
|
+
return true;
|
|
4001
|
+
}
|
|
4002
|
+
}
|
|
4003
|
+
}
|
|
4004
|
+
}
|
|
4005
|
+
return false;
|
|
4006
|
+
}
|
|
4007
|
+
visit(next.blocks);
|
|
4008
|
+
return next;
|
|
4009
|
+
}
|
|
3341
4010
|
function removeDocument2BlockById(document2, blockId) {
|
|
3342
4011
|
const next = cloneDocument(document2);
|
|
3343
4012
|
next.blocks = next.blocks.filter((block) => block.id !== blockId);
|
|
@@ -3374,7 +4043,8 @@ function addDocument2TableBlock(document2, columns = "lll", rowCount = 3, colCou
|
|
|
3374
4043
|
command: "\\begin{tabular}",
|
|
3375
4044
|
closing: "\\end{tabular}",
|
|
3376
4045
|
columns: columns || "l".repeat(cols),
|
|
3377
|
-
rows: tableRows
|
|
4046
|
+
rows: tableRows,
|
|
4047
|
+
...defaultFloatMeta()
|
|
3378
4048
|
};
|
|
3379
4049
|
return insertDocument2BlockAfter(document2, afterBlockId, block);
|
|
3380
4050
|
}
|
|
@@ -3384,7 +4054,8 @@ function addDocument2ImageBlock(document2, src = "", afterBlockId) {
|
|
|
3384
4054
|
kind: "image",
|
|
3385
4055
|
command: "\\includegraphics",
|
|
3386
4056
|
value: src,
|
|
3387
|
-
options: {}
|
|
4057
|
+
options: { width: "0.8\\textwidth" },
|
|
4058
|
+
...defaultFloatMeta()
|
|
3388
4059
|
};
|
|
3389
4060
|
return insertDocument2BlockAfter(document2, afterBlockId, block);
|
|
3390
4061
|
}
|
|
@@ -3409,6 +4080,128 @@ function updateDocument2ImageValue(document2, blockId, value) {
|
|
|
3409
4080
|
visit(next.blocks);
|
|
3410
4081
|
return next;
|
|
3411
4082
|
}
|
|
4083
|
+
function updateDocument2ImageMeta(document2, blockId, patch) {
|
|
4084
|
+
const next = cloneDocument(document2);
|
|
4085
|
+
function visit(blocks) {
|
|
4086
|
+
for (const block of blocks) {
|
|
4087
|
+
if (block.id === blockId && block.kind === "image") {
|
|
4088
|
+
applyFloatMetaPatch(block, patch);
|
|
4089
|
+
return true;
|
|
4090
|
+
}
|
|
4091
|
+
if (block.kind === "list") {
|
|
4092
|
+
for (const item of block.items) {
|
|
4093
|
+
if (visit(item.blocks)) {
|
|
4094
|
+
return true;
|
|
4095
|
+
}
|
|
4096
|
+
}
|
|
4097
|
+
}
|
|
4098
|
+
}
|
|
4099
|
+
return false;
|
|
4100
|
+
}
|
|
4101
|
+
visit(next.blocks);
|
|
4102
|
+
return next;
|
|
4103
|
+
}
|
|
4104
|
+
function updateDocument2TableMeta(document2, blockId, patch) {
|
|
4105
|
+
const next = cloneDocument(document2);
|
|
4106
|
+
function visit(blocks) {
|
|
4107
|
+
for (const block of blocks) {
|
|
4108
|
+
if (block.id === blockId && block.kind === "table") {
|
|
4109
|
+
applyFloatMetaPatch(block, patch);
|
|
4110
|
+
return true;
|
|
4111
|
+
}
|
|
4112
|
+
if (block.kind === "list") {
|
|
4113
|
+
for (const item of block.items) {
|
|
4114
|
+
if (visit(item.blocks)) {
|
|
4115
|
+
return true;
|
|
4116
|
+
}
|
|
4117
|
+
}
|
|
4118
|
+
}
|
|
4119
|
+
}
|
|
4120
|
+
return false;
|
|
4121
|
+
}
|
|
4122
|
+
visit(next.blocks);
|
|
4123
|
+
return next;
|
|
4124
|
+
}
|
|
4125
|
+
function updateMathTokenLabel(document2, tokenId, patch) {
|
|
4126
|
+
const next = cloneDocument(document2);
|
|
4127
|
+
visitFields(next.blocks, (field) => {
|
|
4128
|
+
const token = field.tokens.find((entry) => entry.id === tokenId && entry.kind === "math");
|
|
4129
|
+
if (!token) {
|
|
4130
|
+
return false;
|
|
4131
|
+
}
|
|
4132
|
+
if (typeof patch.labelEnabled === "boolean") {
|
|
4133
|
+
token.labelEnabled = patch.labelEnabled;
|
|
4134
|
+
}
|
|
4135
|
+
if (typeof patch.label === "string") {
|
|
4136
|
+
token.label = patch.label;
|
|
4137
|
+
}
|
|
4138
|
+
return true;
|
|
4139
|
+
});
|
|
4140
|
+
return next;
|
|
4141
|
+
}
|
|
4142
|
+
function refTokenFromKeys(keys, refCommand) {
|
|
4143
|
+
return { id: document2Id("ref"), kind: "ref", keys: [...keys], refCommand };
|
|
4144
|
+
}
|
|
4145
|
+
function insertRefTokenAtCaret(document2, fieldId, textTokenId, caretOffset, keys, refCommand = "ref") {
|
|
4146
|
+
if (keys.length === 0) {
|
|
4147
|
+
return document2;
|
|
4148
|
+
}
|
|
4149
|
+
const next = cloneDocument(document2);
|
|
4150
|
+
const refToken = refTokenFromKeys(keys, refCommand);
|
|
4151
|
+
visitFields(next.blocks, (field) => {
|
|
4152
|
+
if (field.id !== fieldId) {
|
|
4153
|
+
return false;
|
|
4154
|
+
}
|
|
4155
|
+
const textIndex = textTokenId ? field.tokens.findIndex((token) => token.id === textTokenId && token.kind === "text") : field.tokens.findIndex((token) => token.kind === "text");
|
|
4156
|
+
if (textIndex < 0) {
|
|
4157
|
+
field.tokens.push(refToken);
|
|
4158
|
+
field.tokens.push({ id: document2Id("text"), kind: "text", text: "" });
|
|
4159
|
+
return true;
|
|
4160
|
+
}
|
|
4161
|
+
const current = field.tokens[textIndex];
|
|
4162
|
+
const [before, after] = splitTextTokenAt(current, caretOffset);
|
|
4163
|
+
const parts = [...field.tokens.slice(0, textIndex)];
|
|
4164
|
+
if (before.text.length > 0) {
|
|
4165
|
+
parts.push(before);
|
|
4166
|
+
}
|
|
4167
|
+
parts.push(refToken);
|
|
4168
|
+
parts.push(after);
|
|
4169
|
+
parts.push(...field.tokens.slice(textIndex + 1));
|
|
4170
|
+
field.tokens = normalizeFieldTokens(parts);
|
|
4171
|
+
return true;
|
|
4172
|
+
});
|
|
4173
|
+
return next;
|
|
4174
|
+
}
|
|
4175
|
+
function updateRefTokenKeys(document2, tokenId, keys, refCommand) {
|
|
4176
|
+
if (keys.length === 0) {
|
|
4177
|
+
return document2;
|
|
4178
|
+
}
|
|
4179
|
+
const next = cloneDocument(document2);
|
|
4180
|
+
visitFields(next.blocks, (field) => {
|
|
4181
|
+
const token = field.tokens.find((entry) => entry.id === tokenId && entry.kind === "ref");
|
|
4182
|
+
if (!token) {
|
|
4183
|
+
return false;
|
|
4184
|
+
}
|
|
4185
|
+
token.keys = [...keys];
|
|
4186
|
+
if (refCommand) {
|
|
4187
|
+
token.refCommand = refCommand;
|
|
4188
|
+
}
|
|
4189
|
+
return true;
|
|
4190
|
+
});
|
|
4191
|
+
return next;
|
|
4192
|
+
}
|
|
4193
|
+
function removeRefTokenById(document2, tokenId) {
|
|
4194
|
+
const next = cloneDocument(document2);
|
|
4195
|
+
visitFields(next.blocks, (field) => {
|
|
4196
|
+
const index = field.tokens.findIndex((token) => token.id === tokenId && token.kind === "ref");
|
|
4197
|
+
if (index < 0) {
|
|
4198
|
+
return false;
|
|
4199
|
+
}
|
|
4200
|
+
field.tokens = normalizeFieldTokens(stitchTextAroundRemovedToken(field.tokens, index));
|
|
4201
|
+
return true;
|
|
4202
|
+
});
|
|
4203
|
+
return next;
|
|
4204
|
+
}
|
|
3412
4205
|
function mutateListBlockById(blocks, listBlockId, mutator) {
|
|
3413
4206
|
for (const block of blocks) {
|
|
3414
4207
|
if (block.id === listBlockId && block.kind === "list") {
|
|
@@ -3445,12 +4238,372 @@ function removeDocument2ListItem(document2, listBlockId, itemId) {
|
|
|
3445
4238
|
});
|
|
3446
4239
|
return next;
|
|
3447
4240
|
}
|
|
4241
|
+
function citeTokenFromKeys(keys) {
|
|
4242
|
+
return { id: document2Id("cite"), kind: "cite", keys: [...keys] };
|
|
4243
|
+
}
|
|
4244
|
+
function insertCiteTokenAtCaret(document2, fieldId, textTokenId, caretOffset, keys) {
|
|
4245
|
+
if (keys.length === 0) {
|
|
4246
|
+
return document2;
|
|
4247
|
+
}
|
|
4248
|
+
const next = cloneDocument(document2);
|
|
4249
|
+
const citeToken = citeTokenFromKeys(keys);
|
|
4250
|
+
visitFields(next.blocks, (field) => {
|
|
4251
|
+
if (field.id !== fieldId) {
|
|
4252
|
+
return false;
|
|
4253
|
+
}
|
|
4254
|
+
const textIndex = textTokenId ? field.tokens.findIndex((token) => token.id === textTokenId && token.kind === "text") : field.tokens.findIndex((token) => token.kind === "text");
|
|
4255
|
+
if (textIndex < 0) {
|
|
4256
|
+
field.tokens.push(citeToken);
|
|
4257
|
+
field.tokens.push({ id: document2Id("text"), kind: "text", text: "" });
|
|
4258
|
+
return true;
|
|
4259
|
+
}
|
|
4260
|
+
const current = field.tokens[textIndex];
|
|
4261
|
+
const [before, after] = splitTextTokenAt(current, caretOffset);
|
|
4262
|
+
const parts = [...field.tokens.slice(0, textIndex)];
|
|
4263
|
+
if (before.text.length > 0) {
|
|
4264
|
+
parts.push(before);
|
|
4265
|
+
}
|
|
4266
|
+
parts.push(citeToken);
|
|
4267
|
+
parts.push(after);
|
|
4268
|
+
parts.push(...field.tokens.slice(textIndex + 1));
|
|
4269
|
+
field.tokens = normalizeFieldTokens(parts);
|
|
4270
|
+
return true;
|
|
4271
|
+
});
|
|
4272
|
+
return next;
|
|
4273
|
+
}
|
|
4274
|
+
function updateCiteTokenKeys(document2, tokenId, keys) {
|
|
4275
|
+
if (keys.length === 0) {
|
|
4276
|
+
return document2;
|
|
4277
|
+
}
|
|
4278
|
+
const next = cloneDocument(document2);
|
|
4279
|
+
visitFields(next.blocks, (field) => {
|
|
4280
|
+
const token = field.tokens.find((entry) => entry.id === tokenId && entry.kind === "cite");
|
|
4281
|
+
if (!token) {
|
|
4282
|
+
return false;
|
|
4283
|
+
}
|
|
4284
|
+
token.keys = [...keys];
|
|
4285
|
+
return true;
|
|
4286
|
+
});
|
|
4287
|
+
return next;
|
|
4288
|
+
}
|
|
4289
|
+
function removeCiteTokenById(document2, tokenId) {
|
|
4290
|
+
const next = cloneDocument(document2);
|
|
4291
|
+
visitFields(next.blocks, (field) => {
|
|
4292
|
+
const index = field.tokens.findIndex((token) => token.id === tokenId && token.kind === "cite");
|
|
4293
|
+
if (index < 0) {
|
|
4294
|
+
return false;
|
|
4295
|
+
}
|
|
4296
|
+
field.tokens = normalizeFieldTokens(stitchTextAroundRemovedToken(field.tokens, index));
|
|
4297
|
+
return true;
|
|
4298
|
+
});
|
|
4299
|
+
return next;
|
|
4300
|
+
}
|
|
4301
|
+
function ensureDocument2BibliographyBlock(document2, afterBlockId) {
|
|
4302
|
+
if (document2.blocks.some((block2) => block2.kind === "bibliography")) {
|
|
4303
|
+
return document2;
|
|
4304
|
+
}
|
|
4305
|
+
const block = {
|
|
4306
|
+
id: document2Id("block"),
|
|
4307
|
+
kind: "bibliography",
|
|
4308
|
+
command: "\\begin{thebibliography}",
|
|
4309
|
+
closing: "\\end{thebibliography}"
|
|
4310
|
+
};
|
|
4311
|
+
return insertDocument2BlockAfter(document2, afterBlockId ?? null, block);
|
|
4312
|
+
}
|
|
4313
|
+
function addDocument2Reference(document2, partial = {}) {
|
|
4314
|
+
const next = cloneDocument(document2);
|
|
4315
|
+
next.references.push(createEmptyReference2(partial));
|
|
4316
|
+
return next;
|
|
4317
|
+
}
|
|
4318
|
+
function updateDocument2Reference(document2, referenceId, patch) {
|
|
4319
|
+
const next = cloneDocument(document2);
|
|
4320
|
+
const reference = next.references.find((entry) => entry.id === referenceId);
|
|
4321
|
+
if (!reference) {
|
|
4322
|
+
return document2;
|
|
4323
|
+
}
|
|
4324
|
+
if (typeof patch.key === "string" && patch.key.trim().length > 0) {
|
|
4325
|
+
reference.key = patch.key.trim();
|
|
4326
|
+
}
|
|
4327
|
+
if (typeof patch.authors === "string") {
|
|
4328
|
+
reference.authors = patch.authors;
|
|
4329
|
+
}
|
|
4330
|
+
if (typeof patch.title === "string") {
|
|
4331
|
+
reference.title = patch.title;
|
|
4332
|
+
}
|
|
4333
|
+
if (typeof patch.year === "string") {
|
|
4334
|
+
reference.year = patch.year;
|
|
4335
|
+
}
|
|
4336
|
+
if (typeof patch.url === "string") {
|
|
4337
|
+
reference.url = patch.url;
|
|
4338
|
+
}
|
|
4339
|
+
if (typeof patch.venue === "string") {
|
|
4340
|
+
reference.venue = patch.venue;
|
|
4341
|
+
}
|
|
4342
|
+
return next;
|
|
4343
|
+
}
|
|
4344
|
+
function removeDocument2Reference(document2, referenceId) {
|
|
4345
|
+
const next = cloneDocument(document2);
|
|
4346
|
+
next.references = next.references.filter((reference) => reference.id !== referenceId);
|
|
4347
|
+
return next;
|
|
4348
|
+
}
|
|
4349
|
+
function moveDocument2Reference(document2, referenceId, direction) {
|
|
4350
|
+
const next = cloneDocument(document2);
|
|
4351
|
+
const index = next.references.findIndex((reference2) => reference2.id === referenceId);
|
|
4352
|
+
const targetIndex = index + direction;
|
|
4353
|
+
if (index < 0 || targetIndex < 0 || targetIndex >= next.references.length) {
|
|
4354
|
+
return document2;
|
|
4355
|
+
}
|
|
4356
|
+
const [reference] = next.references.splice(index, 1);
|
|
4357
|
+
if (!reference) {
|
|
4358
|
+
return document2;
|
|
4359
|
+
}
|
|
4360
|
+
next.references.splice(targetIndex, 0, reference);
|
|
4361
|
+
return next;
|
|
4362
|
+
}
|
|
4363
|
+
function setDocument2References(document2, references) {
|
|
4364
|
+
const next = cloneDocument(document2);
|
|
4365
|
+
next.references = references.map((reference) => ({ ...reference }));
|
|
4366
|
+
return next;
|
|
4367
|
+
}
|
|
4368
|
+
function updateDocument2Meta(document2, patch) {
|
|
4369
|
+
const next = cloneDocument(document2);
|
|
4370
|
+
const current = next.meta ?? emptyDocument2Meta();
|
|
4371
|
+
next.meta = {
|
|
4372
|
+
title: typeof patch.title === "string" ? patch.title : current.title,
|
|
4373
|
+
authors: typeof patch.authors === "string" ? patch.authors : current.authors,
|
|
4374
|
+
abstract: typeof patch.abstract === "string" ? patch.abstract : current.abstract,
|
|
4375
|
+
date: patch.date ? normalizeDocument2HijriDate({ ...current.date, ...patch.date }) : { ...current.date }
|
|
4376
|
+
};
|
|
4377
|
+
return next;
|
|
4378
|
+
}
|
|
4379
|
+
|
|
4380
|
+
// src/document2/arabicPreamble.ts
|
|
4381
|
+
function arabicXeLatexPreamblePkg(twocolumn = false) {
|
|
4382
|
+
const classOptions = twocolumn ? "12pt,a4paper,twocolumn" : "12pt,a4paper";
|
|
4383
|
+
return `
|
|
4384
|
+
\\documentclass[${classOptions}]{article}
|
|
4385
|
+
` + String.raw`\usepackage{amsmath,amsfonts,amssymb,mathrsfs,tikz,fancyhdr, mathtools}
|
|
4386
|
+
\usepackage{fontspec} % For loading OpenType fonts
|
|
4387
|
+
\usepackage{unicode-math} % For setting the math font
|
|
4388
|
+
\usepackage{polyglossia} % For Arabic support
|
|
4389
|
+
\usepackage{array}
|
|
4390
|
+
\usepackage{cancel}
|
|
4391
|
+
\usepackage{bidi} % For bidirectional text handling
|
|
4392
|
+
\usepackage{multirow}
|
|
4393
|
+
\usepackage{booktabs}
|
|
4394
|
+
\usepackage{graphicx} % For \reflectbox
|
|
4395
|
+
\usepackage{xcolor}
|
|
4396
|
+
\usepackage{tikz}
|
|
4397
|
+
\usepackage{tcolorbox} % For tcolorbox environment
|
|
4398
|
+
\usepackage{textcomp} % For \textrightarrow command
|
|
4399
|
+
|
|
4400
|
+
|
|
4401
|
+
% visit : https://www.symbolcopy.com/punctuation-symbol.html
|
|
4402
|
+
% for inversed punctuation
|
|
4403
|
+
|
|
4404
|
+
% save inverted comma for use - copy paste -> ،
|
|
4405
|
+
% save back tick for use - copy paste -> ` + "`";
|
|
4406
|
+
}
|
|
4407
|
+
function arabicXeLatexPreambleFont(digitsMapping = "arabicdigits") {
|
|
4408
|
+
return `
|
|
4409
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4410
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4411
|
+
% Toggle between eastern and western digits by changing the Mapping in the below fonts (inside math font as well) between "arabicdigits" and "digits"
|
|
4412
|
+
\\setdefaultlanguage[calendar=gregorian]{arabic} % from polyglossia
|
|
4413
|
+
\\setmainfont[Script=Arabic , Mapping=${digitsMapping}]{Amiri}
|
|
4414
|
+
\\newfontfamily\\diwani[Script=Arabic,Mapping=${digitsMapping}]{Diwani Letter}
|
|
4415
|
+
\\newfontfamily\\diwanioutlineshaded[Script=Arabic,Mapping=${digitsMapping}]{Diwani Outline Shaded}
|
|
4416
|
+
\\newfontfamily\\takween[Script=Arabic,Mapping=${digitsMapping}]{Takween}
|
|
4417
|
+
\\newfontfamily\\boldarabic[Script=Arabic,Mapping=${digitsMapping}]{Amiri Bold}
|
|
4418
|
+
\\newfontfamily\\italicarabic[Script=Arabic,Mapping=${digitsMapping}]{Amiri Italic}
|
|
4419
|
+
|
|
4420
|
+
% Explicitly set math font to XITS Math
|
|
4421
|
+
% Remove "Script=Arabic" to cancel reflected symbols and other RTL symbols
|
|
4422
|
+
\\setmathfont[Script=Arabic , Mapping=${digitsMapping}]{XITS Math} % Ensure XITS Math is correctly installed and available
|
|
4423
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4424
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4425
|
+
`;
|
|
4426
|
+
}
|
|
4427
|
+
function arabicXeLatexPreambleCmd() {
|
|
4428
|
+
return String.raw`
|
|
4429
|
+
% Run with XeLaTeX compiler
|
|
4430
|
+
\newcommand{\butextakween}[1]{\text{\takween{#1}}}
|
|
4431
|
+
\newcommand{\butexdiwani}[1]{\text{\diwani{#1}}}
|
|
4432
|
+
\newcommand{\butexdiwanioutline}[1]{\text{\diwanioutlineshaded{#1}}}
|
|
4433
|
+
|
|
4434
|
+
\newcommand{\arabN}{\text{\diwanioutlineshaded{ط}}}
|
|
4435
|
+
\newcommand{\arabZ}{\text{\diwanioutlineshaded{ص}}}
|
|
4436
|
+
\newcommand{\arabQ}{\text{\diwanioutlineshaded{ن}}}
|
|
4437
|
+
\newcommand{\arabR}{\text{\diwanioutlineshaded{ح}}}
|
|
4438
|
+
\newcommand{\arabC}{\text{\diwanioutlineshaded{ع}}}
|
|
4439
|
+
\newcommand{\arabH}{\text{\diwanioutlineshaded{ر}}}
|
|
4440
|
+
|
|
4441
|
+
|
|
4442
|
+
\newcommand{\lowerscript}[1]{\raisebox{-4pt}{\scriptsize #1}}
|
|
4443
|
+
\newcommand{\llowerscript}[1]{\raisebox{-8pt}{\scriptsize #1}}
|
|
4444
|
+
\newcommand{\lllowerscript}[2]{\raisebox{#2pt}{\scriptsize #1}}
|
|
4445
|
+
|
|
4446
|
+
\newcommand{\arabdsub}[3]{\prescript{}{#1}{\prescript{}{#2}{#3}}} % arabic double subscript
|
|
4447
|
+
\newcommand{\arabsub}[2]{\prescript{}{#1}{#2}} % arabic single subscript
|
|
4448
|
+
|
|
4449
|
+
|
|
4450
|
+
|
|
4451
|
+
\newcommand{\upperscript}[1]{\raisebox{8pt}{\scriptsize #1}}
|
|
4452
|
+
\newcommand{\uupperscript}[2]{\raisebox{#2pt}{\scriptsize #1}}
|
|
4453
|
+
\newcommand{\vertbar}{\rule[-1ex]{0.5pt}{2.5ex}}
|
|
4454
|
+
\newcommand{\horzbar}{\rule[.5ex]{2.5ex}{0.5pt}}
|
|
4455
|
+
|
|
4456
|
+
\newcommand{\arabsqrt}[2]{\reflectbox{\(\sqrt[\reflectbox{\(#1\)}]{\reflectbox{\(#2\)}}\)}}
|
|
4457
|
+
\newcommand{\arabvec}[1]{\reflectbox{$\vec{\reflectbox{$#1$}}$}}
|
|
4458
|
+
|
|
4459
|
+
\newcommand{\arabexp}[1]{{}^{#1}\!\raisebox{-4.5pt}{\text{\diwani{ه}}}}
|
|
4460
|
+
\newcommand{\arablog}[2]{\left(\text{#2}\right)\!\prescript{}{\text{#1}}{\text{\diwani{لو}}}}
|
|
4461
|
+
\newcommand{\arabnlog}[1]{\left(\text{#1}\right)\!\prescript{}{\text{\diwani{ه}}}{\text{\diwani{لو}}}}
|
|
4462
|
+
|
|
4463
|
+
\newcommand{\arabcos}[1]{\left(#1\right)\!\!\raisebox{-2.5pt}{\text{\diwani{جتا}}}}
|
|
4464
|
+
\newcommand{\arabsin}[1]{\left(#1\right)\!\!\raisebox{-2.5pt}{\text{\diwani{جا}}}}
|
|
4465
|
+
\newcommand{\arabtan}[1]{\left(#1\right)\!\!\raisebox{-2.5pt}{\text{\diwani{ظا}}}}
|
|
4466
|
+
\newcommand{\arabcot}[1]{\left(#1\right)\!\!\raisebox{-2.5pt}{\text{\diwani{ظتا}}}}
|
|
4467
|
+
\newcommand{\arabsec}[1]{\left(#1\right)\!\!\raisebox{-2.5pt}{\text{\diwani{قا}}}}
|
|
4468
|
+
\newcommand{\arabcsc}[1]{\left(#1\right)\!\!\raisebox{-2.5pt}{\text{\diwani{قتا}}}}
|
|
4469
|
+
|
|
4470
|
+
\newcommand{\arabacos}[1]{\left(#1\right)\!\!\raisebox{-2.5pt}{\text{\diwani{قجتا}}}}
|
|
4471
|
+
\newcommand{\arabasin}[1]{\left(#1\right)\!\!\raisebox{-2.5pt}{\text{\diwani{قجا}}}}
|
|
4472
|
+
\newcommand{\arabatan}[1]{\left(#1\right)\!\!\raisebox{-2.5pt}{\text{\diwani{قظا}}}}
|
|
4473
|
+
\newcommand{\arabacot}[1]{\left(#1\right)\!\!\raisebox{-2.5pt}{\text{\diwani{قظتا}}}}
|
|
4474
|
+
\newcommand{\arabasec}[1]{\left(#1\right)\!\!\raisebox{-2.5pt}{\text{\diwani{ققا}}}}
|
|
4475
|
+
\newcommand{\arabacsc}[1]{\left(#1\right)\!\!\raisebox{-2.5pt}{\text{\diwani{ققتا}}}}
|
|
4476
|
+
|
|
4477
|
+
|
|
4478
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4479
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4480
|
+
% summation
|
|
4481
|
+
\newcommand{\arablim}[2]{\underset{#2 \leftarrow #1}{\text{نـــــها}}}
|
|
4482
|
+
\newcommand{\arabsum}[2]{\underset{#1}{\overset{#2}{\text{مجـــ}}}}
|
|
4483
|
+
\newcommand{\arabprod}[2]{\underset{#1}{\overset{#2}{\text{جـــذ}}}}
|
|
4484
|
+
\newcommand{\arabint}[2]{\prescript{#2}{#1\!\!\!}\int}
|
|
4485
|
+
|
|
4486
|
+
|
|
4487
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4488
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4489
|
+
% we define this command to make it ease for change of notation later
|
|
4490
|
+
\newcommand{\ad}[0]{\text{ء}} % "ad" for arabic differentiation or derivative (ء" لإشتقاق")
|
|
4491
|
+
\newcommand{\arpi}[0]{\!\text{\diwani{ط}}}
|
|
4492
|
+
|
|
4493
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4494
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4495
|
+
% differentials
|
|
4496
|
+
|
|
4497
|
+
\newcommand{\arabdiff}[2]{\frac{#1\ad}{#2\ad}} % arabic differential
|
|
4498
|
+
\newcommand{\arabddiff}[2]{\frac{#1{}^{2}\ad}{{}^{2}#2\ad}} % arabic second differential
|
|
4499
|
+
|
|
4500
|
+
\newcommand{\arabode}[2][-5pt]{\stackrel{\raisebox{#1}{$\cdot$}}{\text{#2}}}
|
|
4501
|
+
\newcommand{\arabodde}[2][-5pt]{\stackrel{\raisebox{#1}{$\vcenter{\hbox{$\cdot\!\cdot$}}$}}{\text{#2}}}
|
|
4502
|
+
\newcommand{\araboddde}[2][-5pt]{\stackrel{\raisebox{#1}{$\vcenter{\hbox{$\cdot\!\cdot\!\cdot$}}$}}{\text{#2}}}
|
|
4503
|
+
\newcommand{\arabpde}[1]{\prescript{}{#1\!\!}{\nabla}} % arabic partial differential equation (PDE)
|
|
4504
|
+
|
|
4505
|
+
\newcommand{\arabprime}[0]{\reflectbox{$\prime$}\!} % arabic prime notation
|
|
4506
|
+
\newcommand{\arabpprime}[0]{\reflectbox{$\prime$}\reflectbox{$\prime$}\!} % arabic prime notation
|
|
4507
|
+
\newcommand{\arabppprime}[0]{\reflectbox{$\prime$}\reflectbox{$\prime$}\reflectbox{$\prime$}\!} % arabic prime notation
|
|
4508
|
+
|
|
4509
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4510
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4511
|
+
% probability
|
|
4512
|
+
\newcommand{\ap}[0]{\!\text{\diwani{حـ}}} % arabic Probability - used a lot so short form
|
|
4513
|
+
\newcommand{\arabExpct}[0]{\text{\diwani{توقـ}}} % arabic Expectation
|
|
4514
|
+
\newcommand{\arabVar}[0]{\!\text{\diwani{با}}} % arabic Variance
|
|
4515
|
+
\newcommand{\arabCov}[0]{\!\text{\diwani{ت}}} % arabic Covariance
|
|
4516
|
+
|
|
4517
|
+
|
|
4518
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4519
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4520
|
+
% custom commands specific to lesson
|
|
4521
|
+
\newcommand{\lagrange}[2]{\left(#2\right)\!\prescript{}{#1}{\text{\diwani{لا}}}}
|
|
4522
|
+
\newcommand{\xii}[0]{\left(\prescript{}{\text{يـ}}{\text{س}}\right)\!}
|
|
4523
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4524
|
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
4525
|
+
|
|
4526
|
+
|
|
4527
|
+
\newcommand{\arsqrt}[2][]{\reflectbox{\(\sqrt[\reflectbox{\(#1\)}]{\reflectbox{\(#2\)}}\)}}
|
|
4528
|
+
\newcommand{\arexp}[0]{\!\raisebox{-4.5pt}{\text{\diwani{ه}}}}
|
|
4529
|
+
\newcommand{\arlog}[0]{\!\!\text{\diwani{لو}}}
|
|
4530
|
+
\newcommand{\arln}[0]{\!\!\prescript{}{\text{\diwani{ه}}}{\text{\diwani{لو}}}}
|
|
4531
|
+
\newcommand{\ardet}[0]{\!\!\text{\diwani{محدد}}}
|
|
4532
|
+
|
|
4533
|
+
\newcommand{\arsum}[0]{\text{مجـــ}}
|
|
4534
|
+
\newcommand{\arprod}[0]{\text{جـــذ}}
|
|
4535
|
+
|
|
4536
|
+
\newcommand{\arlim}[0]{\text{نـــــها}}
|
|
4537
|
+
\newcommand{\armax}[0]{\text{أكبر}}
|
|
4538
|
+
\newcommand{\armin}[0]{\text{أصغر}}
|
|
4539
|
+
\newcommand{\arsup}[0]{\text{أعلى}}
|
|
4540
|
+
\newcommand{\arinf}[0]{\text{أدنى}}
|
|
4541
|
+
|
|
4542
|
+
\newcommand{\arsin}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{جا}}}}
|
|
4543
|
+
\newcommand{\arcos}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{جتا}}}}
|
|
4544
|
+
\newcommand{\artan}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{ظا}}}}
|
|
4545
|
+
\newcommand{\arcot}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{ظتا}}}}
|
|
4546
|
+
\newcommand{\arsec}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{قا}}}}
|
|
4547
|
+
\newcommand{\arcsc}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{قتا}}}}
|
|
4548
|
+
|
|
4549
|
+
\newcommand{\arasin}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{قجا}}}}
|
|
4550
|
+
\newcommand{\aracos}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{قجتا}}}}
|
|
4551
|
+
\newcommand{\aratan}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{قظا}}}}
|
|
4552
|
+
\newcommand{\aracot}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{قظتا}}}}
|
|
4553
|
+
\newcommand{\arasec}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{ققا}}}}
|
|
4554
|
+
\newcommand{\aracsc}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{ققتا}}}}
|
|
4555
|
+
|
|
4556
|
+
\newcommand{\arsinh}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{جزا}}}}
|
|
4557
|
+
\newcommand{\arcosh}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{جتزا}}}}
|
|
4558
|
+
\newcommand{\artanh}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{ظزا}}}}
|
|
4559
|
+
\newcommand{\arcoth}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{ظتزا}}}}
|
|
4560
|
+
\newcommand{\arsech}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{قزا}}}}
|
|
4561
|
+
\newcommand{\arcsch}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{قتزا}}}}
|
|
4562
|
+
|
|
4563
|
+
\newcommand{\arasinh}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{قجزا}}}}
|
|
4564
|
+
\newcommand{\aracosh}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{قجتزا}}}}
|
|
4565
|
+
\newcommand{\aratanh}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{قظزا}}}}
|
|
4566
|
+
\newcommand{\aracoth}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{قظتزا}}}}
|
|
4567
|
+
\newcommand{\arasech}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{ققزا}}}}
|
|
4568
|
+
\newcommand{\aracsch}[0]{\!\!\raisebox{-2.5pt}{\text{\diwani{ققتزا}}}}
|
|
4569
|
+
|
|
4570
|
+
\newcommand{\unit}[1]{\text{#1}}
|
|
4571
|
+
\newcommand{\idx}[1]{#1}
|
|
4572
|
+
\newcommand{\arbinom}[2]{\left(\begin{array}{c} #1 \\ #2 \end{array} \right)}
|
|
4573
|
+
`;
|
|
4574
|
+
}
|
|
4575
|
+
function getArabicXeLatexPreamble(digitsMappingOrOptions = "arabicdigits") {
|
|
4576
|
+
const options = typeof digitsMappingOrOptions === "string" ? { digitsMapping: digitsMappingOrOptions } : digitsMappingOrOptions;
|
|
4577
|
+
const digitsMapping = options.digitsMapping ?? "arabicdigits";
|
|
4578
|
+
const twocolumn = options.twocolumn === true;
|
|
4579
|
+
return arabicXeLatexPreamblePkg(twocolumn) + arabicXeLatexPreambleFont(digitsMapping) + arabicXeLatexPreambleCmd();
|
|
4580
|
+
}
|
|
3448
4581
|
|
|
3449
4582
|
// src/document2/exportLatex.ts
|
|
4583
|
+
function mathBodyLatex(token) {
|
|
4584
|
+
if (!token.math || token.sourceOwner === "raw" || token.sourceOwner === "editor") {
|
|
4585
|
+
return stripDisplayMathDelimiters(token.source);
|
|
4586
|
+
}
|
|
4587
|
+
const rendered = renderMathNodeLatex(token.math);
|
|
4588
|
+
return stripDisplayMathDelimiters(rendered);
|
|
4589
|
+
}
|
|
3450
4590
|
function tokenLatex(token) {
|
|
3451
4591
|
if (token.kind === "text") {
|
|
3452
4592
|
return token.text;
|
|
3453
4593
|
}
|
|
4594
|
+
if (token.kind === "cite") {
|
|
4595
|
+
return citeTokenLatex(token.keys);
|
|
4596
|
+
}
|
|
4597
|
+
if (token.kind === "ref") {
|
|
4598
|
+
return refTokenLatex(token.keys, token.refCommand);
|
|
4599
|
+
}
|
|
4600
|
+
if (token.display && token.labelEnabled && token.label && token.label.trim().length > 0) {
|
|
4601
|
+
const body = mathBodyLatex(token);
|
|
4602
|
+
return `\\begin{equation}
|
|
4603
|
+
${body}
|
|
4604
|
+
\\label{${token.label.trim()}}
|
|
4605
|
+
\\end{equation}`;
|
|
4606
|
+
}
|
|
3454
4607
|
if (!token.math || token.sourceOwner === "raw" || token.sourceOwner === "editor") {
|
|
3455
4608
|
return token.source;
|
|
3456
4609
|
}
|
|
@@ -3460,26 +4613,52 @@ function inlineFieldLatex(field) {
|
|
|
3460
4613
|
return field.tokens.map((token) => tokenLatex(token)).join("");
|
|
3461
4614
|
}
|
|
3462
4615
|
function textBlockLatex(block) {
|
|
3463
|
-
|
|
4616
|
+
const body = `${block.command}{${inlineFieldLatex(block.field)}}`;
|
|
4617
|
+
if (block.command === "\\paragraph" && block.centered) {
|
|
4618
|
+
return `\\begin{center}
|
|
4619
|
+
${body}
|
|
4620
|
+
\\end{center}`;
|
|
4621
|
+
}
|
|
4622
|
+
return body;
|
|
3464
4623
|
}
|
|
3465
4624
|
function indent(value) {
|
|
3466
4625
|
return value.split("\n").map((line) => ` ${line}`).join("\n");
|
|
3467
4626
|
}
|
|
3468
|
-
function listBlockLatex(block) {
|
|
4627
|
+
function listBlockLatex(block, references) {
|
|
3469
4628
|
const items = block.items.map((item) => {
|
|
3470
|
-
const nested = item.blocks.map((child) => "\n" + indent(blockLatex(child))).join("");
|
|
4629
|
+
const nested = item.blocks.map((child) => "\n" + indent(blockLatex(child, references))).join("");
|
|
3471
4630
|
return ` \\item ${inlineFieldLatex(item.field)}${nested}`;
|
|
3472
4631
|
}).join("\n");
|
|
3473
4632
|
return `${block.command}
|
|
3474
4633
|
${items}
|
|
3475
4634
|
${block.closing}`;
|
|
3476
4635
|
}
|
|
3477
|
-
function
|
|
4636
|
+
function tabularInnerLatex(block) {
|
|
3478
4637
|
const rows = block.rows.map((row) => ` ${row.map((cell) => inlineFieldLatex(cell)).join(" & ")}`).join(" \\\\\n");
|
|
3479
4638
|
return `${block.command}{${block.columns}}
|
|
3480
4639
|
${rows}
|
|
3481
4640
|
${block.closing}`;
|
|
3482
4641
|
}
|
|
4642
|
+
function floatCaptionLabelLines(block) {
|
|
4643
|
+
const lines = [];
|
|
4644
|
+
if (block.captionEnabled && block.caption.trim().length > 0) {
|
|
4645
|
+
lines.push(` \\caption{${block.caption.trim()}}`);
|
|
4646
|
+
}
|
|
4647
|
+
if (block.labelEnabled && block.label.trim().length > 0) {
|
|
4648
|
+
lines.push(` \\label{${block.label.trim()}}`);
|
|
4649
|
+
}
|
|
4650
|
+
return lines;
|
|
4651
|
+
}
|
|
4652
|
+
function tableBlockLatex(block) {
|
|
4653
|
+
const lines = ["\\begin{table}[htbp]"];
|
|
4654
|
+
if (block.centered) {
|
|
4655
|
+
lines.push(" \\centering");
|
|
4656
|
+
}
|
|
4657
|
+
lines.push(...floatCaptionLabelLines(block));
|
|
4658
|
+
lines.push(indent(tabularInnerLatex(block)));
|
|
4659
|
+
lines.push("\\end{table}");
|
|
4660
|
+
return lines.join("\n");
|
|
4661
|
+
}
|
|
3483
4662
|
function imageOptionsLatex(block) {
|
|
3484
4663
|
const entries = Object.entries(block.options);
|
|
3485
4664
|
if (entries.length === 0) {
|
|
@@ -3487,23 +4666,81 @@ function imageOptionsLatex(block) {
|
|
|
3487
4666
|
}
|
|
3488
4667
|
return `[${entries.map(([key, value]) => `${key}=${value}`).join(",")}]`;
|
|
3489
4668
|
}
|
|
3490
|
-
function
|
|
4669
|
+
function imageBlockLatex(block) {
|
|
4670
|
+
const lines = ["\\begin{figure}[htbp]"];
|
|
4671
|
+
if (block.centered) {
|
|
4672
|
+
lines.push(" \\centering");
|
|
4673
|
+
}
|
|
4674
|
+
lines.push(` ${block.command}${imageOptionsLatex(block)}{${block.value}}`);
|
|
4675
|
+
lines.push(...floatCaptionLabelLines(block));
|
|
4676
|
+
lines.push("\\end{figure}");
|
|
4677
|
+
return lines.join("\n");
|
|
4678
|
+
}
|
|
4679
|
+
function blockLatex(block, references) {
|
|
3491
4680
|
if (block.kind === "textBlock") {
|
|
3492
4681
|
return textBlockLatex(block);
|
|
3493
4682
|
}
|
|
3494
4683
|
if (block.kind === "list") {
|
|
3495
|
-
return listBlockLatex(block);
|
|
4684
|
+
return listBlockLatex(block, references);
|
|
3496
4685
|
}
|
|
3497
4686
|
if (block.kind === "table") {
|
|
3498
4687
|
return tableBlockLatex(block);
|
|
3499
4688
|
}
|
|
3500
4689
|
if (block.kind === "image") {
|
|
3501
|
-
return
|
|
4690
|
+
return imageBlockLatex(block);
|
|
4691
|
+
}
|
|
4692
|
+
if (block.kind === "bibliography") {
|
|
4693
|
+
const width = String(Math.max(references.length, 9));
|
|
4694
|
+
const items = references.map((reference) => ` ${bibliographyEntryLatex(reference)}`).join("\n");
|
|
4695
|
+
return `${block.command}{${width}}
|
|
4696
|
+
${items}
|
|
4697
|
+
${block.closing}`;
|
|
3502
4698
|
}
|
|
3503
4699
|
return block.value;
|
|
3504
4700
|
}
|
|
3505
|
-
function
|
|
3506
|
-
return
|
|
4701
|
+
function authorLatex(authors) {
|
|
4702
|
+
return authors.split(/\n+/).map((line) => line.trim()).filter((line) => line.length > 0).join(" \\\\ ");
|
|
4703
|
+
}
|
|
4704
|
+
function articleFrontMatterLatex(meta) {
|
|
4705
|
+
const parts = [butexDiwaniDisplayLatex(BUTEX_BASMALA)];
|
|
4706
|
+
if (document2HasMaketitle(meta)) {
|
|
4707
|
+
if (meta.title.trim().length > 0) {
|
|
4708
|
+
parts.push(`\\title{${meta.title.trim()}}`);
|
|
4709
|
+
}
|
|
4710
|
+
if (meta.authors.trim().length > 0) {
|
|
4711
|
+
parts.push(`\\author{${authorLatex(meta.authors)}}`);
|
|
4712
|
+
}
|
|
4713
|
+
parts.push(`\\date{${formatHijriDate(meta.date, { locale: "ar", digitForm: "arabicIndic" })}}`);
|
|
4714
|
+
parts.push("\\maketitle");
|
|
4715
|
+
}
|
|
4716
|
+
if (document2HasAbstract(meta)) {
|
|
4717
|
+
parts.push(`\\begin{abstract}
|
|
4718
|
+
${meta.abstract.trim()}
|
|
4719
|
+
\\end{abstract}`);
|
|
4720
|
+
}
|
|
4721
|
+
return parts;
|
|
4722
|
+
}
|
|
4723
|
+
function document2Latex(document2, options = {}) {
|
|
4724
|
+
const meta = document2.meta ?? emptyDocument2Meta();
|
|
4725
|
+
const front = articleFrontMatterLatex(meta);
|
|
4726
|
+
const bodyBlocks = document2.blocks.map((block) => blockLatex(block, document2.references));
|
|
4727
|
+
const closing = butexDiwaniDisplayLatex(BUTEX_CLOSING_HAMDALA);
|
|
4728
|
+
const body = [...front, ...bodyBlocks, closing].filter((part) => part.length > 0).join("\n\n");
|
|
4729
|
+
const wrapDocument = options.wrapDocument !== false;
|
|
4730
|
+
if (!wrapDocument) {
|
|
4731
|
+
return body;
|
|
4732
|
+
}
|
|
4733
|
+
const preamble = getArabicXeLatexPreamble({
|
|
4734
|
+
digitsMapping: options.digitsMapping ?? "arabicdigits",
|
|
4735
|
+
twocolumn: options.twocolumn === true
|
|
4736
|
+
});
|
|
4737
|
+
return `${preamble}
|
|
4738
|
+
\\begin{document}
|
|
4739
|
+
|
|
4740
|
+
${body}
|
|
4741
|
+
|
|
4742
|
+
\\end{document}
|
|
4743
|
+
`;
|
|
3507
4744
|
}
|
|
3508
4745
|
|
|
3509
4746
|
// src/document2/history.ts
|
|
@@ -3539,18 +4776,99 @@ function document2HistoryCanRedo(stacks) {
|
|
|
3539
4776
|
return stacks.future.length > 0;
|
|
3540
4777
|
}
|
|
3541
4778
|
|
|
4779
|
+
// src/document2/blockSelection.ts
|
|
4780
|
+
function emptyBlockSelection() {
|
|
4781
|
+
return { selection: null, anchor: null };
|
|
4782
|
+
}
|
|
4783
|
+
function normalizeBlockSelection(selection, blockCount) {
|
|
4784
|
+
if (!selection) {
|
|
4785
|
+
return null;
|
|
4786
|
+
}
|
|
4787
|
+
const { from, to } = selection;
|
|
4788
|
+
if (blockCount <= 0 || from < 0 || to < 0 || from >= blockCount || to >= blockCount || from > to) {
|
|
4789
|
+
return null;
|
|
4790
|
+
}
|
|
4791
|
+
return { from, to };
|
|
4792
|
+
}
|
|
4793
|
+
function inRange(selection, index) {
|
|
4794
|
+
return index >= selection.from && index <= selection.to;
|
|
4795
|
+
}
|
|
4796
|
+
function toggleBlockInSelection(state, index, blockCount) {
|
|
4797
|
+
if (index < 0 || index >= blockCount) {
|
|
4798
|
+
return state;
|
|
4799
|
+
}
|
|
4800
|
+
const selection = normalizeBlockSelection(state.selection, blockCount);
|
|
4801
|
+
if (!selection) {
|
|
4802
|
+
return { selection: { from: index, to: index }, anchor: index };
|
|
4803
|
+
}
|
|
4804
|
+
if (inRange(selection, index)) {
|
|
4805
|
+
if (selection.from === selection.to) {
|
|
4806
|
+
return emptyBlockSelection();
|
|
4807
|
+
}
|
|
4808
|
+
if (index === selection.from) {
|
|
4809
|
+
return { selection: { from: selection.from + 1, to: selection.to }, anchor: state.anchor };
|
|
4810
|
+
}
|
|
4811
|
+
if (index === selection.to) {
|
|
4812
|
+
return { selection: { from: selection.from, to: selection.to - 1 }, anchor: state.anchor };
|
|
4813
|
+
}
|
|
4814
|
+
return emptyBlockSelection();
|
|
4815
|
+
}
|
|
4816
|
+
if (index === selection.from - 1) {
|
|
4817
|
+
return { selection: { from: index, to: selection.to }, anchor: state.anchor ?? index };
|
|
4818
|
+
}
|
|
4819
|
+
if (index === selection.to + 1) {
|
|
4820
|
+
return { selection: { from: selection.from, to: index }, anchor: state.anchor ?? index };
|
|
4821
|
+
}
|
|
4822
|
+
return { selection: { from: index, to: index }, anchor: index };
|
|
4823
|
+
}
|
|
4824
|
+
function extendBlockSelectionFromAnchor(state, index, blockCount) {
|
|
4825
|
+
if (index < 0 || index >= blockCount) {
|
|
4826
|
+
return state;
|
|
4827
|
+
}
|
|
4828
|
+
const anchor = state.anchor ?? index;
|
|
4829
|
+
const from = Math.min(anchor, index);
|
|
4830
|
+
const to = Math.max(anchor, index);
|
|
4831
|
+
return {
|
|
4832
|
+
selection: { from, to },
|
|
4833
|
+
anchor: state.anchor ?? index
|
|
4834
|
+
};
|
|
4835
|
+
}
|
|
4836
|
+
function remapSelectionAfterRangeMove(selection, direction) {
|
|
4837
|
+
return { from: selection.from + direction, to: selection.to + direction };
|
|
4838
|
+
}
|
|
4839
|
+
|
|
3542
4840
|
// src/document2/previewModel.ts
|
|
3543
4841
|
function mathTex(token, equationSide) {
|
|
3544
|
-
if (token.kind === "text") {
|
|
3545
|
-
return token.text;
|
|
3546
|
-
}
|
|
3547
4842
|
return mathTokenSourceForSide(token, equationSide);
|
|
3548
4843
|
}
|
|
3549
|
-
function previewInlines(field, islands, output, equationSide) {
|
|
4844
|
+
function previewInlines(field, islands, output, equationSide, document2, previewOptions) {
|
|
3550
4845
|
return field.tokens.map((token) => {
|
|
3551
4846
|
if (token.kind === "text") {
|
|
3552
4847
|
return { kind: "text", text: token.text };
|
|
3553
4848
|
}
|
|
4849
|
+
if (token.kind === "cite") {
|
|
4850
|
+
return {
|
|
4851
|
+
kind: "cite",
|
|
4852
|
+
id: token.id,
|
|
4853
|
+
keys: [...token.keys],
|
|
4854
|
+
label: formatCiteLabel(token.keys, document2.references, {
|
|
4855
|
+
documentDirection: previewOptions.documentDirection,
|
|
4856
|
+
digitForm: previewOptions.digitForm
|
|
4857
|
+
})
|
|
4858
|
+
};
|
|
4859
|
+
}
|
|
4860
|
+
if (token.kind === "ref") {
|
|
4861
|
+
return {
|
|
4862
|
+
kind: "ref",
|
|
4863
|
+
id: token.id,
|
|
4864
|
+
keys: [...token.keys],
|
|
4865
|
+
refCommand: token.refCommand,
|
|
4866
|
+
label: formatRefLabel(token.keys, document2, token.refCommand, {
|
|
4867
|
+
documentDirection: previewOptions.documentDirection,
|
|
4868
|
+
digitForm: previewOptions.digitForm
|
|
4869
|
+
})
|
|
4870
|
+
};
|
|
4871
|
+
}
|
|
3554
4872
|
const island = {
|
|
3555
4873
|
id: token.id,
|
|
3556
4874
|
tex: mathTex(token, equationSide),
|
|
@@ -3562,21 +4880,43 @@ function previewInlines(field, islands, output, equationSide) {
|
|
|
3562
4880
|
return { kind: "math", ...island };
|
|
3563
4881
|
});
|
|
3564
4882
|
}
|
|
3565
|
-
function textBlockPreview(block, islands, output, equationSide) {
|
|
4883
|
+
function textBlockPreview(block, islands, output, equationSide, document2, previewOptions) {
|
|
4884
|
+
const inlines = previewInlines(block.field, islands, output, equationSide, document2, previewOptions);
|
|
3566
4885
|
if (block.command === "\\section") {
|
|
3567
|
-
return { kind: "heading", id: block.id, level: 1, inlines
|
|
4886
|
+
return { kind: "heading", id: block.id, level: 1, inlines };
|
|
3568
4887
|
}
|
|
3569
4888
|
if (block.command === "\\subsection") {
|
|
3570
|
-
return { kind: "heading", id: block.id, level: 2, inlines
|
|
4889
|
+
return { kind: "heading", id: block.id, level: 2, inlines };
|
|
3571
4890
|
}
|
|
3572
4891
|
if (block.command === "\\subsubsection") {
|
|
3573
|
-
return { kind: "heading", id: block.id, level: 3, inlines
|
|
4892
|
+
return { kind: "heading", id: block.id, level: 3, inlines };
|
|
4893
|
+
}
|
|
4894
|
+
return {
|
|
4895
|
+
kind: "paragraph",
|
|
4896
|
+
id: block.id,
|
|
4897
|
+
inlines,
|
|
4898
|
+
...block.centered ? { centered: true } : {}
|
|
4899
|
+
};
|
|
4900
|
+
}
|
|
4901
|
+
function floatNumberLabel(document2, key, previewOptions) {
|
|
4902
|
+
if (!key || key.trim().length === 0) {
|
|
4903
|
+
return void 0;
|
|
4904
|
+
}
|
|
4905
|
+
const hit = labelNumberMap(document2).get(key.trim());
|
|
4906
|
+
if (!hit || hit.kind !== "fig" && hit.kind !== "tab") {
|
|
4907
|
+
return void 0;
|
|
3574
4908
|
}
|
|
3575
|
-
|
|
4909
|
+
const locale = previewOptions.uiLocale ?? "ar";
|
|
4910
|
+
const kindWord = hit.kind === "fig" ? locale === "ar" ? "\u0627\u0644\u0634\u0643\u0644" : "Figure" : locale === "ar" ? "\u0627\u0644\u062C\u062F\u0648\u0644" : "Table";
|
|
4911
|
+
const digits = formatBibliographyNumber(hit.number, {
|
|
4912
|
+
documentDirection: previewOptions.documentDirection,
|
|
4913
|
+
digitForm: previewOptions.digitForm
|
|
4914
|
+
});
|
|
4915
|
+
return `${kindWord} ${digits}`;
|
|
3576
4916
|
}
|
|
3577
|
-
function blockPreview(block, islands, output, equationSide) {
|
|
4917
|
+
function blockPreview(block, islands, output, equationSide, document2, previewOptions) {
|
|
3578
4918
|
if (block.kind === "textBlock") {
|
|
3579
|
-
return textBlockPreview(block, islands, output, equationSide);
|
|
4919
|
+
return textBlockPreview(block, islands, output, equationSide, document2, previewOptions);
|
|
3580
4920
|
}
|
|
3581
4921
|
if (block.kind === "list") {
|
|
3582
4922
|
return {
|
|
@@ -3585,51 +4925,155 @@ function blockPreview(block, islands, output, equationSide) {
|
|
|
3585
4925
|
ordered: block.command === "\\begin{enumerate}",
|
|
3586
4926
|
items: block.items.map((item) => ({
|
|
3587
4927
|
id: item.id,
|
|
3588
|
-
inlines: previewInlines(item.field, islands, output, equationSide),
|
|
3589
|
-
blocks: item.blocks.map((child) => blockPreview(child, islands, output, equationSide))
|
|
4928
|
+
inlines: previewInlines(item.field, islands, output, equationSide, document2, previewOptions),
|
|
4929
|
+
blocks: item.blocks.map((child) => blockPreview(child, islands, output, equationSide, document2, previewOptions))
|
|
3590
4930
|
}))
|
|
3591
4931
|
};
|
|
3592
4932
|
}
|
|
3593
4933
|
if (block.kind === "table") {
|
|
3594
|
-
|
|
4934
|
+
const label = block.labelEnabled ? block.label.trim() : "";
|
|
4935
|
+
return {
|
|
4936
|
+
kind: "table",
|
|
4937
|
+
id: block.id,
|
|
4938
|
+
rows: block.rows.map((row) => row.map((cell) => previewInlines(cell, islands, output, equationSide, document2, previewOptions))),
|
|
4939
|
+
...block.captionEnabled && block.caption.trim().length > 0 ? { caption: block.caption.trim() } : {},
|
|
4940
|
+
...label.length > 0 ? { label, numberLabel: floatNumberLabel(document2, label, previewOptions) } : {}
|
|
4941
|
+
};
|
|
3595
4942
|
}
|
|
3596
4943
|
if (block.kind === "image") {
|
|
3597
|
-
|
|
4944
|
+
const label = block.labelEnabled ? block.label.trim() : "";
|
|
4945
|
+
return {
|
|
4946
|
+
kind: "image",
|
|
4947
|
+
id: block.id,
|
|
4948
|
+
src: block.value,
|
|
4949
|
+
...block.assetId !== void 0 ? { assetId: block.assetId } : {},
|
|
4950
|
+
options: block.options,
|
|
4951
|
+
...block.captionEnabled && block.caption.trim().length > 0 ? { caption: block.caption.trim() } : {},
|
|
4952
|
+
...label.length > 0 ? { label, numberLabel: floatNumberLabel(document2, label, previewOptions) } : {}
|
|
4953
|
+
};
|
|
4954
|
+
}
|
|
4955
|
+
if (block.kind === "bibliography") {
|
|
4956
|
+
return {
|
|
4957
|
+
kind: "bibliography",
|
|
4958
|
+
id: block.id,
|
|
4959
|
+
items: document2.references.map((reference, index) => ({
|
|
4960
|
+
id: reference.id,
|
|
4961
|
+
numberLabel: formatBibliographyNumber(index + 1, {
|
|
4962
|
+
documentDirection: previewOptions.documentDirection,
|
|
4963
|
+
digitForm: previewOptions.digitForm
|
|
4964
|
+
}),
|
|
4965
|
+
key: reference.key,
|
|
4966
|
+
authors: reference.authors,
|
|
4967
|
+
title: reference.title,
|
|
4968
|
+
year: reference.year,
|
|
4969
|
+
url: reference.url,
|
|
4970
|
+
venue: reference.venue
|
|
4971
|
+
}))
|
|
4972
|
+
};
|
|
3598
4973
|
}
|
|
3599
4974
|
return { kind: "omit", id: block.id };
|
|
3600
4975
|
}
|
|
3601
|
-
function
|
|
4976
|
+
function articleChromePreview(document2, uiLocale, previewOptions) {
|
|
4977
|
+
const meta = document2.meta ?? emptyDocument2Meta();
|
|
4978
|
+
const blocks = [
|
|
4979
|
+
{ kind: "basmala", id: "article-basmala", text: BUTEX_BASMALA, tex: butexDiwaniDisplayTex(BUTEX_BASMALA) }
|
|
4980
|
+
];
|
|
4981
|
+
if (document2HasMaketitle(meta)) {
|
|
4982
|
+
blocks.push({
|
|
4983
|
+
kind: "titleBlock",
|
|
4984
|
+
id: "article-title",
|
|
4985
|
+
...meta.title.trim().length > 0 ? { title: meta.title.trim() } : {},
|
|
4986
|
+
...meta.authors.trim().length > 0 ? { authors: meta.authors.trim() } : {},
|
|
4987
|
+
date: formatHijriDate(meta.date, {
|
|
4988
|
+
locale: uiLocale,
|
|
4989
|
+
digitForm: previewOptions.digitForm
|
|
4990
|
+
})
|
|
4991
|
+
});
|
|
4992
|
+
}
|
|
4993
|
+
if (document2HasAbstract(meta)) {
|
|
4994
|
+
blocks.push({ kind: "abstract", id: "article-abstract", text: meta.abstract.trim() });
|
|
4995
|
+
}
|
|
4996
|
+
return blocks;
|
|
4997
|
+
}
|
|
4998
|
+
function document2Preview(document2, output = "svg", equationSide = "arabic", previewOptions = {}) {
|
|
3602
4999
|
const mathIslands = [];
|
|
5000
|
+
const options = {
|
|
5001
|
+
documentDirection: previewOptions.documentDirection ?? "rtl",
|
|
5002
|
+
digitForm: previewOptions.digitForm ?? (previewOptions.documentDirection === "ltr" ? "western" : "arabicIndic"),
|
|
5003
|
+
uiLocale: previewOptions.uiLocale ?? "ar"
|
|
5004
|
+
};
|
|
5005
|
+
const body = document2.blocks.map((block) => blockPreview(block, mathIslands, output, equationSide, document2, options));
|
|
3603
5006
|
return {
|
|
3604
|
-
blocks:
|
|
5007
|
+
blocks: [
|
|
5008
|
+
...articleChromePreview(document2, options.uiLocale ?? "ar", options),
|
|
5009
|
+
...body,
|
|
5010
|
+
{ kind: "closing", id: "article-closing", text: BUTEX_CLOSING_HAMDALA, tex: butexDiwaniDisplayTex(BUTEX_CLOSING_HAMDALA) }
|
|
5011
|
+
],
|
|
3605
5012
|
mathIslands
|
|
3606
5013
|
};
|
|
3607
5014
|
}
|
|
3608
5015
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3609
5016
|
0 && (module.exports = {
|
|
5017
|
+
BUTEX_BASMALA,
|
|
5018
|
+
BUTEX_CLOSING_HAMDALA,
|
|
3610
5019
|
DEFAULT_DOCUMENT2_HISTORY_MAX_DEPTH,
|
|
5020
|
+
DEFAULT_HIJRI_DATE,
|
|
5021
|
+
HIJRI_MONTH_IDS,
|
|
5022
|
+
HIJRI_YEAR_MAX,
|
|
5023
|
+
HIJRI_YEAR_MIN,
|
|
3611
5024
|
addDocument2ImageBlock,
|
|
3612
5025
|
addDocument2ListBlock,
|
|
3613
5026
|
addDocument2ListItem,
|
|
5027
|
+
addDocument2Reference,
|
|
3614
5028
|
addDocument2TableBlock,
|
|
3615
5029
|
addDocument2TextBlock,
|
|
5030
|
+
applyFloatMetaPatch,
|
|
5031
|
+
arabicXeLatexPreambleCmd,
|
|
5032
|
+
arabicXeLatexPreambleFont,
|
|
5033
|
+
arabicXeLatexPreamblePkg,
|
|
5034
|
+
bibliographyEntryLatex,
|
|
5035
|
+
butexDiwaniDisplayLatex,
|
|
5036
|
+
butexDiwaniDisplayTex,
|
|
5037
|
+
citeTokenLatex,
|
|
5038
|
+
cloneDocument2Meta,
|
|
3616
5039
|
cloneDocument2Node,
|
|
5040
|
+
collectDocument2Labels,
|
|
3617
5041
|
createDocument2History,
|
|
3618
5042
|
createEmptyArabicEquationSession,
|
|
3619
5043
|
createEmptyDocument2,
|
|
3620
5044
|
createEmptyEquationSession,
|
|
5045
|
+
createEmptyReference2,
|
|
3621
5046
|
createInlineField2,
|
|
5047
|
+
defaultFloatMeta,
|
|
5048
|
+
detectInlineSpans2,
|
|
3622
5049
|
detectMathSpans2,
|
|
5050
|
+
document2HasAbstract,
|
|
5051
|
+
document2HasMaketitle,
|
|
5052
|
+
document2HasTitleStack,
|
|
3623
5053
|
document2HistoryCanRedo,
|
|
3624
5054
|
document2HistoryCanUndo,
|
|
3625
5055
|
document2Latex,
|
|
3626
5056
|
document2Preview,
|
|
5057
|
+
emptyBlockSelection,
|
|
5058
|
+
emptyDocument2Meta,
|
|
5059
|
+
ensureDocument2BibliographyBlock,
|
|
5060
|
+
extendBlockSelectionFromAnchor,
|
|
5061
|
+
fillDocument2MetaGaps,
|
|
3627
5062
|
findFirstInlineField,
|
|
5063
|
+
formatBibliographyNumber,
|
|
5064
|
+
formatCiteLabel,
|
|
5065
|
+
formatHijriDate,
|
|
5066
|
+
formatRefLabel,
|
|
3628
5067
|
fromDocumentJson2,
|
|
5068
|
+
getArabicXeLatexPreamble,
|
|
5069
|
+
hijriMonthLabel,
|
|
3629
5070
|
inlineFieldLatex,
|
|
5071
|
+
insertCiteTokenAtCaret,
|
|
3630
5072
|
insertDocument2BlockAfter,
|
|
3631
5073
|
insertMathToken,
|
|
3632
5074
|
insertMathTokenAtCaret,
|
|
5075
|
+
insertRefTokenAtCaret,
|
|
5076
|
+
labelNumberMap,
|
|
3633
5077
|
mathNodeFromArabicSession,
|
|
3634
5078
|
mathNodeFromSession,
|
|
3635
5079
|
mathSourceFromArabicSession,
|
|
@@ -3637,15 +5081,44 @@ function document2Preview(document2, output = "svg", equationSide = "arabic") {
|
|
|
3637
5081
|
mathTokenSourceForSide,
|
|
3638
5082
|
mathTokenToArabicEditorSession,
|
|
3639
5083
|
mathTokenToEditorSession,
|
|
5084
|
+
mergeDocument2Meta,
|
|
3640
5085
|
moveDocument2BlockById,
|
|
5086
|
+
moveDocument2BlockRange,
|
|
5087
|
+
moveDocument2Reference,
|
|
5088
|
+
normalizeBlockSelection,
|
|
5089
|
+
normalizeDocument2HijriDate,
|
|
5090
|
+
normalizeDocument2Meta,
|
|
5091
|
+
parseCiteKeys,
|
|
5092
|
+
parseFloatMetaFromJson,
|
|
5093
|
+
parseRefKeys,
|
|
3641
5094
|
pushDocument2Snapshot,
|
|
5095
|
+
refTokenLatex,
|
|
5096
|
+
referenceFromJson,
|
|
5097
|
+
referenceNumberMap,
|
|
5098
|
+
remapSelectionAfterRangeMove,
|
|
5099
|
+
removeCiteTokenById,
|
|
3642
5100
|
removeDocument2BlockById,
|
|
5101
|
+
removeDocument2BlockRange,
|
|
3643
5102
|
removeDocument2ListItem,
|
|
5103
|
+
removeDocument2Reference,
|
|
3644
5104
|
removeMathTokenById,
|
|
5105
|
+
removeRefTokenById,
|
|
3645
5106
|
replaceMathTokenFromSession,
|
|
5107
|
+
resolveCiteNumbers,
|
|
3646
5108
|
restoreDocument2Redo,
|
|
3647
5109
|
restoreDocument2Undo,
|
|
5110
|
+
setDocument2References,
|
|
5111
|
+
stripDisplayMathDelimiters,
|
|
5112
|
+
toggleBlockInSelection,
|
|
5113
|
+
updateCiteTokenKeys,
|
|
5114
|
+
updateDocument2ImageMeta,
|
|
3648
5115
|
updateDocument2ImageValue,
|
|
5116
|
+
updateDocument2Meta,
|
|
5117
|
+
updateDocument2Reference,
|
|
5118
|
+
updateDocument2TableMeta,
|
|
5119
|
+
updateDocument2TextBlockCentered,
|
|
5120
|
+
updateMathTokenLabel,
|
|
5121
|
+
updateRefTokenKeys,
|
|
3649
5122
|
updateTextToken
|
|
3650
5123
|
});
|
|
3651
5124
|
//# sourceMappingURL=document2.js.map
|