@barocss/math-editor 0.2.1 → 0.5.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/ADAPTERS.md +25 -14
- package/API-JAVASCRIPT.md +1 -1
- package/API-REACT.md +5 -1
- package/API-SESSION.md +178 -6
- package/API-SOLID.md +1 -1
- package/API-SVELTE.md +1 -1
- package/API-VUE.md +1 -1
- package/API-WEB-COMPONENT.md +3 -1
- package/CHANGELOG.md +106 -0
- package/EDITING-SCENARIOS.md +174 -0
- package/EMBEDDING.md +4 -0
- package/IMPLEMENTATION.md +122 -2
- package/JSON-MODEL.md +1 -0
- package/LATEX-GUIDE.md +30 -1
- package/LATEX-MODEL.md +12 -0
- package/LATEX-SCOPE.md +12 -3
- package/LICENSE +1 -3
- package/README.md +201 -39
- package/RELEASING.md +81 -10
- package/RENDERING-TESTS.md +79 -0
- package/ROADMAP.md +220 -11
- package/STYLING.md +157 -0
- package/SUPPORT.md +24 -12
- package/VALIDATION.md +444 -4
- package/dist/context-tools.d.ts +21 -0
- package/dist/context-tools.js +37 -0
- package/dist/core.d.ts +5 -1
- package/dist/core.js +5 -1
- package/dist/document-codec.d.ts +0 -1
- package/dist/document-codec.js +0 -1
- package/dist/dom/caret-geometry.d.ts +3 -0
- package/dist/dom/caret-geometry.js +41 -0
- package/dist/dom/context-keyboard.d.ts +2 -0
- package/dist/dom/context-keyboard.js +22 -0
- package/dist/dom/elements.d.ts +1 -2
- package/dist/dom/elements.js +2 -3
- package/dist/dom/latex-panel.d.ts +10 -0
- package/dist/dom/latex-panel.js +59 -0
- package/dist/dom/matrix-selection.d.ts +11 -0
- package/dist/dom/matrix-selection.js +30 -0
- package/dist/dom/menu-position.d.ts +17 -2
- package/dist/dom/menu-position.js +129 -16
- package/dist/dom/presentation-controls.d.ts +4 -0
- package/dist/dom/presentation-controls.js +56 -0
- package/dist/dom/quick-panel.d.ts +12 -0
- package/dist/dom/quick-panel.js +102 -0
- package/dist/dom/selection.d.ts +29 -0
- package/dist/dom/selection.js +53 -0
- package/dist/dom/symbol-panel.d.ts +9 -0
- package/dist/dom/symbol-panel.js +146 -0
- package/dist/dom/theme.d.ts +6 -0
- package/dist/dom/theme.js +68 -0
- package/dist/dom/toolbar-catalog.d.ts +10 -0
- package/dist/dom/toolbar-catalog.js +35 -0
- package/dist/dom/toolbar.d.ts +13 -2
- package/dist/dom/toolbar.js +295 -28
- package/dist/dom.d.ts +9 -1
- package/dist/dom.js +682 -151
- package/dist/editor-labels.d.ts +0 -1
- package/dist/editor-labels.js +0 -1
- package/dist/enter-policy.d.ts +0 -1
- package/dist/enter-policy.js +0 -1
- package/dist/fences.d.ts +0 -1
- package/dist/fences.js +0 -1
- package/dist/i18n.d.ts +0 -1
- package/dist/i18n.js +0 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +4 -1
- package/dist/latex-insertion.d.ts +12 -0
- package/dist/latex-insertion.js +26 -0
- package/dist/latex-paste-panel.d.ts +3 -0
- package/dist/latex-paste-panel.js +18 -0
- package/dist/latex.d.ts +0 -1
- package/dist/latex.js +11 -1
- package/dist/lines.d.ts +0 -1
- package/dist/lines.js +0 -1
- package/dist/locales/en.js +39 -1
- package/dist/locales/en.json +39 -1
- package/dist/locales/ko.js +39 -1
- package/dist/locales/ko.json +39 -1
- package/dist/math-editor-toolbar.d.ts +4 -2
- package/dist/math-editor-toolbar.js +3 -4
- package/dist/math-editor.d.ts +7 -2
- package/dist/math-editor.js +661 -308
- package/dist/math-layout.d.ts +12 -0
- package/dist/math-layout.js +59 -0
- package/dist/math-spacing.d.ts +13 -0
- package/dist/math-spacing.js +87 -0
- package/dist/matrix-range.d.ts +40 -0
- package/dist/matrix-range.js +242 -0
- package/dist/matrix.d.ts +0 -1
- package/dist/matrix.js +0 -1
- package/dist/model.d.ts +4 -1
- package/dist/model.js +49 -5
- package/dist/outputs.d.ts +0 -1
- package/dist/outputs.js +0 -1
- package/dist/preferences.d.ts +24 -0
- package/dist/preferences.js +66 -0
- package/dist/presentation-controls.d.ts +10 -0
- package/dist/presentation-controls.js +10 -0
- package/dist/presentation.d.ts +13 -0
- package/dist/presentation.js +86 -0
- package/dist/quick-panel.d.ts +2 -0
- package/dist/quick-panel.js +17 -0
- package/dist/range.d.ts +2 -1
- package/dist/range.js +11 -1
- package/dist/react.d.ts +0 -1
- package/dist/react.js +0 -1
- package/dist/root-transform.d.ts +19 -0
- package/dist/root-transform.js +69 -0
- package/dist/session.d.ts +31 -2
- package/dist/session.js +108 -7
- package/dist/solid.d.ts +0 -1
- package/dist/solid.js +0 -1
- package/dist/suggestions.d.ts +13 -1
- package/dist/suggestions.js +153 -12
- package/dist/svelte.d.ts +0 -1
- package/dist/svelte.js +0 -1
- package/dist/symbol-browser.d.ts +0 -1
- package/dist/symbol-browser.js +0 -1
- package/dist/symbols.d.ts +0 -1
- package/dist/symbols.js +0 -1
- package/dist/templates.d.ts +0 -1
- package/dist/templates.js +0 -1
- package/dist/tokens.d.ts +0 -1
- package/dist/tokens.js +0 -1
- package/dist/vertical-navigation.d.ts +15 -0
- package/dist/vertical-navigation.js +145 -0
- package/dist/vue.d.ts +0 -1
- package/dist/vue.js +0 -1
- package/dist/web-component.d.ts +0 -1
- package/dist/web-component.js +9 -2
- package/package.json +11 -3
- package/src/fonts/KaTeX_Math-Italic.woff2 +0 -0
- package/src/fonts/KaTeX_Size1-Regular.woff2 +0 -0
- package/src/fonts/README.md +18 -0
- package/src/shapes/README.md +21 -0
- package/src/shapes/parenthesis-bottom.svg +1 -0
- package/src/shapes/parenthesis-top.svg +1 -0
- package/src/shapes/parenthesis.svg +1 -0
- package/src/shapes/radical.svg +1 -0
- package/src/style.css +949 -173
- package/dist/core.d.ts.map +0 -1
- package/dist/core.js.map +0 -1
- package/dist/document-codec.d.ts.map +0 -1
- package/dist/document-codec.js.map +0 -1
- package/dist/dom/elements.d.ts.map +0 -1
- package/dist/dom/elements.js.map +0 -1
- package/dist/dom/menu-position.d.ts.map +0 -1
- package/dist/dom/menu-position.js.map +0 -1
- package/dist/dom/toolbar.d.ts.map +0 -1
- package/dist/dom/toolbar.js.map +0 -1
- package/dist/dom.d.ts.map +0 -1
- package/dist/dom.js.map +0 -1
- package/dist/editor-labels.d.ts.map +0 -1
- package/dist/editor-labels.js.map +0 -1
- package/dist/enter-policy.d.ts.map +0 -1
- package/dist/enter-policy.js.map +0 -1
- package/dist/fences.d.ts.map +0 -1
- package/dist/fences.js.map +0 -1
- package/dist/i18n.d.ts.map +0 -1
- package/dist/i18n.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/latex.d.ts.map +0 -1
- package/dist/latex.js.map +0 -1
- package/dist/lines.d.ts.map +0 -1
- package/dist/lines.js.map +0 -1
- package/dist/math-editor-toolbar.d.ts.map +0 -1
- package/dist/math-editor-toolbar.js.map +0 -1
- package/dist/math-editor.d.ts.map +0 -1
- package/dist/math-editor.js.map +0 -1
- package/dist/matrix.d.ts.map +0 -1
- package/dist/matrix.js.map +0 -1
- package/dist/model.d.ts.map +0 -1
- package/dist/model.js.map +0 -1
- package/dist/outputs.d.ts.map +0 -1
- package/dist/outputs.js.map +0 -1
- package/dist/range.d.ts.map +0 -1
- package/dist/range.js.map +0 -1
- package/dist/react.d.ts.map +0 -1
- package/dist/react.js.map +0 -1
- package/dist/session.d.ts.map +0 -1
- package/dist/session.js.map +0 -1
- package/dist/solid.d.ts.map +0 -1
- package/dist/solid.js.map +0 -1
- package/dist/suggestions.d.ts.map +0 -1
- package/dist/suggestions.js.map +0 -1
- package/dist/svelte.d.ts.map +0 -1
- package/dist/svelte.js.map +0 -1
- package/dist/symbol-browser.d.ts.map +0 -1
- package/dist/symbol-browser.js.map +0 -1
- package/dist/symbols.d.ts.map +0 -1
- package/dist/symbols.js.map +0 -1
- package/dist/templates.d.ts.map +0 -1
- package/dist/templates.js.map +0 -1
- package/dist/tokens.d.ts.map +0 -1
- package/dist/tokens.js.map +0 -1
- package/dist/vue.d.ts.map +0 -1
- package/dist/vue.js.map +0 -1
- package/dist/web-component.d.ts.map +0 -1
- package/dist/web-component.js.map +0 -1
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# Editing scenarios
|
|
2
|
+
|
|
3
|
+
Use this document to manage editing behavior. [Supported features](SUPPORT.md)
|
|
4
|
+
lists notation; this register describes what a person does with that notation.
|
|
5
|
+
[Validation](VALIDATION.md) stores dated execution evidence. Neither the number
|
|
6
|
+
of features nor the number of unit tests proves that an editing flow works.
|
|
7
|
+
|
|
8
|
+
## Status and ownership
|
|
9
|
+
|
|
10
|
+
Keep each scenario ID stable. Add the ID to the browser fixture that exercises
|
|
11
|
+
it and to a bug report when that flow fails. The person changing the behavior
|
|
12
|
+
updates its expected result, test mapping and execution record in the same change.
|
|
13
|
+
The release owner reviews unresolved cases before publishing.
|
|
14
|
+
|
|
15
|
+
| Status | Meaning |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| Recorded | A dated run is recorded for the stated scope. This is not a pass for every adapter or a future build. |
|
|
18
|
+
| Rerun | Related browser checks exist, but this register does not certify the full scenario on the current source. |
|
|
19
|
+
| Extend | Some assertions exist; additional browser steps or checks are required. |
|
|
20
|
+
| Manual | Requires a person or device. No automated pass is claimed. |
|
|
21
|
+
|
|
22
|
+
P0 covers loss of content, blocked input, invalid output and host persistence.
|
|
23
|
+
P1 covers discoverability, navigation and presentation. P2 covers additional
|
|
24
|
+
platform coverage. A known P0 failure blocks release for the affected scope.
|
|
25
|
+
An unrun or unsupported case must never be counted as passed.
|
|
26
|
+
|
|
27
|
+
## Scenario register
|
|
28
|
+
|
|
29
|
+
Start each case with a fresh editor unless the steps specify saved content.
|
|
30
|
+
Use actual key presses for typing and actual pointer movement for drag cases.
|
|
31
|
+
`Cmd` applies on macOS; `Ctrl` applies on Windows/Linux. Do not substitute a
|
|
32
|
+
programmatic value assignment for a focus or typing assertion.
|
|
33
|
+
|
|
34
|
+
| ID | Priority / flow | Steps | Required result | Status / test mapping |
|
|
35
|
+
| --- | --- | --- | --- | --- |
|
|
36
|
+
| EDIT-001 | P0 — Continuous input | Enter `4ab+12`, one key at a time. Pause after `4`. Resume while suggestions are visible. Move left, insert `x`, then delete it. | Each key appears once. The input retains focus. Numbers and variables remain in order; no key changes host prose. | Rerun — `quill-typing-check.js`, `typing-check.js`, `token-paste-check.js` |
|
|
37
|
+
| EDIT-002 | P0 — Operand wrapping | Type `4ab`. Choose absolute value for the `ab` operand. Continue typing after the structure. Repeat with parentheses, fraction and root. | `ab` remains inside the chosen structure; `4` remains outside. The cursor reaches the intended slot or following boundary. No operand disappears. | Rerun — `operand-size-check.js`; `suggestions.test.ts` |
|
|
38
|
+
| EDIT-003 | P0 — Selected suggestion | Type `abcd`. Select `cd` with Shift+Left twice. Use Down/Up, choose root, then Enter. Repeat with mouse drag. | The range stays selected while options change. Only `cd` is wrapped. The input receives focus after acceptance. | Rerun — `selection-suggestions-check.js`. Recorded 2026-09-09 for React and nine hosts before radical suggestions were added; rerun after suggestion changes. |
|
|
39
|
+
| EDIT-004 | P0 — Return to a caret | Select part of `abcd`, press Left or Right, then type `q`. Repeat with a selection that includes a fraction. In the native field, dismiss the menu with Escape before testing Up/Down collapse. | Left uses the ordered start; Right uses the ordered end. Typing inserts at that edge instead of replacing the old range. A fraction boundary does not enter the wrong slot. | Rerun — `selection-collapse-check.js`, `tinymce-inline-check.js` |
|
|
40
|
+
| EDIT-005 | P0 — Radical conversion | Load `\sqrt{x+1}`. Choose Change to Indexed root. Replace the selected `2` with `3`. Return to the radicand, then edit the index to `2` and convert back. Undo and Redo. | The radicand and nested nodes survive. Index `2` is selected on conversion. Index `3` cannot be silently discarded. One conversion is one Undo step. | Recorded, partial scope — `root-transform-check.js` (React/Quill, pointer and keyboard acceptance, 2026-09-09); `root-transform.test.ts` (Undo/Redo and nested trees). Browser Undo/Redo and the other hosts still need a run. |
|
|
41
|
+
| EDIT-006 | P0 — Structure deletion | Create a fraction, scripts, aligned equations and cases. Test Backspace/Delete at inner and outer boundaries with empty and populated slots. Undo each deletion. | Behavior matches the documented boundary rule. Populated grid cells are not silently merged or lost. Undo restores content and structure. | Extend — `empty-slot-deletion-check.js` recorded React/DOM Delete, Backspace and Undo for empty roots, fractions, exponents and root indices on 2026-09-09. Grid and populated-boundary checks remain separate: `grid-deletion.test.ts`, `native-parity-check.js`. |
|
|
42
|
+
| EDIT-007 | P0 — Copy and paste a range | Select text plus a nested fraction. Copy, move the caret, paste, then cut and Undo. Repeat across two editor instances. | The selected structure is preserved; unselected content stays unchanged. Cut can be undone. A rejected paste leaves the document unchanged. | Extend — `native-parity-check.js`, `token-paste-check.js`, `range.test.ts`; real OS clipboard coverage remains separate. |
|
|
43
|
+
| EDIT-008 | P0 — LaTeX import failure | Import `\frac{x}{y}+z`. Edit `x`. Attempt an unsupported command and malformed braces. Cancel, then reopen. | Valid input is editable. Invalid or unsupported input reports a diagnostic and retains the previous formula. Cancel does not replace host content. | Rerun — `latex-paste-host-check.js`, `latex-insertion.test.ts`, `latex.test.ts` |
|
|
44
|
+
| EDIT-009 | P0 — Apply, Cancel and history | Open an existing host formula. Edit and Cancel. Reopen, edit and Apply. Run host Undo and Redo. | Cancel leaves the stored host data unchanged. Apply creates one host history operation. Host serialization contains formula data, not input/menu DOM. | Rerun — host fixtures, including `tinymce-inline-check.js`, `quill-composition-check.js`, `ckeditor-check.js` |
|
|
45
|
+
| EDIT-010 | P0 — Save and reopen | Edit nested content, Apply, Save and Restore. Reload the stored host document and reopen the formula. | Structure, LaTeX and configured presentation survive. The formula is editable after restoration. Do not claim persistence from a preview-only check. | Rerun — `unified-check.js` and host-specific fixtures; record each supported storage format. |
|
|
46
|
+
| EDIT-011 | P0 — Host boundary and read-only | Move from prose into an inline formula with a boundary arrow. Edit, exit and continue prose. Switch the host to read-only with a draft open. | Math key events do not edit prose. Read-only closes or disables the draft according to the host contract and prevents new mutations. | Rerun — `shared-boundary-check.js`, `host-check.js`, host-specific fixtures |
|
|
47
|
+
| EDIT-012 | P1 — Suggestion scrolling | Type `matrix`. Park the pointer over a menu item. Press Down repeatedly with pauses; reverse with Up. Test near the bottom of the viewport and in an iframe. | Each press moves one option. The selected option stays visible. The list does not jump back; the page and host do not scroll unexpectedly. | Rerun — `suggestion-arrow-check.js`, `suggestion-menu-clipping-check.js`, `iframe-field-check.js` |
|
|
48
|
+
| EDIT-013 | P1 — Nested navigation | Enter `x_i^2`, a fraction inside a root, and a limit. Move with Left/Right, Up/Down and Tab at every slot boundary. | The nearest structure owns vertical movement when no suggestion menu is active. Selection and caret positions remain valid. | Rerun — `react-vertical-check.js`, `vertical-check.js`, `vertical-navigation.test.ts` |
|
|
49
|
+
| EDIT-014 | P1 — Rectangular matrix | Type `3x7` and accept the matrix. Fill cells; add/delete rows and columns. Test `1x2` and `2x1` boundaries. | Dimensions match the request. Existing cells retain their content. Cursor movement follows the resulting grid. | Rerun — `matrix-size-shortcut-check.js`, `matrix.test.ts`, `native-tools-host-check.js` |
|
|
50
|
+
| EDIT-015 | P0 — Matrix range editing | Select a cell rectangle. Copy/paste, clear, Undo and transpose. Test a mismatched or oversized paste. | Cell boundaries and nested structures survive. Invalid operations leave the matrix unchanged. Draft operations do not create host history entries. | Rerun — `matrix-range-check.js`, `matrix-range-host-check.js`, `matrix-range.test.ts` |
|
|
51
|
+
| EDIT-016 | P1 — Lines, alignment and cases | Create two lines. Insert aligned equations and cases; add a row and edit both columns. Try Enter in inline mode. | Block layouts retain their rows. Inline mode does not create an extra formula line. Enter follows the configured host commit policy. | Extend — `typing-check.js`, `lines.test.ts`, `equation.test.ts`, `embedding.test.ts`; add a combined browser flow. |
|
|
52
|
+
| EDIT-017 | P1 — Preview agreement | Edit a nested root, scripts, tall fences, integrals with limits, and a chemical formula. Compare exported LaTeX in KaTeX at a matched base size. Repeat with the input active. | Mathematical structure agrees. Baselines, fences, indices and limits remain readable. Focus backgrounds and hit areas do not obscure notation. | Recorded metric baseline — 77 formulas / 288 React/DOM mode-size comparisons passed on 2026-09-10. See the source-only `test/rendering/STATUS.md` ledger. Selected metrics and active-input checks do not certify every glyph or every editing flow. |
|
|
53
|
+
| EDIT-018 | P1 — Language and multiple instances | Switch en/ko with a draft open. Open another editor and its suggestions. Repeat with a registered custom locale. | Labels resolve, formulas do not change, focus and menus stay with the right instance, and search aliases use the locale fallback rules. | Rerun — `plugins-locale-check.js`, `shared-symbol-tools-check.js`, `locale-discovery.test.ts` |
|
|
54
|
+
| EDIT-019 | P0 — Long edit session | Build a fraction, wrap a selection, convert a radical, insert a matrix, undo five steps, redo five, Apply, Save and reopen. Repeat without resetting the page. | No stuck focus, lost selection, duplicated operation or draft leakage. All checkpoints retain the expected formula. | Recorded, scoped — `test/editing/continuous.browser.js`, run with `pnpm --filter @barocss/math-editor test:editing`. React standalone block, Quill/Tiptap/ProseMirror/Lexical/TinyMCE/CKEditor/Slate in-place block/inline, and Editor.js/Gutenberg block passed on 2026-09-10 (17 targets, 499 checkpoints); includes two uninterrupted formula history chains and host Apply/Save/reload/Restore/Cancel. Editor.js has no host history integration, so document Undo/Redo remains unverified there. Inline additionally verifies Enter commit without new paragraphs, right-boundary exit, prose caret position and host Undo. TinyMCE uses its inline host, CKEditor uses ClassicEditor, and Gutenberg uses the standalone provider demo. Other configurations and native OS input remain unverified by this run. |
|
|
55
|
+
| EDIT-020 | P2 — Native IME and clipboard | On a real OS, compose Korean text, move the caret, use suggestions, cancel composition and paste with the system clipboard. | Composed text appears once; composition keys do not apply suggestions or host commands prematurely. Clipboard data is preserved according to the documented formats. | Manual — previously deferred by the user. Synthetic composition/DataTransfer checks do not certify OS behavior. |
|
|
56
|
+
|
|
57
|
+
## Contextual structure tools
|
|
58
|
+
|
|
59
|
+
These scenarios specify the footer independently from the suggestion list. The
|
|
60
|
+
footer has a single target: the nearest enclosing radical or fence. It is shown only
|
|
61
|
+
while that editor is active, outside literal text and model/matrix selections.
|
|
62
|
+
Native text selection within the active slot is allowed, including the selected
|
|
63
|
+
index produced by conversion.
|
|
64
|
+
|
|
65
|
+
| ID | Priority / flow | Steps | Required result | Coverage |
|
|
66
|
+
| --- | --- | --- | --- | --- |
|
|
67
|
+
| EDIT-021 | P1 — Discover without search | Click inside a root. Put the caret at the start of its text. Dismiss suggestions with Escape. Move outside the root. | Footer shows the current structure and conversion even with no query or no open suggestions. Leaving the radical hides it. | `context-tools-check.js` |
|
|
68
|
+
| EDIT-022 | P0 — Footer conversion and index edit | Convert a root using the footer. Replace selected index `2` with `3`. Click the radicand, choose Edit index, type `2`, convert back and Undo. | Content survives, index editing selects the existing index, a non-square index blocks reverse conversion with a visible reason, and Undo restores the structure. | `context-tools-check.js` |
|
|
69
|
+
| EDIT-023 | P0 — Keyboard-only footer | From input, press F6, Escape, F6 and Enter. Tab between available buttons. | F6 enters tools; Escape returns to the same input. Button activation edits the intended structure. Keys do not reach host prose. Tab uses native button order. | F6/Escape/Enter recorded in `context-tools-check.js`; explicit Tab-order assertion remains to add. |
|
|
70
|
+
| EDIT-024 | P0 — Nearest nested target | Open `\sqrt[3]{a+\sqrt{x}}`. Move between `a` and `x`. | Footer identifies the outer indexed root at `a` and inner square root at `x`. Index editing targets the corresponding root. | `context-tools-options-check.js`, `root-transform.test.ts` |
|
|
71
|
+
| EDIT-025 | P1 — Locale without model changes | Show tools, change en to ko, then edit the index. | Structure name, actions, disabled reason and keyboard hint update together. Stored formula content is unchanged by locale selection. | `context-tools-options-check.js`; direct document equality on locale switch remains to add. |
|
|
72
|
+
| EDIT-026 | P0 — Scope and focus | Create a model range, collapse it, blur the field, reopen, then destroy the instance. Repeat focus navigation inside an iframe. | Range mode does not show stale caret actions. Collapse restores context; blur hides it; destroy removes it. Focus stays in the iframe's own document. | `context-tools-check.js`, `context-tools-options-check.js` |
|
|
73
|
+
| EDIT-027 | P0 — Composition guard | Dispatch composition start and end in the native field with context visible. | Actions are disabled during composition and resume afterward. This guard test is not OS IME certification. | Synthetic coverage in `context-tools-options-check.js`; real OS behavior remains EDIT-020. |
|
|
74
|
+
| EDIT-028 | P1 — Embedding opt-out | Set `contextTools: false`, then update to true. Repeat with `context-tools="false"` on a Web Component. | Footer hides without changing the formula or removing suggestion-based conversions. Attribute updates take effect without remounting. | Visibility/update coverage in `context-tools-options-check.js`; per-framework wrapper smoke checks remain to add. |
|
|
75
|
+
|
|
76
|
+
## Inline transformation suggestions
|
|
77
|
+
|
|
78
|
+
The suggestion list is the primary keyboard entry point for structural changes.
|
|
79
|
+
It remains available when both toolbar and context footer are hidden. Alt+Down
|
|
80
|
+
opens or reopens suggestions and highlights the first available transformation;
|
|
81
|
+
Up/Down browses, Enter applies, and Escape dismisses without editing the formula.
|
|
82
|
+
Automatic context-only suggestions require navigation before Enter can apply them,
|
|
83
|
+
so an inline host's commit key is not silently replaced.
|
|
84
|
+
|
|
85
|
+
| ID | Priority / scenario | Steps | Expected result | Coverage |
|
|
86
|
+
| --- | --- | --- | --- | --- |
|
|
87
|
+
| EDIT-029 | P0 — Fence suggestions in inline fields | Type inside parentheses. Press Alt+Down, Enter, then continue typing. Repeat after dismissing the menu. | The list distinguishes changing a fence from wrapping an operand. Existing content and caret are preserved; the menu does not take DOM focus. | `fence-suggestions-check.js`, `context-tools.test.ts` |
|
|
88
|
+
| EDIT-030 | P0 — Browse, cancel and Undo | Open changes, browse with Up/Down, cancel with Escape. Reopen, apply, type, then undo typing and conversion separately. | Browsing and cancellation do not change the formula. Conversion makes one history entry. | `fence-suggestions-check.js` |
|
|
89
|
+
| EDIT-031 | P0 — Nearest wrapper and all fence pairs | Change each of eight fence types. Test nested fractions, roots, mixed delimiters and stale targets. Use F6/Left/Right/Enter if the optional footer is enabled. | Only the nearest supported wrapper changes. Slot IDs, content and caret remain stable. Explicit left/right metadata is removed when selecting a standard pair. | `context-tools.test.ts`, `fence-context-check.js`; browser nested targeting in EDIT-032 |
|
|
90
|
+
| EDIT-032 | P0 — No-toolbar inline iframe | Hide toolbar/footer in an inline iframe field. Change an inner fence with suggestions, switch ko/en and continue typing. Destroy the editor. | The complete workflow works without auxiliary UI. Locale changes leave the document unchanged. Focus uses the iframe document; teardown removes suggestions. | `fence-inline-options-check.js`; installed host/browser breadth remains separate validation work |
|
|
91
|
+
|
|
92
|
+
Execution scope is recorded in [Validation](VALIDATION.md). A mapped case may
|
|
93
|
+
still contain pending assertions, as stated in the Coverage column.
|
|
94
|
+
|
|
95
|
+
Browser fixture names above refer to `apps/math-integrations/tests/`. Unit fixture
|
|
96
|
+
names refer to `packages/math-editor/test/`. A mapping identifies related coverage,
|
|
97
|
+
not an assertion that every step already exists in that file. Extend cases need
|
|
98
|
+
explicit browser assertions before they can receive a full pass.
|
|
99
|
+
|
|
100
|
+
## Test environments
|
|
101
|
+
|
|
102
|
+
Record renderer, adapter, mode and browser separately. An integration using the
|
|
103
|
+
native DOM field does not prove the rich React field, and an iframe can have its
|
|
104
|
+
own focus, event and CSS failures.
|
|
105
|
+
|
|
106
|
+
| Layer | Required scope when that layer changes |
|
|
107
|
+
| --- | --- |
|
|
108
|
+
| Shared model / suggestions | Unit checks plus affected editing scenarios on rich React and native DOM. |
|
|
109
|
+
| Framework adapter | The affected adapter: pure JS, Web Component, Vue, Svelte, Solid, or React wrapper. Record the actual renderer used. |
|
|
110
|
+
| Host integration | Every affected host. Shared field changes need the nine-host smoke set: Tiptap, ProseMirror, Lexical, Editor.js, TinyMCE, CKEditor, Quill, Slate, Gutenberg. |
|
|
111
|
+
| Mode / container | Inline and block where supported; TinyMCE classic iframe as well as inline. Editor.js and Gutenberg block-only scenarios are N/A for inline tests. |
|
|
112
|
+
| Browser | Record Chromium, Firefox or WebKit explicitly. Current Chromium evidence does not cover the other engines. |
|
|
113
|
+
| Build source | Workspace source for development; packed artifacts for release checks. Neither implies the other. |
|
|
114
|
+
|
|
115
|
+
## Per-run record
|
|
116
|
+
|
|
117
|
+
Append detailed evidence to [Validation](VALIDATION.md), using this template.
|
|
118
|
+
Record an immutable revision when possible. For an uncommitted workspace, record
|
|
119
|
+
that fact and save the tested patch or a source fingerprint with the run artifacts.
|
|
120
|
+
A date alone does not identify the tested code.
|
|
121
|
+
|
|
122
|
+
```text
|
|
123
|
+
Run ID: edit-YYYYMMDD-NN
|
|
124
|
+
Scenario IDs:
|
|
125
|
+
Source: commit / workspace fingerprint / package versions and archive hashes
|
|
126
|
+
Fixture revision:
|
|
127
|
+
Renderer and host:
|
|
128
|
+
Mode and container:
|
|
129
|
+
Browser, OS, locale:
|
|
130
|
+
Input formula and steps:
|
|
131
|
+
Expected result:
|
|
132
|
+
Observed result:
|
|
133
|
+
Outcome: PASS / FAIL / BLOCKED / NOT RUN / N/A
|
|
134
|
+
Evidence: log, screenshot pair, trace or recorded host data
|
|
135
|
+
Remaining steps and excluded environments:
|
|
136
|
+
Issue / follow-up:
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
A scenario passes only when all required assertions pass in the recorded scope.
|
|
140
|
+
For partial coverage, report the passing steps and keep the rest unverified.
|
|
141
|
+
Do not convert historical validation totals into a current release pass.
|
|
142
|
+
|
|
143
|
+
## Change workflow
|
|
144
|
+
|
|
145
|
+
1. Assign a scenario ID to each editing bug before changing its behavior.
|
|
146
|
+
2. Reproduce the smallest failing input sequence. Capture the caret, selection,
|
|
147
|
+
highlighted suggestion, document and host data where relevant.
|
|
148
|
+
3. Add or update a regression fixture with the same ID. Check the final model,
|
|
149
|
+
cursor/focus and history behavior, not only whether an element is visible.
|
|
150
|
+
4. Implement the change. Run its model tests, affected browser scenarios and the
|
|
151
|
+
nearest negative case. Compare editor/KaTeX output when notation changes.
|
|
152
|
+
5. Record the result and its scope. Mark related scenarios for rerun if later
|
|
153
|
+
changes touch their input, selection, suggestions, history or host handling.
|
|
154
|
+
6. Before release, run the applicable P0 cases against the release candidate and
|
|
155
|
+
check packed imports. Any excluded host/browser must be stated explicitly.
|
|
156
|
+
|
|
157
|
+
The Markdown register is the source of truth for scope and acceptance criteria.
|
|
158
|
+
The browser fixtures contain executable assertions. The validation report holds
|
|
159
|
+
run evidence. The documentation site renders this register; it does not execute
|
|
160
|
+
the browser checks. Automated release enforcement is not implemented by this
|
|
161
|
+
register alone.
|
|
162
|
+
|
|
163
|
+
## Next work
|
|
164
|
+
|
|
165
|
+
1. Maintain the EDIT-019 baseline across all nine integration demos and React
|
|
166
|
+
standalone block. Extend it separately to TinyMCE iframe, WordPress admin and
|
|
167
|
+
other host configurations. Preserve exact checkpoints and host-history assertions.
|
|
168
|
+
2. Add missing browser steps for EDIT-006, EDIT-007 and EDIT-016. Include negative
|
|
169
|
+
cases and real host Undo/Redo rather than testing only model transformations.
|
|
170
|
+
3. Reuse the EDIT-019 runner pattern for additional scenario IDs. It already
|
|
171
|
+
records source fingerprints and fails on changed source or failed assertions.
|
|
172
|
+
CI/release enforcement remains separate work.
|
|
173
|
+
4. Schedule Firefox/WebKit and real OS IME/clipboard coverage separately. Keep
|
|
174
|
+
manual requirements visible without representing synthetic events as a substitute.
|
package/EMBEDDING.md
CHANGED
|
@@ -100,3 +100,7 @@ The browser tests cover panel synchronization without extra change events, singl
|
|
|
100
100
|
Note opts into the shared `LatexEditor` visual mode with `MathEditorSurface`. Existing tex-only atoms load through `parseLatex`; unsupported input stays in the original source editor. Visual draft changes produce `tex` plus JSON-encoded `mathDocument`. `setMathSource` validates the structure, source equality and inline policy, then applies one host transaction. Cancellation writes nothing. Direct source changes clear stale structure, while font/alignment-only edits retain it.
|
|
101
101
|
|
|
102
102
|
Other products must use the same [import scope](LATEX-SCOPE.md) and core parser. Do not add product-specific regex conversions. Existing Word OMML and Site/Slide ownership boundaries still need their own host adapters; the Note trial does not integrate those products automatically.
|
|
103
|
+
|
|
104
|
+
## Style customization
|
|
105
|
+
|
|
106
|
+
Use inherited CSS variables for colors, slot backgrounds, typography, toolbar density and menu appearance. Scoped themes also follow portaled suggestions in both renderers. See [Styling & themes](STYLING.md) for the public variables, dark/monochrome examples, shared toolbars and iframe/plugin sizing.
|
package/IMPLEMENTATION.md
CHANGED
|
@@ -28,8 +28,10 @@ Navigation does not create a document history entry. Locale changes do not remou
|
|
|
28
28
|
| `tokens.ts` | Lexical variable/numeric/symbol segmentation and boundary affinity |
|
|
29
29
|
| `math-editor.tsx` | Native input lifecycle, IME, pointer hit testing, selection UI, keyboard routing and portal |
|
|
30
30
|
| `range.ts` | Endpoint ordering, balanced selection resolution, slicing, insertion, wrapping and clipboard validation |
|
|
31
|
+
| `matrix-range.ts` | Transient cell rectangles, clipboard shape validation, fresh subtree IDs, atomic paste/clear and full-matrix transpose |
|
|
31
32
|
| `matrix.ts` | Innermost grid lookup, row/column changes, delimiters and grid navigation |
|
|
32
33
|
| `lines.ts` | Top-level line split/join and vertical navigation |
|
|
34
|
+
| `vertical-navigation.ts`, `dom/caret-geometry.ts` | Shared structural Up/Down movement and optional measurements of rendered insertion points |
|
|
33
35
|
| `suggestions.ts` | Longest symbolic triggers, bilingual aliases, candidates and acceptance |
|
|
34
36
|
| `symbols.ts` | Glyph, message key, search aliases, symbolic triggers and LaTeX mapping |
|
|
35
37
|
| `templates.ts` | Fresh editable template trees and insertion through the range model |
|
|
@@ -60,6 +62,8 @@ Passive tokens render as spans. Only the active token renders an input. A hidden
|
|
|
60
62
|
|
|
61
63
|
During composition, the token partition and input element are held stable. Suggestions are visible but disabled. Enter and arrows remain with the IME; parent handlers do not receive editing keystrokes. On composition end, the complete text is committed as one history change and tokenization resumes. Synthetic composition tests are not a substitute for actual OS input-method validation.
|
|
62
64
|
|
|
65
|
+
`moveVertical` walks slot ancestors from the inside out: fractions, scripts, indexed roots, annotations and operator bounds precede enclosing grids and document lines. Grid targets stay in the same column. Both keyboard handlers pass caret measurements from the existing hidden mirrors; React token offsets are translated back to their logical text run. The target is the nearest horizontal insertion point in the requested direction, with vertical distance breaking ties. Paired scripts and operator bounds also consider their base/body, so movement can follow their shared script column. Missing layout uses the first target text run with a clamped UTF-16 offset, avoiding surrogate splits. Navigation preserves the document and undo history. It does not add persistent preferred-column state or change Shift+arrow selection.
|
|
66
|
+
|
|
63
67
|
## Ranges and transformations
|
|
64
68
|
|
|
65
69
|
`MathRange` has anchor/focus points identified by logical text ID and UTF-16 offset. `resolveRange` orders them in document traversal order and finds the deepest shared row. Endpoints in different slots expand to a balanced common structure; endpoints on different document lines produce multiple row slices.
|
|
@@ -175,7 +179,7 @@ The parser accepts a bare brace body and creates an empty annotation. Export alw
|
|
|
175
179
|
|
|
176
180
|
## Compact and filtered toolbars (workspace)
|
|
177
181
|
|
|
178
|
-
Toolbars initially show up to eight structure buttons. More tools / Fewer tools toggles the remainder without changing the formula or history. Rich React also places matrix presets, templates and symbol shortcuts in the expanded section; Undo, Redo and `toolbarEnd` stay visible. Native toolbars
|
|
182
|
+
Toolbars initially show up to eight structure buttons. More tools / Fewer tools toggles the remainder without changing the formula or history. Rich React also places matrix presets, templates and symbol shortcuts in the expanded section; Undo, Redo and `toolbarEnd` stay visible. Native toolbars also expose symbol search, templates and presets behind More tools; both renderers provide contextual matrix controls and cell selection/transpose. The layout wraps naturally on narrow screens; this is not a guaranteed single-row toolbar.
|
|
179
183
|
|
|
180
184
|
```tsx
|
|
181
185
|
<MathEditor toolbar={['fraction', 'root', 'superscript', 'matrix']}
|
|
@@ -214,7 +218,7 @@ Each is a structure with a unique `id` and exactly one MathRow in `slots: [body]
|
|
|
214
218
|
|
|
215
219
|
All limit-family, sum/product and integral nodes accept a single `\limits` or `\nolimits` immediately after the command, before scripts. The optional `limits` field is now boolean: omitted means default, `true` is stacked placement, `false` is side placement. Both explicit values survive JSON validation, copying and LaTeX export. Repeated/conflicting directives are rejected. Existing `limits: true` remains valid; older package builds do not accept `false` or the new limit kinds.
|
|
216
220
|
|
|
217
|
-
Placement is
|
|
221
|
+
Placement is selected through imported LaTeX/model metadata or the workspace contextual toolbar. Imported side conditions remain editable; normal limit suggestions use default placement. This is 0.2.0 functionality.
|
|
218
222
|
|
|
219
223
|
## Fine mathematical spacing (workspace)
|
|
220
224
|
|
|
@@ -240,3 +244,119 @@ Reuse the existing two-slot structures with optional `mathStyle: 'display' | 'te
|
|
|
240
244
|
## Labeled arrows
|
|
241
245
|
|
|
242
246
|
The `xrightarrow` and `xleftarrow` structures have two slots in upper/lower order. Parse the optional lower bracket before the required upper argument, then store in model order. Render the generic slots in three CSS grid rows, with a pseudo-element shaft and a fixed-size head in the middle row. Labels drive grid width; the decoration cannot intercept pointer events. These commands are inserted through the shared catalog and do not require a separate dialog.
|
|
247
|
+
|
|
248
|
+
## Cell selection and grid transformations
|
|
249
|
+
|
|
250
|
+
`MathMatrixRange` is separate from `MathRange`: `{ matrixId, anchor, focus }` uses
|
|
251
|
+
row-major cell indices and resolves to a rectangle. Neither selection is persisted.
|
|
252
|
+
Cross-cell pointers use the nearest shared matrix ancestor; within-cell pointers
|
|
253
|
+
retain text/structure selection. The DOM renderer keeps selection in MathSession;
|
|
254
|
+
rich React owns its view state and calls the same pure matrix operations.
|
|
255
|
+
|
|
256
|
+
Clipboard data has its own bounded matrix MIME payload, plus a regular math
|
|
257
|
+
fragment and LaTeX fallback. Incoming cells receive fresh IDs recursively. Paste
|
|
258
|
+
validates all dimensions before cloning or writing the destination; unselected
|
|
259
|
+
cells and the destination delimiter survive. Transpose reorders existing slots
|
|
260
|
+
and changes `columns`; preserving IDs keeps a nested caret valid. None of these
|
|
261
|
+
operations needs a new model version or parser command.
|
|
262
|
+
|
|
263
|
+
## Shared editing utilities — workspace
|
|
264
|
+
|
|
265
|
+
Native text rows are tokenized with the same `tokenizeMathText`/`tokenIndexAt` rules as rich React. Every rendered run retains its model ID and UTF-16 token start/end. Input events replace only that token's slice. Pointer/keyboard offsets are translated to model coordinates; boundary deletion joins neighboring text without discarding it. IME preedit updates the stable input/mirror and is committed before re-tokenizing. Literal text/operator names remain one input.
|
|
266
|
+
|
|
267
|
+
`latex-insertion.ts` parses before applying a range insertion. `preferences.ts` owns validated UI lists independently of formula sessions/history. `presentation.ts` changes only supported metadata while preserving subtree IDs and caret. The nonmodal native panels are reused by React wrappers, so diagnostics and favorites use one implementation. Host clipboard boundaries stay intact and no system clipboard reads are implicit.
|
|
268
|
+
|
|
269
|
+
### Contextual radical conversions
|
|
270
|
+
|
|
271
|
+
`findStateSuggestions(state, locale, caret?)` augments text search with the nearest
|
|
272
|
+
enclosing radical's conversion actions. `transformRootId` binds an action to that
|
|
273
|
+
structure; `acceptSuggestion` validates the current target before conversion and
|
|
274
|
+
does not remove the query. `root-transform.ts` clones the document, preserves the
|
|
275
|
+
radicand tree and structure ID, and updates the slots. Converting to an indexed
|
|
276
|
+
root adds a selected index `2`; converting to a square root rejects any nonempty
|
|
277
|
+
index other than `2`. Both renderers use this shared path and their normal history
|
|
278
|
+
commit mechanism. Context-only actions require pointer acceptance or arrow-key
|
|
279
|
+
selection before Enter can apply them.
|
|
280
|
+
|
|
281
|
+
### Empty-slot deletion and script fractions
|
|
282
|
+
|
|
283
|
+
`unwrapEmptySlot` removes a non-grid wrapper from inside a truly empty slot.
|
|
284
|
+
Both Delete and Backspace call it before boundary-specific deletion. The other
|
|
285
|
+
slots are retained; an empty root index collapses to a square root, and an empty
|
|
286
|
+
paired script preserves the other script. A populated row or ordinary structural
|
|
287
|
+
boundary is not an empty slot. Grid cells keep their shape and their existing
|
|
288
|
+
explicit deletion controls. The edit uses the normal history commit.
|
|
289
|
+
|
|
290
|
+
Fractional script presentation uses compact row heights and term metrics in both
|
|
291
|
+
renderers. See [Rendering checks](RENDERING-TESTS.md) for the bounded geometry
|
|
292
|
+
comparison and remaining layout work.
|
|
293
|
+
|
|
294
|
+
### Query-independent context footer
|
|
295
|
+
|
|
296
|
+
`rootEditingContext(state)` derives the nearest radical, conversion availability
|
|
297
|
+
and index caret from the model. React and DOM render the same actions below the
|
|
298
|
+
surface. The footer does not use suggestion text, dismissal or candidate indices.
|
|
299
|
+
Transformations use `transformRoot` and normal history; Edit index only moves
|
|
300
|
+
and selects the caret. Model/matrix selections and blur hide context actions.
|
|
301
|
+
F6 and Escape are handled within the editor to retain host/iframe focus. Native
|
|
302
|
+
composition disables footer actions without replacing the composing input.
|
|
303
|
+
|
|
304
|
+
### Shared fence transformations
|
|
305
|
+
|
|
306
|
+
`structureEditingContext` selects the nearest supported radical or fence and
|
|
307
|
+
excludes literal text. `findStateSuggestions` adds fence transformations before
|
|
308
|
+
operand-wrapping actions, while retaining explicit symbol/command matches first.
|
|
309
|
+
`transformFenceId` distinguishes metadata changes from new structure insertion.
|
|
310
|
+
Acceptance validates the current target before preserving content, IDs and caret.
|
|
311
|
+
|
|
312
|
+
React and native DOM handle Alt+Down before modifier-key fallthrough. The shortcut
|
|
313
|
+
reopens a dismissed list and arms the first context action. Normal contextual
|
|
314
|
+
menus still require navigation before Enter overrides host commit behavior.
|
|
315
|
+
The footer is optional; suggestions do not depend on its visibility.
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
## Contextual operator layout
|
|
319
|
+
|
|
320
|
+
`src/math-layout.ts` derives display, text, script and scriptscript contexts from
|
|
321
|
+
model slots on each render. It does not mutate or persist presentation metadata.
|
|
322
|
+
Fractions reduce the style of their terms; scripts reduce their labels; indexed
|
|
323
|
+
root indices use scriptscript style. Explicit fraction styles reset that context. Aligned cells enter display style; matrix and cases cells enter text style.
|
|
324
|
+
|
|
325
|
+
Both React and native DOM consume the same row/operator map. Operator attributes
|
|
326
|
+
select the large or small font and side or stacked limits. Explicit limits remain
|
|
327
|
+
authoritative. Scoped row attributes keep a nested operator body at its own size
|
|
328
|
+
while reducing its bounds. This replaces the inline-only CSS decision, which
|
|
329
|
+
could not identify operators inside fractions or nested scripts.
|
|
330
|
+
|
|
331
|
+
The current CSS application is scoped to operators. Other structures still use
|
|
332
|
+
their existing layout rules; this is not a complete TeX layout engine.
|
|
333
|
+
|
|
334
|
+
### Horizontal text spacing
|
|
335
|
+
|
|
336
|
+
`math-spacing.ts` computes spacing between lexical runs without changing the
|
|
337
|
+
saved document, token boundaries or caret offsets. Both renderers use the same
|
|
338
|
+
values. Common binary operators use 4 mu, relations use 5 mu and punctuation
|
|
339
|
+
uses 3 mu before the next atom (18 mu = 1 em). Neighboring atoms distinguish
|
|
340
|
+
unary signs from binary operators. Binary, relation and punctuation gaps are
|
|
341
|
+
suppressed in script and scriptscript rows.
|
|
342
|
+
|
|
343
|
+
Measuring spans use glyph width instead of adding padding to every math token.
|
|
344
|
+
Literal text fields retain their text layout. Named-function fields use unpadded glyph measurement. Inactive model
|
|
345
|
+
boundaries use 1 px; empty expression slots and the active boundary keep their
|
|
346
|
+
existing input hit areas. Other structure interiors and full TeX atom classification are separate work. These rules do not provide a complete
|
|
347
|
+
TeX horizontal layout engine.
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
### Named functions and fraction boundaries
|
|
351
|
+
|
|
352
|
+
Named functions and fractions participate in the same horizontal-spacing pass as
|
|
353
|
+
text runs. A named function uses a thin gap next to an ordinary atom or another
|
|
354
|
+
named function, and no gap before a plain opening parenthesis. These thin gaps
|
|
355
|
+
remain in script styles at the corresponding reduced font size. Binary and
|
|
356
|
+
relation gaps still disappear in scripts. Fractions contribute an ordinary atom
|
|
357
|
+
and receive their external gap once, rather than adding fixed margins on both
|
|
358
|
+
sides. The function name's measuring span adds no glyph padding.
|
|
359
|
+
|
|
360
|
+
The spacing map contains structure IDs for these two families and token-offset
|
|
361
|
+
keys for text. Other structure families keep their existing outer layout. This
|
|
362
|
+
change does not alter LaTeX output, JSON, selection offsets or editing commands.
|
package/JSON-MODEL.md
CHANGED
|
@@ -244,6 +244,7 @@ This has two top-level lines and exports as `gathered`. A two-row matrix inside
|
|
|
244
244
|
| `MathCaret` | Text node `id`, UTF-16 `start`/`end`, optional affinity | No |
|
|
245
245
|
| `MathState` | `{ document, caret }` while editing | No; save its `document` |
|
|
246
246
|
| `MathRange` | Structural selection endpoints | No |
|
|
247
|
+
| `MathMatrixRange` | `{ matrixId, anchor, focus }` with row-major cell indices; transient rectangular selection | No |
|
|
247
248
|
| `MathHistory` | Past/present/future editing states | No |
|
|
248
249
|
| `MathFragment` | Clipboard `{ version: 1, rows: MathRow[] }` | No; different envelope from a document |
|
|
249
250
|
| Host `tex` / `mathDocument` attributes | Product-specific storage container | No; the host may store serialized document JSON alongside derived LaTeX |
|
package/LATEX-GUIDE.md
CHANGED
|
@@ -43,6 +43,7 @@ Typing LaTeX into an ordinary editor slot is not the same as importing it. Use t
|
|
|
43
43
|
|
|
44
44
|
## Type with suggestions
|
|
45
45
|
|
|
46
|
+
- In the 0.4.0 release, enter a matrix size as `rows x columns` without spaces. `2x1` creates two rows and one column, `1x2` creates one row and two columns, and `3x7` creates three rows and seven columns. Each dimension must be an integer from 1 to 20, without leading zeros. Uppercase `X` and `×` also work. Suggestions offer an empty matrix and a zero matrix; square sizes additionally offer an identity matrix. Enter accepts the highlighted candidate and focuses its first cell; Tab moves through cells in row order. Space or Escape keeps the original text. These are editor shortcuts, not LaTeX commands; accepted matrices export as the usual `bmatrix` environment.
|
|
46
47
|
- Type `nthroot`, `nroot` or `n제곱근` and choose Indexed root. Enter the index, press Tab, then enter the radicand. A selected expression can be wrapped; it becomes the radicand and the index receives focus.
|
|
47
48
|
- Type `text` or `텍스트`, choose Text and write the description. Tab returns to math input. Mathematical suggestions are disabled inside literal text.
|
|
48
49
|
- Type a function name such as `sin`, `cos`, `log` or `ln`, then select its suggestion. Accept the suggestion before typing the argument; plain `log` remains variable text until converted.
|
|
@@ -249,6 +250,34 @@ Numbered `equation`, `\tag` and `\label` are not supported: the model cannot pre
|
|
|
249
250
|
|
|
250
251
|
## Keyboard ranges and brace discovery (0.2.1)
|
|
251
252
|
|
|
252
|
-
Shift+Left/Right extends or shrinks the same model range used by dragging. Structures are crossed as balanced units; copied and deleted ranges use existing model normalization. Shift+Up/Down extends to an adjacent top-level document line, using a logical text offset rather than pixel-based column matching;
|
|
253
|
+
Shift+Left/Right extends or shrinks the same model range used by dragging. Structures are crossed as balanced units; copied and deleted ranges use existing model normalization. Shift+Up/Down extends to an adjacent top-level document line, using a logical text offset rather than pixel-based column matching; an active matrix-cell selection instead uses Shift+arrows to move its rectangular focus corner. Copy, cut, wrapping, deletion and Undo use the existing range behavior. IME composition and modifier shortcuts retain their existing handling.
|
|
253
254
|
|
|
254
255
|
Typing `{` offers both paired braces and cases. Paired braces remain the first candidate; choose Cases explicitly to insert its editable grid.
|
|
256
|
+
|
|
257
|
+
## Insert or adjust existing math — workspace
|
|
258
|
+
|
|
259
|
+
Use **Paste as LaTeX** in More tools, or **Alt+Shift+V**, to paste a source fragment at the current caret or selected range. Ctrl/Cmd+Enter inserts it; unsupported input stays in the source field with a diagnostic. Ordinary paste retains its existing literal-text behavior.
|
|
260
|
+
|
|
261
|
+
When the caret is inside a structure, the toolbar can change its bracket pair, fraction/binomial display size, or operator limit placement. These actions preserve contents and support one-step Undo. Recent & favorites keeps frequently used symbols/templates available without searching again. See [editing utilities](API-SESSION.md#editing-utilities--workspace).
|
|
262
|
+
|
|
263
|
+
### Change a radical while editing
|
|
264
|
+
|
|
265
|
+
Inside `\sqrt{x}`, choose **Change to Indexed root** in the suggestions. The
|
|
266
|
+
result is `\sqrt[2]{x}` with `2` selected for replacement. The content under the
|
|
267
|
+
radical is preserved. An indexed root with an empty index or `2` offers **Change
|
|
268
|
+
to Square root**. Other indices must be edited before that conversion is offered.
|
|
269
|
+
This editing operation does not change the LaTeX grammar or JSON model schema.
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
## Literal caret/tilde and complex root indices
|
|
273
|
+
|
|
274
|
+
A literal `^` or `~` in a model text run exports as `\char"005E{}` or
|
|
275
|
+
`\char"007E{}`. These spellings render in KaTeX math mode and load back into the
|
|
276
|
+
same text run. The importer also accepts `\textasciicircum{}` and
|
|
277
|
+
`\textasciitilde{}` as input aliases. Inside `\text{...}`, text-mode escaping
|
|
278
|
+
remains unchanged. General TeX `\char` codes are not supported.
|
|
279
|
+
|
|
280
|
+
An index containing braces or brackets is grouped when exported. For example,
|
|
281
|
+
`\sqrt[{x^2}]{y}` and `\sqrt[{\left[a\right]}]{y}` keep the optional index
|
|
282
|
+
argument intact. Grouping does not add a JSON node or remove editable structure.
|
|
283
|
+
Simple indices continue to export as `\sqrt[3]{x}`.
|
package/LATEX-MODEL.md
CHANGED
|
@@ -288,3 +288,15 @@ Type `xrightarrow`, `xleftarrow`, or search for “labeled arrow” / “설명
|
|
|
288
288
|
`\begin{equation*} ... \end{equation*}` imports its body into the existing root math row. It creates no new node kind and adds no suggestion item. Export emits the body without the environment wrapper. Nested supported structures remain editable. Missing/mismatched endings and unsupported commands fail atomically.
|
|
289
289
|
|
|
290
290
|
Numbered `equation`, `\tag` and `\label` are not supported: the model cannot preserve numbering or references. Use `equation*` only when formula-only import is intended. `align`, `split` and `array` remain open.
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
### Protected root indices and literal characters
|
|
294
|
+
|
|
295
|
+
| Model content | Canonical LaTeX | Import result |
|
|
296
|
+
| --- | --- | --- |
|
|
297
|
+
| Text run containing `^` | `\char"005E{}` | Same text run, not a superscript |
|
|
298
|
+
| Text run containing `~` | `\char"007E{}` | Same text run, not an accent |
|
|
299
|
+
| `indexedRoot` with a structured index | `\sqrt[{…}]{…}` | Same index and radicand slots; protective braces add no model node |
|
|
300
|
+
|
|
301
|
+
Literal text groups keep their existing text-mode escapes. Only the two character
|
|
302
|
+
codes above are supported; this does not implement arbitrary TeX character codes.
|
package/LATEX-SCOPE.md
CHANGED
|
@@ -19,7 +19,7 @@ The first product target is Note: open an existing supported LaTeX formula in a
|
|
|
19
19
|
| Import for editing | `parseLatex` and the editor model | Parser succeeds and every resulting node remains editable |
|
|
20
20
|
| Export LaTeX | `toLatex` | Supported model produces valid presentation output |
|
|
21
21
|
|
|
22
|
-
KaTeX display support does **not** imply editable import support. For example,
|
|
22
|
+
KaTeX display support does **not** imply editable import support. For example, a host can configure KaTeX macros that the editor does not import. Unsupported notation must fail without a partial conversion.
|
|
23
23
|
|
|
24
24
|
## V1 grammar
|
|
25
25
|
|
|
@@ -69,7 +69,7 @@ Empty editable slots are valid import data, even if a host requires a nonempty f
|
|
|
69
69
|
| `\newcommand`, `\def`, packages, labels, references, document preambles | No macro expansion or document-level TeX processing |
|
|
70
70
|
| `\input`, URLs, HTML or trust-enabled renderer commands | Never execute or resolve resources |
|
|
71
71
|
|
|
72
|
-
New syntax enters this table only with a model mapping, export policy, positive/negative fixtures and editor tests. Additional delimiters and overset/underset annotations are implemented in the workspace.
|
|
72
|
+
New syntax enters this table only with a model mapping, export policy, positive/negative fixtures and editor tests. Additional delimiters and overset/underset annotations are implemented in the workspace. The additional accents and under/over braces documented below are implemented; explicit delimiter sizes remain a future candidate. See the [editing guide and expansion priorities](LATEX-GUIDE.md); these are not implemented support.
|
|
73
73
|
|
|
74
74
|
## API and failure behavior
|
|
75
75
|
|
|
@@ -214,7 +214,7 @@ Each is a structure with a unique `id` and exactly one MathRow in `slots: [body]
|
|
|
214
214
|
|
|
215
215
|
All limit-family, sum/product and integral nodes accept a single `\limits` or `\nolimits` immediately after the command, before scripts. The optional `limits` field is now boolean: omitted means default, `true` is stacked placement, `false` is side placement. Both explicit values survive JSON validation, copying and LaTeX export. Repeated/conflicting directives are rejected. Existing `limits: true` remains valid; older package builds do not accept `false` or the new limit kinds.
|
|
216
216
|
|
|
217
|
-
Placement is
|
|
217
|
+
Placement is selected through imported LaTeX/model metadata; the workspace now also provides contextual toolbar controls. Imported side conditions remain editable; normal limit suggestions use default placement. This is 0.2.0 functionality.
|
|
218
218
|
|
|
219
219
|
## Fine mathematical spacing (workspace)
|
|
220
220
|
|
|
@@ -261,3 +261,12 @@ Type `xrightarrow`, `xleftarrow`, or search for “labeled arrow” / “설명
|
|
|
261
261
|
`\begin{equation*} ... \end{equation*}` imports its body into the existing root math row. It creates no new node kind and adds no suggestion item. Export emits the body without the environment wrapper. Nested supported structures remain editable. Missing/mismatched endings and unsupported commands fail atomically.
|
|
262
262
|
|
|
263
263
|
Numbered `equation`, `\tag` and `\label` are not supported: the model cannot preserve numbering or references. Use `equation*` only when formula-only import is intended. `align`, `split` and `array` remain open.
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
## Compatibility corrections — 2026-09-10
|
|
267
|
+
|
|
268
|
+
Math-mode caret and tilde text runs export with bounded `\char"005E{}` and
|
|
269
|
+
`\char"007E{}` commands. Text-mode aliases remain accepted and literal text-group
|
|
270
|
+
escaping is unchanged. Arbitrary character codes remain unsupported.
|
|
271
|
+
Complex root indices export inside a protective group, preserving their existing
|
|
272
|
+
JSON slots. See [the LaTeX guide](LATEX-GUIDE.md#literal-carettilde-and-complex-root-indices).
|
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) 2026 barocss.com
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -19,5 +19,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
19
19
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
20
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
21
|
THE SOFTWARE.
|
|
22
|
-
|
|
23
|
-
|