@drghaliasri/butex 5.5.2 → 5.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -0
- package/dist/document.d.mts +5 -4
- package/dist/document.d.ts +5 -4
- package/dist/document.js +62 -0
- package/dist/document.js.map +1 -1
- package/dist/document.mjs +61 -0
- package/dist/document.mjs.map +1 -1
- package/dist/document2.d.mts +20 -4
- package/dist/document2.d.ts +20 -4
- package/dist/document2.js +222 -6
- package/dist/document2.js.map +1 -1
- package/dist/document2.mjs +221 -6
- package/dist/document2.mjs.map +1 -1
- package/dist/react-document.d.mts +2 -2
- package/dist/react-document.d.ts +2 -2
- package/dist/react-document.js.map +1 -1
- package/dist/react-document.mjs.map +1 -1
- package/dist/react-document2.d.mts +18 -3
- package/dist/react-document2.d.ts +18 -3
- package/dist/react-document2.js +247 -7
- package/dist/react-document2.js.map +1 -1
- package/dist/react-document2.mjs +247 -7
- package/dist/react-document2.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -143,7 +143,20 @@ type MathObject2Json = {
|
|
|
143
143
|
math_mode: string;
|
|
144
144
|
lines: ChainJson[];
|
|
145
145
|
closing: string;
|
|
146
|
+
/** Side used by the delimited source stored in the containing value/cell. */
|
|
147
|
+
source_side?: Document2ParseMode;
|
|
148
|
+
/** Preserve whether LaTeX export should prefer imported AST rendering or editor source. */
|
|
149
|
+
source_owner?: 'imported-structured' | 'editor';
|
|
150
|
+
label_enabled?: boolean;
|
|
151
|
+
label?: string;
|
|
152
|
+
};
|
|
153
|
+
/** Positional metadata for a raw-only span that has no structured equation AST. */
|
|
154
|
+
type RawMathObject2Json = {
|
|
155
|
+
node_type: 'RawMathObject';
|
|
156
|
+
label_enabled?: boolean;
|
|
157
|
+
label?: string;
|
|
146
158
|
};
|
|
159
|
+
type Document2MathObjectJson = MathObject2Json | RawMathObject2Json;
|
|
147
160
|
type ReferenceFieldSeparator = ',' | '،';
|
|
148
161
|
type Reference2Json = {
|
|
149
162
|
key: string;
|
|
@@ -179,7 +192,7 @@ type Document2BlockJson = {
|
|
|
179
192
|
formats?: TextFormatSpan2Json[];
|
|
180
193
|
/** Stable host asset identity (e.g. S3 key / UUID); optional for \\includegraphics. */
|
|
181
194
|
asset_id?: string;
|
|
182
|
-
math_objects?:
|
|
195
|
+
math_objects?: Array<Document2MathObjectJson | null>;
|
|
183
196
|
options?: Record<string, string>;
|
|
184
197
|
closing?: string;
|
|
185
198
|
items?: Document2ListItemJson[];
|
|
@@ -195,7 +208,7 @@ type Document2BlockJson = {
|
|
|
195
208
|
type Document2ListItemJson = {
|
|
196
209
|
value: string;
|
|
197
210
|
formats?: TextFormatSpan2Json[];
|
|
198
|
-
math_objects?:
|
|
211
|
+
math_objects?: Array<Document2MathObjectJson | null>;
|
|
199
212
|
blocks?: Document2BlockJson[];
|
|
200
213
|
};
|
|
201
214
|
type Document2Diagnostic = {
|
|
@@ -463,6 +476,8 @@ type ButexDocumentEditor2Props = {
|
|
|
463
476
|
value: string;
|
|
464
477
|
}) => string;
|
|
465
478
|
onDocumentChange?: (document: Document2Node) => void;
|
|
479
|
+
/** Canonical JSON wire format for API/database persistence. */
|
|
480
|
+
onDocumentJsonChange?: (document: Document2Json) => void;
|
|
466
481
|
onLatexChange?: (latex: string) => void;
|
|
467
482
|
};
|
|
468
483
|
type Document2InitialState = {
|
|
@@ -470,7 +485,7 @@ type Document2InitialState = {
|
|
|
470
485
|
error: string | null;
|
|
471
486
|
};
|
|
472
487
|
declare function resolveInitialDocument2(initialDocument: Document2Json | Document2Node | undefined, uiLocale?: ButexUiLocale, documentMeta?: Document2MetaProp): Document2InitialState;
|
|
473
|
-
declare function ButexDocumentEditor2({ initialDocument, documentMeta, className, debug, documentDirection, equationSide, editableEquations, previewOnly, uiLocale, mathOutput, digitForm: digitFormProp, onDigitFormChange, resolveImageUrl, onDocumentChange, onLatexChange, }: ButexDocumentEditor2Props): react_jsx_runtime.JSX.Element;
|
|
488
|
+
declare function ButexDocumentEditor2({ initialDocument, documentMeta, className, debug, documentDirection, equationSide, editableEquations, previewOnly, uiLocale, mathOutput, digitForm: digitFormProp, onDigitFormChange, resolveImageUrl, onDocumentChange, onDocumentJsonChange, onLatexChange, }: ButexDocumentEditor2Props): react_jsx_runtime.JSX.Element;
|
|
474
489
|
|
|
475
490
|
type DocumentInsertToolbarProps = {
|
|
476
491
|
canUndo: boolean;
|
|
@@ -143,7 +143,20 @@ type MathObject2Json = {
|
|
|
143
143
|
math_mode: string;
|
|
144
144
|
lines: ChainJson[];
|
|
145
145
|
closing: string;
|
|
146
|
+
/** Side used by the delimited source stored in the containing value/cell. */
|
|
147
|
+
source_side?: Document2ParseMode;
|
|
148
|
+
/** Preserve whether LaTeX export should prefer imported AST rendering or editor source. */
|
|
149
|
+
source_owner?: 'imported-structured' | 'editor';
|
|
150
|
+
label_enabled?: boolean;
|
|
151
|
+
label?: string;
|
|
152
|
+
};
|
|
153
|
+
/** Positional metadata for a raw-only span that has no structured equation AST. */
|
|
154
|
+
type RawMathObject2Json = {
|
|
155
|
+
node_type: 'RawMathObject';
|
|
156
|
+
label_enabled?: boolean;
|
|
157
|
+
label?: string;
|
|
146
158
|
};
|
|
159
|
+
type Document2MathObjectJson = MathObject2Json | RawMathObject2Json;
|
|
147
160
|
type ReferenceFieldSeparator = ',' | '،';
|
|
148
161
|
type Reference2Json = {
|
|
149
162
|
key: string;
|
|
@@ -179,7 +192,7 @@ type Document2BlockJson = {
|
|
|
179
192
|
formats?: TextFormatSpan2Json[];
|
|
180
193
|
/** Stable host asset identity (e.g. S3 key / UUID); optional for \\includegraphics. */
|
|
181
194
|
asset_id?: string;
|
|
182
|
-
math_objects?:
|
|
195
|
+
math_objects?: Array<Document2MathObjectJson | null>;
|
|
183
196
|
options?: Record<string, string>;
|
|
184
197
|
closing?: string;
|
|
185
198
|
items?: Document2ListItemJson[];
|
|
@@ -195,7 +208,7 @@ type Document2BlockJson = {
|
|
|
195
208
|
type Document2ListItemJson = {
|
|
196
209
|
value: string;
|
|
197
210
|
formats?: TextFormatSpan2Json[];
|
|
198
|
-
math_objects?:
|
|
211
|
+
math_objects?: Array<Document2MathObjectJson | null>;
|
|
199
212
|
blocks?: Document2BlockJson[];
|
|
200
213
|
};
|
|
201
214
|
type Document2Diagnostic = {
|
|
@@ -463,6 +476,8 @@ type ButexDocumentEditor2Props = {
|
|
|
463
476
|
value: string;
|
|
464
477
|
}) => string;
|
|
465
478
|
onDocumentChange?: (document: Document2Node) => void;
|
|
479
|
+
/** Canonical JSON wire format for API/database persistence. */
|
|
480
|
+
onDocumentJsonChange?: (document: Document2Json) => void;
|
|
466
481
|
onLatexChange?: (latex: string) => void;
|
|
467
482
|
};
|
|
468
483
|
type Document2InitialState = {
|
|
@@ -470,7 +485,7 @@ type Document2InitialState = {
|
|
|
470
485
|
error: string | null;
|
|
471
486
|
};
|
|
472
487
|
declare function resolveInitialDocument2(initialDocument: Document2Json | Document2Node | undefined, uiLocale?: ButexUiLocale, documentMeta?: Document2MetaProp): Document2InitialState;
|
|
473
|
-
declare function ButexDocumentEditor2({ initialDocument, documentMeta, className, debug, documentDirection, equationSide, editableEquations, previewOnly, uiLocale, mathOutput, digitForm: digitFormProp, onDigitFormChange, resolveImageUrl, onDocumentChange, onLatexChange, }: ButexDocumentEditor2Props): react_jsx_runtime.JSX.Element;
|
|
488
|
+
declare function ButexDocumentEditor2({ initialDocument, documentMeta, className, debug, documentDirection, equationSide, editableEquations, previewOnly, uiLocale, mathOutput, digitForm: digitFormProp, onDigitFormChange, resolveImageUrl, onDocumentChange, onDocumentJsonChange, onLatexChange, }: ButexDocumentEditor2Props): react_jsx_runtime.JSX.Element;
|
|
474
489
|
|
|
475
490
|
type DocumentInsertToolbarProps = {
|
|
476
491
|
canUndo: boolean;
|
package/dist/react-document2.js
CHANGED
|
@@ -739,6 +739,66 @@ function fromMathObjectJson(json, mode = "english") {
|
|
|
739
739
|
closing: json.closing
|
|
740
740
|
};
|
|
741
741
|
}
|
|
742
|
+
function scriptsToJson(node, path) {
|
|
743
|
+
return {
|
|
744
|
+
...node.superscript ? { superscript: chainToJson(node.superscript, `${path}.superscript`) } : {},
|
|
745
|
+
...node.subscript ? { subscript: chainToJson(node.subscript, `${path}.subscript`) } : {}
|
|
746
|
+
};
|
|
747
|
+
}
|
|
748
|
+
function nodeToJson(node, path) {
|
|
749
|
+
const scripts = scriptsToJson(node, path);
|
|
750
|
+
if (node instanceof CharNode || node instanceof NumberNode || node instanceof OperatorNode) {
|
|
751
|
+
return { node_type: node.nodeType, expr: node.expr, ...scripts };
|
|
752
|
+
}
|
|
753
|
+
if (node instanceof DelimiterNode) {
|
|
754
|
+
return {
|
|
755
|
+
node_type: "DelimiterObject",
|
|
756
|
+
left_delim_expr: node.leftDelimExpr,
|
|
757
|
+
inner_expr: chainToJson(node.innerExpr, `${path}.inner_expr`),
|
|
758
|
+
right_delim_expr: node.rightDelimExpr,
|
|
759
|
+
...scripts
|
|
760
|
+
};
|
|
761
|
+
}
|
|
762
|
+
if (node instanceof CommandNode) {
|
|
763
|
+
return {
|
|
764
|
+
node_type: "CommandObject",
|
|
765
|
+
name: node.name,
|
|
766
|
+
optional_args: node.optionalArgs.map((arg, index) => chainToJson(arg, `${path}.optional_args[${String(index)}]`)),
|
|
767
|
+
mandatory_args: node.mandatoryArgs.map((arg, index) => chainToJson(arg, `${path}.mandatory_args[${String(index)}]`)),
|
|
768
|
+
...scripts
|
|
769
|
+
};
|
|
770
|
+
}
|
|
771
|
+
if (node instanceof EnvNode) {
|
|
772
|
+
return {
|
|
773
|
+
node_type: "EnvObject",
|
|
774
|
+
opening: node.opening,
|
|
775
|
+
lines: node.lines.map((line, index) => chainToJson(line, `${path}.lines[${String(index)}]`)),
|
|
776
|
+
closing: node.closing,
|
|
777
|
+
...scripts
|
|
778
|
+
};
|
|
779
|
+
}
|
|
780
|
+
throw new Error(`Unsupported runtime math node at ${path}: ${node.nodeType}`);
|
|
781
|
+
}
|
|
782
|
+
function chainToJson(chain, path) {
|
|
783
|
+
if (!(chain instanceof ChainNode)) {
|
|
784
|
+
throw new Error(`Expected live ChainNode at ${path}`);
|
|
785
|
+
}
|
|
786
|
+
return {
|
|
787
|
+
node_type: "ChainClass",
|
|
788
|
+
chain: chain.chain.map((node, index) => nodeToJson(node, `${path}.chain[${String(index)}]`))
|
|
789
|
+
};
|
|
790
|
+
}
|
|
791
|
+
function toMathObjectJson(math) {
|
|
792
|
+
if (math.nodeType !== "MathObject" || !Array.isArray(math.lines) || math.lines.length === 0) {
|
|
793
|
+
throw new Error("Cannot serialize invalid runtime MathObject");
|
|
794
|
+
}
|
|
795
|
+
return {
|
|
796
|
+
node_type: "MathObject",
|
|
797
|
+
math_mode: math.mathMode,
|
|
798
|
+
lines: math.lines.map((line, index) => chainToJson(line, `$.lines[${String(index)}]`)),
|
|
799
|
+
closing: math.closing
|
|
800
|
+
};
|
|
801
|
+
}
|
|
742
802
|
function renderMathNodeLatex(math) {
|
|
743
803
|
const lines = math.lines.map((line) => line.arabicLatex());
|
|
744
804
|
if (math.mathMode === "$" || math.mathMode === "\\(") {
|
|
@@ -1203,10 +1263,11 @@ function createInlineField2(value = "", mathObjects = [], options = {}, path = "
|
|
|
1203
1263
|
}
|
|
1204
1264
|
const mathJson = mathObjects[mathObjectIndex];
|
|
1205
1265
|
mathObjectIndex += 1;
|
|
1206
|
-
|
|
1266
|
+
const structuredMathJson = mathJson?.node_type === "MathObject" ? mathJson : null;
|
|
1267
|
+
if (structuredMathJson && (structuredMathJson.math_mode !== span.opening || structuredMathJson.closing !== span.closing)) {
|
|
1207
1268
|
pushDiagnostic(diagnostics, options, path, "math_objects order mismatch");
|
|
1208
1269
|
}
|
|
1209
|
-
if (
|
|
1270
|
+
if (structuredMathJson && structuredMathJson.math_mode === span.opening && structuredMathJson.closing === span.closing) {
|
|
1210
1271
|
tokens.push({
|
|
1211
1272
|
id: document2Id("math"),
|
|
1212
1273
|
kind: "math",
|
|
@@ -1214,10 +1275,12 @@ function createInlineField2(value = "", mathObjects = [], options = {}, path = "
|
|
|
1214
1275
|
opening: span.opening,
|
|
1215
1276
|
closing: span.closing,
|
|
1216
1277
|
source: span.source,
|
|
1217
|
-
sourceSide: mode,
|
|
1218
|
-
math: fromMathObjectJson(
|
|
1278
|
+
sourceSide: structuredMathJson.source_side === "arabic" || structuredMathJson.source_side === "english" ? structuredMathJson.source_side : mode,
|
|
1279
|
+
math: fromMathObjectJson(structuredMathJson, mode),
|
|
1219
1280
|
editable: true,
|
|
1220
|
-
sourceOwner: "imported-structured"
|
|
1281
|
+
sourceOwner: structuredMathJson.source_owner === "editor" ? "editor" : "imported-structured",
|
|
1282
|
+
...typeof structuredMathJson.label_enabled === "boolean" ? { labelEnabled: structuredMathJson.label_enabled } : {},
|
|
1283
|
+
...typeof structuredMathJson.label === "string" ? { label: structuredMathJson.label } : {}
|
|
1221
1284
|
});
|
|
1222
1285
|
} else {
|
|
1223
1286
|
tokens.push({
|
|
@@ -1230,7 +1293,9 @@ function createInlineField2(value = "", mathObjects = [], options = {}, path = "
|
|
|
1230
1293
|
math: null,
|
|
1231
1294
|
editable: false,
|
|
1232
1295
|
reason: "\u0647\u0630\u0647 \u0627\u0644\u0645\u0639\u0627\u062F\u0644\u0629 \u0645\u062D\u0641\u0648\u0638\u0629 \u0643\u0646\u0635 \u062E\u0627\u0645 \u0641\u0642\u0637 \u062D\u0627\u0644\u064A\u0627",
|
|
1233
|
-
sourceOwner: "raw"
|
|
1296
|
+
sourceOwner: "raw",
|
|
1297
|
+
...mathJson?.node_type === "RawMathObject" && typeof mathJson.label_enabled === "boolean" ? { labelEnabled: mathJson.label_enabled } : {},
|
|
1298
|
+
...mathJson?.node_type === "RawMathObject" && typeof mathJson.label === "string" ? { label: mathJson.label } : {}
|
|
1234
1299
|
});
|
|
1235
1300
|
}
|
|
1236
1301
|
index = span.end;
|
|
@@ -9288,6 +9353,155 @@ ${body}
|
|
|
9288
9353
|
`;
|
|
9289
9354
|
}
|
|
9290
9355
|
|
|
9356
|
+
// src/document2/exportJson.ts
|
|
9357
|
+
function serializeField(field) {
|
|
9358
|
+
let value = "";
|
|
9359
|
+
let hasPersistedMath = false;
|
|
9360
|
+
const formats = [];
|
|
9361
|
+
const mathObjects = [];
|
|
9362
|
+
for (const token of field.tokens) {
|
|
9363
|
+
if (token.kind === "text") {
|
|
9364
|
+
const start = value.length;
|
|
9365
|
+
value += token.text;
|
|
9366
|
+
if (token.text.length > 0 && (token.style?.bold || token.style?.italic || token.style?.underline)) {
|
|
9367
|
+
formats.push({
|
|
9368
|
+
start,
|
|
9369
|
+
end: value.length,
|
|
9370
|
+
...token.style.bold ? { bold: true } : {},
|
|
9371
|
+
...token.style.italic ? { italic: true } : {},
|
|
9372
|
+
...token.style.underline ? { underline: true } : {}
|
|
9373
|
+
});
|
|
9374
|
+
}
|
|
9375
|
+
continue;
|
|
9376
|
+
}
|
|
9377
|
+
if (token.kind === "cite") {
|
|
9378
|
+
value += citeTokenLatex(token.keys);
|
|
9379
|
+
continue;
|
|
9380
|
+
}
|
|
9381
|
+
if (token.kind === "ref") {
|
|
9382
|
+
value += refTokenLatex(token.keys, token.refCommand);
|
|
9383
|
+
continue;
|
|
9384
|
+
}
|
|
9385
|
+
value += token.source;
|
|
9386
|
+
if (!token.math || token.sourceOwner === "raw") {
|
|
9387
|
+
if (token.labelEnabled !== void 0 || token.label !== void 0) {
|
|
9388
|
+
hasPersistedMath = true;
|
|
9389
|
+
mathObjects.push({
|
|
9390
|
+
node_type: "RawMathObject",
|
|
9391
|
+
...token.labelEnabled !== void 0 ? { label_enabled: token.labelEnabled } : {},
|
|
9392
|
+
...token.label !== void 0 ? { label: token.label } : {}
|
|
9393
|
+
});
|
|
9394
|
+
} else {
|
|
9395
|
+
mathObjects.push(null);
|
|
9396
|
+
}
|
|
9397
|
+
continue;
|
|
9398
|
+
}
|
|
9399
|
+
hasPersistedMath = true;
|
|
9400
|
+
mathObjects.push({
|
|
9401
|
+
...toMathObjectJson(token.math),
|
|
9402
|
+
...token.sourceSide ? { source_side: token.sourceSide } : {},
|
|
9403
|
+
source_owner: token.sourceOwner,
|
|
9404
|
+
...token.labelEnabled !== void 0 ? { label_enabled: token.labelEnabled } : {},
|
|
9405
|
+
...token.label !== void 0 ? { label: token.label } : {}
|
|
9406
|
+
});
|
|
9407
|
+
}
|
|
9408
|
+
return { value, formats, mathObjects, hasPersistedMath };
|
|
9409
|
+
}
|
|
9410
|
+
function fieldJson(field) {
|
|
9411
|
+
const serialized = serializeField(field);
|
|
9412
|
+
return {
|
|
9413
|
+
value: serialized.value,
|
|
9414
|
+
...serialized.formats.length > 0 ? { formats: serialized.formats } : {},
|
|
9415
|
+
...serialized.hasPersistedMath ? { math_objects: serialized.mathObjects } : {}
|
|
9416
|
+
};
|
|
9417
|
+
}
|
|
9418
|
+
function listItemJson(item) {
|
|
9419
|
+
const field = fieldJson(item.field);
|
|
9420
|
+
return {
|
|
9421
|
+
value: field.value ?? "",
|
|
9422
|
+
...field.formats ? { formats: field.formats } : {},
|
|
9423
|
+
...field.math_objects ? { math_objects: field.math_objects } : {},
|
|
9424
|
+
...item.blocks.length > 0 ? { blocks: item.blocks.map(blockJson) } : {}
|
|
9425
|
+
};
|
|
9426
|
+
}
|
|
9427
|
+
function blockJson(block) {
|
|
9428
|
+
if (block.kind === "textBlock") {
|
|
9429
|
+
return {
|
|
9430
|
+
command: block.command,
|
|
9431
|
+
...fieldJson(block.field),
|
|
9432
|
+
...block.command === "\\paragraph" ? { centered: block.centered === true } : {}
|
|
9433
|
+
};
|
|
9434
|
+
}
|
|
9435
|
+
if (block.kind === "list") {
|
|
9436
|
+
return {
|
|
9437
|
+
command: block.command,
|
|
9438
|
+
closing: block.closing,
|
|
9439
|
+
items: block.items.map(listItemJson)
|
|
9440
|
+
};
|
|
9441
|
+
}
|
|
9442
|
+
if (block.kind === "table") {
|
|
9443
|
+
const fields = block.rows.map((row) => row.map(serializeField));
|
|
9444
|
+
const hasPersistedMath = fields.some((row) => row.some((field) => field.hasPersistedMath));
|
|
9445
|
+
return {
|
|
9446
|
+
command: block.command,
|
|
9447
|
+
closing: block.closing,
|
|
9448
|
+
columns: block.columns,
|
|
9449
|
+
rows: fields.map((row) => row.map((field) => field.value)),
|
|
9450
|
+
...fields.some((row) => row.some((field) => field.formats.length > 0)) ? { cell_formats: fields.map((row) => row.map((field) => field.formats)) } : {},
|
|
9451
|
+
...hasPersistedMath ? { math_objects: fields.flatMap((row) => row.flatMap((field) => field.mathObjects)) } : {},
|
|
9452
|
+
centered: block.centered,
|
|
9453
|
+
caption_enabled: block.captionEnabled,
|
|
9454
|
+
caption: block.caption,
|
|
9455
|
+
label_enabled: block.labelEnabled,
|
|
9456
|
+
label: block.label
|
|
9457
|
+
};
|
|
9458
|
+
}
|
|
9459
|
+
if (block.kind === "image") {
|
|
9460
|
+
return {
|
|
9461
|
+
command: block.command,
|
|
9462
|
+
value: block.value,
|
|
9463
|
+
...block.assetId !== void 0 ? { asset_id: block.assetId } : {},
|
|
9464
|
+
options: { ...block.options },
|
|
9465
|
+
centered: block.centered,
|
|
9466
|
+
caption_enabled: block.captionEnabled,
|
|
9467
|
+
caption: block.caption,
|
|
9468
|
+
label_enabled: block.labelEnabled,
|
|
9469
|
+
label: block.label
|
|
9470
|
+
};
|
|
9471
|
+
}
|
|
9472
|
+
if (block.kind === "bibliography") {
|
|
9473
|
+
return { command: block.command, closing: block.closing };
|
|
9474
|
+
}
|
|
9475
|
+
return { command: block.command, value: block.value };
|
|
9476
|
+
}
|
|
9477
|
+
function referenceJson(reference) {
|
|
9478
|
+
return {
|
|
9479
|
+
key: reference.key,
|
|
9480
|
+
authors: reference.authors,
|
|
9481
|
+
title: reference.title,
|
|
9482
|
+
year: reference.year,
|
|
9483
|
+
url: reference.url,
|
|
9484
|
+
venue: reference.venue,
|
|
9485
|
+
field_separator: reference.fieldSeparator
|
|
9486
|
+
};
|
|
9487
|
+
}
|
|
9488
|
+
function toDocumentJson2(document2) {
|
|
9489
|
+
if (document2.nodeType !== "DocumentObject" || !Array.isArray(document2.blocks)) {
|
|
9490
|
+
throw new Error("toDocumentJson2 requires a live Document2Node");
|
|
9491
|
+
}
|
|
9492
|
+
return {
|
|
9493
|
+
node_type: "DocumentObject",
|
|
9494
|
+
meta: {
|
|
9495
|
+
title: document2.meta.title,
|
|
9496
|
+
authors: document2.meta.authors,
|
|
9497
|
+
date: { ...document2.meta.date },
|
|
9498
|
+
abstract: document2.meta.abstract
|
|
9499
|
+
},
|
|
9500
|
+
references: document2.references.map(referenceJson),
|
|
9501
|
+
blocks: document2.blocks.map(blockJson)
|
|
9502
|
+
};
|
|
9503
|
+
}
|
|
9504
|
+
|
|
9291
9505
|
// src/document2/history.ts
|
|
9292
9506
|
var DEFAULT_DOCUMENT2_HISTORY_MAX_DEPTH = 100;
|
|
9293
9507
|
function createDocument2History(maxDepth = DEFAULT_DOCUMENT2_HISTORY_MAX_DEPTH) {
|
|
@@ -9631,6 +9845,7 @@ var DOCUMENT2_MESSAGES = {
|
|
|
9631
9845
|
imagePath: "\u0645\u0633\u0627\u0631 \u0645\u0644\u0641 \u0627\u0644\u0635\u0648\u0631\u0629",
|
|
9632
9846
|
imagePathLabel: "\u0645\u0633\u0627\u0631 \u0627\u0644\u0635\u0648\u0631\u0629",
|
|
9633
9847
|
loadDocumentError: "\u062A\u0639\u0630\u0631 \u062A\u062D\u0645\u064A\u0644 \u0627\u0644\u0645\u0633\u062A\u0646\u062F",
|
|
9848
|
+
runtimePersistenceError: "\u0644\u0627 \u064A\u0645\u0643\u0646 \u062A\u062D\u0645\u064A\u0644 Document2Node \u0628\u0639\u062F JSON.stringify. \u0627\u062D\u0641\u0638 Document2Json \u0628\u0627\u0633\u062A\u062E\u062F\u0627\u0645 toDocumentJson2.",
|
|
9634
9849
|
emptyImagePath: "\u0644\u0627 \u064A\u0648\u062C\u062F \u0645\u0633\u0627\u0631 \u0635\u0648\u0631\u0629",
|
|
9635
9850
|
blockSelection: "\u062A\u062D\u062F\u064A\u062F \u0627\u0644\u0643\u062A\u0644",
|
|
9636
9851
|
selectBlock: "\u062A\u062D\u062F\u064A\u062F \u0627\u0644\u0643\u062A\u0644\u0629",
|
|
@@ -9774,6 +9989,7 @@ var DOCUMENT2_MESSAGES = {
|
|
|
9774
9989
|
imagePath: "File path (\\includegraphics)",
|
|
9775
9990
|
imagePathLabel: "Image path",
|
|
9776
9991
|
loadDocumentError: "Could not load document",
|
|
9992
|
+
runtimePersistenceError: "A Document2Node cannot be loaded after JSON.stringify. Persist Document2Json with toDocumentJson2 instead.",
|
|
9777
9993
|
emptyImagePath: "Empty image path",
|
|
9778
9994
|
blockSelection: "Block selection",
|
|
9779
9995
|
selectBlock: "Select block",
|
|
@@ -17038,7 +17254,19 @@ function formatDocument2Diagnostic(d, messages) {
|
|
|
17038
17254
|
return `${messages.importWarning}: ${d.message} \u2014 ${messages.path}: ${d.path}`;
|
|
17039
17255
|
}
|
|
17040
17256
|
function isDocument2Node(value) {
|
|
17041
|
-
|
|
17257
|
+
const hasRuntimeShape = typeof value === "object" && value !== null && value.nodeType === "DocumentObject" && Array.isArray(value.blocks) && Array.isArray(value.diagnostics);
|
|
17258
|
+
if (!hasRuntimeShape) {
|
|
17259
|
+
return false;
|
|
17260
|
+
}
|
|
17261
|
+
try {
|
|
17262
|
+
toDocumentJson2(value);
|
|
17263
|
+
return true;
|
|
17264
|
+
} catch {
|
|
17265
|
+
return false;
|
|
17266
|
+
}
|
|
17267
|
+
}
|
|
17268
|
+
function hasDocument2RuntimeShape(value) {
|
|
17269
|
+
return typeof value === "object" && value !== null && value.nodeType === "DocumentObject";
|
|
17042
17270
|
}
|
|
17043
17271
|
function applyDocumentMetaSeed(document2, documentMeta) {
|
|
17044
17272
|
const current = document2.meta ?? emptyDocument2Meta();
|
|
@@ -17057,6 +17285,13 @@ function resolveInitialDocument2(initialDocument, uiLocale = "ar", documentMeta)
|
|
|
17057
17285
|
if (isDocument2Node(initialDocument)) {
|
|
17058
17286
|
return { document: applyDocumentMetaSeed(initialDocument, documentMeta), error: null };
|
|
17059
17287
|
}
|
|
17288
|
+
if (hasDocument2RuntimeShape(initialDocument)) {
|
|
17289
|
+
const messages = document2Messages(uiLocale);
|
|
17290
|
+
return {
|
|
17291
|
+
document: applyDocumentMetaSeed(createEmptyDocument2(), documentMeta),
|
|
17292
|
+
error: `${messages.loadDocumentError}: ${messages.runtimePersistenceError}`
|
|
17293
|
+
};
|
|
17294
|
+
}
|
|
17060
17295
|
try {
|
|
17061
17296
|
const imported = fromDocumentJson2(initialDocument);
|
|
17062
17297
|
return {
|
|
@@ -17089,6 +17324,7 @@ function ButexDocumentEditor2({
|
|
|
17089
17324
|
onDigitFormChange,
|
|
17090
17325
|
resolveImageUrl,
|
|
17091
17326
|
onDocumentChange,
|
|
17327
|
+
onDocumentJsonChange,
|
|
17092
17328
|
onLatexChange
|
|
17093
17329
|
}) {
|
|
17094
17330
|
const messages = document2Messages(uiLocale);
|
|
@@ -17120,6 +17356,7 @@ function ButexDocumentEditor2({
|
|
|
17120
17356
|
const pendingFocusRef = (0, import_react13.useRef)(null);
|
|
17121
17357
|
documentRef.current = documentNode;
|
|
17122
17358
|
const latex = document2Latex(documentNode);
|
|
17359
|
+
const documentJson = (0, import_react13.useMemo)(() => toDocumentJson2(documentNode), [documentNode]);
|
|
17123
17360
|
const documentLabels = (0, import_react13.useMemo)(() => collectDocument2Labels(documentNode), [documentNode]);
|
|
17124
17361
|
const preview = (0, import_react13.useMemo)(
|
|
17125
17362
|
() => document2Preview(documentNode, mathOutput, equationSide, {
|
|
@@ -17204,6 +17441,9 @@ function ButexDocumentEditor2({
|
|
|
17204
17441
|
(0, import_react13.useEffect)(() => {
|
|
17205
17442
|
onDocumentChange?.(documentNode);
|
|
17206
17443
|
}, [documentNode, onDocumentChange]);
|
|
17444
|
+
(0, import_react13.useEffect)(() => {
|
|
17445
|
+
onDocumentJsonChange?.(documentJson);
|
|
17446
|
+
}, [documentJson, onDocumentJsonChange]);
|
|
17207
17447
|
(0, import_react13.useEffect)(() => {
|
|
17208
17448
|
onLatexChange?.(latex);
|
|
17209
17449
|
}, [latex, onLatexChange]);
|