@barocss/math-editor 0.2.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ADAPTERS.md +25 -14
- package/API-JAVASCRIPT.md +1 -1
- package/API-REACT.md +5 -1
- package/API-SESSION.md +168 -6
- package/API-SOLID.md +1 -1
- package/API-SVELTE.md +1 -1
- package/API-VUE.md +1 -1
- package/API-WEB-COMPONENT.md +1 -1
- package/CHANGELOG.md +45 -0
- package/EMBEDDING.md +4 -0
- package/IMPLEMENTATION.md +27 -2
- package/JSON-MODEL.md +1 -0
- package/LATEX-GUIDE.md +8 -1
- package/LATEX-SCOPE.md +2 -2
- package/LICENSE +1 -3
- package/README.md +145 -37
- package/ROADMAP.md +93 -11
- package/STYLING.md +157 -0
- package/SUPPORT.md +24 -12
- package/VALIDATION.md +113 -4
- package/dist/core.d.ts +5 -1
- package/dist/core.js +5 -1
- package/dist/document-codec.d.ts +0 -1
- package/dist/document-codec.js +0 -1
- package/dist/dom/caret-geometry.d.ts +3 -0
- package/dist/dom/caret-geometry.js +41 -0
- package/dist/dom/elements.d.ts +1 -2
- package/dist/dom/elements.js +2 -3
- package/dist/dom/latex-panel.d.ts +10 -0
- package/dist/dom/latex-panel.js +59 -0
- package/dist/dom/matrix-selection.d.ts +11 -0
- package/dist/dom/matrix-selection.js +30 -0
- package/dist/dom/menu-position.d.ts +14 -2
- package/dist/dom/menu-position.js +84 -15
- package/dist/dom/presentation-controls.d.ts +4 -0
- package/dist/dom/presentation-controls.js +56 -0
- package/dist/dom/quick-panel.d.ts +12 -0
- package/dist/dom/quick-panel.js +102 -0
- package/dist/dom/selection.d.ts +29 -0
- package/dist/dom/selection.js +53 -0
- package/dist/dom/symbol-panel.d.ts +9 -0
- package/dist/dom/symbol-panel.js +146 -0
- package/dist/dom/theme.d.ts +6 -0
- package/dist/dom/theme.js +68 -0
- package/dist/dom/toolbar-catalog.d.ts +10 -0
- package/dist/dom/toolbar-catalog.js +35 -0
- package/dist/dom/toolbar.d.ts +13 -2
- package/dist/dom/toolbar.js +295 -28
- package/dist/dom.d.ts +7 -1
- package/dist/dom.js +510 -128
- package/dist/editor-labels.d.ts +0 -1
- package/dist/editor-labels.js +0 -1
- package/dist/enter-policy.d.ts +0 -1
- package/dist/enter-policy.js +0 -1
- package/dist/fences.d.ts +0 -1
- package/dist/fences.js +0 -1
- package/dist/i18n.d.ts +0 -1
- package/dist/i18n.js +0 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +4 -1
- package/dist/latex-insertion.d.ts +12 -0
- package/dist/latex-insertion.js +26 -0
- package/dist/latex-paste-panel.d.ts +3 -0
- package/dist/latex-paste-panel.js +18 -0
- package/dist/latex.d.ts +0 -1
- package/dist/latex.js +0 -1
- package/dist/lines.d.ts +0 -1
- package/dist/lines.js +0 -1
- package/dist/locales/en.js +27 -1
- package/dist/locales/en.json +27 -1
- package/dist/locales/ko.js +27 -1
- package/dist/locales/ko.json +27 -1
- package/dist/math-editor-toolbar.d.ts +4 -2
- package/dist/math-editor-toolbar.js +3 -4
- package/dist/math-editor.d.ts +5 -2
- package/dist/math-editor.js +285 -46
- package/dist/matrix-range.d.ts +40 -0
- package/dist/matrix-range.js +242 -0
- package/dist/matrix.d.ts +0 -1
- package/dist/matrix.js +0 -1
- package/dist/model.d.ts +0 -1
- package/dist/model.js +0 -1
- package/dist/outputs.d.ts +0 -1
- package/dist/outputs.js +0 -1
- package/dist/preferences.d.ts +24 -0
- package/dist/preferences.js +66 -0
- package/dist/presentation-controls.d.ts +10 -0
- package/dist/presentation-controls.js +10 -0
- package/dist/presentation.d.ts +13 -0
- package/dist/presentation.js +86 -0
- package/dist/quick-panel.d.ts +2 -0
- package/dist/quick-panel.js +17 -0
- package/dist/range.d.ts +2 -1
- package/dist/range.js +11 -1
- package/dist/react.d.ts +0 -1
- package/dist/react.js +0 -1
- package/dist/session.d.ts +31 -2
- package/dist/session.js +108 -7
- package/dist/solid.d.ts +0 -1
- package/dist/solid.js +0 -1
- package/dist/suggestions.d.ts +4 -1
- package/dist/suggestions.js +100 -12
- package/dist/svelte.d.ts +0 -1
- package/dist/svelte.js +0 -1
- package/dist/symbol-browser.d.ts +0 -1
- package/dist/symbol-browser.js +0 -1
- package/dist/symbols.d.ts +0 -1
- package/dist/symbols.js +0 -1
- package/dist/templates.d.ts +0 -1
- package/dist/templates.js +0 -1
- package/dist/tokens.d.ts +0 -1
- package/dist/tokens.js +0 -1
- package/dist/vertical-navigation.d.ts +15 -0
- package/dist/vertical-navigation.js +145 -0
- package/dist/vue.d.ts +0 -1
- package/dist/vue.js +0 -1
- package/dist/web-component.d.ts +0 -1
- package/dist/web-component.js +0 -1
- package/package.json +1 -1
- package/src/style.css +254 -129
- package/dist/core.d.ts.map +0 -1
- package/dist/core.js.map +0 -1
- package/dist/document-codec.d.ts.map +0 -1
- package/dist/document-codec.js.map +0 -1
- package/dist/dom/elements.d.ts.map +0 -1
- package/dist/dom/elements.js.map +0 -1
- package/dist/dom/menu-position.d.ts.map +0 -1
- package/dist/dom/menu-position.js.map +0 -1
- package/dist/dom/toolbar.d.ts.map +0 -1
- package/dist/dom/toolbar.js.map +0 -1
- package/dist/dom.d.ts.map +0 -1
- package/dist/dom.js.map +0 -1
- package/dist/editor-labels.d.ts.map +0 -1
- package/dist/editor-labels.js.map +0 -1
- package/dist/enter-policy.d.ts.map +0 -1
- package/dist/enter-policy.js.map +0 -1
- package/dist/fences.d.ts.map +0 -1
- package/dist/fences.js.map +0 -1
- package/dist/i18n.d.ts.map +0 -1
- package/dist/i18n.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/latex.d.ts.map +0 -1
- package/dist/latex.js.map +0 -1
- package/dist/lines.d.ts.map +0 -1
- package/dist/lines.js.map +0 -1
- package/dist/math-editor-toolbar.d.ts.map +0 -1
- package/dist/math-editor-toolbar.js.map +0 -1
- package/dist/math-editor.d.ts.map +0 -1
- package/dist/math-editor.js.map +0 -1
- package/dist/matrix.d.ts.map +0 -1
- package/dist/matrix.js.map +0 -1
- package/dist/model.d.ts.map +0 -1
- package/dist/model.js.map +0 -1
- package/dist/outputs.d.ts.map +0 -1
- package/dist/outputs.js.map +0 -1
- package/dist/range.d.ts.map +0 -1
- package/dist/range.js.map +0 -1
- package/dist/react.d.ts.map +0 -1
- package/dist/react.js.map +0 -1
- package/dist/session.d.ts.map +0 -1
- package/dist/session.js.map +0 -1
- package/dist/solid.d.ts.map +0 -1
- package/dist/solid.js.map +0 -1
- package/dist/suggestions.d.ts.map +0 -1
- package/dist/suggestions.js.map +0 -1
- package/dist/svelte.d.ts.map +0 -1
- package/dist/svelte.js.map +0 -1
- package/dist/symbol-browser.d.ts.map +0 -1
- package/dist/symbol-browser.js.map +0 -1
- package/dist/symbols.d.ts.map +0 -1
- package/dist/symbols.js.map +0 -1
- package/dist/templates.d.ts.map +0 -1
- package/dist/templates.js.map +0 -1
- package/dist/tokens.d.ts.map +0 -1
- package/dist/tokens.js.map +0 -1
- package/dist/vue.d.ts.map +0 -1
- package/dist/vue.js.map +0 -1
- package/dist/web-component.d.ts.map +0 -1
- package/dist/web-component.js.map +0 -1
package/ADAPTERS.md
CHANGED
|
@@ -79,7 +79,7 @@ import { MathEditorSurface } from '@barocss/math-editor/react';
|
|
|
79
79
|
<MathEditorSurface locale="en" mode="inline" toolbar={false} onChange={save} />
|
|
80
80
|
```
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
`MathEditor` keeps the rich React renderer and token-level active input. `MathEditorSurface` uses the native renderer and session options. The workspace native toolbar now includes the symbol browser, templates and grid context controls described below; these additions are included in 0.4.0. The renderers share document formats but own separate history instances. See the remaining differences below.
|
|
83
83
|
|
|
84
84
|
## Web Component
|
|
85
85
|
|
|
@@ -141,20 +141,24 @@ The directive reads its accessor in a reactive effect and cleans up with `onClea
|
|
|
141
141
|
|
|
142
142
|
| Capability | Existing React `MathEditor` | Native surface and all wrappers |
|
|
143
143
|
|---|---|---|
|
|
144
|
-
|
|
|
144
|
+
| Structure, symbol and template catalog | Yes | Same model and suggestion catalog |
|
|
145
|
+
| Suggestion and selection menu presentation | Glyph, name, detail and keyboard guidance | Same presentation in the 0.4.0 release; options scroll independently of the host |
|
|
145
146
|
| Multiline block, grids and grid keyboard commands | Yes | Implemented; representative Chromium coverage |
|
|
146
147
|
| Single top-level row inline policy | No dedicated prop | Yes |
|
|
147
148
|
| Separately mounted/custom toolbar | Not a session API | Yes |
|
|
148
149
|
| English/Korean/custom locale registry | Yes | Yes |
|
|
149
|
-
| Active input granularity | Lexical token |
|
|
150
|
-
| Variable/constant/symbol colors | Editing and preview |
|
|
151
|
-
| Pointer range, structural clipboard, wrapping |
|
|
152
|
-
| Drag starting inside the active input across structures | Yes |
|
|
153
|
-
| Searchable all-symbol panel, matrix
|
|
154
|
-
|
|
|
155
|
-
|
|
|
156
|
-
|
|
157
|
-
|
|
150
|
+
| Active input granularity | Lexical token | Lexical token (workspace) |
|
|
151
|
+
| Variable/constant/symbol colors | Editing and preview | Editing and preview (workspace); named functions retain their own color |
|
|
152
|
+
| Pointer range, structural clipboard, wrapping | Yes | Exact partial-text highlights included in 0.4.0 |
|
|
153
|
+
| Drag starting inside the active input across structures | Yes | Implemented in workspace; local input selection becomes a model range after leaving the input |
|
|
154
|
+
| Searchable all-symbol panel, templates and matrix presets | Yes | Available through More tools in 0.4.0 |
|
|
155
|
+
| Matrix rectangles, shape-checked clipboard and transpose | Implemented in workspace | Implemented in workspace |
|
|
156
|
+
| Active grid row/column and delimiter controls | Yes | Implemented in workspace; aligned/cases expose row controls |
|
|
157
|
+
| Shift+arrow model ranges | Yes | Yes; vertical extension uses logical line offsets |
|
|
158
|
+
| Composition candidate preview | Disabled choices while composing | Menu hidden and toolbar mutations disabled while composing |
|
|
159
|
+
| OS IME matrix / full accessibility audit | Deferred / pending | Deferred / pending |
|
|
160
|
+
|
|
161
|
+
The native renderer remains an integration preview. Its active input now covers one lexical token, with model offsets mapped across token boundaries. Composition keeps that input stable until commit. A persistent preferred column for vertical navigation, and a full accessibility/browser audit remain open. Complete English/Korean packs are bundled; additional complete packs and native OS IME validation remain deferred work. The new toolbar and selection UI use existing model operations and add no LaTeX syntax. Use `parseMathDocument` to validate schema and IDs before trusted document loading. Bounded LaTeX import is available through `importLatex`; ordinary plain-text paste remains literal. The workspace adds explicit `pasteLatex` and Alt+Shift+V insertion, recent/favorite items, and contextual presentation controls; see [editing utilities](API-SESSION.md#editing-utilities--workspace).
|
|
158
162
|
|
|
159
163
|
## Local verification and packaging
|
|
160
164
|
|
|
@@ -178,7 +182,9 @@ The DOM entry also exports `mountMathLatex` and `mountMathPreview`. See [Embeddi
|
|
|
178
182
|
|
|
179
183
|
## Compact and filtered toolbars (workspace)
|
|
180
184
|
|
|
181
|
-
Toolbars initially show up to eight structure buttons. More tools / Fewer tools toggles the
|
|
185
|
+
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 More tools also exposes the searchable All symbols panel, templates, 2×2/3×3/4×4 matrix and identity presets, and symbol shortcuts. It remains available when every selected structure button already fits. Undo and Redo stay visible; rich React also retains its `toolbarEnd` slot. The layout wraps on narrow screens.
|
|
186
|
+
|
|
187
|
+
The native grid toolbar follows the active caret: matrices expose row/column insertion and deletion plus delimiter selection; aligned/cases expose row operations. A text or model selection disables these grid mutations. These native toolbar additions are included in 0.4.0. See [the session toolbar API](API-SESSION.md#independent-toolbar-and-outputs) for attaching, disabling and destroying an external toolbar.
|
|
182
188
|
|
|
183
189
|
```tsx
|
|
184
190
|
<MathEditor toolbar={['fraction', 'root', 'superscript', 'matrix']}
|
|
@@ -186,7 +192,8 @@ Toolbars initially show up to eight structure buttons. More tools / Fewer tools
|
|
|
186
192
|
```
|
|
187
193
|
|
|
188
194
|
```js
|
|
189
|
-
mountMathEditor(host,
|
|
195
|
+
mountMathEditor(host, {
|
|
196
|
+
session,
|
|
190
197
|
toolbar: ['fraction', 'root', 'norm'],
|
|
191
198
|
toolbarMaxItems: 2,
|
|
192
199
|
});
|
|
@@ -196,4 +203,8 @@ mountMathToolbar(toolbarHost, session, {
|
|
|
196
203
|
});
|
|
197
204
|
```
|
|
198
205
|
|
|
199
|
-
`toolbar: false` hides the toolbar. A structure array filters
|
|
206
|
+
`toolbar: false` hides the toolbar. A structure array filters visible structure buttons. The workspace native toolbar also filters templates by all their structure kinds and limits matrix presets/context controls to allowed grid 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 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; the native discovery/context additions are included in 0.4.0.
|
|
207
|
+
|
|
208
|
+
## Style customization
|
|
209
|
+
|
|
210
|
+
Use inherited CSS variables for colors, slot backgrounds, typography, toolbar density and menu appearance. Scoped themes also follow portaled suggestions in both renderers. See [Styling & themes](STYLING.md) for the public variables, dark/monochrome examples, shared toolbars and iframe/plugin sizing.
|
package/API-JAVASCRIPT.md
CHANGED
package/API-REACT.md
CHANGED
|
@@ -10,7 +10,7 @@ React offers two components. Choose intentionally: they share document structure
|
|
|
10
10
|
## Install
|
|
11
11
|
|
|
12
12
|
```sh
|
|
13
|
-
npm install @barocss/math-editor@0.
|
|
13
|
+
npm install @barocss/math-editor@0.4.0 react react-dom
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
## Rich editor
|
|
@@ -200,3 +200,7 @@ Import validates the whole expression and host `multiline`/`excludedStructures`
|
|
|
200
200
|
Use `autoFocus`, `toolbar={false}`, `showTokenLegend={false}`, `showLineNumbers={false}` and `enterBehavior="commit"` for an in-place rich editor. Keep `onChange` in a local draft, commit that draft in `onCommit`, and discard it in `onCancel`. Suggestions and selection wrapping take priority over Enter; Escape closes suggestions before requesting cancellation. IME composition reserves its keys. `Shift+Enter` retains normal line/grid behavior subject to `multiline`.
|
|
201
201
|
|
|
202
202
|
Wrap the editor in a non-editable island when embedding inside contenteditable. The host must exclude nested events, selections and renderer mutations from its own text pipeline. Do not save a host transaction for every math keystroke. Set `--me-font-size` on the wrapper to scale token previews and inputs together; its default is22px.
|
|
203
|
+
|
|
204
|
+
## Workspace editing utilities
|
|
205
|
+
|
|
206
|
+
The rich editor and native surface now share explicit LaTeX insertion, recent/favorite items and contextual presentation controls. `MathEditorHandle.pasteLatex(source)` inserts at the caret/range; `importLatex` still replaces the whole formula. Supply a `preferences` store from `createMathPreferences()` to share favorites across editor instances. The default is instance-local memory. See the [full utility API and keyboard behavior](API-SESSION.md#editing-utilities--workspace).
|
package/API-SESSION.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Session and native DOM API reference
|
|
2
2
|
|
|
3
|
-
This reference applies to pure JavaScript, `MathEditorSurface`, Web Component, Vue, Svelte and Solid native integrations in 0.2.0. Rich React `MathEditor` owns separate history and has its own [props](API-REACT.md).
|
|
3
|
+
This reference applies to pure JavaScript, `MathEditorSurface`, Web Component, Vue, Svelte and Solid native integrations. The base session/DOM API is available in 0.2.0; the native discovery/context toolbar, `setDisabled` and precise pointer-selection changes below are additions in 0.4.0. Rich React `MathEditor` owns separate history and has its own [props](API-REACT.md).
|
|
4
4
|
|
|
5
5
|
## Imports
|
|
6
6
|
|
|
@@ -21,20 +21,75 @@ import '@barocss/math-editor/style.css';
|
|
|
21
21
|
|
|
22
22
|
| Method | Contract |
|
|
23
23
|
|---|---|
|
|
24
|
-
| `getSnapshot()` | Copy containing `state`, optional `range`, `locale`, `mode`, `canUndo`, `canRedo`, `latex` |
|
|
24
|
+
| `getSnapshot()` | Copy containing `state`, optional `range` / `matrixRange`, `locale`, `mode`, `canUndo`, `canRedo`, `latex` |
|
|
25
25
|
| `subscribe(listener)` | Listener receives `(snapshot, documentChanged)`; returns unsubscribe |
|
|
26
|
-
| `execute(command)` | Boolean result; text/structure/template/newline/undo/redo |
|
|
26
|
+
| `execute(command)` | Boolean result; text/structure/template/newline/undo/redo and matrix selection/clear/transpose |
|
|
27
27
|
| `apply(state)` | Apply `MathState`; returns false for invalid inline multiline state |
|
|
28
28
|
| `select(caret)` | Set `MathCaret`, clear structural range, emit non-document change |
|
|
29
29
|
| `selectRange(range?)` | Set/clear `MathRange`, emit non-document change |
|
|
30
|
+
| `selectMatrixRange(range?)` | Validate and set/clear a cell rectangle; clear structural range, emit non-document change; false leaves state unchanged |
|
|
31
|
+
| `copyMatrix()` | Copy selected cells as `MathMatrixFragment`, or undefined |
|
|
32
|
+
| `pasteMatrix(fragment)` | Paste at the selected rectangle or active matrix cell as one edit; false leaves document, selection and history unchanged |
|
|
30
33
|
| `configure({ locale?, mode? })` | Keep document/history; throws on multiline-to-inline change |
|
|
31
34
|
| `load(document)` | Open trusted document and reset history/range; emits document change |
|
|
32
|
-
| `copy()` | `MathFragment` for structural range
|
|
35
|
+
| `copy()` | `MathFragment` for structural range; matrix rectangle becomes a single-matrix fragment; otherwise undefined |
|
|
33
36
|
| `paste(fragment)` | Boolean result; rejects multiline in inline mode |
|
|
34
37
|
| `destroy()` | Release subscribers; host must also destroy renderers/tools |
|
|
35
38
|
|
|
36
39
|
A snapshot's `state` contains `document` and `caret`. Never mutate a snapshot expecting it to affect the session. Use a command or `apply` instead. `false` is also returned for undo/redo when no history change occurs; it is not always an error.
|
|
37
40
|
|
|
41
|
+
## Matrix cell selections
|
|
42
|
+
|
|
43
|
+
Available in 0.4.0. `MathRange` and `MathMatrixRange` are
|
|
44
|
+
mutually exclusive. `select(caret)`, document changes, load and Undo/Redo clear cell
|
|
45
|
+
selection. Selecting cells does not emit a document change or create history.
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
import { createMathSession } from '@barocss/math-editor/core';
|
|
49
|
+
|
|
50
|
+
const session = createMathSession({ document: savedDocument });
|
|
51
|
+
// Assume a loaded matrix has three columns; select rows 1–2, columns 2–3.
|
|
52
|
+
session.selectMatrixRange({ matrixId, anchor: 1, focus: 5 });
|
|
53
|
+
const cells = session.copyMatrix();
|
|
54
|
+
// Move to another matrix/cell or select its destination rectangle first.
|
|
55
|
+
if (cells && !session.pasteMatrix(cells)) {
|
|
56
|
+
// The destination shape or 20 × 20 bound rejected this paste; no partial write.
|
|
57
|
+
}
|
|
58
|
+
session.execute({ type: 'matrix-select' }); // Current cell, ready for Shift+arrows.
|
|
59
|
+
session.execute({ type: 'matrix-select', all: true });
|
|
60
|
+
session.execute({ type: 'matrix-clear' });
|
|
61
|
+
session.execute({ type: 'matrix-transpose' }); // Entire selected/active matrix.
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
`MathMatrixRange` is `{ matrixId: string, anchor: number, focus: number }`.
|
|
65
|
+
Endpoints are zero-based row-major cell indices. Reversed endpoints work; bounds
|
|
66
|
+
are derived from row and column coordinates, not the linear span between indices.
|
|
67
|
+
`MathMatrixFragment` is `{ version: 1, columns, cells: MathRow[], environment }`.
|
|
68
|
+
Its `cells` are row-major and may contain any supported nested formula.
|
|
69
|
+
|
|
70
|
+
| Destination | Paste behavior |
|
|
71
|
+
| --- | --- |
|
|
72
|
+
| Caret in a matrix or one selected cell | Replace whole cells from that anchor; grow/pad the matrix up to 20 × 20 |
|
|
73
|
+
| Larger selected rectangle | Require matching dimensions; a single copied cell fills every selected cell |
|
|
74
|
+
| Different rectangle dimensions, invalid payload or size overflow | Return false with no write, selection change or history entry |
|
|
75
|
+
| Outside a matrix in the browser UI | Insert the copied rectangle as a new matrix through its normal math-fragment fallback |
|
|
76
|
+
|
|
77
|
+
Pasting keeps the destination delimiter, preserves unselected cells, and assigns
|
|
78
|
+
fresh IDs recursively to inserted content. Typing over a cell selection clears
|
|
79
|
+
its contents and inserts text into the upper-left cell. Delete/Cut clear contents
|
|
80
|
+
without deleting rows or columns. Enter/Escape resumes editing; Shift+arrows
|
|
81
|
+
extends the rectangle. Transpose reorders the entire matrix, retaining existing
|
|
82
|
+
cell IDs, delimiter and nested caret. Each content operation takes one Undo.
|
|
83
|
+
|
|
84
|
+
Browser clipboard handlers write `MATH_MATRIX_CLIPBOARD_TYPE`
|
|
85
|
+
(`application/x-barocss-math-matrix+json`), the existing math fragment MIME, and
|
|
86
|
+
plain LaTeX. Read external matrix payloads with `parseMatrixFragment`; normal
|
|
87
|
+
`parseFragment` remains the structural clipboard parser. `paste(fragment)` does
|
|
88
|
+
not overwrite a cell rectangle: use `pasteMatrix` for that operation. Tab-separated
|
|
89
|
+
spreadsheet data inside a matrix is treated as cell text, not interpreted LaTeX.
|
|
90
|
+
Clipboard formats can be stripped by other applications; OS interoperability is
|
|
91
|
+
a separate check. Neither selection nor clipboard metadata changes MathDocument v1.
|
|
92
|
+
|
|
38
93
|
## Commands
|
|
39
94
|
|
|
40
95
|
```ts
|
|
@@ -46,7 +101,7 @@ session.execute({ type: 'undo' });
|
|
|
46
101
|
session.execute({ type: 'redo' });
|
|
47
102
|
```
|
|
48
103
|
|
|
49
|
-
These examples assume an existing session.
|
|
104
|
+
These examples assume an existing session. `kind` accepts the exported `StructureKind`; see the [structure catalog](JSON-MODEL.md) for the current kinds and slot contracts. A selected structural range can only wrap in supported wrapping kinds. Use exported grid helpers plus `apply()` for grid resizing; there is no `execute({ type: 'resizeMatrix' })` command.
|
|
50
105
|
|
|
51
106
|
## mountMathEditor(host, options)
|
|
52
107
|
|
|
@@ -57,19 +112,32 @@ These examples assume an existing session. Structure kinds: `fraction`, `root`,
|
|
|
57
112
|
| `session` | Host session; mount-only; survives renderer destruction |
|
|
58
113
|
| `defaultValue` | Trusted document for an internally created session; mount-only |
|
|
59
114
|
| `menuHost` | Suggestion portal HTMLElement; mount-only; nearest native dialog or body by default |
|
|
115
|
+
| `menuAvoidElements` | Workspace: optional callback returning host controls the suggestion menu should avoid; measured in their current position when the menu opens or moves |
|
|
60
116
|
| `locale`, `mode` | Configure locale/mode; same defaults as session |
|
|
61
117
|
| `toolbar` | Boolean or readonly structure kind list; block defaults on, inline off |
|
|
118
|
+
| `toolbarMaxItems` | Initially visible structure buttons; defaults to eight; More tools reveals the expanded controls |
|
|
62
119
|
| `showLineNumbers` | Whether UI-only multiline gutter is displayed |
|
|
63
120
|
| `enterBehavior` | `newline` or `commit`; block defaults newline, inline commit |
|
|
64
121
|
| `onChange(document, latex)` | Committed document changes |
|
|
122
|
+
| `onRender()` | Workspace: final DOM/caret notification, including focus and selection-only updates; no automatic model write |
|
|
65
123
|
| `onCommit(snapshot)` | Host completion request; no automatic save or block creation |
|
|
66
124
|
| `onCancel()` | Escape after dismissing suggestions/grid state; host decides whether to close |
|
|
67
125
|
| `onExit(direction)` | Host caret handoff, `-1` before or `1` after |
|
|
68
126
|
|
|
69
127
|
Return value: `{ session, focus(), update(options), destroy() }`. `update` accepts mutable options only and merges them. Locale updates preserve history. Do not pass a fresh session to `update`; recreate the renderer if changing ownership.
|
|
70
128
|
|
|
129
|
+
`onRender` runs synchronously after the native surface/menu update, before host mutation observers reconcile their selections. It can also run during initial mounting, before `mountMathEditor` returns. Hosts can inspect the current input and schedule caret restoration; avoid issuing commands or calling `focus()` from the callback, which can trigger another render. This notification is distinct from `onChange` and does not imply a document or history change. It is available in 0.4.0.
|
|
130
|
+
|
|
131
|
+
Notifications are suppressed during composition and after teardown. A notification does not guarantee that an input is focused. Any deferred caret restoration should check that its input is still connected and focused, so a later callback cannot revive a closed draft or steal focus from another control.
|
|
132
|
+
|
|
71
133
|
Inline mode means one top-level row, not a fixed visual height. It rejects newline commands and multiline paste and throws when loading multiline documents. Enter accepts suggestions first; grid keyboard operations have their own priority. CSS alone cannot establish these model constraints.
|
|
72
134
|
|
|
135
|
+
For a compact draft, pass `menuAvoidElements: () => [actionsElement]` to keep
|
|
136
|
+
suggestions clear of Apply, Cancel and tool-expansion controls. The callback can
|
|
137
|
+
return elements added after mounting. Placement remains constrained by the
|
|
138
|
+
viewport and clipping ancestors; the menu scrolls when the available gap is short.
|
|
139
|
+
This option changes presentation only and adds no model data.
|
|
140
|
+
|
|
73
141
|
## Saving without caret-only writes
|
|
74
142
|
|
|
75
143
|
```ts
|
|
@@ -84,10 +152,43 @@ If a server persists changes asynchronously, debounce/serialize writes and handl
|
|
|
84
152
|
|
|
85
153
|
## Independent toolbar and outputs
|
|
86
154
|
|
|
87
|
-
`mountMathToolbar(host,
|
|
155
|
+
`mountMathToolbar(host, sessionOrNull, { kinds?, maxItems?, locale?, onExecute? })` mounts a toolbar whose current workspace handle exposes:
|
|
156
|
+
|
|
157
|
+
| Method | Contract |
|
|
158
|
+
|---|---|
|
|
159
|
+
| `setSession(sessionOrNull)` | Switch the active draft subscription; `null` disables mutations; switching/detaching closes symbol search |
|
|
160
|
+
| `setDisabled(boolean)` | Disable mutations while keeping the session attached; disabling closes symbol search; restore with `false` after composition |
|
|
161
|
+
| `destroy()` | Remove the toolbar, its panels and session subscription |
|
|
162
|
+
|
|
163
|
+
`maxItems` defaults to eight. `locale` supplies labels before a session is attached; an active session supplies its own locale. Use `onExecute: () => editor.focus()` to return focus after a successful command. Opening or searching the symbol browser leaves focus in that browser. The toolbar uses the session's caret/range even when the math input has blurred.
|
|
164
|
+
|
|
165
|
+
The workspace More tools section exposes the full symbol catalog with search, templates, matrix/identity presets and symbol shortcuts. `kinds` filters structure buttons, templates containing excluded kinds, and grid presets/context controls; it does not limit model or parser support. Active matrices provide row/column operations and delimiter selection; aligned/cases provide row operations. Grid mutations are disabled while text or a model range is selected. The symbol panel stays inside its toolbar host, and Escape closes it without requesting host Cancel.
|
|
166
|
+
|
|
167
|
+
An internally mounted toolbar is disabled during native formula composition. Hosts mounting an independent toolbar must coordinate composition with `setDisabled`, or temporarily detach with `setSession(null)`. Host integrations also own containment: keep the toolbar and its panels inside the declared `toolbarHost` so an outside-click handler does not commit the draft while browsing. See [adapter embedding](ADAPTERS.md) for lifecycle ownership.
|
|
168
|
+
|
|
169
|
+
`mountMathLatex(host, session)` renders derived LaTeX and returns `destroy()`.
|
|
88
170
|
|
|
89
171
|
`mountMathPreview(host, session, { render(host, snapshot) })` delegates rendering to your application. `render` may return a cleanup function. The math-editor package does not ship KaTeX as a runtime requirement; import your chosen renderer separately. All output handles must be destroyed when their hosts are removed.
|
|
90
172
|
|
|
173
|
+
The website's sized PNG download/copy controls belong to its preview renderer. They are not native DOM/session image-export methods; a reusable library SVG/PNG export API remains future work.
|
|
174
|
+
|
|
175
|
+
## Native selection behavior
|
|
176
|
+
|
|
177
|
+
Shift+Left/Right extends or shrinks a model range; Shift+Up/Down extends across top-level lines using logical offsets. In the workspace, passive highlights cover exact selected text endpoints. Dragging within the active input keeps native text selection; crossing its boundary can extend a model range across structures. Structural normalization remains unchanged: a `MathRange` crossing fraction slots or matrix cells selects their common structure. Cross-cell pointer gestures instead create a separate `MathMatrixRange` in the workspace; see the matrix selection contract above.
|
|
178
|
+
|
|
179
|
+
After a model selection, plain Left/Up restores the caret at its document-ordered
|
|
180
|
+
start; Right/Down restores it at the end. The same rule applies to reverse drags
|
|
181
|
+
and Shift+arrow selections, without consuming another character or changing the
|
|
182
|
+
formula. Alt+Up/Down browses the wrapping suggestions while retaining the range;
|
|
183
|
+
Enter applies a candidate. Ordinary input suggestions still use Up/Down.
|
|
184
|
+
|
|
185
|
+
The first Escape dismisses a selection's wrapping suggestions while preserving
|
|
186
|
+
the selection and draft. A subsequent Escape reaches the host Cancel callback.
|
|
187
|
+
Changing the selection or beginning a new pointer gesture makes suggestions
|
|
188
|
+
available again.
|
|
189
|
+
|
|
190
|
+
The active native input still edits a whole logical text run with one role color. Passive runs retain lexical colors. The cell-selection work adds full-matrix transpose through existing model structures; no new LaTeX grammar is needed. Native OS IME validation and additional complete locale packs remain deferred; see [renderer parity](ADAPTERS.md#current-renderer-parity) for remaining limits.
|
|
191
|
+
|
|
91
192
|
## Reusable browser-storage adapter with restore and error reporting
|
|
92
193
|
|
|
93
194
|
This adapter avoids writes for caret changes, debounces edits, flushes on page hide, and removes its listeners on teardown. Restore runs before subscribing so opening saved content does not immediately write it back. It does not validate documents itself: supply your application's schema validator as `decode`, which must throw for invalid or unsupported JSON. Use a different key per document. Call `dispose()` before changing the session's document/key.
|
|
@@ -161,3 +262,64 @@ if (!result.ok) {
|
|
|
161
262
|
This operation replaces the current formula in one undo step; redo restores the imported formula. Inline sessions reject multiple top-level lines before modifying state. All framework adapters using a session share this API; Web Components expose it as `element.session.importLatex(source)`.
|
|
162
263
|
|
|
163
264
|
For state-independent inspection, use `parseLatex(source, { multiline?, excludedStructures? })` from `/core`. For opening a different saved document, validate JSON with `parseMathDocument` and call `session.load`. Loading deliberately resets history, importing does not. See [the exact syntax contract](LATEX-SCOPE.md); arbitrary LaTeX macros are not supported. These APIs are available in 0.2.0.
|
|
265
|
+
|
|
266
|
+
## Editing utilities — workspace
|
|
267
|
+
|
|
268
|
+
These additions are included in 0.4.0. Earlier releases do not provide these APIs.
|
|
269
|
+
|
|
270
|
+
### LaTeX insertion
|
|
271
|
+
|
|
272
|
+
`session.pasteLatex(source)` inserts at the current caret or replaces the selected model range. It returns `LatexInsertionResult`: success includes the parsed document and resulting state; failure includes source offsets and diagnostics. It creates one Undo entry, leaves the caret after the inserted fragment, and generates fresh IDs. It does not reset history or replace the entire document. `importLatex(source)` continues to replace the whole formula.
|
|
273
|
+
|
|
274
|
+
```ts
|
|
275
|
+
const result = session.pasteLatex(String.raw`\frac{a}{b} + x_i^2`);
|
|
276
|
+
if (!result.ok) console.log(result.diagnostics);
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
Empty input, unsupported syntax, multiline insertion inside a nested slot or inline session, structures in literal text, and matrix-rectangle targets are rejected without changing document, caret, selection or history. Ordinary clipboard paste is still literal. More tools → Paste as LaTeX opens a nonmodal source field. Alt+Shift+V opens it even when the toolbar is hidden; Ctrl/Cmd+Enter inserts and Escape closes. The UI accepts a user paste and does not read the system clipboard automatically.
|
|
280
|
+
|
|
281
|
+
The pure `insertLatex(state, source, range?, options?)` helper supplies the same behavior without a session. The rich React `MathEditorHandle.pasteLatex` method applies the same helper with its multiline/excluded-structure policy.
|
|
282
|
+
|
|
283
|
+
### Recent items and favorites
|
|
284
|
+
|
|
285
|
+
`createMathPreferences(saved?)` creates a UI-only store. Each session has `session.preferences`; pass an existing store in `createMathSession({ preferences })` to share it. An internally owned native session also accepts mount-only `DOMMathEditorOptions.preferences`. Rich React accepts `preferences` as a prop.
|
|
286
|
+
|
|
287
|
+
```ts
|
|
288
|
+
import { createMathPreferences, createMathSession } from '@barocss/math-editor/core';
|
|
289
|
+
|
|
290
|
+
const preferences = createMathPreferences();
|
|
291
|
+
const first = createMathSession({ preferences });
|
|
292
|
+
const second = createMathSession({ preferences });
|
|
293
|
+
preferences.toggleFavorite('symbol-α');
|
|
294
|
+
preferences.toggleFavorite('template-quadratic');
|
|
295
|
+
const saved = preferences.getSnapshot(); // { version: 1, recent: [], favorites: [...] }
|
|
296
|
+
const restored = createMathPreferences(saved);
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
The default store lives in memory. The host can serialize `getSnapshot()` and use `subscribe(listener)` to persist changes; unsubscribe when finished. No localStorage, cookies, network calls or user identity are implicit. `record(id)` moves a known item to the front of the 12-entry recent list. `toggleFavorite(id)` adds/removes a favorite, bounded to 100. `clearRecent()` clears recents. Unknown IDs are ignored; restored lists are validated and deduplicated. These actions do not change formula JSON, document change callbacks or Undo.
|
|
300
|
+
|
|
301
|
+
More tools → Recent & favorites supplies search, All/Recent/Favorites filters and separate star buttons. Symbol/template selections are recorded; arbitrary typed text and full imported formulas are not stored. Toolbar template filters still apply. A preference store can outlive an individual editor.
|
|
302
|
+
|
|
303
|
+
### Contextual presentation settings
|
|
304
|
+
|
|
305
|
+
Place the caret inside a fence, fraction/binomial, or supported limit/sum/product/integral. The toolbar displays settings for the nearest applicable structure. Nested contents, IDs and caret remain unchanged. A structural or matrix range disables these settings.
|
|
306
|
+
|
|
307
|
+
```ts
|
|
308
|
+
import { activePresentation } from '@barocss/math-editor/core';
|
|
309
|
+
const target = activePresentation(session.getSnapshot().state);
|
|
310
|
+
if (target) session.execute({
|
|
311
|
+
type: 'presentation', id: target.id, change: { mathStyle: 'text' },
|
|
312
|
+
});
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
Choose the change appropriate to the target:
|
|
316
|
+
|
|
317
|
+
| Change | Accepted values | Applies to |
|
|
318
|
+
| --- | --- | --- |
|
|
319
|
+
| `fence` | `parentheses`, `brackets`, `braces`, `angle`, `absolute`, `norm`, `openClosed`, `closedOpen` | Structural fences; changes both ends together |
|
|
320
|
+
| `mathStyle` | `default`, `display`, `text` | Fractions and binomials |
|
|
321
|
+
| `limits` | `default`, `above-below`, `side` | Supported limit, sum/product and integral variants |
|
|
322
|
+
|
|
323
|
+
`default` removes the explicit metadata. `setMathPresentation(state, id, change)` is the pure equivalent. Unsupported changes or stale IDs return the original state; the session command returns false. This is presentation editing of existing syntax, not algebraic conversion or general TeX styling.
|
|
324
|
+
|
|
325
|
+
Toolbars expose `closePanels()` to dismiss their nonmodal utilities without editing the formula. `onOpenPanel` and `onPasteLatex` are optional mounting callbacks for a host that coordinates its own utility panels. Built-in surfaces keep only one utility/discovery panel open at a time.
|
package/API-SOLID.md
CHANGED
package/API-SVELTE.md
CHANGED
package/API-VUE.md
CHANGED
package/API-WEB-COMPONENT.md
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,50 @@
|
|
|
1
1
|
# @barocss/math-editor
|
|
2
2
|
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Exclude JavaScript and declaration source maps from the npm package. Verify their absence alongside the MIT license and runtime entry points during release preparation.
|
|
8
|
+
|
|
9
|
+
- Unify native token editing and role colors with the rich React editor. Preserve token-boundary navigation, deletion and composition in framework and host adapters.
|
|
10
|
+
|
|
11
|
+
Add explicit LaTeX insertion at the caret or selection through `pasteLatex` and a nonmodal paste form. Add shareable recent/favorite symbol and template preferences, plus contextual bracket, fraction-size and operator-limit controls. Preserve formula contents, IDs and undo boundaries, and document the APIs and unreleased scope in English and Korean UI packs.
|
|
12
|
+
|
|
13
|
+
## 0.3.0
|
|
14
|
+
|
|
15
|
+
### Minor Changes
|
|
16
|
+
|
|
17
|
+
- Recognize matrix dimensions such as `2x1`, `1x2`, `3x7` and `4x4` as suggestion shortcuts, including uppercase `X` and `×`. Support 1–20 rows and 1–20 columns. Offer matching empty and zero matrices, with identity matrices only for square sizes. Focus the first cell after insertion and keep row-order Tab editing. Preserve the typed expression until a candidate is accepted, keep surrounding terms, and restore the shortcut in one Undo.
|
|
18
|
+
|
|
19
|
+
- Match native suggestion and selection menus to the rich React presentation, with larger glyphs, descriptions, localized guidance and one scrollable options list. Short host panels prioritize selectable rows; keyboard navigation keeps the host page stationary.
|
|
20
|
+
|
|
21
|
+
- Add rectangular matrix-cell selection to both editing surfaces. Drag between cells or Shift-click to select a rectangle; use Select cells and Shift+arrows for keyboard selection. Copy/cut preserves nested formulas and writes a matrix clipboard payload alongside the existing fragment and LaTeX formats. Paste validates dimensions before applying, grows from a single-cell anchor within 20 × 20, and supports tab-separated cell text.
|
|
22
|
+
|
|
23
|
+
Add full-matrix transpose while preserving cell IDs, delimiters and nested caret positions. Cell paste, clear, cut and transpose are single history edits. Expose the selection and transformations through the framework-free session/core APIs, with English/Korean controls and updated documentation.
|
|
24
|
+
|
|
25
|
+
- Add native toolbar symbol search, editable formula templates, matrix presets and contextual row, column and delimiter controls. Keep additional tools behind More, preserve custom structure filters, and support composition disabling for independently mounted toolbars.
|
|
26
|
+
|
|
27
|
+
Highlight exact selected text segments and allow selection to extend from the active input across formula structures. Preserve ordinary native input selection, Shift-drag anchors, iframe document ownership, clipboard behavior and structural Undo.
|
|
28
|
+
|
|
29
|
+
- Add structural Up/Down navigation in the React and native DOM editors. Fractions,
|
|
30
|
+
scripts, indexed roots, annotations, grids, and equation lines choose a nearby
|
|
31
|
+
rendered caret position. The core `moveVertical` helper also works without a DOM.
|
|
32
|
+
|
|
33
|
+
Allow a separately mounted math toolbar to attach to the active editor through
|
|
34
|
+
`setSession(session)` and detach with `setSession(null)`. A detached toolbar keeps
|
|
35
|
+
its labels and disables editing commands.
|
|
36
|
+
|
|
37
|
+
- Expose inherited CSS variables for editor colors, token colors, slot backgrounds, toolbar density and menu appearance. Keep per-editor themes on portaled suggestion and selection menus, including live theme switches and iframe documents. Add a styling guide and website theme/size/density examples without changing formula data or LaTeX output.
|
|
38
|
+
|
|
39
|
+
### Patch Changes
|
|
40
|
+
|
|
41
|
+
- Preserve keyboard suggestion navigation while the mouse rests over the list. Highlight a pointer candidate only on actual mouse movement, so menu redraws cannot restore the previous choice or scroll position. Notify host adapters after pointer highlighting to preserve the native input caret during Quill reconciliation.
|
|
42
|
+
- Keep suggestion menus at their normal size inside scrolling host editors such as CKEditor and Quill. Respect transformed containers and dialog boundaries, isolate menu text alignment from the host document, and highlight pointer candidates without resetting list scroll.
|
|
43
|
+
- Use the embedding document for native editor elements, suggestion menus, range measurements, and event listeners. This keeps typing, toolbar controls, selection, and scrolling menus working inside same-origin iframe editors such as the WordPress block editor.
|
|
44
|
+
- Avoid a DOM Range exception when clicking an empty caret slot in the native DOM editor, including embedded Tiptap and ProseMirror math editing.
|
|
45
|
+
- Preserve operands when partial structure suggestions follow a coefficient, including absolute values, roots, fractions, and fences. Keep native suggestion-list scrolling from rebuilding the list and resetting its position; scroll keyboard-selected options into view.
|
|
46
|
+
- Restore the input caret when a plain arrow follows a Shift+arrow or dragged model selection. Left/Up collapses to the document-ordered start and Right/Down to the end, without changing the formula or host history. Apply the same behavior in both renderers. Use Alt+Up/Down to navigate wrapping suggestions while retaining a selection; Enter and pointer selection remain available.
|
|
47
|
+
|
|
3
48
|
## 0.2.1
|
|
4
49
|
|
|
5
50
|
### Patch Changes
|
package/EMBEDDING.md
CHANGED
|
@@ -100,3 +100,7 @@ The browser tests cover panel synchronization without extra change events, singl
|
|
|
100
100
|
Note opts into the shared `LatexEditor` visual mode with `MathEditorSurface`. Existing tex-only atoms load through `parseLatex`; unsupported input stays in the original source editor. Visual draft changes produce `tex` plus JSON-encoded `mathDocument`. `setMathSource` validates the structure, source equality and inline policy, then applies one host transaction. Cancellation writes nothing. Direct source changes clear stale structure, while font/alignment-only edits retain it.
|
|
101
101
|
|
|
102
102
|
Other products must use the same [import scope](LATEX-SCOPE.md) and core parser. Do not add product-specific regex conversions. Existing Word OMML and Site/Slide ownership boundaries still need their own host adapters; the Note trial does not integrate those products automatically.
|
|
103
|
+
|
|
104
|
+
## Style customization
|
|
105
|
+
|
|
106
|
+
Use inherited CSS variables for colors, slot backgrounds, typography, toolbar density and menu appearance. Scoped themes also follow portaled suggestions in both renderers. See [Styling & themes](STYLING.md) for the public variables, dark/monochrome examples, shared toolbars and iframe/plugin sizing.
|
package/IMPLEMENTATION.md
CHANGED
|
@@ -28,8 +28,10 @@ Navigation does not create a document history entry. Locale changes do not remou
|
|
|
28
28
|
| `tokens.ts` | Lexical variable/numeric/symbol segmentation and boundary affinity |
|
|
29
29
|
| `math-editor.tsx` | Native input lifecycle, IME, pointer hit testing, selection UI, keyboard routing and portal |
|
|
30
30
|
| `range.ts` | Endpoint ordering, balanced selection resolution, slicing, insertion, wrapping and clipboard validation |
|
|
31
|
+
| `matrix-range.ts` | Transient cell rectangles, clipboard shape validation, fresh subtree IDs, atomic paste/clear and full-matrix transpose |
|
|
31
32
|
| `matrix.ts` | Innermost grid lookup, row/column changes, delimiters and grid navigation |
|
|
32
33
|
| `lines.ts` | Top-level line split/join and vertical navigation |
|
|
34
|
+
| `vertical-navigation.ts`, `dom/caret-geometry.ts` | Shared structural Up/Down movement and optional measurements of rendered insertion points |
|
|
33
35
|
| `suggestions.ts` | Longest symbolic triggers, bilingual aliases, candidates and acceptance |
|
|
34
36
|
| `symbols.ts` | Glyph, message key, search aliases, symbolic triggers and LaTeX mapping |
|
|
35
37
|
| `templates.ts` | Fresh editable template trees and insertion through the range model |
|
|
@@ -60,6 +62,8 @@ Passive tokens render as spans. Only the active token renders an input. A hidden
|
|
|
60
62
|
|
|
61
63
|
During composition, the token partition and input element are held stable. Suggestions are visible but disabled. Enter and arrows remain with the IME; parent handlers do not receive editing keystrokes. On composition end, the complete text is committed as one history change and tokenization resumes. Synthetic composition tests are not a substitute for actual OS input-method validation.
|
|
62
64
|
|
|
65
|
+
`moveVertical` walks slot ancestors from the inside out: fractions, scripts, indexed roots, annotations and operator bounds precede enclosing grids and document lines. Grid targets stay in the same column. Both keyboard handlers pass caret measurements from the existing hidden mirrors; React token offsets are translated back to their logical text run. The target is the nearest horizontal insertion point in the requested direction, with vertical distance breaking ties. Paired scripts and operator bounds also consider their base/body, so movement can follow their shared script column. Missing layout uses the first target text run with a clamped UTF-16 offset, avoiding surrogate splits. Navigation preserves the document and undo history. It does not add persistent preferred-column state or change Shift+arrow selection.
|
|
66
|
+
|
|
63
67
|
## Ranges and transformations
|
|
64
68
|
|
|
65
69
|
`MathRange` has anchor/focus points identified by logical text ID and UTF-16 offset. `resolveRange` orders them in document traversal order and finds the deepest shared row. Endpoints in different slots expand to a balanced common structure; endpoints on different document lines produce multiple row slices.
|
|
@@ -175,7 +179,7 @@ The parser accepts a bare brace body and creates an empty annotation. Export alw
|
|
|
175
179
|
|
|
176
180
|
## Compact and filtered toolbars (workspace)
|
|
177
181
|
|
|
178
|
-
Toolbars initially show up to eight structure buttons. More tools / Fewer tools toggles the remainder without changing the formula or history. Rich React also places matrix presets, templates and symbol shortcuts in the expanded section; Undo, Redo and `toolbarEnd` stay visible. Native toolbars
|
|
182
|
+
Toolbars initially show up to eight structure buttons. More tools / Fewer tools toggles the remainder without changing the formula or history. Rich React also places matrix presets, templates and symbol shortcuts in the expanded section; Undo, Redo and `toolbarEnd` stay visible. Native toolbars also expose symbol search, templates and presets behind More tools; both renderers provide contextual matrix controls and cell selection/transpose. The layout wraps naturally on narrow screens; this is not a guaranteed single-row toolbar.
|
|
179
183
|
|
|
180
184
|
```tsx
|
|
181
185
|
<MathEditor toolbar={['fraction', 'root', 'superscript', 'matrix']}
|
|
@@ -214,7 +218,7 @@ Each is a structure with a unique `id` and exactly one MathRow in `slots: [body]
|
|
|
214
218
|
|
|
215
219
|
All limit-family, sum/product and integral nodes accept a single `\limits` or `\nolimits` immediately after the command, before scripts. The optional `limits` field is now boolean: omitted means default, `true` is stacked placement, `false` is side placement. Both explicit values survive JSON validation, copying and LaTeX export. Repeated/conflicting directives are rejected. Existing `limits: true` remains valid; older package builds do not accept `false` or the new limit kinds.
|
|
216
220
|
|
|
217
|
-
Placement is
|
|
221
|
+
Placement is selected through imported LaTeX/model metadata or the workspace contextual toolbar. Imported side conditions remain editable; normal limit suggestions use default placement. This is 0.2.0 functionality.
|
|
218
222
|
|
|
219
223
|
## Fine mathematical spacing (workspace)
|
|
220
224
|
|
|
@@ -240,3 +244,24 @@ Reuse the existing two-slot structures with optional `mathStyle: 'display' | 'te
|
|
|
240
244
|
## Labeled arrows
|
|
241
245
|
|
|
242
246
|
The `xrightarrow` and `xleftarrow` structures have two slots in upper/lower order. Parse the optional lower bracket before the required upper argument, then store in model order. Render the generic slots in three CSS grid rows, with a pseudo-element shaft and a fixed-size head in the middle row. Labels drive grid width; the decoration cannot intercept pointer events. These commands are inserted through the shared catalog and do not require a separate dialog.
|
|
247
|
+
|
|
248
|
+
## Cell selection and grid transformations
|
|
249
|
+
|
|
250
|
+
`MathMatrixRange` is separate from `MathRange`: `{ matrixId, anchor, focus }` uses
|
|
251
|
+
row-major cell indices and resolves to a rectangle. Neither selection is persisted.
|
|
252
|
+
Cross-cell pointers use the nearest shared matrix ancestor; within-cell pointers
|
|
253
|
+
retain text/structure selection. The DOM renderer keeps selection in MathSession;
|
|
254
|
+
rich React owns its view state and calls the same pure matrix operations.
|
|
255
|
+
|
|
256
|
+
Clipboard data has its own bounded matrix MIME payload, plus a regular math
|
|
257
|
+
fragment and LaTeX fallback. Incoming cells receive fresh IDs recursively. Paste
|
|
258
|
+
validates all dimensions before cloning or writing the destination; unselected
|
|
259
|
+
cells and the destination delimiter survive. Transpose reorders existing slots
|
|
260
|
+
and changes `columns`; preserving IDs keeps a nested caret valid. None of these
|
|
261
|
+
operations needs a new model version or parser command.
|
|
262
|
+
|
|
263
|
+
## Shared editing utilities — workspace
|
|
264
|
+
|
|
265
|
+
Native text rows are tokenized with the same `tokenizeMathText`/`tokenIndexAt` rules as rich React. Every rendered run retains its model ID and UTF-16 token start/end. Input events replace only that token's slice. Pointer/keyboard offsets are translated to model coordinates; boundary deletion joins neighboring text without discarding it. IME preedit updates the stable input/mirror and is committed before re-tokenizing. Literal text/operator names remain one input.
|
|
266
|
+
|
|
267
|
+
`latex-insertion.ts` parses before applying a range insertion. `preferences.ts` owns validated UI lists independently of formula sessions/history. `presentation.ts` changes only supported metadata while preserving subtree IDs and caret. The nonmodal native panels are reused by React wrappers, so diagnostics and favorites use one implementation. Host clipboard boundaries stay intact and no system clipboard reads are implicit.
|
package/JSON-MODEL.md
CHANGED
|
@@ -244,6 +244,7 @@ This has two top-level lines and exports as `gathered`. A two-row matrix inside
|
|
|
244
244
|
| `MathCaret` | Text node `id`, UTF-16 `start`/`end`, optional affinity | No |
|
|
245
245
|
| `MathState` | `{ document, caret }` while editing | No; save its `document` |
|
|
246
246
|
| `MathRange` | Structural selection endpoints | No |
|
|
247
|
+
| `MathMatrixRange` | `{ matrixId, anchor, focus }` with row-major cell indices; transient rectangular selection | No |
|
|
247
248
|
| `MathHistory` | Past/present/future editing states | No |
|
|
248
249
|
| `MathFragment` | Clipboard `{ version: 1, rows: MathRow[] }` | No; different envelope from a document |
|
|
249
250
|
| Host `tex` / `mathDocument` attributes | Product-specific storage container | No; the host may store serialized document JSON alongside derived LaTeX |
|
package/LATEX-GUIDE.md
CHANGED
|
@@ -43,6 +43,7 @@ Typing LaTeX into an ordinary editor slot is not the same as importing it. Use t
|
|
|
43
43
|
|
|
44
44
|
## Type with suggestions
|
|
45
45
|
|
|
46
|
+
- In the 0.4.0 release, enter a matrix size as `rows x columns` without spaces. `2x1` creates two rows and one column, `1x2` creates one row and two columns, and `3x7` creates three rows and seven columns. Each dimension must be an integer from 1 to 20, without leading zeros. Uppercase `X` and `×` also work. Suggestions offer an empty matrix and a zero matrix; square sizes additionally offer an identity matrix. Enter accepts the highlighted candidate and focuses its first cell; Tab moves through cells in row order. Space or Escape keeps the original text. These are editor shortcuts, not LaTeX commands; accepted matrices export as the usual `bmatrix` environment.
|
|
46
47
|
- Type `nthroot`, `nroot` or `n제곱근` and choose Indexed root. Enter the index, press Tab, then enter the radicand. A selected expression can be wrapped; it becomes the radicand and the index receives focus.
|
|
47
48
|
- Type `text` or `텍스트`, choose Text and write the description. Tab returns to math input. Mathematical suggestions are disabled inside literal text.
|
|
48
49
|
- Type a function name such as `sin`, `cos`, `log` or `ln`, then select its suggestion. Accept the suggestion before typing the argument; plain `log` remains variable text until converted.
|
|
@@ -249,6 +250,12 @@ Numbered `equation`, `\tag` and `\label` are not supported: the model cannot pre
|
|
|
249
250
|
|
|
250
251
|
## Keyboard ranges and brace discovery (0.2.1)
|
|
251
252
|
|
|
252
|
-
Shift+Left/Right extends or shrinks the same model range used by dragging. Structures are crossed as balanced units; copied and deleted ranges use existing model normalization. Shift+Up/Down extends to an adjacent top-level document line, using a logical text offset rather than pixel-based column matching;
|
|
253
|
+
Shift+Left/Right extends or shrinks the same model range used by dragging. Structures are crossed as balanced units; copied and deleted ranges use existing model normalization. Shift+Up/Down extends to an adjacent top-level document line, using a logical text offset rather than pixel-based column matching; an active matrix-cell selection instead uses Shift+arrows to move its rectangular focus corner. Copy, cut, wrapping, deletion and Undo use the existing range behavior. IME composition and modifier shortcuts retain their existing handling.
|
|
253
254
|
|
|
254
255
|
Typing `{` offers both paired braces and cases. Paired braces remain the first candidate; choose Cases explicitly to insert its editable grid.
|
|
256
|
+
|
|
257
|
+
## Insert or adjust existing math — workspace
|
|
258
|
+
|
|
259
|
+
Use **Paste as LaTeX** in More tools, or **Alt+Shift+V**, to paste a source fragment at the current caret or selected range. Ctrl/Cmd+Enter inserts it; unsupported input stays in the source field with a diagnostic. Ordinary paste retains its existing literal-text behavior.
|
|
260
|
+
|
|
261
|
+
When the caret is inside a structure, the toolbar can change its bracket pair, fraction/binomial display size, or operator limit placement. These actions preserve contents and support one-step Undo. Recent & favorites keeps frequently used symbols/templates available without searching again. See [editing utilities](API-SESSION.md#editing-utilities--workspace).
|
package/LATEX-SCOPE.md
CHANGED
|
@@ -69,7 +69,7 @@ Empty editable slots are valid import data, even if a host requires a nonempty f
|
|
|
69
69
|
| `\newcommand`, `\def`, packages, labels, references, document preambles | No macro expansion or document-level TeX processing |
|
|
70
70
|
| `\input`, URLs, HTML or trust-enabled renderer commands | Never execute or resolve resources |
|
|
71
71
|
|
|
72
|
-
New syntax enters this table only with a model mapping, export policy, positive/negative fixtures and editor tests. Additional delimiters and overset/underset annotations are implemented in the workspace.
|
|
72
|
+
New syntax enters this table only with a model mapping, export policy, positive/negative fixtures and editor tests. Additional delimiters and overset/underset annotations are implemented in the workspace. The additional accents and under/over braces documented below are implemented; explicit delimiter sizes remain a future candidate. See the [editing guide and expansion priorities](LATEX-GUIDE.md); these are not implemented support.
|
|
73
73
|
|
|
74
74
|
## API and failure behavior
|
|
75
75
|
|
|
@@ -214,7 +214,7 @@ Each is a structure with a unique `id` and exactly one MathRow in `slots: [body]
|
|
|
214
214
|
|
|
215
215
|
All limit-family, sum/product and integral nodes accept a single `\limits` or `\nolimits` immediately after the command, before scripts. The optional `limits` field is now boolean: omitted means default, `true` is stacked placement, `false` is side placement. Both explicit values survive JSON validation, copying and LaTeX export. Repeated/conflicting directives are rejected. Existing `limits: true` remains valid; older package builds do not accept `false` or the new limit kinds.
|
|
216
216
|
|
|
217
|
-
Placement is
|
|
217
|
+
Placement is selected through imported LaTeX/model metadata; the workspace now also provides contextual toolbar controls. Imported side conditions remain editable; normal limit suggestions use default placement. This is 0.2.0 functionality.
|
|
218
218
|
|
|
219
219
|
## Fine mathematical spacing (workspace)
|
|
220
220
|
|
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) 2026 barocss.com
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -19,5 +19,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
19
19
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
20
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
21
|
THE SOFTWARE.
|
|
22
|
-
|
|
23
|
-
|