@barocss/math-editor 0.4.0 → 0.6.1

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.
Files changed (76) hide show
  1. package/API-SESSION.md +35 -1
  2. package/API-WEB-COMPONENT.md +2 -0
  3. package/CHANGELOG.md +109 -0
  4. package/CLIPBOARD.md +54 -0
  5. package/EDITING-SCENARIOS.md +209 -0
  6. package/GETTING-STARTED.md +54 -0
  7. package/IMPLEMENTATION.md +105 -0
  8. package/KEYBOARD.md +41 -0
  9. package/LATEX-GUIDE.md +52 -2
  10. package/LATEX-MODEL.md +12 -0
  11. package/LATEX-SCOPE.md +10 -1
  12. package/README.md +119 -23
  13. package/RELEASING.md +95 -10
  14. package/RENDERING-TESTS.md +79 -0
  15. package/ROADMAP.md +238 -6
  16. package/STYLING.md +28 -1
  17. package/TEXT-EDITORS.md +157 -0
  18. package/VALIDATION.md +433 -0
  19. package/dist/context-tools.d.ts +21 -0
  20. package/dist/context-tools.js +37 -0
  21. package/dist/dom/caret-geometry.js +1 -1
  22. package/dist/dom/context-keyboard.d.ts +2 -0
  23. package/dist/dom/context-keyboard.js +22 -0
  24. package/dist/dom/help.d.ts +5 -0
  25. package/dist/dom/help.js +104 -0
  26. package/dist/dom/menu-position.d.ts +3 -0
  27. package/dist/dom/menu-position.js +49 -4
  28. package/dist/dom/readable-layout.d.ts +3 -0
  29. package/dist/dom/readable-layout.js +52 -0
  30. package/dist/dom/toolbar-catalog.d.ts +1 -1
  31. package/dist/dom/toolbar.d.ts +2 -0
  32. package/dist/dom/toolbar.js +8 -1
  33. package/dist/dom.d.ts +13 -1
  34. package/dist/dom.js +323 -51
  35. package/dist/enter-policy.js +1 -1
  36. package/dist/latex.js +11 -0
  37. package/dist/lines.d.ts +2 -0
  38. package/dist/lines.js +15 -0
  39. package/dist/locales/en.js +33 -3
  40. package/dist/locales/en.json +33 -3
  41. package/dist/locales/ko.js +33 -3
  42. package/dist/locales/ko.json +33 -3
  43. package/dist/math-editor-toolbar.js +2 -1
  44. package/dist/math-editor.d.ts +4 -1
  45. package/dist/math-editor.js +506 -296
  46. package/dist/math-layout.d.ts +12 -0
  47. package/dist/math-layout.js +59 -0
  48. package/dist/math-spacing.d.ts +13 -0
  49. package/dist/math-spacing.js +87 -0
  50. package/dist/model.d.ts +6 -0
  51. package/dist/model.js +72 -5
  52. package/dist/range.d.ts +10 -2
  53. package/dist/range.js +31 -6
  54. package/dist/root-transform.d.ts +19 -0
  55. package/dist/root-transform.js +69 -0
  56. package/dist/selection-shortcuts.d.ts +13 -0
  57. package/dist/selection-shortcuts.js +35 -0
  58. package/dist/session.d.ts +1 -0
  59. package/dist/session.js +1 -1
  60. package/dist/suggestions.d.ts +9 -0
  61. package/dist/suggestions.js +53 -0
  62. package/dist/symbols.d.ts +1 -1
  63. package/dist/symbols.js +1 -0
  64. package/dist/vertical-navigation.d.ts +5 -0
  65. package/dist/vertical-navigation.js +33 -0
  66. package/dist/web-component.js +9 -1
  67. package/package.json +11 -3
  68. package/src/fonts/KaTeX_Math-Italic.woff2 +0 -0
  69. package/src/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  70. package/src/fonts/README.md +18 -0
  71. package/src/shapes/README.md +21 -0
  72. package/src/shapes/parenthesis-bottom.svg +1 -0
  73. package/src/shapes/parenthesis-top.svg +1 -0
  74. package/src/shapes/parenthesis.svg +1 -0
  75. package/src/shapes/radical.svg +1 -0
  76. package/src/style.css +882 -61
package/KEYBOARD.md ADDED
@@ -0,0 +1,41 @@
1
+ # Keyboard reference
2
+
3
+ Open **Keyboard & clipboard help** from the math toolbar, or press **F1 while the formula has focus**. This also works in a toolbar-free inline field. Some keyboards require Fn+F1. Close help to return to the previously focused input without editing the formula.
4
+
5
+ Use Cmd on macOS and Ctrl on Windows/Linux. Alt is Option on macOS. The host and operating system can reserve keys; the field only handles its shortcuts while it has focus.
6
+
7
+ | Context | Keys | Action |
8
+ | --- | --- | --- |
9
+ | Active input | Left / Right | Move the caret; repeated keydown continues across token and slot boundaries |
10
+ | Active input, no suggestion menu | Up / Down | Move between supported structural slots or lines; repeated vertical movement retains the preferred column |
11
+ | Editable slots | Tab / Shift+Tab | Next / previous slot |
12
+ | Formula selection | Shift+Left / Right | Extend or shrink the selected range |
13
+ | Active formula | Ctrl+Left / Right (Option+Left / Right on macOS) | Move by text units or whole math structures |
14
+ | Active formula | Ctrl+Shift+Left / Right (Option+Shift+Left / Right on macOS) | Extend or shrink selection by text units or structures |
15
+ | Matrix cell | Alt+Shift+Backspace | Delete the current column; Undo restores it |
16
+ | Matrix cell | Alt+Shift+Up | Delete the current row; Undo restores it |
17
+ | Nonempty math selection | `(`, `[`, `{`, `\|` | Wrap in parentheses, brackets, braces or absolute value |
18
+ | Nonempty math selection | `/` | Use the selection as numerator; enter the denominator next |
19
+ | Nonempty math selection | `^` / `_` | Use the selection as base; enter the exponent or subscript next |
20
+ | Active formula | Alt+Down | Open suggestions, including transformations for the nearest supported structure |
21
+ | Suggestions open | Up / Down, Enter | Choose and apply a suggestion |
22
+ | Suggestions open | Escape | Dismiss suggestions before returning to ordinary navigation |
23
+ | Active formula | Ctrl/Cmd+Z / Ctrl/Cmd+Shift+Z | Undo / Redo |
24
+ | Selected range | Ctrl/Cmd+C / X | Copy / Cut |
25
+ | Active formula | Ctrl/Cmd+V | Paste available editor data or literal text |
26
+ | Active formula | Alt+Shift+V | Open Paste as LaTeX |
27
+ | LaTeX paste panel | Ctrl/Cmd+Enter / Escape | Insert / close the panel |
28
+ | Active formula | F1 | Open help |
29
+ | Context footer available | F6 | Move focus between the input and contextual controls |
30
+
31
+ ## Enter depends on context
32
+
33
+ An active suggestion normally receives Enter. Escape dismisses it first if you want a different action. Operand-only suggestions require navigation before Enter applies them, so ordinary Enter does not unexpectedly wrap an operand.
34
+
35
+ In a block field, Enter follows the configured newline/commit policy. Shift+Enter bypasses suggestion acceptance and creates a row in a grid or a line at the outer block level. Inline fields do not create top-level formula lines. Their completion and boundary-exit behavior belongs to the embedding host.
36
+
37
+ ## Delete depends on context
38
+
39
+ Backspace/Delete removes a selection. At a structure boundary it can unwrap retained contents. An empty slot can remove or reduce its enclosing structure. Populated grids require their grid selection/deletion policy so cells are not silently flattened. At the end of a top-level line, Delete joins the following line; Backspace at the next line's start joins backward. Undo restores the change.
40
+
41
+ The direct wrapping keys apply only to a nonempty math selection. Literal text, matrix rectangles and multiline ranges retain their own rules. See [selection editing](LATEX-GUIDE.md#select-replace-and-wrap), [copy and paste](CLIPBOARD.md) and [practice exercises](https://math-editor.barocss.com/#tutorial).
package/LATEX-GUIDE.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  This guide describes **version 0.2.0**, including bounded LaTeX import and editable notation. See [installation and API guides](README.md) for package usage and [the support contract](LATEX-SCOPE.md) for the exact grammar.
4
4
 
5
+ Start with [practice exercises](GETTING-STARTED.md), [copy and paste](CLIPBOARD.md), or the [keyboard reference](KEYBOARD.md).
6
+
5
7
  ## Load and edit a formula
6
8
 
7
9
  In the demo, open **Import LaTeX**, enter a supported expression and apply it. Click a displayed slot to edit it. A successful import is undoable; a failed import preserves the existing formula and returns diagnostics.
@@ -58,7 +60,23 @@ Standard function names: `sin`, `cos`, `tan`, `cot`, `sec`, `csc`, `arcsin`, `ar
58
60
 
59
61
  Drag across a formula to select a model range. The regular suggestion list offers fraction, root, superscript, subscript, parentheses, brackets and absolute value. Click a candidate, or use arrow keys and Enter. Compound bases receive parentheses when wrapped in an exponent.
60
62
 
61
- Typing a printable character replaces the selected range and resumes editing. Backspace/Delete removes the selection. Undo restores content. Wrapping multiple top-level lines is disabled. In combined scripts, Backspace in an empty script removes that side while retaining the other script.
63
+ With a nonempty math selection, these keys apply immediately without choosing a suggestion:
64
+
65
+ | Key | Result | Caret after wrapping |
66
+ | --- | --- | --- |
67
+ | `(` | Parentheses | After the closing parenthesis |
68
+ | `[` | Square brackets | After the closing bracket |
69
+ | `{` | Braces | After the closing brace |
70
+ | `\|` | Absolute value | After the closing bar |
71
+ | `/` | Fraction with selection as numerator | Empty denominator |
72
+ | `^` | Selection as the base of a power | Empty exponent |
73
+ | `_` | Selection as the subscript base | Empty subscript |
74
+
75
+ Compound power bases receive parentheses. Each wrap is one Undo step; subsequent typing is a separate edit. This works with mouse dragging, Shift+arrows and native input selections in React and DOM fields, including toolbar-free inline fields. The key handling is shared by the framework and host adapters through their renderer.
76
+
77
+ Other printable characters replace the selection. Without a selection, the existing suggestion behavior stays unchanged; `{` can still offer braces and cases. Literal text slots retain text input. Ctrl/Cmd/Alt combinations and IME composition are not structural shortcuts. Multi-line selections remain selected and unchanged when a wrapping key is pressed. Rectangular matrix-cell selection retains its own typing behavior.
78
+
79
+ Backspace/Delete removes the selection. Undo restores content. In combined scripts, Backspace in an empty script removes that side while retaining the other script.
62
80
 
63
81
  ## Text boundaries
64
82
 
@@ -68,7 +86,7 @@ The editor retains structure and canonical notation, not the exact original sour
68
86
 
69
87
  ## What should be added next?
70
88
 
71
- See the [prioritized LaTeX backlog](ROADMAP.md#remaining-latex-priorities-workspace-review-2026-09-08). Norm fences and additional integrals come first, followed by annotated braces and more accents. Fine spacing, styles and equation environments need explicit preservation policies. These are candidates, not current parser support.
89
+ Norms, triple/contour integrals, brace annotations and additional accents are already supported. See the [current roadmap](ROADMAP.md#subsequent-milestones) for remaining work. New notation must keep the model, parser, keyboard editing and rendering aligned.
72
90
 
73
91
  Each addition needs a documented JSON shape, import/export round trips, unsupported-input diagnostics, actual per-character typing, cursor movement, selection, deletion and Undo tests in both renderers. See [roadmap](ROADMAP.md) for progress and [validation](VALIDATION.md) for tested coverage.
74
92
 
@@ -259,3 +277,35 @@ Typing `{` offers both paired braces and cases. Paired braces remain the first c
259
277
  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
278
 
261
279
  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).
280
+
281
+ ### Change a radical while editing
282
+
283
+ Inside `\sqrt{x}`, choose **Change to Indexed root** in the suggestions. The
284
+ result is `\sqrt[2]{x}` with `2` selected for replacement. The content under the
285
+ radical is preserved. An indexed root with an empty index or `2` offers **Change
286
+ to Square root**. Other indices must be edited before that conversion is offered.
287
+ This editing operation does not change the LaTeX grammar or JSON model schema.
288
+
289
+
290
+ ## Literal caret/tilde and complex root indices
291
+
292
+ A literal `^` or `~` in a model text run exports as `\char"005E{}` or
293
+ `\char"007E{}`. These spellings render in KaTeX math mode and load back into the
294
+ same text run. The importer also accepts `\textasciicircum{}` and
295
+ `\textasciitilde{}` as input aliases. Inside `\text{...}`, text-mode escaping
296
+ remains unchanged. General TeX `\char` codes are not supported.
297
+
298
+ An index containing braces or brackets is grouped when exported. For example,
299
+ `\sqrt[{x^2}]{y}` and `\sqrt[{\left[a\right]}]{y}` keep the optional index
300
+ argument intact. Grouping does not add a JSON node or remove editable structure.
301
+ Simple indices continue to export as `\sqrt[3]{x}`.
302
+
303
+ ## Boundary deletion and continued editing
304
+
305
+ - At the outside right edge of a non-grid structure, Backspace removes the wrapper and retains its contents. At the outside left edge, Delete does the same and leaves the caret before the retained contents.
306
+ - An empty non-grid slot can remove its wrapper with Backspace or Delete. Removing an empty root index or one empty paired-script slot retains the other structure parts.
307
+ - Populated matrices, aligned equations and cases use a separate boundary selection before a second deletion removes the whole grid. Removing a wrapper never silently flattens a populated grid into text. A cell's ordinary text deletion remains local.
308
+ - Backspace at the start of a top-level line joins the previous line. Delete at the end joins the next line. Undo restores the original structure and lines.
309
+ - Repeated Up/Down movement retains its preferred horizontal position through shorter rows. Horizontal movement, typing and pointer placement reset that preference. Visible suggestions retain ownership of Up/Down; Escape dismisses them.
310
+ - Shift+Enter bypasses suggestions. In a grid it inserts a row; in a block top-level expression it follows the newline policy. Inline mode remains one top-level line.
311
+ - Invalid structured clipboard data leaves the formula unchanged and reports an error. Multiline paste is rejected in inline mode and inside nested math slots. Plain clipboard text remains literal; use the explicit LaTeX paste action for parsing.
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, KaTeX can display annotations such as underbraces that the editor cannot yet import. Unsupported notation must fail without a partial conversion.
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
@@ -2,11 +2,23 @@
2
2
 
3
3
  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
4
 
5
- **Release:** core **0.4.0**, with nine host editor plugins at **0.1.0**. This editor does not calculate, solve equations or parse arbitrary LaTeX.
5
+ This editor does not calculate, solve equations or parse arbitrary LaTeX.
6
6
 
7
- ## Editing additions in 0.4.0
7
+ Selection shortcuts: highlight math and press `(`, `[`, `{`, `|`, `/`, `^` or `_` to wrap it immediately. Fractions focus the denominator; powers and subscripts focus their empty script. See [selection editing](LATEX-GUIDE.md#select-replace-and-wrap) for behavior and exceptions.
8
8
 
9
- The native renderer now edits one lexical token at a time, matching the main React field's role colors. New utilities provide **Paste as LaTeX** (Alt+Shift+V), **Recent & favorites** for symbols/templates, and contextual **bracket, fraction-size and limit-placement settings**. These utilities are included in 0.4.0. See [editing utilities and API](API-SESSION.md#editing-utilities--workspace).
9
+ ## Learn the editor
10
+
11
+ Try the [interactive exercises](https://math-editor.barocss.com/#tutorial), read [copy and paste](https://math-editor.barocss.com/docs/clipboard.html), or open the [keyboard reference](https://math-editor.barocss.com/docs/keyboard.html). F1 opens help while a math field has focus, including toolbar-free inline fields.
12
+
13
+ ## Package ownership
14
+
15
+ Each host plugin owns its source and version. Workspace apps import source without
16
+ a prerequisite build; npm consumers receive generated runtime and declarations.
17
+ The private common module is included in each plugin and is not installed separately.
18
+
19
+ ## Editing utilities
20
+
21
+ The native renderer now edits one lexical token at a time, matching the main React field's role colors. New utilities provide **Paste as LaTeX** (Alt+Shift+V), **Recent & favorites** for symbols/templates, and contextual **bracket, fraction-size and limit-placement settings**. See [editing utilities and API](API-SESSION.md#editing-utilities--workspace).
10
22
 
11
23
  ## Packages
12
24
 
@@ -14,19 +26,19 @@ Choose the core package for a standalone math field. Choose one additional host
14
26
 
15
27
  | Package | Purpose | Formula placement | Release status |
16
28
  | --- | --- | --- | --- |
17
- | `@barocss/math-editor` | Math model, LaTeX import/export, editor, toolbar and framework adapters | Standalone, inline or multiline | 0.4.0; MIT |
18
- | `@barocss/math-editor-tiptap` | Tiptap node extension | Inline and block | 0.1.0; MIT |
19
- | `@barocss/math-editor-prosemirror` | ProseMirror schema, commands and node views | Inline and block | 0.1.0; MIT |
20
- | `@barocss/math-editor-lexical` | Lexical math node and registration | Inline and block | 0.1.0; MIT |
21
- | `@barocss/math-editor-editorjs` | Editor.js math Tool | Block | 0.1.0; MIT |
22
- | `@barocss/math-editor-tinymce` | TinyMCE plugin with in-place or panel editing | Inline and block | 0.1.0; MIT |
23
- | `@barocss/math-editor-ckeditor` | CKEditor 5 model objects and widgets | Inline and block | 0.1.0; MIT |
24
- | `@barocss/math-editor-quill` | Quill math embeds and registration | Inline and block | 0.1.0; MIT |
25
- | `@barocss/math-editor-slate` | Slate void elements and React rendering | Inline and block | 0.1.0; MIT |
26
- | `@barocss/math-editor-gutenberg` | WordPress Gutenberg math block | Block | 0.1.0; MIT |
27
- | `@barocss/math-editor-integrations` | Shared implementation used to build the nine host packages | Internal development | Private; not an install target |
28
-
29
- The host plugins require `@barocss/math-editor@^0.4.0`. 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.
29
+ | `@barocss/math-editor` | Math model, LaTeX import/export, editor, toolbar and framework adapters | Standalone, inline or multiline | MIT |
30
+ | `@barocss/math-editor-tiptap` | Tiptap node extension | Inline and block | MIT |
31
+ | `@barocss/math-editor-prosemirror` | ProseMirror schema, commands and node views | Inline and block | MIT |
32
+ | `@barocss/math-editor-lexical` | Lexical math node and registration | Inline and block | MIT |
33
+ | `@barocss/math-editor-editorjs` | Editor.js math Tool | Block | MIT |
34
+ | `@barocss/math-editor-tinymce` | TinyMCE plugin with in-place or panel editing | Inline and block | MIT |
35
+ | `@barocss/math-editor-ckeditor` | CKEditor 5 model objects and widgets | Inline and block | MIT |
36
+ | `@barocss/math-editor-quill` | Quill math embeds and registration | Inline and block | MIT |
37
+ | `@barocss/math-editor-slate` | Slate void elements and React rendering | Inline and block | MIT |
38
+ | `@barocss/math-editor-gutenberg` | WordPress Gutenberg math block | Block | MIT |
39
+ | `@barocss/math-editor-integrations` | Common data, draft UI, messages and styles; each host owns its plugin source | Internal development | Private; not an install target |
40
+
41
+ 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
42
 
31
43
  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
44
 
@@ -52,16 +64,16 @@ Each guide covers installation, document replacement, saving and lifecycle clean
52
64
 
53
65
  See [framework adapters and inline/custom toolbar integration](https://math-editor.barocss.com/docs/adapters.html), [custom locales](https://math-editor.barocss.com/docs/localization.html), and [progress / roadmap](https://math-editor.barocss.com/docs/roadmap.html). The new native renderer has explicit parity gaps; existing React consumers keep their current UI.
54
66
 
55
- **Included in 0.4.0:** the native toolbar now includes searchable All symbols, templates, matrix presets and active-grid controls. Native ranges show exact partial-text highlights, and a drag can start in the active input and continue across structures. See [renderer parity](https://math-editor.barocss.com/docs/adapters.html#current-renderer-parity) for the remaining limits.
67
+ The native toolbar includes searchable All symbols, templates, matrix presets and active-grid controls. Native ranges show exact partial-text highlights, and a drag can start in the active input and continue across structures. See [renderer parity](https://math-editor.barocss.com/docs/adapters.html#current-renderer-parity) for the remaining limits.
56
68
 
57
69
  For editor-only, external toolbar, LaTeX, preview, inline and popup compositions, see [Embedding](https://math-editor.barocss.com/docs/embedding.html) and the [layout examples](https://math-editor.barocss.com/layouts.html).
58
70
 
59
71
  ## Quick start
60
72
 
61
- Install version 0.4.0 from npm:
73
+ Install the latest published version from npm:
62
74
 
63
75
  ```sh
64
- npm install @barocss/math-editor@0.4.0
76
+ npm install @barocss/math-editor
65
77
  # For the rich React UI:
66
78
  npm install react react-dom
67
79
  ```
@@ -72,7 +84,6 @@ To develop the package and demo from this monorepo:
72
84
 
73
85
  ```sh
74
86
  pnpm install
75
- pnpm --filter @barocss/math-editor build
76
87
  pnpm --filter @barocss/math-demo dev
77
88
  # http://localhost:5184
78
89
  ```
@@ -152,12 +163,14 @@ Native passive text preserves these lexical colors; its whole active run still u
152
163
  | Grid | Shift+Enter | Insert a row |
153
164
  | Matrix | Shift+Space | Insert a column |
154
165
  | Grid | Alt+Shift+Up | Delete the current row |
155
- | Matrix | Alt+Shift+Left | Delete the current column |
166
+ | Matrix | Alt+Shift+Backspace | Delete the current column |
156
167
  | Aligned / cases | Enter | Insert a row, unless applying a suggestion |
157
168
  | Just after a fraction/root/delimiter | Backspace | Unwrap, preserving contents |
158
169
  | Outer grid edge | Backspace / Delete | Delete empty grid; select filled grid first, press again to delete |
159
170
  | Preview surface | Cmd/Ctrl+A | Select the whole math document |
160
171
  | Active input | Cmd/Ctrl+A | Select the current input text: a React token or native logical run |
172
+ | Editor | Ctrl+Left / Right (Mac: Option+Left / Right) | Move to a lexical unit boundary; cross a fraction/root/fence as one structure |
173
+ | Editor | Same modifier + Shift+Left / Right | Extend or shrink selection by lexical units and structures |
161
174
  | Editor | Shift+Left / Right | Extend or shrink the model range across text and balanced structures |
162
175
  | Editor | Shift+Up / Down | Extend the model range across top-level lines using logical offsets |
163
176
  | Preview surface | Enter / F2 | Enter editing |
@@ -165,7 +178,9 @@ Native passive text preserves these lexical colors; its whole active run still u
165
178
  | Model selection | Backspace / Delete | Delete selection |
166
179
  | Editor | Cmd/Ctrl+Z / Cmd/Ctrl+Shift+Z | Undo / redo |
167
180
 
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. Suggestions retain arrow-key priority. Composition, literal text and noncollapsed text selections do not trigger structural movement. React and native surfaces share this behavior.
181
+ Unit movement stays within the current variable or number until its edge, then crosses an adjacent structure intact. From a nested slot edge it exits the enclosing structure. An unshifted unit arrow collapses an existing selection to its ordered edge. It does not change LaTeX or add undo entries. Matrix rectangle selection keeps its existing arrow behavior.
182
+
183
+ 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
184
 
170
185
  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
186
 
@@ -206,7 +221,7 @@ pnpm --filter @barocss/math-demo build
206
221
  pnpm --filter @barocss/math-demo test:e2e
207
222
  ```
208
223
 
209
- The demo consumes package exports from `dist`; rebuild the package before browser tests. Browser tests use Playwright Chromium and start port 5184 if needed. Actual OS Korean IME tests remain deferred at the user's request.
224
+ 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
225
 
211
226
  - [Symbol / English / Korean name table](https://math-editor.barocss.com/docs/symbols.html)
212
227
  - [LaTeX editing guide and upcoming notation](https://math-editor.barocss.com/docs/latex-guide.html)
@@ -344,9 +359,90 @@ These operations are available in both renderers and the framework-free
344
359
 
345
360
  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](https://math-editor.barocss.com/docs/styling.html) for the public variables, dark/monochrome examples, shared toolbars and iframe/plugin sizing.
346
361
 
362
+ Nested fractions and scripts have a `14px` editing minimum. Set
363
+ `--me-min-font-size: 16px` on your editor wrapper for a larger minimum, or `0px`
364
+ for unmodified TeX size ratios. Inline rows grow to contain elevated scripts;
365
+ allow the host line height to grow too. This display setting does not change
366
+ the saved LaTeX. See [STYLING.md](./STYLING.md) for the size policy.
367
+
368
+ For complex fractions, try `--me-font-size: 26px` with
369
+ `--me-min-font-size: 16px`. Keep the preview/export size separate. In the website
370
+ playground, use **Math size → 26px**; visual text-editor popups also offer zoom.
371
+
347
372
  ## License
348
373
 
349
374
  MIT License. Copyright (c) 2026 barocss.com.
350
375
 
351
376
  The npm package includes the full license in `LICENSE`. Bundled KaTeX fonts retain
352
377
  their separate copyright and MIT notice in `src/fonts/LICENSE-KaTeX.txt`.
378
+
379
+ ### Change an existing radical
380
+
381
+ Place the caret inside a square root and choose **Change to Indexed root** in
382
+ the suggestions. The radicand, including nested structures, stays intact. The
383
+ new index is `2` and is selected so you can immediately type `3`, `n`, or another
384
+ index. The explicit choice creates one Undo step.
385
+
386
+ **Change to Square root** is available inside an indexed root with an empty
387
+ index or index `2`. Other indices must be edited first; conversion does not
388
+ discard them. The nearest enclosing radical is the target. Conversion choices
389
+ do not consume the text used to search, and an unselected conversion does not
390
+ intercept Enter. Both React and native DOM integrations support this behavior.
391
+
392
+ Empty non-grid slots support Delete and Backspace directly. Removing the wrapper
393
+ keeps other slot content and can be undone. See [Rendering checks](RENDERING-TESTS.md)
394
+ for editor/KaTeX comparison fixtures and the current visual verification scope.
395
+
396
+ ### Contextual structure tools
397
+
398
+ While the caret is inside a radical, the optional editor footer shows its current type,
399
+ conversion action and, for indexed roots, **Edit index**. No search text is needed.
400
+ Dismissing suggestions leaves the footer available. An unavailable conversion
401
+ stays disabled with an explanation. F6 moves focus to the tools; Escape returns
402
+ to input. The footer hides outside the radical, on blur, or during model selection.
403
+
404
+ Set `contextTools={false}` on rich React, or `contextTools: false` in native DOM
405
+ options, to hide this footer. Native framework wrappers accept the same option.
406
+ The Web Component uses `context-tools="false"`. This setting does not remove
407
+ conversion suggestions. See [Editing scenarios](EDITING-SCENARIOS.md) EDIT-021
408
+ through EDIT-028 for acceptance criteria and pending coverage.
409
+
410
+ ### Change brackets from suggestions
411
+
412
+ Place the caret inside brackets and press **Alt+Down** (Option+Down on macOS).
413
+ The existing suggestion list opens with a transformation selected. Use Up/Down
414
+ and Enter to change the surrounding brackets; Escape closes the list unchanged.
415
+ “Change brackets” preserves the enclosed formula and caret, unlike an action
416
+ that wraps text in a new pair. Available pairs include parentheses, brackets,
417
+ braces, angle brackets, absolute value, norm and both half-open intervals.
418
+
419
+ This works in inline fields with `toolbar: false` and `contextTools: false`.
420
+ Automatic contextual suggestions do not consume Enter until you navigate them.
421
+ The optional footer also offers bracket buttons via F6, Left/Right and Enter.
422
+ Nested roots and fences share a nearest-wrapper target. See EDIT-029 through
423
+ EDIT-032 in [Editing scenarios](EDITING-SCENARIOS.md).
424
+
425
+ ### Prime notation (workspace)
426
+
427
+ The symbol catalog supports `\prime`. LaTeX imports such as `f^{\prime}(x)`,
428
+ `f^\prime(x)` and `f^{\prime\prime}(x)` use editable superscript slots and
429
+ preserve the prime count on export. Bare `\prime` is a symbol; use a superscript
430
+ for derivative notation. Apostrophe shorthand such as `f'(x)` remains accepted.
431
+ The editor does not compare answers. Hosts own question-specific suggestions and grading.
432
+
433
+ ## Development validation
434
+
435
+ The [editing scenarios](https://math-editor.barocss.com/docs/editing-scenarios.html)
436
+ define expected input, selection, deletion, history and host behavior. The
437
+ [validation report](https://math-editor.barocss.com/docs/validation.html) records
438
+ what was actually checked, including browser and host limits.
439
+
440
+ From a source checkout, start both math demo servers and run
441
+ `node scripts/check-math-editor.mjs`. This checks the model, actual editing,
442
+ framework/host lifecycle, selected KaTeX geometry and documentation build.
443
+ Workspace changes and a passing check do not imply that npm or the site has
444
+ already been published. See the changesets and release guide before publishing.
445
+
446
+ ## Text editor plugins
447
+
448
+ CodeMirror 6, CodeMirror 5, and Monaco have separate source-editing adapters. A VS Code extension uses a Webview beside the document. See the [text editor guide](./TEXT-EDITORS.md) for package names, setup, source-preservation rules, and validation scope. WGSL/GLSL editing is separate.
package/RELEASING.md CHANGED
@@ -1,31 +1,116 @@
1
1
  # Releasing math editor
2
2
 
3
- The source stays in this monorepo. Release only `@barocss/math-editor`; framework subpaths share its version. The initial release is **0.1.0**, public, on the **latest** npm tag.
3
+ See [Editing scenarios](EDITING-SCENARIOS.md) for stable scenario IDs, acceptance criteria, coverage gaps and per-run reporting.
4
+
5
+
6
+ The source stays in this monorepo. The local batch release includes
7
+ `@barocss/math-editor`, nine public rich-text plugins and four text packages
8
+ (`math-editor-text`, `math-editor-codemirror6`, `math-editor-codemirror5`,
9
+ `math-editor-monaco`, all under `@barocss`). All use MIT, public npm
10
+ access and the `latest` tag. Framework adapters are core subpaths and share the
11
+ core version. The private integration workspace and other products are excluded.
12
+
13
+ Versions remain independent; a batch release does not force every package to change.
14
+ VS Code is a separate VSIX/Marketplace release and is not published by this npm command.
4
15
 
5
16
  ## Local release
6
17
 
7
18
  ```sh
8
19
  # Repository root. Login is handled by npm, never by storing credentials in the repository.
9
- npm login
10
- pnpm release:math:prepare
11
- # After reviewing changes and browser validation:
20
+ npm login --registry=https://registry.npmjs.org/
21
+ # After reviewing versions, changelogs and browser validation:
12
22
  pnpm release:math
13
23
  ```
14
24
 
15
- Both commands check formatting, types and unit tests, clean/build the package, create a temporary tarball and verify all package entry points. The publish command sends only that verified tarball to the public npm registry. It never runs recursive publishing. `pnpm release` is an alias for this math-only workflow. npm may request account authentication or 2FA during publishing.
25
+ This one command runs core formatting/type/unit checks,
26
+ integration type/unit checks, builds, package validation and release-tool tests. It verifies the core
27
+ entry points and each plugin's packed declarations, runtime imports and required
28
+ files. It then runs **one `pnpm -r publish` command** for the fourteen allowed names.
29
+ `pnpm release` is an alias for this workflow.
30
+
31
+ Only the inspected package contents enter a generated workspace under
32
+ `output/math-batch-releases/release-*/`. Wrapper manifests use
33
+ `publishConfig.directory` to point at those contents. They give pnpm an explicit
34
+ core-first dependency order without adding dependencies to the published plugin
35
+ manifests. Publish lifecycle scripts are disabled because validation and builds
36
+ already ran. Git checks are disabled only for this generated workspace.
37
+
38
+ pnpm checks npm and skips package versions that already exist. It packs the
39
+ inspected contents again, so the final archive checksum can differ from the
40
+ preparation archive. The batch is not an atomic registry transaction. npm may
41
+ still request authentication for individual packages; one command does not
42
+ guarantee one authentication prompt.
43
+
44
+ For checks without publishing:
45
+
46
+ ```sh
47
+ # Build and inspect all fourteen packages. No registry publication.
48
+ pnpm release:math:prepare
49
+ # Also exercise recursive publishing with npm's dry-run flag.
50
+ # This can read registry metadata; it does not upload packages.
51
+ pnpm release:math:dry-run
52
+ ```
53
+
54
+ `release.json` records the candidate versions, artifact hashes and command status.
55
+ On success, `pnpm-publish-summary.json` lists newly published packages; versions
56
+ skipped by pnpm are absent. A dry-run summary is not evidence of publication.
57
+ If publishing fails, preserve the report and check each candidate version on npm.
58
+ pnpm 8 may not write its summary after a partial failure. Resolve any uncertain
59
+ results before running the batch again; never use `--force` to retry.
16
60
 
17
61
  Before releasing UI changes, also run `pnpm --filter @barocss/math-demo test:e2e` and the demo build. Verify the intended package name/version and changelog. A version already published to npm must never be reused. The repository's release workflow is manual validation only; it does not publish on main pushes.
18
62
 
19
63
  ## Subsequent versions
20
64
 
21
- 1. Run `pnpm changeset`, select only `@barocss/math-editor`, and write a user-facing change summary.
65
+ 1. Run `pnpm changeset`, select the affected math core and/or public plugins, and write a user-facing change summary.
22
66
  2. Use patch for compatible fixes and minor for features. During 0.x development, clearly identify breaking API changes in a minor release. Reserve 1.0.0 for the agreed stable API.
23
- 3. Run `pnpm version:math`. It runs Changesets in a temporary math-only workspace and copies back only this package manifest/changelog, preventing dependent product version bumps. The consumed changeset summary is retained in CHANGELOG.md.
67
+ 3. Run `pnpm version:math:plan` to preview the core, nine rich-text plugin and four text-package versions. Run `pnpm version:math` to apply that plan. Changesets runs in a temporary math-only workspace and copies back only affected math manifests/changelogs. Unrelated product changesets remain untouched. Review plugin peer-range changes before publishing.
24
68
  4. Review and commit the version/changelog and any dependency/lockfile changes with the implementation. Run release validation, then publish locally.
25
- 5. Record a package-specific Git tag such as `math-editor-v0.1.1` on the release commit, and update the site with the matching package version.
69
+ 5. Record package-specific Git tags on the release commit, and update the site with the matching package version. The batch command does not create commits or tags.
26
70
 
27
- The first 0.1.0 changelog is seeded explicitly; do not add a version-bump changeset just to publish the initial version. Avoid `pnpm version-packages` for a math-only release because that command processes the entire workspace plan.
71
+ The scoped Changesets configuration only promotes peer dependents when the new
72
+ version leaves their supported range. Widen a compatible peer range explicitly
73
+ and add a patch changeset; incompatible range changes still require release review.
74
+
75
+ Text tarballs are installed with the packed core into a temporary consumer using
76
+ `npm install --offline --ignore-scripts --legacy-peer-deps`. Host SDKs come from the
77
+ local installation. Strict public declaration checks and runtime import checks run
78
+ there. This validates package contents and local installation, not npm availability
79
+ or a fresh registry peer installation. Monaco interaction is covered by browser QA.
80
+ See [text editor validation](../../apps/math-text-demo/test/README.md) for native
81
+ IME and physical mobile checks that remain open.
82
+
83
+ Versioning is separate from publishing. Repeating a publish command must not create
84
+ another version. Avoid `pnpm version-packages` and unfiltered `pnpm -r publish`
85
+ for a math-only release because they can include other products.
86
+
87
+ The [host release guide](../math-editor-integrations/docs/RELEASING.md) lists the
88
+ nine plugins and explains changes to shared implementation. For an explicit
89
+ core-only release, use `pnpm version:math:core`,
90
+ `pnpm release:math:core:prepare` and `pnpm release:math:core`.
28
91
 
29
92
  ## Website
30
93
 
31
- `apps/math-demo` remains the site source. The intended static deployment repository is `barocss/math-editor-site`, with GitHub Pages at `math-editor.barocss.com`. Website deployment is separate from npm publication; page-only changes do not require a package version bump. Keep the displayed version and built editor version in sync. Successful npm publication alone does not mean the site or DNS has been configured.
94
+ `apps/math-demo` remains the site source. The static deployment repository is
95
+ `barocss/math-editor-site`, with GitHub Pages at `math-editor.barocss.com`.
96
+ Build the site directly from workspace source:
97
+
98
+ ```sh
99
+ pnpm build:math:site
100
+ ```
101
+
102
+ This builds the main site and the nine-plugin integration sample without a core
103
+ tarball, package `dist` build, npm login, registry lookup or publication check.
104
+ Workspace package exports resolve local source, including the private common
105
+ module. No package version bump is required to rebuild or deploy the site.
106
+ `release.json` records `source: "workspace-source"` and the local package versions
107
+ as metadata; those versions do not claim that the packages are published.
108
+
109
+ For an explicit package-artifact check, the previous command remains available:
110
+
111
+ ```sh
112
+ pnpm release:math:site /path/to/barocss-math-editor.tgz
113
+ ```
114
+
115
+ Both commands print the prepared static site directory and do not deploy it.
116
+ Website deployment and npm publication are independent operations.
@@ -0,0 +1,79 @@
1
+ # Rendering regression checks
2
+
3
+ Compare the editor with KaTeX using the same exported LaTeX, base font size and
4
+ display mode. Keep [editing scenarios](EDITING-SCENARIOS.md) for input behavior;
5
+ this guide defines the visual checks for EDIT-017. KaTeX is the reference image,
6
+ not an editable DOM replacement.
7
+
8
+ ## Three checks for each fixture
9
+
10
+ 1. **Model/output:** the editable tree exports the intended LaTeX and KaTeX accepts it.
11
+ 2. **Geometry:** compare relative positions, font sizes and gaps. Absolute page
12
+ coordinates are not comparable across different containers.
13
+ 3. **Visual review:** save the editor, active-input and KaTeX images together.
14
+ Check curves, stroke thickness, baselines and clipping. Numerical checks alone
15
+ do not establish that the two images look equivalent.
16
+
17
+ The active input, measuring element and passive glyph must use the same font
18
+ metrics. A cursor or hover background must not move a fraction or hide a fence.
19
+ Wait for `document.fonts.ready`. Disable preview fit scaling for comparison and
20
+ set the KaTeX root's computed font size to the editor's base size; matching the
21
+ parent container's font size is not sufficient.
22
+
23
+ ## Initial executable fixtures
24
+
25
+ Run `apps/math-integrations/tests/rendering-regression-check.js` through the
26
+ existing Playwright CLI browser workflow with the local site on port 5184.
27
+ The file is an async `(page) => ...` fixture, not a standalone Node script.
28
+ Omit its final semicolon when passing the function to `run-code`.
29
+
30
+ | Fixture | LaTeX | Renderers / sizes |
31
+ | --- | --- | --- |
32
+ | `indexed-root-power` | `\left(\sqrt[20]{ab}\right)^{\frac{2}{3}}` | Rich React and native DOM; 22px and 36px |
33
+ | `fraction-power` | `x^{\frac{2}{3}}` | Rich React and native DOM; 22px and 36px |
34
+ | `fraction-subscript` | `x_{\frac{2}{3}}` | Rich React and native DOM; 22px and 36px |
35
+
36
+ The 12 combinations currently assert:
37
+
38
+ - Fraction terms use half of the base font size and match KaTeX's computed term
39
+ size within 0.1px. This applies to these implicit-style fixtures, not every
40
+ explicit `\dfrac` or `\tfrac` expression.
41
+ - The exponent is above the base and the subscript is below it.
42
+ - The fraction center's vertical offset from the base glyph center differs from
43
+ KaTeX by less than 0.25em. This is a regression threshold, not pixel equality.
44
+ - The gap from the base box to its fraction script is between 0 and 0.25em.
45
+ - Activating a numerator retains its font size, and typing retains focus.
46
+ - The formula does not produce a KaTeX error.
47
+
48
+ Screenshots are saved as
49
+ `output/playwright/{renderer}-{fixture}-{size}-{editor|katex|active}.png`.
50
+ The returned metrics include editor and reference coordinates. Preserve them
51
+ with the source fingerprint, browser version and screenshot pairs for a run.
52
+ These filenames are overwritten on rerun; archive them if they are used as a
53
+ release baseline. Do not update an accepted baseline simply to hide a failure.
54
+
55
+ ## Why the first correction is bounded
56
+
57
+ Script fractions previously retained body-sized minimum row heights and spacing.
58
+ They now have compact terms and rows. A simple base uses a small script offset;
59
+ a tall structured base uses an offset proportional to the fraction height.
60
+ Empty boundary nodes reserve only a narrow passive cursor position.
61
+
62
+ This fixes the initial cases without changing the JSON model. It is not a
63
+ complete TeX layout engine. Remaining comparison fixtures should cover paired
64
+ scripts, nested fractions in both slots, explicit style overrides, multi-line
65
+ collision, large operators, fences, accents and narrow host containers.
66
+
67
+ As those fixtures grow, consolidate script levels, the math axis, baseline and
68
+ stroke metrics into shared layout rules. Avoid extending a list of formula-
69
+ specific CSS exceptions without a failing fixture and reference measurement.
70
+ Both renderers must use the same rule, and every new notation feature needs
71
+ an editor/KaTeX comparison in passive and active states.
72
+
73
+ ## Release use
74
+
75
+ Run changed fixtures during development. Run the rendering set and applicable
76
+ editing scenarios against release candidate artifacts before publishing. The
77
+ current fixture uses workspace sources and Chromium; it does not certify packed
78
+ packages, all host containers, Firefox/WebKit or OS IME behavior. CI scheduling
79
+ and automatic screenshot-diff approval are not implemented by this guide.