@drghaliasri/butex 5.6.0 → 6.0.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 +84 -0
- package/dist/document2-cli.js +3346 -0
- package/dist/document2-cli.js.map +1 -0
- package/dist/document2.d.mts +55 -2
- package/dist/document2.d.ts +55 -2
- package/dist/document2.js +566 -190
- package/dist/document2.js.map +1 -1
- package/dist/document2.mjs +561 -190
- package/dist/document2.mjs.map +1 -1
- package/dist/react-document2.d.mts +42 -3
- package/dist/react-document2.d.ts +42 -3
- package/dist/react-document2.js +1462 -1063
- package/dist/react-document2.js.map +1 -1
- package/dist/react-document2.mjs +1487 -1088
- package/dist/react-document2.mjs.map +1 -1
- package/package.json +14 -1
package/dist/document2.mjs
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// src/document2/ids.ts
|
|
2
2
|
var nextId = 1;
|
|
3
|
+
var instanceId = `${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
|
|
3
4
|
function document2Id(prefix) {
|
|
4
|
-
const id = `${prefix}_${String(nextId)}`;
|
|
5
|
+
const id = `${prefix}_${instanceId}_${String(nextId)}`;
|
|
5
6
|
nextId += 1;
|
|
6
7
|
return id;
|
|
7
8
|
}
|
|
@@ -1177,6 +1178,19 @@ function asBlockJson(value) {
|
|
|
1177
1178
|
}
|
|
1178
1179
|
return value;
|
|
1179
1180
|
}
|
|
1181
|
+
function blockIdFromJson(json, state) {
|
|
1182
|
+
const imported = typeof json.id === "string" ? json.id.trim() : "";
|
|
1183
|
+
if (imported.length > 0 && !state.used.has(imported)) {
|
|
1184
|
+
state.used.add(imported);
|
|
1185
|
+
return imported;
|
|
1186
|
+
}
|
|
1187
|
+
let generated = document2Id("block");
|
|
1188
|
+
while (state.used.has(generated)) {
|
|
1189
|
+
generated = document2Id("block");
|
|
1190
|
+
}
|
|
1191
|
+
state.used.add(generated);
|
|
1192
|
+
return generated;
|
|
1193
|
+
}
|
|
1180
1194
|
function pushDiagnostic(diagnostics, options, path, message) {
|
|
1181
1195
|
if (options.strict) {
|
|
1182
1196
|
throw new Error(message);
|
|
@@ -1358,40 +1372,44 @@ function pushFormattedTextTokens(tokens, text, sourceStart, formats) {
|
|
|
1358
1372
|
function closingForList(command) {
|
|
1359
1373
|
return command === "\\begin{itemize}" ? "\\end{itemize}" : "\\end{enumerate}";
|
|
1360
1374
|
}
|
|
1361
|
-
function parseTextBlock(json, options, path, diagnostics) {
|
|
1375
|
+
function parseTextBlock(json, options, path, diagnostics, blockIds) {
|
|
1362
1376
|
const value = requireString(json.value, `${json.command} requires string value`);
|
|
1363
1377
|
return {
|
|
1364
|
-
id:
|
|
1378
|
+
id: blockIdFromJson(json, blockIds),
|
|
1365
1379
|
kind: "textBlock",
|
|
1366
1380
|
command: json.command,
|
|
1367
1381
|
field: createInlineField2(value, json.math_objects ?? [], options, `${path}.value`, diagnostics, json.command === "\\paragraph" ? json.formats ?? [] : []),
|
|
1368
1382
|
...json.centered === true ? { centered: true } : {}
|
|
1369
1383
|
};
|
|
1370
1384
|
}
|
|
1371
|
-
function parseListItem(json, options, path, diagnostics) {
|
|
1385
|
+
function parseListItem(json, options, path, diagnostics, blockIds) {
|
|
1372
1386
|
const value = requireString(json.value, "Document list item requires string value");
|
|
1373
1387
|
const blocksJson = Array.isArray(json.blocks) ? json.blocks : [];
|
|
1374
1388
|
return {
|
|
1375
1389
|
id: document2Id("item"),
|
|
1376
1390
|
field: createInlineField2(value, json.math_objects ?? [], options, `${path}.value`, diagnostics, json.formats ?? []),
|
|
1377
|
-
blocks: blocksJson.map(
|
|
1391
|
+
blocks: blocksJson.map(
|
|
1392
|
+
(block, index) => parseBlock(asBlockJson(block), options, `${path}.blocks[${String(index)}]`, diagnostics, blockIds)
|
|
1393
|
+
)
|
|
1378
1394
|
};
|
|
1379
1395
|
}
|
|
1380
|
-
function parseListBlock(json, options, path, diagnostics) {
|
|
1396
|
+
function parseListBlock(json, options, path, diagnostics, blockIds) {
|
|
1381
1397
|
if (!Array.isArray(json.items)) {
|
|
1382
1398
|
throw new Error(`${json.command} requires items array`);
|
|
1383
1399
|
}
|
|
1384
1400
|
const command = json.command;
|
|
1385
1401
|
const closing = closingForList(command);
|
|
1386
1402
|
return {
|
|
1387
|
-
id:
|
|
1403
|
+
id: blockIdFromJson(json, blockIds),
|
|
1388
1404
|
kind: "list",
|
|
1389
1405
|
command,
|
|
1390
1406
|
closing,
|
|
1391
|
-
items: json.items.map(
|
|
1407
|
+
items: json.items.map(
|
|
1408
|
+
(item, index) => parseListItem(item, options, `${path}.items[${String(index)}]`, diagnostics, blockIds)
|
|
1409
|
+
)
|
|
1392
1410
|
};
|
|
1393
1411
|
}
|
|
1394
|
-
function parseTableBlock(json, options, path, diagnostics) {
|
|
1412
|
+
function parseTableBlock(json, options, path, diagnostics, blockIds) {
|
|
1395
1413
|
if (!Array.isArray(json.rows)) {
|
|
1396
1414
|
throw new Error("\\begin{tabular} requires rows array");
|
|
1397
1415
|
}
|
|
@@ -1414,7 +1432,7 @@ function parseTableBlock(json, options, path, diagnostics) {
|
|
|
1414
1432
|
pushDiagnostic(diagnostics, options, path, `math_objects count mismatch: detected ${String(mathObjectIndex)}, got ${String(mathObjects.length)}`);
|
|
1415
1433
|
}
|
|
1416
1434
|
return {
|
|
1417
|
-
id:
|
|
1435
|
+
id: blockIdFromJson(json, blockIds),
|
|
1418
1436
|
kind: "table",
|
|
1419
1437
|
command: "\\begin{tabular}",
|
|
1420
1438
|
closing: "\\end{tabular}",
|
|
@@ -1423,11 +1441,11 @@ function parseTableBlock(json, options, path, diagnostics) {
|
|
|
1423
1441
|
...parseFloatMetaFromJson(json)
|
|
1424
1442
|
};
|
|
1425
1443
|
}
|
|
1426
|
-
function parseImageBlock(json) {
|
|
1444
|
+
function parseImageBlock(json, blockIds) {
|
|
1427
1445
|
const assetId = typeof json.asset_id === "string" && json.asset_id.length > 0 ? json.asset_id : void 0;
|
|
1428
1446
|
const value = assetId !== void 0 ? typeof json.value === "string" ? json.value : "" : requireString(json.value, "\\includegraphics requires string value");
|
|
1429
1447
|
return {
|
|
1430
|
-
id:
|
|
1448
|
+
id: blockIdFromJson(json, blockIds),
|
|
1431
1449
|
kind: "image",
|
|
1432
1450
|
command: "\\includegraphics",
|
|
1433
1451
|
value,
|
|
@@ -1436,43 +1454,43 @@ function parseImageBlock(json) {
|
|
|
1436
1454
|
...parseFloatMetaFromJson(json)
|
|
1437
1455
|
};
|
|
1438
1456
|
}
|
|
1439
|
-
function parseRawBlock(json) {
|
|
1457
|
+
function parseRawBlock(json, blockIds) {
|
|
1440
1458
|
return {
|
|
1441
|
-
id:
|
|
1459
|
+
id: blockIdFromJson(json, blockIds),
|
|
1442
1460
|
kind: "raw",
|
|
1443
1461
|
command: "\\raw",
|
|
1444
1462
|
value: typeof json.value === "string" ? json.value : ""
|
|
1445
1463
|
};
|
|
1446
1464
|
}
|
|
1447
|
-
function parseBibliographyBlock() {
|
|
1465
|
+
function parseBibliographyBlock(json, blockIds) {
|
|
1448
1466
|
return {
|
|
1449
|
-
id:
|
|
1467
|
+
id: blockIdFromJson(json, blockIds),
|
|
1450
1468
|
kind: "bibliography",
|
|
1451
1469
|
command: "\\begin{thebibliography}",
|
|
1452
1470
|
closing: "\\end{thebibliography}"
|
|
1453
1471
|
};
|
|
1454
1472
|
}
|
|
1455
|
-
function parseBlock(json, options, path, diagnostics) {
|
|
1473
|
+
function parseBlock(json, options, path, diagnostics, blockIds) {
|
|
1456
1474
|
if (TEXT_COMMANDS.has(json.command)) {
|
|
1457
|
-
return parseTextBlock(json, options, path, diagnostics);
|
|
1475
|
+
return parseTextBlock(json, options, path, diagnostics, blockIds);
|
|
1458
1476
|
}
|
|
1459
1477
|
if (LIST_COMMANDS.has(json.command)) {
|
|
1460
|
-
return parseListBlock(json, options, path, diagnostics);
|
|
1478
|
+
return parseListBlock(json, options, path, diagnostics, blockIds);
|
|
1461
1479
|
}
|
|
1462
1480
|
if (json.command === "\\begin{tabular}") {
|
|
1463
|
-
return parseTableBlock(json, options, path, diagnostics);
|
|
1481
|
+
return parseTableBlock(json, options, path, diagnostics, blockIds);
|
|
1464
1482
|
}
|
|
1465
1483
|
if (json.command === "\\includegraphics") {
|
|
1466
|
-
return parseImageBlock(json);
|
|
1484
|
+
return parseImageBlock(json, blockIds);
|
|
1467
1485
|
}
|
|
1468
1486
|
if (json.command === "\\begin{thebibliography}" || json.command === "\\bibliography") {
|
|
1469
|
-
return parseBibliographyBlock();
|
|
1487
|
+
return parseBibliographyBlock(json, blockIds);
|
|
1470
1488
|
}
|
|
1471
1489
|
if (json.command === "\\raw") {
|
|
1472
|
-
return parseRawBlock(json);
|
|
1490
|
+
return parseRawBlock(json, blockIds);
|
|
1473
1491
|
}
|
|
1474
1492
|
return {
|
|
1475
|
-
id:
|
|
1493
|
+
id: blockIdFromJson(json, blockIds),
|
|
1476
1494
|
kind: "raw",
|
|
1477
1495
|
command: "\\raw",
|
|
1478
1496
|
value: typeof json.value === "string" ? json.value : json.command
|
|
@@ -1486,11 +1504,14 @@ function fromDocumentJson2(json, options = {}) {
|
|
|
1486
1504
|
throw new Error("DocumentObject requires blocks array");
|
|
1487
1505
|
}
|
|
1488
1506
|
const diagnostics = [];
|
|
1507
|
+
const blockIds = { used: /* @__PURE__ */ new Set() };
|
|
1489
1508
|
return {
|
|
1490
1509
|
nodeType: "DocumentObject",
|
|
1491
1510
|
meta: normalizeDocument2Meta(json.meta),
|
|
1492
1511
|
references: parseReferences(json.references),
|
|
1493
|
-
blocks: json.blocks.map(
|
|
1512
|
+
blocks: json.blocks.map(
|
|
1513
|
+
(block, index) => parseBlock(asBlockJson(block), options, `$.blocks[${String(index)}]`, diagnostics, blockIds)
|
|
1514
|
+
),
|
|
1494
1515
|
diagnostics
|
|
1495
1516
|
};
|
|
1496
1517
|
}
|
|
@@ -4574,21 +4595,21 @@ function splitTextForInsertion(token) {
|
|
|
4574
4595
|
function cloneDocument2Node(document2) {
|
|
4575
4596
|
return cloneDocument(document2);
|
|
4576
4597
|
}
|
|
4577
|
-
function insertBlockAfter(blocks,
|
|
4578
|
-
if (!
|
|
4598
|
+
function insertBlockAfter(blocks, afterBlockId2, block) {
|
|
4599
|
+
if (!afterBlockId2) {
|
|
4579
4600
|
blocks.push(block);
|
|
4580
4601
|
return;
|
|
4581
4602
|
}
|
|
4582
|
-
const index = blocks.findIndex((entry) => entry.id ===
|
|
4603
|
+
const index = blocks.findIndex((entry) => entry.id === afterBlockId2);
|
|
4583
4604
|
if (index < 0) {
|
|
4584
4605
|
blocks.push(block);
|
|
4585
4606
|
return;
|
|
4586
4607
|
}
|
|
4587
4608
|
blocks.splice(index + 1, 0, block);
|
|
4588
4609
|
}
|
|
4589
|
-
function insertDocument2BlockAfter(document2,
|
|
4610
|
+
function insertDocument2BlockAfter(document2, afterBlockId2, block) {
|
|
4590
4611
|
const next = cloneDocument(document2);
|
|
4591
|
-
insertBlockAfter(next.blocks,
|
|
4612
|
+
insertBlockAfter(next.blocks, afterBlockId2, block);
|
|
4592
4613
|
return next;
|
|
4593
4614
|
}
|
|
4594
4615
|
function moveDocument2BlockById(document2, blockId, direction) {
|
|
@@ -4808,7 +4829,7 @@ function replaceMathTokenFromSession(document2, tokenId, session, opening, closi
|
|
|
4808
4829
|
});
|
|
4809
4830
|
return next;
|
|
4810
4831
|
}
|
|
4811
|
-
function addDocument2TextBlock(document2, command = "\\paragraph",
|
|
4832
|
+
function addDocument2TextBlock(document2, command = "\\paragraph", afterBlockId2) {
|
|
4812
4833
|
const block = {
|
|
4813
4834
|
id: document2Id("block"),
|
|
4814
4835
|
kind: "textBlock",
|
|
@@ -4816,7 +4837,7 @@ function addDocument2TextBlock(document2, command = "\\paragraph", afterBlockId)
|
|
|
4816
4837
|
field: createInlineField2(""),
|
|
4817
4838
|
...command === "\\paragraph" ? { centered: false } : {}
|
|
4818
4839
|
};
|
|
4819
|
-
return insertDocument2BlockAfter(document2,
|
|
4840
|
+
return insertDocument2BlockAfter(document2, afterBlockId2, block);
|
|
4820
4841
|
}
|
|
4821
4842
|
function updateDocument2TextBlockCentered(document2, blockId, centered) {
|
|
4822
4843
|
const next = cloneDocument(document2);
|
|
@@ -4855,10 +4876,10 @@ function newListBlock(ordered) {
|
|
|
4855
4876
|
items: [{ id: document2Id("item"), field: createInlineField2(""), blocks: [] }]
|
|
4856
4877
|
};
|
|
4857
4878
|
}
|
|
4858
|
-
function addDocument2ListBlock(document2, ordered,
|
|
4859
|
-
return insertDocument2BlockAfter(document2,
|
|
4879
|
+
function addDocument2ListBlock(document2, ordered, afterBlockId2) {
|
|
4880
|
+
return insertDocument2BlockAfter(document2, afterBlockId2, newListBlock(ordered));
|
|
4860
4881
|
}
|
|
4861
|
-
function addDocument2TableBlock(document2, columns = "lll", rowCount = 3, colCount = 3,
|
|
4882
|
+
function addDocument2TableBlock(document2, columns = "lll", rowCount = 3, colCount = 3, afterBlockId2) {
|
|
4862
4883
|
const rows = Math.max(1, rowCount);
|
|
4863
4884
|
const cols = Math.max(1, colCount);
|
|
4864
4885
|
const tableRows = [];
|
|
@@ -4878,18 +4899,29 @@ function addDocument2TableBlock(document2, columns = "lll", rowCount = 3, colCou
|
|
|
4878
4899
|
rows: tableRows,
|
|
4879
4900
|
...defaultFloatMeta()
|
|
4880
4901
|
};
|
|
4881
|
-
return insertDocument2BlockAfter(document2,
|
|
4902
|
+
return insertDocument2BlockAfter(document2, afterBlockId2, block);
|
|
4903
|
+
}
|
|
4904
|
+
function normalizeImageInput(srcOrAsset) {
|
|
4905
|
+
if (typeof srcOrAsset === "string") {
|
|
4906
|
+
return srcOrAsset.length > 0 ? { value: srcOrAsset, assetId: srcOrAsset } : { value: "" };
|
|
4907
|
+
}
|
|
4908
|
+
if (srcOrAsset && srcOrAsset.assetId.length > 0) {
|
|
4909
|
+
return { value: srcOrAsset.value ?? srcOrAsset.assetId, assetId: srcOrAsset.assetId };
|
|
4910
|
+
}
|
|
4911
|
+
return { value: "" };
|
|
4882
4912
|
}
|
|
4883
|
-
function addDocument2ImageBlock(document2,
|
|
4913
|
+
function addDocument2ImageBlock(document2, srcOrAsset, afterBlockId2) {
|
|
4914
|
+
const image = normalizeImageInput(srcOrAsset);
|
|
4884
4915
|
const block = {
|
|
4885
4916
|
id: document2Id("block"),
|
|
4886
4917
|
kind: "image",
|
|
4887
4918
|
command: "\\includegraphics",
|
|
4888
|
-
value:
|
|
4919
|
+
value: image.value,
|
|
4920
|
+
...image.assetId !== void 0 ? { assetId: image.assetId } : {},
|
|
4889
4921
|
options: { width: "0.8\\columnwidth" },
|
|
4890
4922
|
...defaultFloatMeta()
|
|
4891
4923
|
};
|
|
4892
|
-
return insertDocument2BlockAfter(document2,
|
|
4924
|
+
return insertDocument2BlockAfter(document2, afterBlockId2, block);
|
|
4893
4925
|
}
|
|
4894
4926
|
function updateDocument2ImageValue(document2, blockId, value) {
|
|
4895
4927
|
const next = cloneDocument(document2);
|
|
@@ -4912,6 +4944,55 @@ function updateDocument2ImageValue(document2, blockId, value) {
|
|
|
4912
4944
|
visit(next.blocks);
|
|
4913
4945
|
return next;
|
|
4914
4946
|
}
|
|
4947
|
+
function updateDocument2ImageAsset(document2, blockId, asset) {
|
|
4948
|
+
const next = cloneDocument(document2);
|
|
4949
|
+
const image = normalizeImageInput(asset);
|
|
4950
|
+
function visit(blocks) {
|
|
4951
|
+
for (const block of blocks) {
|
|
4952
|
+
if (block.id === blockId && block.kind === "image") {
|
|
4953
|
+
block.value = image.value;
|
|
4954
|
+
if (image.assetId !== void 0) {
|
|
4955
|
+
block.assetId = image.assetId;
|
|
4956
|
+
} else {
|
|
4957
|
+
delete block.assetId;
|
|
4958
|
+
}
|
|
4959
|
+
return true;
|
|
4960
|
+
}
|
|
4961
|
+
if (block.kind === "list") {
|
|
4962
|
+
for (const item of block.items) {
|
|
4963
|
+
if (visit(item.blocks)) {
|
|
4964
|
+
return true;
|
|
4965
|
+
}
|
|
4966
|
+
}
|
|
4967
|
+
}
|
|
4968
|
+
}
|
|
4969
|
+
return false;
|
|
4970
|
+
}
|
|
4971
|
+
visit(next.blocks);
|
|
4972
|
+
return next;
|
|
4973
|
+
}
|
|
4974
|
+
function clearDocument2ImageAsset(document2, blockId) {
|
|
4975
|
+
const next = cloneDocument(document2);
|
|
4976
|
+
function visit(blocks) {
|
|
4977
|
+
for (const block of blocks) {
|
|
4978
|
+
if (block.id === blockId && block.kind === "image") {
|
|
4979
|
+
block.value = "";
|
|
4980
|
+
delete block.assetId;
|
|
4981
|
+
return true;
|
|
4982
|
+
}
|
|
4983
|
+
if (block.kind === "list") {
|
|
4984
|
+
for (const item of block.items) {
|
|
4985
|
+
if (visit(item.blocks)) {
|
|
4986
|
+
return true;
|
|
4987
|
+
}
|
|
4988
|
+
}
|
|
4989
|
+
}
|
|
4990
|
+
}
|
|
4991
|
+
return false;
|
|
4992
|
+
}
|
|
4993
|
+
visit(next.blocks);
|
|
4994
|
+
return next;
|
|
4995
|
+
}
|
|
4915
4996
|
function updateDocument2ImageMeta(document2, blockId, patch) {
|
|
4916
4997
|
const next = cloneDocument(document2);
|
|
4917
4998
|
function visit(blocks) {
|
|
@@ -5130,7 +5211,7 @@ function removeCiteTokenById(document2, tokenId) {
|
|
|
5130
5211
|
});
|
|
5131
5212
|
return next;
|
|
5132
5213
|
}
|
|
5133
|
-
function ensureDocument2BibliographyBlock(document2,
|
|
5214
|
+
function ensureDocument2BibliographyBlock(document2, afterBlockId2) {
|
|
5134
5215
|
if (document2.blocks.some((block2) => block2.kind === "bibliography")) {
|
|
5135
5216
|
return document2;
|
|
5136
5217
|
}
|
|
@@ -5140,7 +5221,7 @@ function ensureDocument2BibliographyBlock(document2, afterBlockId) {
|
|
|
5140
5221
|
command: "\\begin{thebibliography}",
|
|
5141
5222
|
closing: "\\end{thebibliography}"
|
|
5142
5223
|
};
|
|
5143
|
-
return insertDocument2BlockAfter(document2,
|
|
5224
|
+
return insertDocument2BlockAfter(document2, afterBlockId2 ?? null, block);
|
|
5144
5225
|
}
|
|
5145
5226
|
function addDocument2Reference(document2, partial = {}) {
|
|
5146
5227
|
const next = cloneDocument(document2);
|
|
@@ -5212,6 +5293,440 @@ function updateDocument2Meta(document2, patch) {
|
|
|
5212
5293
|
return next;
|
|
5213
5294
|
}
|
|
5214
5295
|
|
|
5296
|
+
// src/document2/exportJson.ts
|
|
5297
|
+
function serializeField(field) {
|
|
5298
|
+
let value = "";
|
|
5299
|
+
let hasPersistedMath = false;
|
|
5300
|
+
const formats = [];
|
|
5301
|
+
const mathObjects = [];
|
|
5302
|
+
for (const token of field.tokens) {
|
|
5303
|
+
if (token.kind === "text") {
|
|
5304
|
+
const start = value.length;
|
|
5305
|
+
value += token.text;
|
|
5306
|
+
if (token.text.length > 0 && (token.style?.bold || token.style?.italic || token.style?.underline)) {
|
|
5307
|
+
formats.push({
|
|
5308
|
+
start,
|
|
5309
|
+
end: value.length,
|
|
5310
|
+
...token.style.bold ? { bold: true } : {},
|
|
5311
|
+
...token.style.italic ? { italic: true } : {},
|
|
5312
|
+
...token.style.underline ? { underline: true } : {}
|
|
5313
|
+
});
|
|
5314
|
+
}
|
|
5315
|
+
continue;
|
|
5316
|
+
}
|
|
5317
|
+
if (token.kind === "cite") {
|
|
5318
|
+
value += citeTokenLatex(token.keys);
|
|
5319
|
+
continue;
|
|
5320
|
+
}
|
|
5321
|
+
if (token.kind === "ref") {
|
|
5322
|
+
value += refTokenLatex(token.keys, token.refCommand);
|
|
5323
|
+
continue;
|
|
5324
|
+
}
|
|
5325
|
+
value += token.source;
|
|
5326
|
+
if (!token.math || token.sourceOwner === "raw") {
|
|
5327
|
+
if (token.labelEnabled !== void 0 || token.label !== void 0) {
|
|
5328
|
+
hasPersistedMath = true;
|
|
5329
|
+
mathObjects.push({
|
|
5330
|
+
node_type: "RawMathObject",
|
|
5331
|
+
...token.labelEnabled !== void 0 ? { label_enabled: token.labelEnabled } : {},
|
|
5332
|
+
...token.label !== void 0 ? { label: token.label } : {}
|
|
5333
|
+
});
|
|
5334
|
+
} else {
|
|
5335
|
+
mathObjects.push(null);
|
|
5336
|
+
}
|
|
5337
|
+
continue;
|
|
5338
|
+
}
|
|
5339
|
+
hasPersistedMath = true;
|
|
5340
|
+
mathObjects.push({
|
|
5341
|
+
...toMathObjectJson(token.math),
|
|
5342
|
+
...token.sourceSide ? { source_side: token.sourceSide } : {},
|
|
5343
|
+
source_owner: token.sourceOwner,
|
|
5344
|
+
...token.labelEnabled !== void 0 ? { label_enabled: token.labelEnabled } : {},
|
|
5345
|
+
...token.label !== void 0 ? { label: token.label } : {}
|
|
5346
|
+
});
|
|
5347
|
+
}
|
|
5348
|
+
return { value, formats, mathObjects, hasPersistedMath };
|
|
5349
|
+
}
|
|
5350
|
+
function fieldJson(field) {
|
|
5351
|
+
const serialized = serializeField(field);
|
|
5352
|
+
return {
|
|
5353
|
+
value: serialized.value,
|
|
5354
|
+
...serialized.formats.length > 0 ? { formats: serialized.formats } : {},
|
|
5355
|
+
...serialized.hasPersistedMath ? { math_objects: serialized.mathObjects } : {}
|
|
5356
|
+
};
|
|
5357
|
+
}
|
|
5358
|
+
function listItemJson(item) {
|
|
5359
|
+
const field = fieldJson(item.field);
|
|
5360
|
+
return {
|
|
5361
|
+
value: field.value ?? "",
|
|
5362
|
+
...field.formats ? { formats: field.formats } : {},
|
|
5363
|
+
...field.math_objects ? { math_objects: field.math_objects } : {},
|
|
5364
|
+
...item.blocks.length > 0 ? { blocks: item.blocks.map(blockJson) } : {}
|
|
5365
|
+
};
|
|
5366
|
+
}
|
|
5367
|
+
function blockJson(block) {
|
|
5368
|
+
if (block.kind === "textBlock") {
|
|
5369
|
+
return {
|
|
5370
|
+
id: block.id,
|
|
5371
|
+
command: block.command,
|
|
5372
|
+
...fieldJson(block.field),
|
|
5373
|
+
...block.command === "\\paragraph" ? { centered: block.centered === true } : {}
|
|
5374
|
+
};
|
|
5375
|
+
}
|
|
5376
|
+
if (block.kind === "list") {
|
|
5377
|
+
return {
|
|
5378
|
+
id: block.id,
|
|
5379
|
+
command: block.command,
|
|
5380
|
+
closing: block.closing,
|
|
5381
|
+
items: block.items.map(listItemJson)
|
|
5382
|
+
};
|
|
5383
|
+
}
|
|
5384
|
+
if (block.kind === "table") {
|
|
5385
|
+
const fields = block.rows.map((row) => row.map(serializeField));
|
|
5386
|
+
const hasPersistedMath = fields.some((row) => row.some((field) => field.hasPersistedMath));
|
|
5387
|
+
return {
|
|
5388
|
+
id: block.id,
|
|
5389
|
+
command: block.command,
|
|
5390
|
+
closing: block.closing,
|
|
5391
|
+
columns: block.columns,
|
|
5392
|
+
rows: fields.map((row) => row.map((field) => field.value)),
|
|
5393
|
+
...fields.some((row) => row.some((field) => field.formats.length > 0)) ? { cell_formats: fields.map((row) => row.map((field) => field.formats)) } : {},
|
|
5394
|
+
...hasPersistedMath ? { math_objects: fields.flatMap((row) => row.flatMap((field) => field.mathObjects)) } : {},
|
|
5395
|
+
centered: block.centered,
|
|
5396
|
+
caption_enabled: block.captionEnabled,
|
|
5397
|
+
caption: block.caption,
|
|
5398
|
+
label_enabled: block.labelEnabled,
|
|
5399
|
+
label: block.label
|
|
5400
|
+
};
|
|
5401
|
+
}
|
|
5402
|
+
if (block.kind === "image") {
|
|
5403
|
+
return {
|
|
5404
|
+
id: block.id,
|
|
5405
|
+
command: block.command,
|
|
5406
|
+
value: block.value,
|
|
5407
|
+
...block.assetId !== void 0 ? { asset_id: block.assetId } : {},
|
|
5408
|
+
options: { ...block.options },
|
|
5409
|
+
centered: block.centered,
|
|
5410
|
+
caption_enabled: block.captionEnabled,
|
|
5411
|
+
caption: block.caption,
|
|
5412
|
+
label_enabled: block.labelEnabled,
|
|
5413
|
+
label: block.label
|
|
5414
|
+
};
|
|
5415
|
+
}
|
|
5416
|
+
if (block.kind === "bibliography") {
|
|
5417
|
+
return { id: block.id, command: block.command, closing: block.closing };
|
|
5418
|
+
}
|
|
5419
|
+
return { id: block.id, command: block.command, value: block.value };
|
|
5420
|
+
}
|
|
5421
|
+
function referenceJson(reference) {
|
|
5422
|
+
return {
|
|
5423
|
+
key: reference.key,
|
|
5424
|
+
authors: reference.authors,
|
|
5425
|
+
title: reference.title,
|
|
5426
|
+
year: reference.year,
|
|
5427
|
+
url: reference.url,
|
|
5428
|
+
venue: reference.venue,
|
|
5429
|
+
field_separator: reference.fieldSeparator
|
|
5430
|
+
};
|
|
5431
|
+
}
|
|
5432
|
+
function toDocumentJson2(document2) {
|
|
5433
|
+
if (document2.nodeType !== "DocumentObject" || !Array.isArray(document2.blocks)) {
|
|
5434
|
+
throw new Error("toDocumentJson2 requires a live Document2Node");
|
|
5435
|
+
}
|
|
5436
|
+
return {
|
|
5437
|
+
node_type: "DocumentObject",
|
|
5438
|
+
meta: {
|
|
5439
|
+
title: document2.meta.title,
|
|
5440
|
+
authors: document2.meta.authors,
|
|
5441
|
+
date: { ...document2.meta.date },
|
|
5442
|
+
abstract: document2.meta.abstract
|
|
5443
|
+
},
|
|
5444
|
+
references: document2.references.map(referenceJson),
|
|
5445
|
+
blocks: document2.blocks.map(blockJson)
|
|
5446
|
+
};
|
|
5447
|
+
}
|
|
5448
|
+
|
|
5449
|
+
// src/document2/jsonCommands.ts
|
|
5450
|
+
var Document2CommandError = class extends Error {
|
|
5451
|
+
code;
|
|
5452
|
+
constructor(code, message) {
|
|
5453
|
+
super(message);
|
|
5454
|
+
this.name = "Document2CommandError";
|
|
5455
|
+
this.code = code;
|
|
5456
|
+
}
|
|
5457
|
+
};
|
|
5458
|
+
function isObject3(value) {
|
|
5459
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5460
|
+
}
|
|
5461
|
+
function requireString2(value, field, allowEmpty = true) {
|
|
5462
|
+
if (typeof value !== "string" || !allowEmpty && value.trim().length === 0) {
|
|
5463
|
+
throw new Document2CommandError("invalid_command", `${field} must be a${allowEmpty ? "" : " non-empty"} string`);
|
|
5464
|
+
}
|
|
5465
|
+
return value;
|
|
5466
|
+
}
|
|
5467
|
+
function parseAnchor(value) {
|
|
5468
|
+
if (!isObject3(value)) {
|
|
5469
|
+
throw new Document2CommandError("invalid_command", "anchor must be an object");
|
|
5470
|
+
}
|
|
5471
|
+
const hasEnd = value.end === true;
|
|
5472
|
+
const afterBlockId2 = typeof value.after_block_id === "string" ? value.after_block_id.trim() : "";
|
|
5473
|
+
const hasAfterBlock = afterBlockId2.length > 0;
|
|
5474
|
+
if (hasEnd && hasAfterBlock) {
|
|
5475
|
+
throw new Document2CommandError("invalid_command", "anchor cannot contain both end and after_block_id");
|
|
5476
|
+
}
|
|
5477
|
+
if (hasEnd) {
|
|
5478
|
+
return { end: true };
|
|
5479
|
+
}
|
|
5480
|
+
if (hasAfterBlock) {
|
|
5481
|
+
return { after_block_id: afterBlockId2 };
|
|
5482
|
+
}
|
|
5483
|
+
throw new Document2CommandError("invalid_command", "anchor requires end: true or a non-empty after_block_id");
|
|
5484
|
+
}
|
|
5485
|
+
function optionalString(value, field) {
|
|
5486
|
+
if (!(field in value)) {
|
|
5487
|
+
return void 0;
|
|
5488
|
+
}
|
|
5489
|
+
if (typeof value[field] !== "string") {
|
|
5490
|
+
throw new Document2CommandError("invalid_command", `${field} must be a string when provided`);
|
|
5491
|
+
}
|
|
5492
|
+
return value[field];
|
|
5493
|
+
}
|
|
5494
|
+
function parseTextBlockKind(value) {
|
|
5495
|
+
if (value === "section" || value === "subsection" || value === "subsubsection" || value === "paragraph") {
|
|
5496
|
+
return value;
|
|
5497
|
+
}
|
|
5498
|
+
throw new Document2CommandError("invalid_command", "kind must be section, subsection, subsubsection, or paragraph");
|
|
5499
|
+
}
|
|
5500
|
+
function parseCommand2(value) {
|
|
5501
|
+
if (!isObject3(value) || typeof value.op !== "string") {
|
|
5502
|
+
throw new Document2CommandError("invalid_command", "command requires an op");
|
|
5503
|
+
}
|
|
5504
|
+
if (value.op === "insert_text_block") {
|
|
5505
|
+
return {
|
|
5506
|
+
op: value.op,
|
|
5507
|
+
kind: parseTextBlockKind(value.kind),
|
|
5508
|
+
text: requireString2(value.text, "text"),
|
|
5509
|
+
anchor: parseAnchor(value.anchor)
|
|
5510
|
+
};
|
|
5511
|
+
}
|
|
5512
|
+
if (value.op === "replace_text_block") {
|
|
5513
|
+
return {
|
|
5514
|
+
op: value.op,
|
|
5515
|
+
block_id: requireString2(value.block_id, "block_id", false).trim(),
|
|
5516
|
+
text: requireString2(value.text, "text")
|
|
5517
|
+
};
|
|
5518
|
+
}
|
|
5519
|
+
if (value.op === "remove_block") {
|
|
5520
|
+
return {
|
|
5521
|
+
op: value.op,
|
|
5522
|
+
block_id: requireString2(value.block_id, "block_id", false).trim()
|
|
5523
|
+
};
|
|
5524
|
+
}
|
|
5525
|
+
if (value.op === "insert_figure") {
|
|
5526
|
+
const figureValue = optionalString(value, "value");
|
|
5527
|
+
const caption = optionalString(value, "caption");
|
|
5528
|
+
const label = optionalString(value, "label");
|
|
5529
|
+
return {
|
|
5530
|
+
op: value.op,
|
|
5531
|
+
asset_id: requireString2(value.asset_id, "asset_id", false).trim(),
|
|
5532
|
+
...figureValue !== void 0 ? { value: figureValue } : {},
|
|
5533
|
+
...caption !== void 0 ? { caption } : {},
|
|
5534
|
+
...label !== void 0 ? { label } : {},
|
|
5535
|
+
anchor: parseAnchor(value.anchor)
|
|
5536
|
+
};
|
|
5537
|
+
}
|
|
5538
|
+
throw new Document2CommandError("invalid_command", `Unsupported document command: ${value.op}`);
|
|
5539
|
+
}
|
|
5540
|
+
function parseDocument(json) {
|
|
5541
|
+
try {
|
|
5542
|
+
return fromDocumentJson2(json);
|
|
5543
|
+
} catch (error) {
|
|
5544
|
+
const message = error instanceof Error ? error.message : "Invalid DocumentObject JSON";
|
|
5545
|
+
throw new Document2CommandError("invalid_document", message);
|
|
5546
|
+
}
|
|
5547
|
+
}
|
|
5548
|
+
function commandForKind(kind) {
|
|
5549
|
+
if (kind === "section") {
|
|
5550
|
+
return "\\section";
|
|
5551
|
+
}
|
|
5552
|
+
if (kind === "subsection") {
|
|
5553
|
+
return "\\subsection";
|
|
5554
|
+
}
|
|
5555
|
+
if (kind === "subsubsection") {
|
|
5556
|
+
return "\\subsubsection";
|
|
5557
|
+
}
|
|
5558
|
+
return "\\paragraph";
|
|
5559
|
+
}
|
|
5560
|
+
function insertionIndex(document2, anchor) {
|
|
5561
|
+
if ("end" in anchor) {
|
|
5562
|
+
return document2.blocks.length;
|
|
5563
|
+
}
|
|
5564
|
+
const index = document2.blocks.findIndex((block) => block.id === anchor.after_block_id);
|
|
5565
|
+
if (index < 0) {
|
|
5566
|
+
throw new Document2CommandError("anchor_not_found", `Anchor block was not found: ${anchor.after_block_id}`);
|
|
5567
|
+
}
|
|
5568
|
+
return index + 1;
|
|
5569
|
+
}
|
|
5570
|
+
function afterBlockId(document2, index) {
|
|
5571
|
+
return index > 0 ? document2.blocks[index - 1]?.id ?? null : null;
|
|
5572
|
+
}
|
|
5573
|
+
function insertedBlock(document2, index) {
|
|
5574
|
+
const block = document2.blocks[index];
|
|
5575
|
+
if (!block) {
|
|
5576
|
+
throw new Document2CommandError("invalid_command", "Document command did not insert a block");
|
|
5577
|
+
}
|
|
5578
|
+
return block;
|
|
5579
|
+
}
|
|
5580
|
+
function insertTextBlock(document2, command) {
|
|
5581
|
+
const index = insertionIndex(document2, command.anchor);
|
|
5582
|
+
const next = addDocument2TextBlock(document2, commandForKind(command.kind), afterBlockId(document2, index));
|
|
5583
|
+
const block = insertedBlock(next, index);
|
|
5584
|
+
if (block.kind !== "textBlock") {
|
|
5585
|
+
throw new Document2CommandError("block_kind_mismatch", "Inserted block is not a text block");
|
|
5586
|
+
}
|
|
5587
|
+
block.field = createInlineField2(command.text);
|
|
5588
|
+
return next;
|
|
5589
|
+
}
|
|
5590
|
+
function replaceTextBlock(document2, command) {
|
|
5591
|
+
const index = document2.blocks.findIndex((block2) => block2.id === command.block_id);
|
|
5592
|
+
if (index < 0) {
|
|
5593
|
+
throw new Document2CommandError("block_not_found", `Document block was not found: ${command.block_id}`);
|
|
5594
|
+
}
|
|
5595
|
+
const block = document2.blocks[index];
|
|
5596
|
+
if (!block || block.kind !== "textBlock") {
|
|
5597
|
+
throw new Document2CommandError("block_kind_mismatch", `Document block is not a text block: ${command.block_id}`);
|
|
5598
|
+
}
|
|
5599
|
+
if (block.field.tokens.some((token) => token.kind !== "text" || token.style !== void 0)) {
|
|
5600
|
+
throw new Document2CommandError(
|
|
5601
|
+
"unsupported_inline_content",
|
|
5602
|
+
"Whole-block replacement is not supported for formatted or structured inline content"
|
|
5603
|
+
);
|
|
5604
|
+
}
|
|
5605
|
+
const next = parseDocument(toDocumentJson2(document2));
|
|
5606
|
+
const nextBlock = next.blocks[index];
|
|
5607
|
+
if (!nextBlock || nextBlock.kind !== "textBlock") {
|
|
5608
|
+
throw new Document2CommandError("block_kind_mismatch", `Document block is not a text block: ${command.block_id}`);
|
|
5609
|
+
}
|
|
5610
|
+
nextBlock.field = createInlineField2(command.text);
|
|
5611
|
+
return next;
|
|
5612
|
+
}
|
|
5613
|
+
function removeBlock(document2, command) {
|
|
5614
|
+
if (!document2.blocks.some((block) => block.id === command.block_id)) {
|
|
5615
|
+
throw new Document2CommandError("block_not_found", `Document block was not found: ${command.block_id}`);
|
|
5616
|
+
}
|
|
5617
|
+
return removeDocument2BlockById(document2, command.block_id);
|
|
5618
|
+
}
|
|
5619
|
+
function insertFigure(document2, command) {
|
|
5620
|
+
const index = insertionIndex(document2, command.anchor);
|
|
5621
|
+
const next = addDocument2ImageBlock(
|
|
5622
|
+
document2,
|
|
5623
|
+
{ assetId: command.asset_id, ...command.value !== void 0 ? { value: command.value } : {} },
|
|
5624
|
+
afterBlockId(document2, index)
|
|
5625
|
+
);
|
|
5626
|
+
const block = insertedBlock(next, index);
|
|
5627
|
+
if (block.kind !== "image") {
|
|
5628
|
+
throw new Document2CommandError("block_kind_mismatch", "Inserted block is not a figure");
|
|
5629
|
+
}
|
|
5630
|
+
if (command.caption !== void 0) {
|
|
5631
|
+
block.caption = command.caption;
|
|
5632
|
+
block.captionEnabled = command.caption.trim().length > 0;
|
|
5633
|
+
}
|
|
5634
|
+
if (command.label !== void 0) {
|
|
5635
|
+
block.label = command.label;
|
|
5636
|
+
block.labelEnabled = command.label.trim().length > 0;
|
|
5637
|
+
}
|
|
5638
|
+
return next;
|
|
5639
|
+
}
|
|
5640
|
+
function applyDocument2Command(json, commandInput) {
|
|
5641
|
+
const document2 = parseDocument(json);
|
|
5642
|
+
const command = parseCommand2(commandInput);
|
|
5643
|
+
let next;
|
|
5644
|
+
if (command.op === "insert_text_block") {
|
|
5645
|
+
next = insertTextBlock(document2, command);
|
|
5646
|
+
} else if (command.op === "replace_text_block") {
|
|
5647
|
+
next = replaceTextBlock(document2, command);
|
|
5648
|
+
} else if (command.op === "remove_block") {
|
|
5649
|
+
next = removeBlock(document2, command);
|
|
5650
|
+
} else {
|
|
5651
|
+
next = insertFigure(document2, command);
|
|
5652
|
+
}
|
|
5653
|
+
return toDocumentJson2(next);
|
|
5654
|
+
}
|
|
5655
|
+
|
|
5656
|
+
// src/document2/outline.ts
|
|
5657
|
+
var EXCERPT_LIMIT = 160;
|
|
5658
|
+
function normalizeExcerpt(value) {
|
|
5659
|
+
const normalized = value.replace(/\s+/g, " ").trim();
|
|
5660
|
+
if (normalized.length <= EXCERPT_LIMIT) {
|
|
5661
|
+
return normalized;
|
|
5662
|
+
}
|
|
5663
|
+
return `${normalized.slice(0, EXCERPT_LIMIT - 3)}...`;
|
|
5664
|
+
}
|
|
5665
|
+
function outlineKind(command) {
|
|
5666
|
+
if (command === "\\section") {
|
|
5667
|
+
return "section";
|
|
5668
|
+
}
|
|
5669
|
+
if (command === "\\subsection") {
|
|
5670
|
+
return "subsection";
|
|
5671
|
+
}
|
|
5672
|
+
if (command === "\\subsubsection") {
|
|
5673
|
+
return "subsubsection";
|
|
5674
|
+
}
|
|
5675
|
+
if (command === "\\paragraph") {
|
|
5676
|
+
return "paragraph";
|
|
5677
|
+
}
|
|
5678
|
+
if (command === "\\begin{itemize}" || command === "\\begin{enumerate}") {
|
|
5679
|
+
return "list";
|
|
5680
|
+
}
|
|
5681
|
+
if (command === "\\begin{tabular}") {
|
|
5682
|
+
return "table";
|
|
5683
|
+
}
|
|
5684
|
+
if (command === "\\includegraphics") {
|
|
5685
|
+
return "figure";
|
|
5686
|
+
}
|
|
5687
|
+
if (command === "\\begin{thebibliography}" || command === "\\bibliography") {
|
|
5688
|
+
return "bibliography";
|
|
5689
|
+
}
|
|
5690
|
+
return "raw";
|
|
5691
|
+
}
|
|
5692
|
+
function blockExcerpt(block) {
|
|
5693
|
+
if (block.command === "\\begin{itemize}" || block.command === "\\begin{enumerate}") {
|
|
5694
|
+
return normalizeExcerpt((block.items ?? []).map((item) => item.value).join(" "));
|
|
5695
|
+
}
|
|
5696
|
+
if (block.command === "\\begin{tabular}") {
|
|
5697
|
+
return normalizeExcerpt((block.rows ?? []).flat().join(" "));
|
|
5698
|
+
}
|
|
5699
|
+
if (block.command === "\\includegraphics") {
|
|
5700
|
+
return normalizeExcerpt(block.caption || block.asset_id || block.value || "");
|
|
5701
|
+
}
|
|
5702
|
+
return normalizeExcerpt(block.value ?? "");
|
|
5703
|
+
}
|
|
5704
|
+
function document2Outline(json) {
|
|
5705
|
+
if (!json || json.node_type !== "DocumentObject" || !Array.isArray(json.blocks)) {
|
|
5706
|
+
throw new Document2CommandError("invalid_document", "DocumentObject requires a blocks array");
|
|
5707
|
+
}
|
|
5708
|
+
const usedIds = /* @__PURE__ */ new Set();
|
|
5709
|
+
return json.blocks.map((block) => {
|
|
5710
|
+
if (!block || typeof block !== "object" || typeof block.command !== "string") {
|
|
5711
|
+
throw new Document2CommandError("invalid_document", "Document outline requires blocks with string commands");
|
|
5712
|
+
}
|
|
5713
|
+
const id = typeof block.id === "string" ? block.id.trim() : "";
|
|
5714
|
+
if (id.length === 0) {
|
|
5715
|
+
throw new Document2CommandError("missing_block_id", "Document outline requires canonical block IDs");
|
|
5716
|
+
}
|
|
5717
|
+
if (usedIds.has(id)) {
|
|
5718
|
+
throw new Document2CommandError("duplicate_block_id", `Duplicate document block ID: ${id}`);
|
|
5719
|
+
}
|
|
5720
|
+
usedIds.add(id);
|
|
5721
|
+
return {
|
|
5722
|
+
id,
|
|
5723
|
+
kind: outlineKind(block.command),
|
|
5724
|
+
command: block.command,
|
|
5725
|
+
excerpt: blockExcerpt(block)
|
|
5726
|
+
};
|
|
5727
|
+
});
|
|
5728
|
+
}
|
|
5729
|
+
|
|
5215
5730
|
// src/document2/keys.ts
|
|
5216
5731
|
var DOCUMENT2_KEY_PATTERN = /^[\p{L}\p{M}0-9:._-]+$/u;
|
|
5217
5732
|
function normalizeDocument2Key(key) {
|
|
@@ -5696,155 +6211,6 @@ ${body}
|
|
|
5696
6211
|
`;
|
|
5697
6212
|
}
|
|
5698
6213
|
|
|
5699
|
-
// src/document2/exportJson.ts
|
|
5700
|
-
function serializeField(field) {
|
|
5701
|
-
let value = "";
|
|
5702
|
-
let hasPersistedMath = false;
|
|
5703
|
-
const formats = [];
|
|
5704
|
-
const mathObjects = [];
|
|
5705
|
-
for (const token of field.tokens) {
|
|
5706
|
-
if (token.kind === "text") {
|
|
5707
|
-
const start = value.length;
|
|
5708
|
-
value += token.text;
|
|
5709
|
-
if (token.text.length > 0 && (token.style?.bold || token.style?.italic || token.style?.underline)) {
|
|
5710
|
-
formats.push({
|
|
5711
|
-
start,
|
|
5712
|
-
end: value.length,
|
|
5713
|
-
...token.style.bold ? { bold: true } : {},
|
|
5714
|
-
...token.style.italic ? { italic: true } : {},
|
|
5715
|
-
...token.style.underline ? { underline: true } : {}
|
|
5716
|
-
});
|
|
5717
|
-
}
|
|
5718
|
-
continue;
|
|
5719
|
-
}
|
|
5720
|
-
if (token.kind === "cite") {
|
|
5721
|
-
value += citeTokenLatex(token.keys);
|
|
5722
|
-
continue;
|
|
5723
|
-
}
|
|
5724
|
-
if (token.kind === "ref") {
|
|
5725
|
-
value += refTokenLatex(token.keys, token.refCommand);
|
|
5726
|
-
continue;
|
|
5727
|
-
}
|
|
5728
|
-
value += token.source;
|
|
5729
|
-
if (!token.math || token.sourceOwner === "raw") {
|
|
5730
|
-
if (token.labelEnabled !== void 0 || token.label !== void 0) {
|
|
5731
|
-
hasPersistedMath = true;
|
|
5732
|
-
mathObjects.push({
|
|
5733
|
-
node_type: "RawMathObject",
|
|
5734
|
-
...token.labelEnabled !== void 0 ? { label_enabled: token.labelEnabled } : {},
|
|
5735
|
-
...token.label !== void 0 ? { label: token.label } : {}
|
|
5736
|
-
});
|
|
5737
|
-
} else {
|
|
5738
|
-
mathObjects.push(null);
|
|
5739
|
-
}
|
|
5740
|
-
continue;
|
|
5741
|
-
}
|
|
5742
|
-
hasPersistedMath = true;
|
|
5743
|
-
mathObjects.push({
|
|
5744
|
-
...toMathObjectJson(token.math),
|
|
5745
|
-
...token.sourceSide ? { source_side: token.sourceSide } : {},
|
|
5746
|
-
source_owner: token.sourceOwner,
|
|
5747
|
-
...token.labelEnabled !== void 0 ? { label_enabled: token.labelEnabled } : {},
|
|
5748
|
-
...token.label !== void 0 ? { label: token.label } : {}
|
|
5749
|
-
});
|
|
5750
|
-
}
|
|
5751
|
-
return { value, formats, mathObjects, hasPersistedMath };
|
|
5752
|
-
}
|
|
5753
|
-
function fieldJson(field) {
|
|
5754
|
-
const serialized = serializeField(field);
|
|
5755
|
-
return {
|
|
5756
|
-
value: serialized.value,
|
|
5757
|
-
...serialized.formats.length > 0 ? { formats: serialized.formats } : {},
|
|
5758
|
-
...serialized.hasPersistedMath ? { math_objects: serialized.mathObjects } : {}
|
|
5759
|
-
};
|
|
5760
|
-
}
|
|
5761
|
-
function listItemJson(item) {
|
|
5762
|
-
const field = fieldJson(item.field);
|
|
5763
|
-
return {
|
|
5764
|
-
value: field.value ?? "",
|
|
5765
|
-
...field.formats ? { formats: field.formats } : {},
|
|
5766
|
-
...field.math_objects ? { math_objects: field.math_objects } : {},
|
|
5767
|
-
...item.blocks.length > 0 ? { blocks: item.blocks.map(blockJson) } : {}
|
|
5768
|
-
};
|
|
5769
|
-
}
|
|
5770
|
-
function blockJson(block) {
|
|
5771
|
-
if (block.kind === "textBlock") {
|
|
5772
|
-
return {
|
|
5773
|
-
command: block.command,
|
|
5774
|
-
...fieldJson(block.field),
|
|
5775
|
-
...block.command === "\\paragraph" ? { centered: block.centered === true } : {}
|
|
5776
|
-
};
|
|
5777
|
-
}
|
|
5778
|
-
if (block.kind === "list") {
|
|
5779
|
-
return {
|
|
5780
|
-
command: block.command,
|
|
5781
|
-
closing: block.closing,
|
|
5782
|
-
items: block.items.map(listItemJson)
|
|
5783
|
-
};
|
|
5784
|
-
}
|
|
5785
|
-
if (block.kind === "table") {
|
|
5786
|
-
const fields = block.rows.map((row) => row.map(serializeField));
|
|
5787
|
-
const hasPersistedMath = fields.some((row) => row.some((field) => field.hasPersistedMath));
|
|
5788
|
-
return {
|
|
5789
|
-
command: block.command,
|
|
5790
|
-
closing: block.closing,
|
|
5791
|
-
columns: block.columns,
|
|
5792
|
-
rows: fields.map((row) => row.map((field) => field.value)),
|
|
5793
|
-
...fields.some((row) => row.some((field) => field.formats.length > 0)) ? { cell_formats: fields.map((row) => row.map((field) => field.formats)) } : {},
|
|
5794
|
-
...hasPersistedMath ? { math_objects: fields.flatMap((row) => row.flatMap((field) => field.mathObjects)) } : {},
|
|
5795
|
-
centered: block.centered,
|
|
5796
|
-
caption_enabled: block.captionEnabled,
|
|
5797
|
-
caption: block.caption,
|
|
5798
|
-
label_enabled: block.labelEnabled,
|
|
5799
|
-
label: block.label
|
|
5800
|
-
};
|
|
5801
|
-
}
|
|
5802
|
-
if (block.kind === "image") {
|
|
5803
|
-
return {
|
|
5804
|
-
command: block.command,
|
|
5805
|
-
value: block.value,
|
|
5806
|
-
...block.assetId !== void 0 ? { asset_id: block.assetId } : {},
|
|
5807
|
-
options: { ...block.options },
|
|
5808
|
-
centered: block.centered,
|
|
5809
|
-
caption_enabled: block.captionEnabled,
|
|
5810
|
-
caption: block.caption,
|
|
5811
|
-
label_enabled: block.labelEnabled,
|
|
5812
|
-
label: block.label
|
|
5813
|
-
};
|
|
5814
|
-
}
|
|
5815
|
-
if (block.kind === "bibliography") {
|
|
5816
|
-
return { command: block.command, closing: block.closing };
|
|
5817
|
-
}
|
|
5818
|
-
return { command: block.command, value: block.value };
|
|
5819
|
-
}
|
|
5820
|
-
function referenceJson(reference) {
|
|
5821
|
-
return {
|
|
5822
|
-
key: reference.key,
|
|
5823
|
-
authors: reference.authors,
|
|
5824
|
-
title: reference.title,
|
|
5825
|
-
year: reference.year,
|
|
5826
|
-
url: reference.url,
|
|
5827
|
-
venue: reference.venue,
|
|
5828
|
-
field_separator: reference.fieldSeparator
|
|
5829
|
-
};
|
|
5830
|
-
}
|
|
5831
|
-
function toDocumentJson2(document2) {
|
|
5832
|
-
if (document2.nodeType !== "DocumentObject" || !Array.isArray(document2.blocks)) {
|
|
5833
|
-
throw new Error("toDocumentJson2 requires a live Document2Node");
|
|
5834
|
-
}
|
|
5835
|
-
return {
|
|
5836
|
-
node_type: "DocumentObject",
|
|
5837
|
-
meta: {
|
|
5838
|
-
title: document2.meta.title,
|
|
5839
|
-
authors: document2.meta.authors,
|
|
5840
|
-
date: { ...document2.meta.date },
|
|
5841
|
-
abstract: document2.meta.abstract
|
|
5842
|
-
},
|
|
5843
|
-
references: document2.references.map(referenceJson),
|
|
5844
|
-
blocks: document2.blocks.map(blockJson)
|
|
5845
|
-
};
|
|
5846
|
-
}
|
|
5847
|
-
|
|
5848
6214
|
// src/document2/history.ts
|
|
5849
6215
|
var DEFAULT_DOCUMENT2_HISTORY_MAX_DEPTH = 100;
|
|
5850
6216
|
function createDocument2History(maxDepth = DEFAULT_DOCUMENT2_HISTORY_MAX_DEPTH) {
|
|
@@ -6122,6 +6488,7 @@ export {
|
|
|
6122
6488
|
DEFAULT_DOCUMENT2_HISTORY_MAX_DEPTH,
|
|
6123
6489
|
DEFAULT_HIJRI_DATE,
|
|
6124
6490
|
DEFAULT_REFERENCE_FIELD_SEPARATOR,
|
|
6491
|
+
Document2CommandError,
|
|
6125
6492
|
HIJRI_MONTH_IDS,
|
|
6126
6493
|
HIJRI_YEAR_MAX,
|
|
6127
6494
|
HIJRI_YEAR_MIN,
|
|
@@ -6132,6 +6499,7 @@ export {
|
|
|
6132
6499
|
addDocument2Reference,
|
|
6133
6500
|
addDocument2TableBlock,
|
|
6134
6501
|
addDocument2TextBlock,
|
|
6502
|
+
applyDocument2Command,
|
|
6135
6503
|
applyFloatMetaPatch,
|
|
6136
6504
|
arabicXeLatexPreambleCmd,
|
|
6137
6505
|
arabicXeLatexPreambleFont,
|
|
@@ -6147,6 +6515,7 @@ export {
|
|
|
6147
6515
|
butexMaghribiDisplayLatex,
|
|
6148
6516
|
butexMaghribiDisplayTex,
|
|
6149
6517
|
citeTokenLatex,
|
|
6518
|
+
clearDocument2ImageAsset,
|
|
6150
6519
|
cloneDocument2Meta,
|
|
6151
6520
|
cloneDocument2Node,
|
|
6152
6521
|
collectDocument2Labels,
|
|
@@ -6166,6 +6535,7 @@ export {
|
|
|
6166
6535
|
document2HistoryCanUndo,
|
|
6167
6536
|
document2KeyError,
|
|
6168
6537
|
document2Latex,
|
|
6538
|
+
document2Outline,
|
|
6169
6539
|
document2Preview,
|
|
6170
6540
|
emptyBlockSelection,
|
|
6171
6541
|
emptyDocument2Meta,
|
|
@@ -6232,6 +6602,7 @@ export {
|
|
|
6232
6602
|
toggleBlockInSelection,
|
|
6233
6603
|
toggleTextTokenStyle,
|
|
6234
6604
|
updateCiteTokenKeys,
|
|
6605
|
+
updateDocument2ImageAsset,
|
|
6235
6606
|
updateDocument2ImageMeta,
|
|
6236
6607
|
updateDocument2ImageValue,
|
|
6237
6608
|
updateDocument2Meta,
|