@drghaliasri/butex 4.2.0 → 4.3.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 +55 -1
- package/dist/react-document2.d.mts +3 -1
- package/dist/react-document2.d.ts +3 -1
- package/dist/react-document2.js +13 -10
- package/dist/react-document2.js.map +1 -1
- package/dist/react-document2.mjs +13 -10
- package/dist/react-document2.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -231,6 +231,60 @@ const preview = document2Preview(documentNode, 'svg');
|
|
|
231
231
|
|
|
232
232
|
V2 exports Arabic TeX by default for equations saved from the embedded editor. Imported raw-only math is preserved as raw source and marked non-editable until a structured equation object is attached.
|
|
233
233
|
|
|
234
|
+
### Document JSON contract (`value` + `math_objects`)
|
|
235
|
+
|
|
236
|
+
Both document layers import the same shape. A text field holds `value` (the full string, **with math delimiters kept in place**) and an optional parallel `math_objects` array that supplies the structured equation AST for each math span found in that string.
|
|
237
|
+
|
|
238
|
+
Rules:
|
|
239
|
+
|
|
240
|
+
- **Detect, then align.** The importer scans `value` for delimiters (`$…$`, `\(…\)`, `\[…\]`, `$$…$$`, and math environments) and binds each detected span to `math_objects` **in reading order (left-to-right)**.
|
|
241
|
+
- **Count and order must match.** Extra or missing entries produce a diagnostic; the browser never silently remaps. `math_mode`/`closing` on each `MathObject` must match the delimiter in `value`.
|
|
242
|
+
- **Per field, not per document.** Each paragraph, heading, and list `item` carries its own `math_objects`.
|
|
243
|
+
- **Tables are the exception:** one flat `math_objects` array lives on the `\begin{tabular}` block and is consumed **row-major** across all cells (each cell takes as many entries as it has spans).
|
|
244
|
+
- **Missing `math_objects`** → the span renders as a non-editable raw math chip from its delimited source.
|
|
245
|
+
- The browser **does not** parse equation LaTeX bodies into `ChainClass`; structured chains come from `math_objects` (import) or the equation editor (GUI).
|
|
246
|
+
|
|
247
|
+
Paragraph with one inline span:
|
|
248
|
+
|
|
249
|
+
```json
|
|
250
|
+
{
|
|
251
|
+
"command": "\\paragraph",
|
|
252
|
+
"value": "لدينا $x^2$ ثابت.",
|
|
253
|
+
"math_objects": [
|
|
254
|
+
{ "node_type": "MathObject", "math_mode": "$",
|
|
255
|
+
"lines": [{ "node_type": "ChainClass", "chain": [] }], "closing": "$" }
|
|
256
|
+
]
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
List item with a display span (`math_mode`/`closing` match the delimiter in `value`):
|
|
261
|
+
|
|
262
|
+
```json
|
|
263
|
+
{
|
|
264
|
+
"value": "الحل \\[a+b\\]",
|
|
265
|
+
"math_objects": [
|
|
266
|
+
{ "node_type": "MathObject", "math_mode": "\\[",
|
|
267
|
+
"lines": [{ "node_type": "ChainClass", "chain": [] }], "closing": "\\]" }
|
|
268
|
+
]
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Table: one flat array, consumed row-major (here `$x$`, then `$y$`):
|
|
273
|
+
|
|
274
|
+
```json
|
|
275
|
+
{
|
|
276
|
+
"command": "\\begin{tabular}",
|
|
277
|
+
"columns": "cc",
|
|
278
|
+
"rows": [["الرمز $x$", "القيمة"], ["الرمز $y$", "القيمة"]],
|
|
279
|
+
"math_objects": [
|
|
280
|
+
{ "node_type": "MathObject", "math_mode": "$",
|
|
281
|
+
"lines": [{ "node_type": "ChainClass", "chain": [] }], "closing": "$" },
|
|
282
|
+
{ "node_type": "MathObject", "math_mode": "$",
|
|
283
|
+
"lines": [{ "node_type": "ChainClass", "chain": [] }], "closing": "$" }
|
|
284
|
+
]
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
234
288
|
### Document React widget v2 (`butex/react-document2`)
|
|
235
289
|
|
|
236
290
|
Use this entry for the new document editor integration. It opens embedded `<ButexEditor />` sessions in Arabic/RTL mode by default and renders document preview math islands with MathJax **SVG** by default (`mathOutput` defaults to `'svg'`; pass `mathOutput="chtml"` only if the host loads `tex-chtml.js`).
|
|
@@ -254,7 +308,7 @@ export default function Page() {
|
|
|
254
308
|
}
|
|
255
309
|
```
|
|
256
310
|
|
|
257
|
-
Host apps still register BuTeX with MathJax before preview rendering. `uiLocale` selects Arabic (`"ar"`, the default) or English (`"en"`) document-editor chrome and is passed to the embedded equation editor. `documentDirection` independently controls prose inputs and preview flow without creating a second document tree. `equationSide` independently controls whether structured equations open, render, and save from the `"english"` or `"arabic"` side. Set `editableEquations={false}` to show math islands without equation insertion, deletion, or editor access. Raw-only equations keep their original source because the browser does not parse raw LaTeX into equation ASTs. Document editor v2 defaults to **`tex-svg.js`**; use `tex-chtml.js` only if you pass `mathOutput="chtml"`.
|
|
311
|
+
Host apps still register BuTeX with MathJax before preview rendering. `uiLocale` selects Arabic (`"ar"`, the default) or English (`"en"`) document-editor chrome and is passed to the embedded equation editor. `documentDirection` independently controls prose inputs and preview flow without creating a second document tree. `equationSide` independently controls whether structured equations open, render, and save from the `"english"` or `"arabic"` side. Set `editableEquations={false}` to show math islands without equation insertion, deletion, or editor access. Set `previewOnly={true}` to render only the read-only document preview with no toolbar, editor panel, or equation drawer. Raw-only equations keep their original source because the browser does not parse raw LaTeX into equation ASTs. Document editor v2 defaults to **`tex-svg.js`**; use `tex-chtml.js` only if you pass `mathOutput="chtml"`.
|
|
258
312
|
|
|
259
313
|
### Styling/theming contract
|
|
260
314
|
|
|
@@ -285,6 +285,8 @@ type ButexDocumentEditor2Props = {
|
|
|
285
285
|
documentDirection?: 'rtl' | 'ltr';
|
|
286
286
|
equationSide?: EditorSide;
|
|
287
287
|
editableEquations?: boolean;
|
|
288
|
+
/** When true, render only the read-only document preview (no toolbar, editor panel, or equation drawer). */
|
|
289
|
+
previewOnly?: boolean;
|
|
288
290
|
uiLocale?: ButexUiLocale;
|
|
289
291
|
mathOutput?: Document2MathOutput;
|
|
290
292
|
onDocumentChange?: (document: Document2Node) => void;
|
|
@@ -295,7 +297,7 @@ type Document2InitialState = {
|
|
|
295
297
|
error: string | null;
|
|
296
298
|
};
|
|
297
299
|
declare function resolveInitialDocument2(initialDocument: Document2Json | Document2Node | undefined, uiLocale?: ButexUiLocale): Document2InitialState;
|
|
298
|
-
declare function ButexDocumentEditor2({ initialDocument, className, debug, documentDirection, equationSide, editableEquations, uiLocale, mathOutput, onDocumentChange, onLatexChange, }: ButexDocumentEditor2Props): react_jsx_runtime.JSX.Element;
|
|
300
|
+
declare function ButexDocumentEditor2({ initialDocument, className, debug, documentDirection, equationSide, editableEquations, previewOnly, uiLocale, mathOutput, onDocumentChange, onLatexChange, }: ButexDocumentEditor2Props): react_jsx_runtime.JSX.Element;
|
|
299
301
|
|
|
300
302
|
type DocumentInsertToolbarProps = {
|
|
301
303
|
canUndo: boolean;
|
|
@@ -285,6 +285,8 @@ type ButexDocumentEditor2Props = {
|
|
|
285
285
|
documentDirection?: 'rtl' | 'ltr';
|
|
286
286
|
equationSide?: EditorSide;
|
|
287
287
|
editableEquations?: boolean;
|
|
288
|
+
/** When true, render only the read-only document preview (no toolbar, editor panel, or equation drawer). */
|
|
289
|
+
previewOnly?: boolean;
|
|
288
290
|
uiLocale?: ButexUiLocale;
|
|
289
291
|
mathOutput?: Document2MathOutput;
|
|
290
292
|
onDocumentChange?: (document: Document2Node) => void;
|
|
@@ -295,7 +297,7 @@ type Document2InitialState = {
|
|
|
295
297
|
error: string | null;
|
|
296
298
|
};
|
|
297
299
|
declare function resolveInitialDocument2(initialDocument: Document2Json | Document2Node | undefined, uiLocale?: ButexUiLocale): Document2InitialState;
|
|
298
|
-
declare function ButexDocumentEditor2({ initialDocument, className, debug, documentDirection, equationSide, editableEquations, uiLocale, mathOutput, onDocumentChange, onLatexChange, }: ButexDocumentEditor2Props): react_jsx_runtime.JSX.Element;
|
|
300
|
+
declare function ButexDocumentEditor2({ initialDocument, className, debug, documentDirection, equationSide, editableEquations, previewOnly, uiLocale, mathOutput, onDocumentChange, onLatexChange, }: ButexDocumentEditor2Props): react_jsx_runtime.JSX.Element;
|
|
299
301
|
|
|
300
302
|
type DocumentInsertToolbarProps = {
|
|
301
303
|
canUndo: boolean;
|
package/dist/react-document2.js
CHANGED
|
@@ -11556,6 +11556,7 @@ function ButexDocumentEditor2({
|
|
|
11556
11556
|
documentDirection = "rtl",
|
|
11557
11557
|
equationSide = "arabic",
|
|
11558
11558
|
editableEquations = true,
|
|
11559
|
+
previewOnly = false,
|
|
11559
11560
|
uiLocale = "ar",
|
|
11560
11561
|
mathOutput = "svg",
|
|
11561
11562
|
onDocumentChange,
|
|
@@ -11598,10 +11599,10 @@ function ButexDocumentEditor2({
|
|
|
11598
11599
|
injectBuTeXDocument2Styles();
|
|
11599
11600
|
}, []);
|
|
11600
11601
|
(0, import_react6.useEffect)(() => {
|
|
11601
|
-
if (!editableEquations) {
|
|
11602
|
+
if (!editableEquations || previewOnly) {
|
|
11602
11603
|
setSelectedMath(null);
|
|
11603
11604
|
}
|
|
11604
|
-
}, [editableEquations]);
|
|
11605
|
+
}, [editableEquations, previewOnly]);
|
|
11605
11606
|
(0, import_react6.useEffect)(() => {
|
|
11606
11607
|
const next = resolveInitialDocument2(initialDocument, uiLocale);
|
|
11607
11608
|
setDocumentNode(next.document);
|
|
@@ -11890,6 +11891,8 @@ function ButexDocumentEditor2({
|
|
|
11890
11891
|
pendingFocusRef.current = focusAfterDeletedMath(current, next, tokenId);
|
|
11891
11892
|
applyDocument(next, "immediate");
|
|
11892
11893
|
}
|
|
11894
|
+
const showEditorPanel = !previewOnly && editorOpen;
|
|
11895
|
+
const showPreviewPanel = previewOnly || previewOpen;
|
|
11893
11896
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
11894
11897
|
"div",
|
|
11895
11898
|
{
|
|
@@ -11898,7 +11901,7 @@ function ButexDocumentEditor2({
|
|
|
11898
11901
|
dir: uiLocaleDirection(uiLocale),
|
|
11899
11902
|
lang: uiLocale,
|
|
11900
11903
|
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "butex-document2-widget__shell", children: [
|
|
11901
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "butex-document2-widget__toolbar", children: [
|
|
11904
|
+
!previewOnly ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "butex-document2-widget__toolbar", children: [
|
|
11902
11905
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
11903
11906
|
DocumentInsertToolbar,
|
|
11904
11907
|
{
|
|
@@ -11928,19 +11931,19 @@ function ButexDocumentEditor2({
|
|
|
11928
11931
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", onClick: collapseAllBlocks, children: messages.collapseAll }),
|
|
11929
11932
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", onClick: openAllBlocks, children: messages.openAll })
|
|
11930
11933
|
] })
|
|
11931
|
-
] }),
|
|
11934
|
+
] }) : null,
|
|
11932
11935
|
error ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "butex-document2-widget__error", children: error }) : null,
|
|
11933
11936
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
11934
11937
|
"div",
|
|
11935
11938
|
{
|
|
11936
|
-
className: `butex-document2-widget__layout butex-document2-widget__layout--editor-${
|
|
11939
|
+
className: `butex-document2-widget__layout butex-document2-widget__layout--editor-${showEditorPanel ? "open" : "closed"} butex-document2-widget__layout--preview-${showPreviewPanel ? "open" : "closed"}`,
|
|
11937
11940
|
children: [
|
|
11938
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
11941
|
+
!previewOnly ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
11939
11942
|
"section",
|
|
11940
11943
|
{
|
|
11941
11944
|
className: "butex-document2-widget__panel butex-document2-widget__editor-panel",
|
|
11942
11945
|
"aria-label": messages.documentEditor,
|
|
11943
|
-
"aria-hidden": !
|
|
11946
|
+
"aria-hidden": !showEditorPanel,
|
|
11944
11947
|
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "butex-document2-widget__blocks", children: documentNode.blocks.map((block, blockIndex) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
11945
11948
|
BlockEditor,
|
|
11946
11949
|
{
|
|
@@ -11970,13 +11973,13 @@ function ButexDocumentEditor2({
|
|
|
11970
11973
|
block.id
|
|
11971
11974
|
)) })
|
|
11972
11975
|
}
|
|
11973
|
-
),
|
|
11976
|
+
) : null,
|
|
11974
11977
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
11975
11978
|
"section",
|
|
11976
11979
|
{
|
|
11977
11980
|
className: "butex-document2-widget__panel butex-document2-widget__preview-panel",
|
|
11978
11981
|
"aria-label": messages.documentPreview,
|
|
11979
|
-
"aria-hidden": !
|
|
11982
|
+
"aria-hidden": !showPreviewPanel,
|
|
11980
11983
|
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(DocumentPreview, { blocks: preview.blocks, output: mathOutput, documentDirection, uiLocale })
|
|
11981
11984
|
}
|
|
11982
11985
|
)
|
|
@@ -11993,7 +11996,7 @@ function ButexDocumentEditor2({
|
|
|
11993
11996
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("strong", { children: "AST" }),
|
|
11994
11997
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("pre", { children: JSON.stringify(documentNode, null, 2) })
|
|
11995
11998
|
] }) : null,
|
|
11996
|
-
selectedMath ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
11999
|
+
!previewOnly && selectedMath ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
11997
12000
|
EquationDrawer,
|
|
11998
12001
|
{
|
|
11999
12002
|
session: selectedMath.session,
|