@barocss/math-editor 0.2.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (202) hide show
  1. package/ADAPTERS.md +25 -14
  2. package/API-JAVASCRIPT.md +1 -1
  3. package/API-REACT.md +5 -1
  4. package/API-SESSION.md +178 -6
  5. package/API-SOLID.md +1 -1
  6. package/API-SVELTE.md +1 -1
  7. package/API-VUE.md +1 -1
  8. package/API-WEB-COMPONENT.md +3 -1
  9. package/CHANGELOG.md +106 -0
  10. package/EDITING-SCENARIOS.md +174 -0
  11. package/EMBEDDING.md +4 -0
  12. package/IMPLEMENTATION.md +122 -2
  13. package/JSON-MODEL.md +1 -0
  14. package/LATEX-GUIDE.md +30 -1
  15. package/LATEX-MODEL.md +12 -0
  16. package/LATEX-SCOPE.md +12 -3
  17. package/LICENSE +1 -3
  18. package/README.md +201 -39
  19. package/RELEASING.md +81 -10
  20. package/RENDERING-TESTS.md +79 -0
  21. package/ROADMAP.md +220 -11
  22. package/STYLING.md +157 -0
  23. package/SUPPORT.md +24 -12
  24. package/VALIDATION.md +444 -4
  25. package/dist/context-tools.d.ts +21 -0
  26. package/dist/context-tools.js +37 -0
  27. package/dist/core.d.ts +5 -1
  28. package/dist/core.js +5 -1
  29. package/dist/document-codec.d.ts +0 -1
  30. package/dist/document-codec.js +0 -1
  31. package/dist/dom/caret-geometry.d.ts +3 -0
  32. package/dist/dom/caret-geometry.js +41 -0
  33. package/dist/dom/context-keyboard.d.ts +2 -0
  34. package/dist/dom/context-keyboard.js +22 -0
  35. package/dist/dom/elements.d.ts +1 -2
  36. package/dist/dom/elements.js +2 -3
  37. package/dist/dom/latex-panel.d.ts +10 -0
  38. package/dist/dom/latex-panel.js +59 -0
  39. package/dist/dom/matrix-selection.d.ts +11 -0
  40. package/dist/dom/matrix-selection.js +30 -0
  41. package/dist/dom/menu-position.d.ts +17 -2
  42. package/dist/dom/menu-position.js +129 -16
  43. package/dist/dom/presentation-controls.d.ts +4 -0
  44. package/dist/dom/presentation-controls.js +56 -0
  45. package/dist/dom/quick-panel.d.ts +12 -0
  46. package/dist/dom/quick-panel.js +102 -0
  47. package/dist/dom/selection.d.ts +29 -0
  48. package/dist/dom/selection.js +53 -0
  49. package/dist/dom/symbol-panel.d.ts +9 -0
  50. package/dist/dom/symbol-panel.js +146 -0
  51. package/dist/dom/theme.d.ts +6 -0
  52. package/dist/dom/theme.js +68 -0
  53. package/dist/dom/toolbar-catalog.d.ts +10 -0
  54. package/dist/dom/toolbar-catalog.js +35 -0
  55. package/dist/dom/toolbar.d.ts +13 -2
  56. package/dist/dom/toolbar.js +295 -28
  57. package/dist/dom.d.ts +9 -1
  58. package/dist/dom.js +682 -151
  59. package/dist/editor-labels.d.ts +0 -1
  60. package/dist/editor-labels.js +0 -1
  61. package/dist/enter-policy.d.ts +0 -1
  62. package/dist/enter-policy.js +0 -1
  63. package/dist/fences.d.ts +0 -1
  64. package/dist/fences.js +0 -1
  65. package/dist/i18n.d.ts +0 -1
  66. package/dist/i18n.js +0 -1
  67. package/dist/index.d.ts +4 -1
  68. package/dist/index.js +4 -1
  69. package/dist/latex-insertion.d.ts +12 -0
  70. package/dist/latex-insertion.js +26 -0
  71. package/dist/latex-paste-panel.d.ts +3 -0
  72. package/dist/latex-paste-panel.js +18 -0
  73. package/dist/latex.d.ts +0 -1
  74. package/dist/latex.js +11 -1
  75. package/dist/lines.d.ts +0 -1
  76. package/dist/lines.js +0 -1
  77. package/dist/locales/en.js +39 -1
  78. package/dist/locales/en.json +39 -1
  79. package/dist/locales/ko.js +39 -1
  80. package/dist/locales/ko.json +39 -1
  81. package/dist/math-editor-toolbar.d.ts +4 -2
  82. package/dist/math-editor-toolbar.js +3 -4
  83. package/dist/math-editor.d.ts +7 -2
  84. package/dist/math-editor.js +661 -308
  85. package/dist/math-layout.d.ts +12 -0
  86. package/dist/math-layout.js +59 -0
  87. package/dist/math-spacing.d.ts +13 -0
  88. package/dist/math-spacing.js +87 -0
  89. package/dist/matrix-range.d.ts +40 -0
  90. package/dist/matrix-range.js +242 -0
  91. package/dist/matrix.d.ts +0 -1
  92. package/dist/matrix.js +0 -1
  93. package/dist/model.d.ts +4 -1
  94. package/dist/model.js +49 -5
  95. package/dist/outputs.d.ts +0 -1
  96. package/dist/outputs.js +0 -1
  97. package/dist/preferences.d.ts +24 -0
  98. package/dist/preferences.js +66 -0
  99. package/dist/presentation-controls.d.ts +10 -0
  100. package/dist/presentation-controls.js +10 -0
  101. package/dist/presentation.d.ts +13 -0
  102. package/dist/presentation.js +86 -0
  103. package/dist/quick-panel.d.ts +2 -0
  104. package/dist/quick-panel.js +17 -0
  105. package/dist/range.d.ts +2 -1
  106. package/dist/range.js +11 -1
  107. package/dist/react.d.ts +0 -1
  108. package/dist/react.js +0 -1
  109. package/dist/root-transform.d.ts +19 -0
  110. package/dist/root-transform.js +69 -0
  111. package/dist/session.d.ts +31 -2
  112. package/dist/session.js +108 -7
  113. package/dist/solid.d.ts +0 -1
  114. package/dist/solid.js +0 -1
  115. package/dist/suggestions.d.ts +13 -1
  116. package/dist/suggestions.js +153 -12
  117. package/dist/svelte.d.ts +0 -1
  118. package/dist/svelte.js +0 -1
  119. package/dist/symbol-browser.d.ts +0 -1
  120. package/dist/symbol-browser.js +0 -1
  121. package/dist/symbols.d.ts +0 -1
  122. package/dist/symbols.js +0 -1
  123. package/dist/templates.d.ts +0 -1
  124. package/dist/templates.js +0 -1
  125. package/dist/tokens.d.ts +0 -1
  126. package/dist/tokens.js +0 -1
  127. package/dist/vertical-navigation.d.ts +15 -0
  128. package/dist/vertical-navigation.js +145 -0
  129. package/dist/vue.d.ts +0 -1
  130. package/dist/vue.js +0 -1
  131. package/dist/web-component.d.ts +0 -1
  132. package/dist/web-component.js +9 -2
  133. package/package.json +11 -3
  134. package/src/fonts/KaTeX_Math-Italic.woff2 +0 -0
  135. package/src/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  136. package/src/fonts/README.md +18 -0
  137. package/src/shapes/README.md +21 -0
  138. package/src/shapes/parenthesis-bottom.svg +1 -0
  139. package/src/shapes/parenthesis-top.svg +1 -0
  140. package/src/shapes/parenthesis.svg +1 -0
  141. package/src/shapes/radical.svg +1 -0
  142. package/src/style.css +949 -173
  143. package/dist/core.d.ts.map +0 -1
  144. package/dist/core.js.map +0 -1
  145. package/dist/document-codec.d.ts.map +0 -1
  146. package/dist/document-codec.js.map +0 -1
  147. package/dist/dom/elements.d.ts.map +0 -1
  148. package/dist/dom/elements.js.map +0 -1
  149. package/dist/dom/menu-position.d.ts.map +0 -1
  150. package/dist/dom/menu-position.js.map +0 -1
  151. package/dist/dom/toolbar.d.ts.map +0 -1
  152. package/dist/dom/toolbar.js.map +0 -1
  153. package/dist/dom.d.ts.map +0 -1
  154. package/dist/dom.js.map +0 -1
  155. package/dist/editor-labels.d.ts.map +0 -1
  156. package/dist/editor-labels.js.map +0 -1
  157. package/dist/enter-policy.d.ts.map +0 -1
  158. package/dist/enter-policy.js.map +0 -1
  159. package/dist/fences.d.ts.map +0 -1
  160. package/dist/fences.js.map +0 -1
  161. package/dist/i18n.d.ts.map +0 -1
  162. package/dist/i18n.js.map +0 -1
  163. package/dist/index.d.ts.map +0 -1
  164. package/dist/index.js.map +0 -1
  165. package/dist/latex.d.ts.map +0 -1
  166. package/dist/latex.js.map +0 -1
  167. package/dist/lines.d.ts.map +0 -1
  168. package/dist/lines.js.map +0 -1
  169. package/dist/math-editor-toolbar.d.ts.map +0 -1
  170. package/dist/math-editor-toolbar.js.map +0 -1
  171. package/dist/math-editor.d.ts.map +0 -1
  172. package/dist/math-editor.js.map +0 -1
  173. package/dist/matrix.d.ts.map +0 -1
  174. package/dist/matrix.js.map +0 -1
  175. package/dist/model.d.ts.map +0 -1
  176. package/dist/model.js.map +0 -1
  177. package/dist/outputs.d.ts.map +0 -1
  178. package/dist/outputs.js.map +0 -1
  179. package/dist/range.d.ts.map +0 -1
  180. package/dist/range.js.map +0 -1
  181. package/dist/react.d.ts.map +0 -1
  182. package/dist/react.js.map +0 -1
  183. package/dist/session.d.ts.map +0 -1
  184. package/dist/session.js.map +0 -1
  185. package/dist/solid.d.ts.map +0 -1
  186. package/dist/solid.js.map +0 -1
  187. package/dist/suggestions.d.ts.map +0 -1
  188. package/dist/suggestions.js.map +0 -1
  189. package/dist/svelte.d.ts.map +0 -1
  190. package/dist/svelte.js.map +0 -1
  191. package/dist/symbol-browser.d.ts.map +0 -1
  192. package/dist/symbol-browser.js.map +0 -1
  193. package/dist/symbols.d.ts.map +0 -1
  194. package/dist/symbols.js.map +0 -1
  195. package/dist/templates.d.ts.map +0 -1
  196. package/dist/templates.js.map +0 -1
  197. package/dist/tokens.d.ts.map +0 -1
  198. package/dist/tokens.js.map +0 -1
  199. package/dist/vue.d.ts.map +0 -1
  200. package/dist/vue.js.map +0 -1
  201. package/dist/web-component.d.ts.map +0 -1
  202. package/dist/web-component.js.map +0 -1
package/README.md CHANGED
@@ -1,40 +1,86 @@
1
1
  # @barocss/math-editor
2
2
 
3
- See the [JSON model specification](JSON-MODEL.md) for required fields, exact slot order, invariants and persistence limits.
3
+ See [Editing scenarios](EDITING-SCENARIOS.md) for stable scenario IDs, acceptance criteria, coverage gaps and per-run reporting.
4
4
 
5
5
 
6
- ## Framework-specific API guides
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.
7
7
 
8
- [Pure JavaScript](API-JAVASCRIPT.md) · [React](API-REACT.md) · [Web Component](API-WEB-COMPONENT.md) · [Vue 3](API-VUE.md) · [Svelte](API-SVELTE.md) · [Solid](API-SOLID.md) · [Session and DOM API](API-SESSION.md)
8
+ This editor does not calculate, solve equations or parse arbitrary LaTeX.
9
9
 
10
- Each guide covers installation, a complete integration, document replacement, saving, lifecycle cleanup and host limitations.
10
+ ## Packaging changes in 0.4.1
11
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.
12
15
 
13
- An embeddable math editor with a framework-independent model, an existing rich React UI, and a new native DOM surface for pure JavaScript, Web Components, Vue, Svelte, Solid and React. Write expressions in place, select existing math, and wrap it in fractions, roots, powers or delimiters. The demo includes a live KaTeX preview.
16
+ ## Editing additions in 0.4.0
14
17
 
15
- **Status:** working prototype, not yet a production-ready replacement for the math features in Note, Word or Slides. This package does not calculate, solve equations or parse arbitrary LaTeX.
18
+ 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).
16
19
 
17
- See [framework adapters and inline/custom toolbar integration](ADAPTERS.md), [custom locales](LOCALIZATION.md), and [progress / roadmap](ROADMAP.md). The new native renderer has explicit parity gaps; existing React consumers keep their current UI.
20
+ ## Packages
18
21
 
19
- For editor-only, external toolbar, LaTeX, preview, inline and popup compositions, see [Embedding](EMBEDDING.md) and `/layouts.html` in the demo.
22
+ Choose the core package for a standalone math field. Choose one additional host package to embed that field in an existing editor. The host packages share the same math model, parser, suggestions and toolbar. Each requires the core and its own host SDK as peer dependencies.
23
+
24
+ | Package | Purpose | Formula placement | Release status |
25
+ | --- | --- | --- | --- |
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.
39
+
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.
41
+
42
+ Host guides: [Tiptap](https://math-editor.barocss.com/docs/integrations/tiptap.html) · [ProseMirror](https://math-editor.barocss.com/docs/integrations/prosemirror.html) · [Lexical](https://math-editor.barocss.com/docs/integrations/lexical.html) · [Editor.js](https://math-editor.barocss.com/docs/integrations/editorjs.html) · [TinyMCE](https://math-editor.barocss.com/docs/integrations/tinymce.html) · [CKEditor 5](https://math-editor.barocss.com/docs/integrations/ckeditor.html) · [Quill](https://math-editor.barocss.com/docs/integrations/quill.html) · [Slate](https://math-editor.barocss.com/docs/integrations/slate.html) · [WordPress Gutenberg](https://math-editor.barocss.com/docs/integrations/gutenberg.html).
43
+
44
+ The [unified host sample](https://math-editor.barocss.com/integrations/) includes all nine editors. During development, guides are served under `http://localhost:5184/docs/integrations/`, and the host sample runs on port 5185. Website deployment is separate from npm publication.
45
+
46
+ ## Framework adapters in the core package
47
+
48
+ These are subpath exports of `@barocss/math-editor`, not separate npm packages.
49
+
50
+ | Environment | Import | Guide |
51
+ | --- | --- | --- |
52
+ | Model and sessions without a UI | `@barocss/math-editor/core` | [Session API](https://math-editor.barocss.com/docs/api-session.html) |
53
+ | Pure JavaScript | `@barocss/math-editor/dom` | [JavaScript](https://math-editor.barocss.com/docs/api-javascript.html) |
54
+ | React | `@barocss/math-editor` for the rich UI; `/react` for the native DOM surface | [React](https://math-editor.barocss.com/docs/api-react.html) |
55
+ | Web Component | `@barocss/math-editor/web-component` | [Web Component](https://math-editor.barocss.com/docs/api-web-component.html) |
56
+ | Vue 3 | `@barocss/math-editor/vue` | [Vue](https://math-editor.barocss.com/docs/api-vue.html) |
57
+ | Svelte | `@barocss/math-editor/svelte` | [Svelte](https://math-editor.barocss.com/docs/api-svelte.html) |
58
+ | Solid | `@barocss/math-editor/solid` | [Solid](https://math-editor.barocss.com/docs/api-solid.html) |
59
+
60
+ Each guide covers installation, document replacement, saving and lifecycle cleanup. See the [framework samples](https://math-editor.barocss.com/adapters.html) to try each environment, and the [JSON model specification](https://math-editor.barocss.com/docs/json-model.html) for the storage contract.
61
+
62
+ 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.
63
+
64
+ **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.
65
+
66
+ 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).
20
67
 
21
68
  ## Quick start
22
69
 
23
- Install version 0.2.1 from npm:
70
+ Install version 0.4.1 from npm:
24
71
 
25
72
  ```sh
26
- npm install @barocss/math-editor@0.2.1
73
+ npm install @barocss/math-editor@0.4.1
27
74
  # For the rich React UI:
28
75
  npm install react react-dom
29
76
  ```
30
77
 
31
- Import `@barocss/math-editor/style.css` once. Framework-free consumers use `/core` and `/dom`; each framework adapter has its own subpath. See [ADAPTERS.md](ADAPTERS.md).
78
+ Import `@barocss/math-editor/style.css` once. Framework-free consumers use `/core` and `/dom`; each framework adapter has its own subpath. See [ADAPTERS.md](https://math-editor.barocss.com/docs/adapters.html).
32
79
 
33
80
  To develop the package and demo from this monorepo:
34
81
 
35
82
  ```sh
36
83
  pnpm install
37
- pnpm --filter @barocss/math-editor build
38
84
  pnpm --filter @barocss/math-demo dev
39
85
  # http://localhost:5184
40
86
  ```
@@ -67,10 +113,11 @@ function Formula({ documentId, saved, save }: {
67
113
  | `defaultValue?: MathDocument` | Read on mount. Change the React `key` to open another document. This is not a controlled `value` prop. |
68
114
  | `locale?: MathLocale` | Defaults to `ko`. Changes UI text without resetting the document or undo history. |
69
115
  | `autoFocus?: boolean` | Start in the initial editable token. Defaults to `false`. |
70
- | `enterBehavior?: 'newline' | 'commit'` | `commit` calls `onCommit` on Enter after suggestions/selection handling; Shift+Enter retains normal row behavior. |
116
+ | `enterBehavior?: 'newline' \| 'commit'` | `commit` calls `onCommit` on Enter after suggestions/selection handling; Shift+Enter retains normal row behavior. |
71
117
  | `onCommit?()` / `onCancel?()` | Host draft apply/cancel callbacks. Escape dismisses suggestions first; composition reserves its own keys. |
72
118
  | `showPopovers?: boolean` | Defaults to `true`. Set `false` while keeping the editor mounted in an inactive host tab; its undo history is preserved. |
73
- | `toolbar?: boolean` | Show the rich React toolbar panels; defaults to `true`. |
119
+ | `toolbar?: boolean \| readonly StructureKind[]` | Show or filter rich React structure buttons; defaults to `true`. |
120
+ | `toolbarMaxItems?: number` | Initially visible structure buttons; defaults to eight. |
74
121
  | `toolbarEnd?: ReactNode` | Host actions such as reset/save appended to the toolbar. |
75
122
  | `showTokenLegend?: boolean` | Show lexical color guidance; defaults to `true`. |
76
123
  | `showLineNumbers?: boolean` | Defaults to `true`. Displays UI-only line numbers when there are two or more top-level rows. Never included in the model, clipboard or LaTeX. |
@@ -84,19 +131,21 @@ Matching literal characters appear before editable structures and templates. For
84
131
 
85
132
  ## Editing flows
86
133
 
87
- Use **All symbols** to browse all 90 symbols without knowing a name in advance. Search by glyph, English/Korean name, alias or LaTeX command, then click to insert at the last caret or replace the model selection. Escape closes the browser. Search-field clipboard actions do not affect the formula.
134
+ Use **All symbols** to browse the complete symbol catalog without knowing a name in advance. Search by glyph, English/Korean name, alias or LaTeX command, then click to insert at the last caret or replace the model selection. Escape closes the browser. Search-field clipboard actions do not affect the formula. The workspace native toolbar exposes this browser through More tools.
88
135
 
89
- - Type `x/`, then Enter: convert to a fraction and enter the denominator. `/`, `^` and `_` remain opt-in suggestions, not immediate structural conversions.
90
- - Type `matrix`, `identity`, `aligned` or `cases`, then choose a suggestion. Korean aliases work in both UI languages.
136
+ - Type `x/`, choose Fraction, then Enter to enter its denominator. The literal `÷` candidate comes first. `/`, `^` and `_` remain opt-in suggestions, not immediate structural conversions.
137
+ - Type `matrix`, `identity`, `aligned` or `cases`, then choose a suggestion. Korean aliases work in both UI languages. In the 0.4.0 release, type `rows x columns` without spaces, such as `2x1`, `1x2`, `3x7` or `4x4`. Each dimension can be 1–20. Suggestions offer an empty matrix and a zero matrix; square sizes also offer an identity matrix. Uppercase `X` and `×` also work. Enter accepts a suggestion; Space or Escape keeps the typed expression.
91
138
  - Type `30degree`, `30도` or `30각도`, then Enter to insert `30°` on the current line. `angle` inserts the separate symbol `∠`.
92
- - Search `reals`, `integers`, `setminus`, `parallel`, or their Korean names. [The complete catalog](./SUPPORT.md) lists every symbol and alias.
139
+ - Search `reals`, `integers`, `setminus`, `parallel`, or their Korean names. [The complete catalog](https://math-editor.barocss.com/docs/support.html) lists every symbol and alias.
93
140
  - Use the template selector for zero matrices, column vectors, the quadratic formula and the Pythagorean theorem. Every part remains editable. Template insertion replaces a model selection if one is active; otherwise it inserts at the caret.
94
- - Click a token to edit it. Only the current token mounts a native `input`; the others are ordinary elements. Blur switches to preview. Escape closes suggestions first, then returns to preview.
141
+ - Click text to edit it. Rich React activates one lexical token; the native renderer activates a whole logical text run. Only that active text mounts an `input`. Blur switches to preview. Escape closes suggestions first, then returns to preview.
95
142
  - Drag to select math. The selection tools and main toolbar wrap it in a fraction, root, power, subscript, parentheses, brackets or absolute value. Fractions focus the denominator; powers/subscripts focus their new slot; roots/delimiters place the caret after the structure.
96
143
  - Complex power bases receive parentheses. Existing structured delimiters are preserved. This is a conservative display rule, not symbolic algebra.
97
144
 
98
145
  Variables, numeric literals and symbols use distinct colors. Classification is lexical: a letter named `c` or `e` is not automatically a declared constant. The model does not resolve names or binding scopes.
99
146
 
147
+ Native passive text preserves these lexical colors; its whole active run still uses one role color. Precise selection highlights do not change that input granularity.
148
+
100
149
  ## Keyboard reference
101
150
 
102
151
  | Context | Key | Action |
@@ -104,6 +153,7 @@ Variables, numeric literals and symbols use distinct colors. Classification is l
104
153
  | Suggestions | Up / Down, Enter | Choose and apply; IME composition reserves these keys for the input method |
105
154
  | Any active slot | Tab / Shift+Tab | Traverse tokens and structural slots |
106
155
  | Token boundary | Left / Right | Move into a neighboring token or slot |
156
+ | Fraction, scripts, indexed root or operator slots | Up / Down | Move to a related slot at the nearest rendered horizontal caret position |
107
157
  | Top-level row | Enter | Split the row, unless applying a suggestion |
108
158
  | Start of a later top-level row | Backspace | Join the previous row |
109
159
  | Grid | Up / Down | Move to the same column in the adjacent row |
@@ -115,19 +165,27 @@ Variables, numeric literals and symbols use distinct colors. Classification is l
115
165
  | Just after a fraction/root/delimiter | Backspace | Unwrap, preserving contents |
116
166
  | Outer grid edge | Backspace / Delete | Delete empty grid; select filled grid first, press again to delete |
117
167
  | Preview surface | Cmd/Ctrl+A | Select the whole math document |
118
- | Active input | Cmd/Ctrl+A | Select the current token text |
168
+ | Active input | Cmd/Ctrl+A | Select the current input text: a React token or native logical run |
169
+ | Editor | Shift+Left / Right | Extend or shrink the model range across text and balanced structures |
170
+ | Editor | Shift+Up / Down | Extend the model range across top-level lines using logical offsets |
119
171
  | Preview surface | Enter / F2 | Enter editing |
120
172
  | Model selection | Cmd/Ctrl+C / X / V | Copy / cut / replace with clipboard contents |
121
173
  | Model selection | Backspace / Delete | Delete selection |
122
174
  | Editor | Cmd/Ctrl+Z / Cmd/Ctrl+Shift+Z | Undo / redo |
123
175
 
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.
177
+
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.
179
+
124
180
  ## Selection and clipboard boundaries
125
181
 
126
- A range within one row preserves partial text and balanced structures. Selecting across a numerator and denominator expands to their common fraction; selecting across matrix cells expands to their common matrix. This is not a spreadsheet-style rectangular cell selection. Multiple document lines can be copied, replaced or deleted, but cannot be wrapped into a single structure.
182
+ A range within one row preserves partial text and balanced structures. Selecting across a numerator and denominator expands to their common fraction; cross-cell pointer selection now creates a matrix rectangle in the workspace. A structural `MathRange` still expands to the common matrix; rectangular editing uses the separate `MathMatrixRange` contract. Multiple document lines can be copied, replaced or deleted, but cannot be wrapped into a single structure.
183
+
184
+ Workspace native highlights now show the exact selected text endpoints. A drag inside the active input uses native text selection until it leaves the input; it can then continue as a model range across structures. These refinements are included in 0.4.0 and retain the same clipboard and balanced-structure rules.
127
185
 
128
186
  Internal copies include `application/x-barocss-math+json` and plain-text LaTeX. Paste validates the custom payload and generates fresh IDs. Plain external text is inserted literally; newlines become top-level rows. Multiple-line paste into a nested slot is rejected without changing the document. If a destination strips custom clipboard formats, pasting back provides text rather than reconstructed math.
129
187
 
130
- The demo's **Copy** button exports LaTeX only. Workspace builds also provide explicit bounded LaTeX import; see [the import contract](LATEX-SCOPE.md). Version 0.2.0 includes bounded LaTeX import. Ordinary clipboard text is still inserted literally.
188
+ The demo's LaTeX Copy action exports source text; its separate sized PNG download/copy controls render the website preview. The library exports mathematical data and LaTeX, with no reusable SVG/PNG image-export API yet. Version 0.2.0 includes explicit bounded LaTeX import; see [the import contract](https://math-editor.barocss.com/docs/latex-scope.html). Ordinary clipboard text is still inserted literally.
131
189
 
132
190
  ## Model and package boundaries
133
191
 
@@ -156,14 +214,14 @@ pnpm --filter @barocss/math-demo build
156
214
  pnpm --filter @barocss/math-demo test:e2e
157
215
  ```
158
216
 
159
- 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.
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.
160
218
 
161
- - [Symbol / English / Korean name table](./SYMBOLS.md)
162
- - [LaTeX editing guide and upcoming notation](./LATEX-GUIDE.md)
163
- - [Supported formulas, templates and full symbol catalog](./SUPPORT.md)
164
- - [Implementation guide](./IMPLEMENTATION.md)
165
- - [Validation evidence and limitations](./VALIDATION.md)
166
- - [Roadmap and acceptance criteria](./ROADMAP.md)
219
+ - [Symbol / English / Korean name table](https://math-editor.barocss.com/docs/symbols.html)
220
+ - [LaTeX editing guide and upcoming notation](https://math-editor.barocss.com/docs/latex-guide.html)
221
+ - [Supported formulas, templates and full symbol catalog](https://math-editor.barocss.com/docs/support.html)
222
+ - [Implementation guide](https://math-editor.barocss.com/docs/implementation.html)
223
+ - [Validation evidence and limitations](https://math-editor.barocss.com/docs/validation.html)
224
+ - [Roadmap and acceptance criteria](https://math-editor.barocss.com/docs/roadmap.html)
167
225
 
168
226
 
169
227
  ## LaTeX loading (0.2.0)
@@ -180,12 +238,12 @@ if (result.ok) {
180
238
  }
181
239
  ```
182
240
 
183
- The shared contract is **editable structure ↔ exported LaTeX ↔ imported structure**, within the [documented limits](LATEX-SCOPE.md). It covers the current structure and symbol catalog, not arbitrary KaTeX input. Failed imports never modify a session. Framework adapters do not implement their own parsers. Use source editing as a fallback in hosts.
241
+ The shared contract is **editable structure ↔ exported LaTeX ↔ imported structure**, within the [documented limits](https://math-editor.barocss.com/docs/latex-scope.html). It covers the current structure and symbol catalog, not arbitrary KaTeX input. Failed imports never modify a session. Framework adapters do not implement their own parsers. Use source editing as a fallback in hosts.
184
242
 
185
243
 
186
- During an existing edit, use `session.importLatex(source)` rather than resetting `defaultValue`: this preserves Undo/Redo and enforces inline policy. The rich React editor exposes `MathEditorHandle.importLatex` through `apiRef`; see [React import](API-REACT.md) and [shared session import](API-SESSION.md). Both paths use the same parser and fail without a partial update.
244
+ During an existing edit, use `session.importLatex(source)` rather than resetting `defaultValue`: this preserves Undo/Redo and enforces inline policy. The rich React editor exposes `MathEditorHandle.importLatex` through `apiRef`; see [React import](https://math-editor.barocss.com/docs/api-react.html) and [shared session import](https://math-editor.barocss.com/docs/api-session.html). Both paths use the same parser and fail without a partial update.
187
245
 
188
- Workspace presentation refinements include aligned script bases, lining numerals and background-only token focus. See [implementation notes](IMPLEMENTATION.md#editing-typography-and-focus-2026-09-08-workspace), [supported notation](SUPPORT.md) and the [remaining LaTeX priorities](ROADMAP.md#remaining-latex-priorities-workspace-review-2026-09-08). These changes are included in 0.2.0.
246
+ Workspace presentation refinements include aligned script bases, lining numerals and background-only token focus. See [implementation notes](https://math-editor.barocss.com/docs/implementation.html#editing-typography-and-focus-2026-09-08-workspace), [supported notation](https://math-editor.barocss.com/docs/support.html) and the [remaining LaTeX priorities](https://math-editor.barocss.com/docs/roadmap.html#remaining-latex-priorities-workspace-review-2026-09-08). These changes are included in 0.2.0.
189
247
 
190
248
  Workspace norm support: one editable body, shared double-bar fences, `norm`/`노름`/`||` suggestions, range wrapping and LaTeX import/export. The parser accepts short `\lVert…\rVert` and scalable double-bar aliases; export uses `\left\Vert…\right\Vert`. Available in 0.2.0.
191
249
 
@@ -195,7 +253,9 @@ Workspace: `\overbrace`/`\underbrace` support includes LaTeX parsing/export, loc
195
253
 
196
254
  ## Compact and filtered toolbars (workspace)
197
255
 
198
- Toolbars initially show up to eight structure buttons. More tools / Fewer tools toggles the remainder without changing the formula or history. Rich React also places matrix presets, templates and symbol shortcuts in the expanded section; Undo, Redo and `toolbarEnd` stay visible. Native toolbars contain structure buttons and history only and show a toggle when needed. The layout wraps naturally on narrow screens; this is not a guaranteed single-row toolbar.
256
+ Toolbars initially show up to eight structure buttons. More tools / Fewer tools toggles the expanded section without changing the formula or history. In the workspace native toolbar, More tools also reveals All symbols search, templates, 2×2/3×3/4×4 matrix and identity presets, and symbol shortcuts. More remains available even when all selected structures already fit. Undo and Redo stay visible; rich React also retains `toolbarEnd`. The layout wraps on narrow screens.
257
+
258
+ The workspace native grid toolbar follows the active caret. Matrices expose row/column insertion and deletion plus delimiter selection; aligned/cases expose row operations. Text or model selections disable row/column and delimiter mutations. The workspace adds Select cells, Select all cells and Transpose matrix in both renderers. These additions are included in 0.4.0.
199
259
 
200
260
  ```tsx
201
261
  <MathEditor toolbar={['fraction', 'root', 'superscript', 'matrix']}
@@ -203,7 +263,8 @@ Toolbars initially show up to eight structure buttons. More tools / Fewer tools
203
263
  ```
204
264
 
205
265
  ```js
206
- mountMathEditor(host, session, {
266
+ mountMathEditor(host, {
267
+ session,
207
268
  toolbar: ['fraction', 'root', 'norm'],
208
269
  toolbarMaxItems: 2,
209
270
  });
@@ -213,7 +274,7 @@ mountMathToolbar(toolbarHost, session, {
213
274
  });
214
275
  ```
215
276
 
216
- `toolbar: false` hides the toolbar. A structure array filters its structure buttons only: it does not disable those structures in suggestions, parsing or the model, and does not filter React's auxiliary template/symbol controls. `toolbarMaxItems` (independent toolbar: `maxItems`) is a nonnegative count; zero initially hides all structure buttons behind More. A sufficiently large count shows all selected structure buttons initially. Expanded state belongs to the mounted toolbar and is not saved in the math document. The rich React `toolbar` array and compact behavior are available in 0.2.0.
277
+ `toolbar: false` hides the toolbar. A structure array filters structure buttons; the workspace native toolbar also filters templates by their structure kinds and limits grid presets/context controls to allowed kinds. Symbol search remains available. Rich React's auxiliary controls retain their existing behavior. Toolbar filtering does not restrict suggestions, parsing or the model. `toolbarMaxItems` (independent toolbar: `maxItems`) is a nonnegative count; zero initially hides all structure buttons behind More. A sufficiently large count shows all selected structure buttons initially. Expanded state is not saved in the math document. The rich React `toolbar` array and compact behavior are available in 0.2.0; the native discovery/context additions are included in 0.4.0.
217
278
 
218
279
  Workspace: added `\tilde`, `\bar`, `\dot`, `\ddot`, `\widehat` and `\widetilde` with exact-command parsing/export, localized suggestions, one-slot wrapping and fixed/stretchy accent rendering. Available in 0.2.0.
219
280
 
@@ -227,18 +288,119 @@ Set `--me-font-size` on the host (for example `18px`) to keep React token previe
227
288
 
228
289
  ### Explicit fraction sizes (workspace)
229
290
 
230
- Import or type the suggestions `dfrac`, `tfrac`, `dbinom`, and `tbinom` for display/text fraction and binomial presets. The editor preserves their size on export. See [LaTeX guide](LATEX-GUIDE.md); available in 0.2.0.
291
+ Import or type the suggestions `dfrac`, `tfrac`, `dbinom`, and `tbinom` for display/text fraction and binomial presets. The editor preserves their size on export. See [LaTeX guide](https://math-editor.barocss.com/docs/latex-guide.html); available in 0.2.0.
231
292
 
232
293
  ### Math alphabet support (workspace)
233
294
 
234
- `\mathbf`, `\mathcal` and multi-letter `\mathbb` now support import, suggestions, range wrapping, editing and export. See [alphabet scope and examples](LATEX-GUIDE.md#mathematical-alphabets--020). Available in 0.2.0.
295
+ `\mathbf`, `\mathcal` and multi-letter `\mathbb` now support import, suggestions, range wrapping, editing and export. See [alphabet scope and examples](https://math-editor.barocss.com/docs/latex-guide.html#mathematical-alphabets--020). Available in 0.2.0.
235
296
 
236
297
  ### Labeled arrows (workspace)
237
298
 
238
- `\xrightarrow[below]{above}` and `\xleftarrow[below]{above}` support parsing, suggestions, editable math labels and export. See [label syntax and slot order](LATEX-GUIDE.md#labeled-arrows--020). Available in 0.2.0.
299
+ `\xrightarrow[below]{above}` and `\xleftarrow[below]{above}` support parsing, suggestions, editable math labels and export. See [label syntax and slot order](https://math-editor.barocss.com/docs/latex-guide.html#labeled-arrows--020). Available in 0.2.0.
239
300
 
240
301
  ## Keyboard ranges and brace discovery (0.2.1)
241
302
 
242
- Shift+Left/Right extends or shrinks the same model range used by dragging. Structures are crossed as balanced units; copied and deleted ranges use existing model normalization. Shift+Up/Down extends to an adjacent top-level document line, using a logical text offset rather than pixel-based column matching; grid-cell rectangular selection is not added. Copy, cut, wrapping, deletion and Undo use the existing range behavior. IME composition and modifier shortcuts retain their existing handling.
303
+ Shift+Left/Right extends or shrinks the same model range used by dragging. Structures are crossed as balanced units; copied and deleted ranges use existing model normalization. Shift+Up/Down extends to an adjacent top-level document line, using a logical text offset rather than pixel-based column matching; when a matrix-cell selection is active, Shift+arrows instead moves its rectangular focus corner. Copy, cut, wrapping, deletion and Undo use the existing range behavior. IME composition and modifier shortcuts retain their existing handling.
304
+
305
+ After a model selection, plain Left/Up restores the caret at its document-ordered
306
+ start; Right/Down restores it at the end. The same rule applies to reverse drags
307
+ and Shift+arrow selections, without consuming another character or changing the
308
+ formula. Alt+Up/Down browses the wrapping suggestions while retaining the range;
309
+ Enter applies a candidate. Ordinary input suggestions still use Up/Down.
243
310
 
244
311
  Typing `{` offers both paired braces and cases. Paired braces remain the first candidate; choose Cases explicitly to insert its editable grid.
312
+
313
+
314
+ ### Sharing a native toolbar between editors (workspace)
315
+
316
+ `mountMathToolbar(host, sessionOrNull, options)` now returns
317
+ `{ setSession, setDisabled, destroy }`. Call `setSession(activeEditor.session)` when an editor
318
+ becomes active and `setSession(null)` when editing ends. Detaching disables editing
319
+ actions and unsubscribes from the previous session. `options.locale` supplies labels
320
+ before the first session is attached; active sessions supply their own locale.
321
+ `setDisabled(true)` keeps the session attached while disabling mutations and closing
322
+ symbol search; restore it with `false` after composition. An internally mounted
323
+ native toolbar coordinates this automatically. Independent toolbar hosts own focus,
324
+ draft lifecycle and composition handling. `onExecute` runs after a successful command
325
+ so the host can return focus to the math editor; browsing tools does not commit the
326
+ draft. See the [session toolbar API](https://math-editor.barocss.com/docs/api-session.html#independent-toolbar-and-outputs).
327
+ The Tiptap/ProseMirror integration coordinates these through its `toolbarHost` option.
328
+
329
+ These native UI additions use the existing model and LaTeX grammar. English/Korean
330
+ remain the complete bundled locale packs, and actual OS IME testing remains deferred.
331
+
332
+ ## Matrix cell editing — workspace
333
+
334
+ Drag across matrix cells or Shift+click another cell to select a rectangle. For
335
+ keyboard selection, choose **Select cells**, then extend with Shift+arrows;
336
+ **Select all cells** selects the whole matrix. Copy and cut include nested formulas.
337
+ Delete clears selected contents while keeping the grid; typing replaces the
338
+ rectangle with text in its upper-left cell. Enter or Escape returns to editing.
339
+
340
+ Paste a copied rectangle into a matching selection, or start at one cell and let
341
+ the matrix grow within 20 × 20. A single copied cell fills a larger selection.
342
+ Rectangular tab-separated spreadsheet text is also accepted inside matrices;
343
+ ragged or mismatched shapes fail without partial writes. Copied cells pasted
344
+ outside a matrix become a new matrix. The plain-text clipboard fallback is LaTeX.
345
+
346
+ **Transpose matrix** exchanges all rows and columns, preserving the delimiter,
347
+ nested content and caret. Paste, cut, clear and transpose each take one Undo.
348
+ These operations are available in both renderers and the framework-free
349
+ [session API](https://math-editor.barocss.com/docs/api-session.html#matrix-cell-selections).
350
+
351
+ ## Style customization
352
+
353
+ 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.
354
+
355
+ ## License
356
+
357
+ MIT License. Copyright (c) 2026 barocss.com.
358
+
359
+ The npm package includes the full license in `LICENSE`. Bundled KaTeX fonts retain
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).
package/RELEASING.md CHANGED
@@ -1,31 +1,102 @@
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` and the nine public host plugins. All use MIT, public npm
8
+ access and the `latest` tag. Framework adapters are core subpaths and share the
9
+ core version. The private integration workspace and other products are excluded.
10
+
11
+ The published baseline is core **0.4.0** and host plugins **0.1.0**. Later versions
12
+ remain independent; a batch release does not force every package to change.
4
13
 
5
14
  ## Local release
6
15
 
7
16
  ```sh
8
17
  # 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:
18
+ npm login --registry=https://registry.npmjs.org/
19
+ # After reviewing versions, changelogs and browser validation:
12
20
  pnpm release:math
13
21
  ```
14
22
 
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.
23
+ This one command runs release-tool tests, core formatting/type/unit checks,
24
+ integration type/unit checks, builds and package validation. It verifies the core
25
+ entry points and each plugin's packed declarations, runtime imports and required
26
+ files. It then runs **one `pnpm -r publish` command** for the ten allowed names.
27
+ `pnpm release` is an alias for this workflow.
28
+
29
+ Only the inspected package contents enter a generated workspace under
30
+ `output/math-batch-releases/release-*/`. Wrapper manifests use
31
+ `publishConfig.directory` to point at those contents. They give pnpm an explicit
32
+ core-first dependency order without adding dependencies to the published plugin
33
+ manifests. Publish lifecycle scripts are disabled because validation and builds
34
+ already ran. Git checks are disabled only for this generated workspace.
35
+
36
+ pnpm checks npm and skips package versions that already exist. It packs the
37
+ inspected contents again, so the final archive checksum can differ from the
38
+ preparation archive. The batch is not an atomic registry transaction. npm may
39
+ still request authentication for individual packages; one command does not
40
+ guarantee one authentication prompt.
41
+
42
+ For checks without publishing:
43
+
44
+ ```sh
45
+ # Build and inspect all ten packages. No registry publication.
46
+ pnpm release:math:prepare
47
+ # Also exercise recursive publishing with npm's dry-run flag.
48
+ # This can read registry metadata; it does not upload packages.
49
+ pnpm release:math:dry-run
50
+ ```
51
+
52
+ `release.json` records the candidate versions, artifact hashes and command status.
53
+ On success, `pnpm-publish-summary.json` lists newly published packages; versions
54
+ skipped by pnpm are absent. A dry-run summary is not evidence of publication.
55
+ If publishing fails, preserve the report and check each candidate version on npm.
56
+ pnpm 8 may not write its summary after a partial failure. Resolve any uncertain
57
+ results before running the batch again; never use `--force` to retry.
16
58
 
17
59
  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
60
 
19
61
  ## Subsequent versions
20
62
 
21
- 1. Run `pnpm changeset`, select only `@barocss/math-editor`, and write a user-facing change summary.
63
+ 1. Run `pnpm changeset`, select the affected math core and/or public plugins, and write a user-facing change summary.
22
64
  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.
65
+ 3. Run `pnpm version:math:plan` to preview the core and nine plugin 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
66
  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.
67
+ 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.
68
+
69
+ Versioning is separate from publishing. Repeating a publish command must not create
70
+ another version. Avoid `pnpm version-packages` and unfiltered `pnpm -r publish`
71
+ for a math-only release because they can include other products.
26
72
 
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.
73
+ The [host release guide](../math-editor-integrations/docs/RELEASING.md) lists the
74
+ nine plugins and explains changes to shared implementation. For an explicit
75
+ core-only release, use `pnpm version:math:core`,
76
+ `pnpm release:math:core:prepare` and `pnpm release:math:core`.
28
77
 
29
78
  ## Website
30
79
 
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.
80
+ `apps/math-demo` remains the site source. The static deployment repository is
81
+ `barocss/math-editor-site`, with GitHub Pages at `math-editor.barocss.com`.
82
+ Build the site directly from workspace source:
83
+
84
+ ```sh
85
+ pnpm build:math:site
86
+ ```
87
+
88
+ This builds the main site and the nine-plugin integration sample without a core
89
+ tarball, package `dist` build, npm login, registry lookup or publication check.
90
+ Workspace package exports resolve local source, including the private common
91
+ module. No package version bump is required to rebuild or deploy the site.
92
+ `release.json` records `source: "workspace-source"` and the local package versions
93
+ as metadata; those versions do not claim that the packages are published.
94
+
95
+ For an explicit package-artifact check, the previous command remains available:
96
+
97
+ ```sh
98
+ pnpm release:math:site /path/to/barocss-math-editor.tgz
99
+ ```
100
+
101
+ Both commands print the prepared static site directory and do not deploy it.
102
+ 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.