@barocss/math-editor 0.4.0 → 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/API-SESSION.md +10 -0
- package/API-WEB-COMPONENT.md +2 -0
- package/CHANGELOG.md +61 -0
- package/EDITING-SCENARIOS.md +174 -0
- package/IMPLEMENTATION.md +95 -0
- package/LATEX-GUIDE.md +22 -0
- package/LATEX-MODEL.md +12 -0
- package/LATEX-SCOPE.md +10 -1
- package/README.md +73 -19
- package/RELEASING.md +81 -10
- package/RENDERING-TESTS.md +79 -0
- package/ROADMAP.md +132 -5
- package/VALIDATION.md +331 -0
- package/dist/context-tools.d.ts +21 -0
- package/dist/context-tools.js +37 -0
- package/dist/dom/context-keyboard.d.ts +2 -0
- package/dist/dom/context-keyboard.js +22 -0
- package/dist/dom/menu-position.d.ts +3 -0
- package/dist/dom/menu-position.js +45 -1
- package/dist/dom.d.ts +2 -0
- package/dist/dom.js +187 -38
- package/dist/latex.js +11 -0
- package/dist/locales/en.js +13 -1
- package/dist/locales/en.json +13 -1
- package/dist/locales/ko.js +13 -1
- package/dist/locales/ko.json +13 -1
- package/dist/math-editor.d.ts +3 -1
- package/dist/math-editor.js +394 -280
- 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/model.d.ts +4 -0
- package/dist/model.js +49 -4
- package/dist/root-transform.d.ts +19 -0
- package/dist/root-transform.js +69 -0
- package/dist/suggestions.d.ts +9 -0
- package/dist/suggestions.js +53 -0
- package/dist/web-component.js +9 -1
- 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 +695 -44
package/API-SESSION.md
CHANGED
|
@@ -323,3 +323,13 @@ Choose the change appropriate to the target:
|
|
|
323
323
|
`default` removes the explicit metadata. `setMathPresentation(state, id, change)` is the pure equivalent. Unsupported changes or stale IDs return the original state; the session command returns false. This is presentation editing of existing syntax, not algebraic conversion or general TeX styling.
|
|
324
324
|
|
|
325
325
|
Toolbars expose `closePanels()` to dismiss their nonmodal utilities without editing the formula. `onOpenPanel` and `onPasteLatex` are optional mounting callbacks for a host that coordinates its own utility panels. Built-in surfaces keep only one utility/discovery panel open at a time.
|
|
326
|
+
|
|
327
|
+
### Keyboard access to transformations
|
|
328
|
+
|
|
329
|
+
In React and native DOM fields, **Alt+Down** opens or reopens suggestions and
|
|
330
|
+
selects the first available contextual transformation. Up/Down browses and Enter
|
|
331
|
+
applies; Escape dismisses. On macOS, Alt is the Option key. Root and bracket
|
|
332
|
+
transformations preserve the existing operand. The shortcut works with
|
|
333
|
+
`toolbar: false` and `contextTools: false`, including inline mode. Normal text
|
|
334
|
+
input continues to use the standard suggestion ordering; a context-only menu
|
|
335
|
+
requires navigation before Enter can apply a change instead of a host commit.
|
package/API-WEB-COMPONENT.md
CHANGED
|
@@ -126,3 +126,5 @@ Persist the `MathDocument` passed to `onChange`; LaTeX is derived output and is
|
|
|
126
126
|
Keep the mount host empty. The editor owns its descendants; framework rendering into the same host can destroy caret and composition state. Use one editing surface per session. Destroy the renderer on teardown; a session supplied by the host remains the host's responsibility.
|
|
127
127
|
|
|
128
128
|
See [session and DOM API](API-SESSION.md) for exact options, commands, events and cleanup, and [renderer differences](ADAPTERS.md#current-renderer-parity) before choosing a native wrapper over the rich React editor.
|
|
129
|
+
|
|
130
|
+
Set `context-tools="false"` to hide the contextual structure footer. Changing this attribute updates the mounted editor. Conversion suggestions remain available.
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,66 @@
|
|
|
1
1
|
# @barocss/math-editor
|
|
2
2
|
|
|
3
|
+
## 0.5.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Show query-independent radical tools below the active editing surface. Include conversion, index editing, disabled explanations, F6/Escape focus navigation, en/ko labels and a contextTools opt-out (context-tools for Web Components). Preserve model history and hide stale context during range selection or blur.
|
|
8
|
+
- Add contextual bracket transformations to suggestions, with Alt+Down discovery and keyboard acceptance in inline fields without toolbar or footer. Preserve contents, caret and history; target the nearest root/fence and reject stale actions. Include optional footer bracket controls and localized keyboard guidance.
|
|
9
|
+
- Add contextual suggestions to convert a square root to an indexed root while preserving the radicand. Select the new index `2` for immediate editing. Allow conversion back to a square root only for an empty index or `2`. Include English/Korean labels and shared behavior in React and native DOM integrations.
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Resolve operator presentation from mathematical slot context in React and native
|
|
14
|
+
DOM editors. Use text/script-size glyphs and side limits inside fractions and
|
|
15
|
+
scripts, preserve explicit limit placement, and apply smaller nested bounds.
|
|
16
|
+
Add context-resolution unit tests and KaTeX glyph-width/font/position checks.
|
|
17
|
+
- Align named-function and fraction boundaries with mathematical spacing in React
|
|
18
|
+
and native DOM. Remove repeated function glyph padding and fixed fraction outer
|
|
19
|
+
margins. Preserve thin function spacing in script styles and omit it before plain
|
|
20
|
+
opening parentheses.
|
|
21
|
+
- Use bundled KaTeX math faces for variables, upright symbols and display operators. Remove artificial integral skew, scale delimiter widths, and preserve curved over/underbrace ends with licensed KaTeX SVG slices. Refine radical sizing, root-index placement, matrix columns and integral limit spacing in both editable and passive views.
|
|
22
|
+
|
|
23
|
+
Extend the source-only geometry audit with opt-in horizontal-position checks, font asset fingerprints, explicit font loading and multiple-integral/long-brace cases. Retain the KaTeX MIT attribution for bundled assets.
|
|
24
|
+
|
|
25
|
+
- Use shared mathematical spacing for text runs in React and native DOM. Distinguish
|
|
26
|
+
unary signs from binary operators, space relations and punctuation, and suppress
|
|
27
|
+
these gaps inside scripts. Remove excess glyph padding and reduce inactive caret
|
|
28
|
+
boundary width while preserving empty input targets.
|
|
29
|
+
- Use small operator glyphs and side limits in inline mode. Reduce nested script
|
|
30
|
+
size, adjust radicals inside superscripts, and preserve curved end caps on very
|
|
31
|
+
tall parentheses. Extend source-only KaTeX comparisons to large fences, deep
|
|
32
|
+
nesting, and actual inline mode.
|
|
33
|
+
- Fix KaTeX-compatible export and import for literal caret and tilde characters in
|
|
34
|
+
math text runs. Protect complex root-index arguments without changing JSON
|
|
35
|
+
structure. Add clearance between nested radical rules and extend rendering
|
|
36
|
+
regression checks.
|
|
37
|
+
- Use KaTeX-derived SVG contours for radicals and short/tall parentheses. Keep
|
|
38
|
+
existing editing boxes while improving tapered strokes and curved ends. Include
|
|
39
|
+
the outline assets and attribution in the package, and extend visual comparison
|
|
40
|
+
fixtures to simple roots and short parentheses.
|
|
41
|
+
- Correct the size, height and spacing of fraction terms used as scripts. Add editor/KaTeX geometry and screenshot fixtures for fractional powers and subscripts. Allow Delete and Backspace inside empty non-grid slots to remove their wrapper while retaining other content and Undo support.
|
|
42
|
+
- Match ordinary script and root-index font scales more closely to KaTeX in passive and active editing. Add a source-only rendering audit with per-formula measurements, screenshots and a tracked difference ledger.
|
|
43
|
+
- Keep formula selections intact when Up/Down navigates a visible wrapping suggestion menu. Enter applies the highlighted wrapper to the selected content. Left/Right still restores the caret, and Shift+arrows extends the selection. Apply the same behavior to React and native DOM fields used by host integrations.
|
|
44
|
+
- Align nested fraction terms, matrix rows, annotations and operator limits more closely with KaTeX. Scale large and contour integral geometry with the configured font size. Preserve explicit display-fraction sizes and positions inside scripts. Use matching input and passive-text metrics to retain edit positions.
|
|
45
|
+
|
|
46
|
+
Expand the source-only geometry audit to 33 formulas, including two font sizes, React and DOM rendering, active typing checks and a local image comparison gallery.
|
|
47
|
+
|
|
48
|
+
## 0.4.1
|
|
49
|
+
|
|
50
|
+
### Patch Changes
|
|
51
|
+
|
|
52
|
+
- Move each host implementation, tests and host-specific styles into its own plugin
|
|
53
|
+
package. Keep only shared data, draft-field UI and messages in the private common
|
|
54
|
+
package. Preserve the public entry points and stored formula format.
|
|
55
|
+
|
|
56
|
+
Declare ProseMirror as Tiptap's public dependency instead of bundling a second
|
|
57
|
+
copy of its host implementation. Keep host SDKs and the math core external, and
|
|
58
|
+
include common helpers and declarations within each published artifact.
|
|
59
|
+
|
|
60
|
+
Resolve workspace imports from source without a prior build. Use publishConfig
|
|
61
|
+
entry-point overrides for the core and all public plugins, and verify staged npm
|
|
62
|
+
artifacts against their generated runtime and declaration paths.
|
|
63
|
+
|
|
3
64
|
## 0.4.0
|
|
4
65
|
|
|
5
66
|
### Minor Changes
|
|
@@ -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/IMPLEMENTATION.md
CHANGED
|
@@ -265,3 +265,98 @@ operations needs a new model version or parser command.
|
|
|
265
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
266
|
|
|
267
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/LATEX-GUIDE.md
CHANGED
|
@@ -259,3 +259,25 @@ Typing `{` offers both paired braces and cases. Paired braces remain the first c
|
|
|
259
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
260
|
|
|
261
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
|
|
|
@@ -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/README.md
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
# @barocss/math-editor
|
|
2
2
|
|
|
3
|
+
See [Editing scenarios](EDITING-SCENARIOS.md) for stable scenario IDs, acceptance criteria, coverage gaps and per-run reporting.
|
|
4
|
+
|
|
5
|
+
|
|
3
6
|
An embeddable math editor for writing LaTeX-compatible formulas. Edit expressions in place, select existing math, and wrap it in fractions, roots, powers or delimiters. The package includes a framework-independent model, a rich React editor, and a native DOM editor with framework adapters.
|
|
4
7
|
|
|
5
|
-
|
|
8
|
+
This editor does not calculate, solve equations or parse arbitrary LaTeX.
|
|
9
|
+
|
|
10
|
+
## Packaging changes in 0.4.1
|
|
11
|
+
|
|
12
|
+
Each host plugin owns its source and version. Workspace apps import source without
|
|
13
|
+
a prerequisite build; npm consumers receive generated runtime and declarations.
|
|
14
|
+
The private common module is included in each plugin and is not installed separately.
|
|
6
15
|
|
|
7
16
|
## Editing additions in 0.4.0
|
|
8
17
|
|
|
@@ -14,19 +23,19 @@ Choose the core package for a standalone math field. Choose one additional host
|
|
|
14
23
|
|
|
15
24
|
| Package | Purpose | Formula placement | Release status |
|
|
16
25
|
| --- | --- | --- | --- |
|
|
17
|
-
| `@barocss/math-editor` | Math model, LaTeX import/export, editor, toolbar and framework adapters | Standalone, inline or multiline |
|
|
18
|
-
| `@barocss/math-editor-tiptap` | Tiptap node extension | Inline and block |
|
|
19
|
-
| `@barocss/math-editor-prosemirror` | ProseMirror schema, commands and node views | Inline and block |
|
|
20
|
-
| `@barocss/math-editor-lexical` | Lexical math node and registration | Inline and block |
|
|
21
|
-
| `@barocss/math-editor-editorjs` | Editor.js math Tool | Block |
|
|
22
|
-
| `@barocss/math-editor-tinymce` | TinyMCE plugin with in-place or panel editing | Inline and block |
|
|
23
|
-
| `@barocss/math-editor-ckeditor` | CKEditor 5 model objects and widgets | Inline and block |
|
|
24
|
-
| `@barocss/math-editor-quill` | Quill math embeds and registration | Inline and block |
|
|
25
|
-
| `@barocss/math-editor-slate` | Slate void elements and React rendering | Inline and block |
|
|
26
|
-
| `@barocss/math-editor-gutenberg` | WordPress Gutenberg math block | Block |
|
|
27
|
-
| `@barocss/math-editor-integrations` |
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
| `@barocss/math-editor` | Math model, LaTeX import/export, editor, toolbar and framework adapters | Standalone, inline or multiline | MIT |
|
|
27
|
+
| `@barocss/math-editor-tiptap` | Tiptap node extension | Inline and block | MIT |
|
|
28
|
+
| `@barocss/math-editor-prosemirror` | ProseMirror schema, commands and node views | Inline and block | MIT |
|
|
29
|
+
| `@barocss/math-editor-lexical` | Lexical math node and registration | Inline and block | MIT |
|
|
30
|
+
| `@barocss/math-editor-editorjs` | Editor.js math Tool | Block | MIT |
|
|
31
|
+
| `@barocss/math-editor-tinymce` | TinyMCE plugin with in-place or panel editing | Inline and block | MIT |
|
|
32
|
+
| `@barocss/math-editor-ckeditor` | CKEditor 5 model objects and widgets | Inline and block | MIT |
|
|
33
|
+
| `@barocss/math-editor-quill` | Quill math embeds and registration | Inline and block | MIT |
|
|
34
|
+
| `@barocss/math-editor-slate` | Slate void elements and React rendering | Inline and block | MIT |
|
|
35
|
+
| `@barocss/math-editor-gutenberg` | WordPress Gutenberg math block | Block | MIT |
|
|
36
|
+
| `@barocss/math-editor-integrations` | Common data, draft UI, messages and styles; each host owns its plugin source | Internal development | Private; not an install target |
|
|
37
|
+
|
|
38
|
+
Install the core with each host plugin; the package manifests declare compatible peer versions. The core and all nine host packages use the MIT license, with copyright attributed to barocss.com. Each package includes its own LICENSE file. Host SDKs retain their own licenses.
|
|
30
39
|
|
|
31
40
|
Each host package exports its adapter, `/shared` helpers and `/style.css`. Load the core stylesheet as well. Gutenberg also exports `/data` for its stored-data codec. Install only the host package you use; there is no public all-host bundle. Formula placement, keyboard entry, history and clipboard behavior depend on the host.
|
|
32
41
|
|
|
@@ -58,10 +67,10 @@ For editor-only, external toolbar, LaTeX, preview, inline and popup compositions
|
|
|
58
67
|
|
|
59
68
|
## Quick start
|
|
60
69
|
|
|
61
|
-
Install version 0.4.
|
|
70
|
+
Install version 0.4.1 from npm:
|
|
62
71
|
|
|
63
72
|
```sh
|
|
64
|
-
npm install @barocss/math-editor@0.4.
|
|
73
|
+
npm install @barocss/math-editor@0.4.1
|
|
65
74
|
# For the rich React UI:
|
|
66
75
|
npm install react react-dom
|
|
67
76
|
```
|
|
@@ -72,7 +81,6 @@ To develop the package and demo from this monorepo:
|
|
|
72
81
|
|
|
73
82
|
```sh
|
|
74
83
|
pnpm install
|
|
75
|
-
pnpm --filter @barocss/math-editor build
|
|
76
84
|
pnpm --filter @barocss/math-demo dev
|
|
77
85
|
# http://localhost:5184
|
|
78
86
|
```
|
|
@@ -165,7 +173,7 @@ Native passive text preserves these lexical colors; its whole active run still u
|
|
|
165
173
|
| Model selection | Backspace / Delete | Delete selection |
|
|
166
174
|
| Editor | Cmd/Ctrl+Z / Cmd/Ctrl+Shift+Z | Undo / redo |
|
|
167
175
|
|
|
168
|
-
Vertical arrows use the nearest inner structure before an enclosing grid, then fall back to another equation line. Paired scripts can move along their shared column; a base moves up to its superscript and down to its subscript.
|
|
176
|
+
Vertical arrows use the nearest inner structure before an enclosing grid, then fall back to another equation line. Paired scripts can move along their shared column; a base moves up to its superscript and down to its subscript. Visible suggestions retain Up/Down priority, including after Shift+arrow or drag selection. Enter applies the highlighted wrapper to the selected content; Left/Right restores the caret, and Shift+arrows adjusts the range. Composition, literal text and noncollapsed text selections do not trigger structural movement. React and native surfaces share this behavior.
|
|
169
177
|
|
|
170
178
|
The framework-free `moveVertical(state, direction, geometry?)` helper is exported from `/core`. Without rendered geometry, it selects the first text run in the target slot and clamps the current offset. At a lexical token boundary, rendered geometry distinguishes the previous token's end from the next token's start. Each move uses the current caret's horizontal position; a preferred column is not retained across repeated moves through shorter rows. Shift+arrow selection remains a separate operation.
|
|
171
179
|
|
|
@@ -206,7 +214,7 @@ pnpm --filter @barocss/math-demo build
|
|
|
206
214
|
pnpm --filter @barocss/math-demo test:e2e
|
|
207
215
|
```
|
|
208
216
|
|
|
209
|
-
The demo consumes
|
|
217
|
+
The demo consumes workspace source exports and does not require a package build. Release checks use `publishConfig.exports` and inspect the packed JavaScript and declarations. Browser tests use Playwright Chromium and start port 5184 if needed. Actual OS Korean IME tests remain deferred at the user's request.
|
|
210
218
|
|
|
211
219
|
- [Symbol / English / Korean name table](https://math-editor.barocss.com/docs/symbols.html)
|
|
212
220
|
- [LaTeX editing guide and upcoming notation](https://math-editor.barocss.com/docs/latex-guide.html)
|
|
@@ -350,3 +358,49 @@ MIT License. Copyright (c) 2026 barocss.com.
|
|
|
350
358
|
|
|
351
359
|
The npm package includes the full license in `LICENSE`. Bundled KaTeX fonts retain
|
|
352
360
|
their separate copyright and MIT notice in `src/fonts/LICENSE-KaTeX.txt`.
|
|
361
|
+
|
|
362
|
+
### Change an existing radical
|
|
363
|
+
|
|
364
|
+
Place the caret inside a square root and choose **Change to Indexed root** in
|
|
365
|
+
the suggestions. The radicand, including nested structures, stays intact. The
|
|
366
|
+
new index is `2` and is selected so you can immediately type `3`, `n`, or another
|
|
367
|
+
index. The explicit choice creates one Undo step.
|
|
368
|
+
|
|
369
|
+
**Change to Square root** is available inside an indexed root with an empty
|
|
370
|
+
index or index `2`. Other indices must be edited first; conversion does not
|
|
371
|
+
discard them. The nearest enclosing radical is the target. Conversion choices
|
|
372
|
+
do not consume the text used to search, and an unselected conversion does not
|
|
373
|
+
intercept Enter. Both React and native DOM integrations support this behavior.
|
|
374
|
+
|
|
375
|
+
Empty non-grid slots support Delete and Backspace directly. Removing the wrapper
|
|
376
|
+
keeps other slot content and can be undone. See [Rendering checks](RENDERING-TESTS.md)
|
|
377
|
+
for editor/KaTeX comparison fixtures and the current visual verification scope.
|
|
378
|
+
|
|
379
|
+
### Contextual structure tools
|
|
380
|
+
|
|
381
|
+
While the caret is inside a radical, the optional editor footer shows its current type,
|
|
382
|
+
conversion action and, for indexed roots, **Edit index**. No search text is needed.
|
|
383
|
+
Dismissing suggestions leaves the footer available. An unavailable conversion
|
|
384
|
+
stays disabled with an explanation. F6 moves focus to the tools; Escape returns
|
|
385
|
+
to input. The footer hides outside the radical, on blur, or during model selection.
|
|
386
|
+
|
|
387
|
+
Set `contextTools={false}` on rich React, or `contextTools: false` in native DOM
|
|
388
|
+
options, to hide this footer. Native framework wrappers accept the same option.
|
|
389
|
+
The Web Component uses `context-tools="false"`. This setting does not remove
|
|
390
|
+
conversion suggestions. See [Editing scenarios](EDITING-SCENARIOS.md) EDIT-021
|
|
391
|
+
through EDIT-028 for acceptance criteria and pending coverage.
|
|
392
|
+
|
|
393
|
+
### Change brackets from suggestions
|
|
394
|
+
|
|
395
|
+
Place the caret inside brackets and press **Alt+Down** (Option+Down on macOS).
|
|
396
|
+
The existing suggestion list opens with a transformation selected. Use Up/Down
|
|
397
|
+
and Enter to change the surrounding brackets; Escape closes the list unchanged.
|
|
398
|
+
“Change brackets” preserves the enclosed formula and caret, unlike an action
|
|
399
|
+
that wraps text in a new pair. Available pairs include parentheses, brackets,
|
|
400
|
+
braces, angle brackets, absolute value, norm and both half-open intervals.
|
|
401
|
+
|
|
402
|
+
This works in inline fields with `toolbar: false` and `contextTools: false`.
|
|
403
|
+
Automatic contextual suggestions do not consume Enter until you navigate them.
|
|
404
|
+
The optional footer also offers bracket buttons via F6, Left/Right and Enter.
|
|
405
|
+
Nested roots and fences share a nearest-wrapper target. See EDIT-029 through
|
|
406
|
+
EDIT-032 in [Editing scenarios](EDITING-SCENARIOS.md).
|