@barocss/math-editor 0.1.0 → 0.2.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 +31 -2
- package/API-JAVASCRIPT.md +157 -0
- package/API-REACT.md +202 -0
- package/API-SESSION.md +163 -0
- package/API-SOLID.md +90 -0
- package/API-SVELTE.md +83 -0
- package/API-VUE.md +104 -0
- package/API-WEB-COMPONENT.md +128 -0
- package/CHANGELOG.md +16 -0
- package/EMBEDDING.md +7 -0
- package/IMPLEMENTATION.md +132 -1
- package/JSON-MODEL.md +441 -0
- package/LATEX-GUIDE.md +248 -0
- package/LATEX-MODEL.md +290 -0
- package/LATEX-SCOPE.md +260 -4
- package/LOCALIZATION.md +7 -1
- package/README.md +91 -4
- package/RELEASING.md +1 -1
- package/ROADMAP.md +107 -16
- package/SUPPORT.md +128 -13
- package/SYMBOLS.md +33 -1
- package/VALIDATION.md +171 -0
- package/dist/core.d.ts +2 -0
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +2 -0
- package/dist/core.js.map +1 -1
- package/dist/document-codec.d.ts +4 -0
- package/dist/document-codec.d.ts.map +1 -0
- package/dist/document-codec.js +37 -0
- package/dist/document-codec.js.map +1 -0
- package/dist/dom/menu-position.d.ts +3 -0
- package/dist/dom/menu-position.d.ts.map +1 -0
- package/dist/dom/menu-position.js +44 -0
- package/dist/dom/menu-position.js.map +1 -0
- package/dist/dom/toolbar.d.ts +2 -0
- package/dist/dom/toolbar.d.ts.map +1 -1
- package/dist/dom/toolbar.js +16 -1
- package/dist/dom/toolbar.js.map +1 -1
- package/dist/dom.d.ts +1 -0
- package/dist/dom.d.ts.map +1 -1
- package/dist/dom.js +134 -24
- package/dist/dom.js.map +1 -1
- package/dist/editor-labels.d.ts.map +1 -1
- package/dist/editor-labels.js +42 -0
- package/dist/editor-labels.js.map +1 -1
- package/dist/fences.d.ts +11 -0
- package/dist/fences.d.ts.map +1 -0
- package/dist/fences.js +21 -0
- package/dist/fences.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/latex.d.ts +26 -0
- package/dist/latex.d.ts.map +1 -0
- package/dist/latex.js +689 -0
- package/dist/latex.js.map +1 -0
- package/dist/locales/en.js +108 -1
- package/dist/locales/en.json +108 -1
- package/dist/locales/ko.js +120 -2
- package/dist/locales/ko.json +120 -2
- package/dist/math-editor-toolbar.d.ts +5 -2
- package/dist/math-editor-toolbar.d.ts.map +1 -1
- package/dist/math-editor-toolbar.js +10 -6
- package/dist/math-editor-toolbar.js.map +1 -1
- package/dist/math-editor.d.ts +24 -4
- package/dist/math-editor.d.ts.map +1 -1
- package/dist/math-editor.js +218 -39
- package/dist/math-editor.js.map +1 -1
- package/dist/model.d.ts +10 -2
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +262 -9
- package/dist/model.js.map +1 -1
- package/dist/range.d.ts +1 -1
- package/dist/range.d.ts.map +1 -1
- package/dist/range.js +116 -6
- package/dist/range.js.map +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.d.ts.map +1 -1
- package/dist/session.d.ts +3 -0
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +9 -1
- package/dist/session.js.map +1 -1
- package/dist/suggestions.d.ts +4 -0
- package/dist/suggestions.d.ts.map +1 -1
- package/dist/suggestions.js +158 -21
- package/dist/suggestions.js.map +1 -1
- package/dist/symbols.d.ts +1 -1
- package/dist/symbols.d.ts.map +1 -1
- package/dist/symbols.js +56 -5
- package/dist/symbols.js.map +1 -1
- package/package.json +3 -2
- package/src/fonts/KaTeX_AMS-Regular.woff2 +0 -0
- package/src/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
- package/src/fonts/KaTeX_Main-Bold.woff2 +0 -0
- package/src/fonts/KaTeX_Main-Regular.woff2 +0 -0
- package/src/fonts/KaTeX_Size2-Regular.woff2 +0 -0
- package/src/fonts/LICENSE-KaTeX.txt +21 -0
- package/src/style.css +868 -45
package/LATEX-GUIDE.md
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
# Writing and editing LaTeX
|
|
2
|
+
|
|
3
|
+
This guide describes **version 0.2.0**, including bounded LaTeX import and editable notation. See [installation and API guides](README.md) for package usage and [the support contract](LATEX-SCOPE.md) for the exact grammar.
|
|
4
|
+
|
|
5
|
+
## Load and edit a formula
|
|
6
|
+
|
|
7
|
+
In the demo, open **Import LaTeX**, enter a supported expression and apply it. Click a displayed slot to edit it. A successful import is undoable; a failed import preserves the existing formula and returns diagnostics.
|
|
8
|
+
|
|
9
|
+
For a session-based integration:
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { createMathSession } from '@barocss/math-editor/core';
|
|
13
|
+
|
|
14
|
+
const session = createMathSession();
|
|
15
|
+
const result = session.importLatex(String.raw`\log_{2}x + x_i^2`);
|
|
16
|
+
if (!result.ok) {
|
|
17
|
+
console.log(result.diagnostics);
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
React's rich editor exposes the same operation through `apiRef`; see [React](API-REACT.md). Vue, Svelte, Solid, Web Component and native React surfaces share the [session API](API-SESSION.md).
|
|
22
|
+
|
|
23
|
+
Typing LaTeX into an ordinary editor slot is not the same as importing it. Use the import API for complete source expressions. Ordinary clipboard text is inserted literally; structured editor clipboard data preserves model nodes.
|
|
24
|
+
|
|
25
|
+
## Expressions you can try now
|
|
26
|
+
|
|
27
|
+
| Expression | Editable parts | Important behavior |
|
|
28
|
+
|---|---|---|
|
|
29
|
+
| `\frac{a+b}{c}` | Numerator and denominator | Select existing math and choose Fraction to make it the numerator |
|
|
30
|
+
| `\sqrt{x+1}` | Radicand | Square root; use indexed-root notation for an explicit index |
|
|
31
|
+
| `\sqrt[3]{x}` | Index and radicand | Tab moves from index to radicand; empty-index Backspace keeps a square root |
|
|
32
|
+
| `\vec{x}`, `\hat{x}`, `\overline{AB}` | One editable body | Select math to wrap it; Tab out and Backspace to unwrap without losing content |
|
|
33
|
+
| `x_i^2` or `x^2_i` | Shared base, lower script, upper script | Both forms normalize to `{x}_{i}^{2}` |
|
|
34
|
+
| `{x_i}^2` | Nested script structures | Explicit grouping keeps nesting distinct from shared scripts |
|
|
35
|
+
| `\sin^2 x` | Function name, exponent, following `x` | The exponent belongs to the function name; the argument remains neighboring math |
|
|
36
|
+
| `\log_{2}x` | Function name, subscript and argument | The base is an editable script; no numerical evaluation |
|
|
37
|
+
| `\operatorname{custom}(x)` | Custom operator name and following math | A name outside the standard catalog exports with `operatorname` |
|
|
38
|
+
| `\text{if x > 0}` | One literal text slot | Spaces and punctuation are text, not structural shortcuts |
|
|
39
|
+
| `\begin{cases}x&\text{if x > 0}\\0&\text{otherwise}\end{cases}` | Expression/condition cells and text | Use text nodes for words inside conditions |
|
|
40
|
+
| `\begin{pmatrix}1&0\\0&1\end{pmatrix}` | Four cells | Tab changes cells; row/column operations preserve contents through Undo |
|
|
41
|
+
| `\begin{aligned}x&=1\\y&=2\end{aligned}` | Two columns per row | Enter the relation explicitly in the right column |
|
|
42
|
+
| `\begin{gathered}x=1\\y=2\end{gathered}` | Two top-level lines | Inline hosts reject multiple top-level lines |
|
|
43
|
+
|
|
44
|
+
## Type with suggestions
|
|
45
|
+
|
|
46
|
+
- 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
|
+
- Type `text` or `텍스트`, choose Text and write the description. Tab returns to math input. Mathematical suggestions are disabled inside literal text.
|
|
48
|
+
- 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.
|
|
49
|
+
- Type `operatorname` to enter a custom upright function name. Tab moves to the argument position.
|
|
50
|
+
- After a function suggestion, choose an exponent or subscript to attach it to that function name.
|
|
51
|
+
- At the end of an existing lower script, type `^` and choose Exponent to add an upper script to the same base. The reverse works with `_` and Subscript.
|
|
52
|
+
- A symbol query can show a literal character first. For example, `/` offers division before Fraction. Use the candidate label or arrow keys to choose the structure you intend.
|
|
53
|
+
|
|
54
|
+
Standard function names: `sin`, `cos`, `tan`, `cot`, `sec`, `csc`, `arcsin`, `arccos`, `arctan`, `sinh`, `cosh`, `tanh`, `log`, `ln`, `exp`, `min`, `max`, `det`, `gcd`. These represent notation; they do not calculate values. Hosts can add translated search aliases through [locale JSON](LOCALIZATION.md).
|
|
55
|
+
|
|
56
|
+
## Select, replace and wrap
|
|
57
|
+
|
|
58
|
+
Drag across a formula to select a model range. The regular suggestion list offers fraction, root, superscript, subscript, parentheses, brackets and absolute value. Click a candidate, or use arrow keys and Enter. Compound bases receive parentheses when wrapped in an exponent.
|
|
59
|
+
|
|
60
|
+
Typing a printable character replaces the selected range and resumes editing. Backspace/Delete removes the selection. Undo restores content. Wrapping multiple top-level lines is disabled. In combined scripts, Backspace in an empty script removes that side while retaining the other script.
|
|
61
|
+
|
|
62
|
+
## Text boundaries
|
|
63
|
+
|
|
64
|
+
`textGroup` and `operatorName` contain literal-only rows. Escape LaTeX special characters, for example `\text{a\_b costs \$2}`. Nested mathematical structures, styles and embedded `$...$` inside these text arguments are not supported. Do not use `\text` to hide unsupported math from the parser.
|
|
65
|
+
|
|
66
|
+
The editor retains structure and canonical notation, not the exact original source spelling. IDs, redundant groups, aliases and formatting whitespace can change after import/export. See [JSON model](JSON-MODEL.md) and [LaTeX-to-model mapping](LATEX-MODEL.md).
|
|
67
|
+
|
|
68
|
+
## What should be added next?
|
|
69
|
+
|
|
70
|
+
See the [prioritized LaTeX backlog](ROADMAP.md#remaining-latex-priorities-workspace-review-2026-09-08). Norm fences and additional integrals come first, followed by annotated braces and more accents. Fine spacing, styles and equation environments need explicit preservation policies. These are candidates, not current parser support.
|
|
71
|
+
|
|
72
|
+
Each addition needs a documented JSON shape, import/export round trips, unsupported-input diagnostics, actual per-character typing, cursor movement, selection, deletion and Undo tests in both renderers. See [roadmap](ROADMAP.md) for progress and [validation](VALIDATION.md) for tested coverage.
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
## Cauchy–Schwarz example
|
|
76
|
+
|
|
77
|
+
This expression imports in the workspace, including `cdots`, shared scripts and the slanted relation:
|
|
78
|
+
|
|
79
|
+
```latex
|
|
80
|
+
(a_1^2 + a_2^2 + \cdots + a_n^2)(b_1^2 + b_2^2 + \cdots + b_n^2) \geqslant (a_1b_1 + a_2b_2 + \cdots + a_nb_n)^2
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The final parenthesized expression is the base of the exponent. Its export uses `\left` / `\right`; the slanted relation remains `\geqslant`. The original source whitespace is normalized. Use the explicit LaTeX import control for this complete expression.
|
|
84
|
+
|
|
85
|
+
## Binomials and typing an operand first (workspace)
|
|
86
|
+
|
|
87
|
+
Type `binom`, `binomial`, `이항계수` or `조합`, then choose the binomial coefficient. Enter the upper term, press Tab and enter the lower term. `\binom{n}{k}` imports as two editable slots; exporting preserves the command. Nested fractions and scripts work in either term. Available in 0.2.0.
|
|
88
|
+
|
|
89
|
+
You can also type an operand first. Single variables, numbers and names without a command match offer parentheses, brackets, absolute value, root, fraction, scripts and binomial wrapping. For example, type `12`, click Parentheses, then type `+x`: the result is `\left(12\right)+x`. These actions preserve the operand instead of replacing it. Symbol matches remain above wrapping actions; full command names keep their existing search behavior.
|
|
90
|
+
|
|
91
|
+
Parentheses, brackets, absolute value and square root resume after the wrapped expression. Fraction and binomial move to the second term; exponent and subscript move to their new slot. Drag a range to wrap several terms. An operand-only menu requires an arrow key before Enter applies a choice; Enter alone keeps its normal newline/host behavior. Escape dismisses the menu. Undo restores the unwrapped input in one step.
|
|
92
|
+
|
|
93
|
+
## Limits (workspace)
|
|
94
|
+
|
|
95
|
+
Type `lim`, `limit` or `극한` and apply the suggestion. Enter the approach condition, press Tab, then enter the expression. For an arrow, type `->` and choose `→`. A typical export is `\lim_{x\to 0}{\frac{\sin x}{x}}`.
|
|
96
|
+
|
|
97
|
+
The model has two slots: condition first, expression second. LaTeX without a braced body consumes one following atom, as for sums and integrals; use braces to include a whole expression. Missing conditions or bodies remain empty editable slots. Backspace immediately after the structure removes its wrapper while retaining its contents; Undo restores it.
|
|
98
|
+
|
|
99
|
+
This supports `\lim`, not evaluation, upper limits, `\limsup`, `\liminf`, `\nolimits`. Explicit `\limits` is now supported. Function names and the `lim` glyph share a teal color; the condition and body retain their variable, number and symbol colors. Hosts can override `--me-function` on their editor element. All additions here are workspace-only until release.
|
|
100
|
+
|
|
101
|
+
### Spacing, explicit limits and upright math (workspace)
|
|
102
|
+
|
|
103
|
+
| Input | Model / export policy |
|
|
104
|
+
| --- | --- |
|
|
105
|
+
| `\quad`, `\qquad` | Zero-slot spacing structures, one/two em; original command preserved |
|
|
106
|
+
| `\sum\limits_{i=1}^n`, `\prod\limits`, `\int\limits`, `\lim\limits` | Operator with `limits: true`; explicit directive preserved |
|
|
107
|
+
| `\mathrm{dx}` | One-slot `roman` math group; same command exported |
|
|
108
|
+
| `{\rm dx}` | Scoped upright declaration; normalizes to `\mathrm{dx}` |
|
|
109
|
+
|
|
110
|
+
Type `quad` / `qquad` (or `간격` / `큰간격`) for an explicit gap. The caret resumes after the gap; Backspace there removes it and Undo restores it. Type `mathrm` / `직립체` for an editable upright group. Math inside a roman group keeps semantic colors and structure editing. It is not a literal text group.
|
|
111
|
+
|
|
112
|
+
`\limits` is accepted immediately after the supported operator, before its scripts. Arbitrary TeX dimensions (`\hspace`, `\kern`) and other font declarations remain unsupported. These additions are included in 0.2.0.
|
|
113
|
+
|
|
114
|
+
## Additional fences and annotations (workspace)
|
|
115
|
+
|
|
116
|
+
| Input | Model | Editing |
|
|
117
|
+
| --- | --- | --- |
|
|
118
|
+
| `\left\{x\right\}` | `braces`, one body slot | Search `braces` or `중괄호` |
|
|
119
|
+
| `\langle u,v\rangle` or `\left\langle u,v\right\rangle` | `angle`, one body slot | Search `angle`, `내적` or `꺾쇠괄호` |
|
|
120
|
+
| `\left(a,b\right]` | `openClosed`, one body slot | Search `openclosed` or `열린닫힌구간` |
|
|
121
|
+
| `\left[a,b\right)` | `closedOpen`, one body slot | Search `closedopen` or `닫힌열린구간` |
|
|
122
|
+
| Other `\left…\right…` pairs, including `\left.x\right|` | `fenced`, one body slot and independent `left`/`right` | Imported ends are preserved; `.` denotes an invisible end |
|
|
123
|
+
| `\overset{a}{b}` | `overset`, `[annotation, body]` | Search `overset` or `위주석`; Tab moves from annotation to body |
|
|
124
|
+
| `\underset{a}{b}` | `underset`, `[annotation, body]` | Search `underset` or `아래주석`; Tab follows model order, even though the annotation is below |
|
|
125
|
+
|
|
126
|
+
Select an expression and choose a fence or annotation in the regular suggestion menu. Fences wrap the expression and resume after it. Annotations keep the selected expression in the body and focus the empty annotation slot. Nested fractions, scripts and other editable structures are allowed in both annotation slots. Backspace after a structure removes its wrapper while preserving its content; Undo restores it.
|
|
127
|
+
|
|
128
|
+
All structured fences scale with their contents. Short angle notation normalizes to scalable `\left\langle…\right\rangle` on export. Supported physical ends are `(`, `)`, `[`, `]`, `{`, `}`, `⟨`, `⟩`, `|` and `.`. Plain punctuation stays literal unless imported with a structural command. Norm bars are supported in the workspace; `\big`/`\Big` remain unsupported; brace annotations are implemented in the workspace.
|
|
129
|
+
|
|
130
|
+
Fence shortcuts: type `{` for braces, or `<` / `⟨` for angle brackets. The literal less-than symbol stays ahead of the angle-bracket action. Korean `꺽쇠` and `꺾쇠` both find angle brackets; `langle` is also accepted. Select the desired candidate with arrow keys and Enter, or click it.
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
Equation-only cases are supported in the workspace: `\begin{cases}ax+by=c\\dx+ey=f\end{cases}`. Each row may have one expression cell or two cells separated by `&`. The model always stores two cells per row; a missing condition becomes an editable empty cell. Export includes the `&` for that empty condition. More than two cells still fails validation.
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
### Double integrals (workspace)
|
|
137
|
+
|
|
138
|
+
`\iint_R f(x,y)` imports as `doubleIntegral` with exactly three slots: `[lower/domain, upper, body]`, matching integral navigation. Missing bounds remain editable empty slots. `\iint\limits` preserves the explicit placement directive. Export uses `\iint_{lower}^{upper}{body}`. Search `iint`, `이중적분` or `∬` to insert; Tab visits the domain, upper bound and body in order. The reported expression with `\rm dx \rm dy`, `\xi`, `\eta` and `\text{Area}` is covered by import/round-trip and browser editing fixtures. This is notation support, not numerical integration. Triple and contour integrals are now implemented in the workspace; see the section below.
|
|
139
|
+
|
|
140
|
+
Integral and double-integral bounds now sit beside the slanted glyph by default: the upper bound is offset farther right than the lower bound. An explicit `\limits` directive retains the stacked above/below layout. This presentation change preserves the existing lower/upper/body model and Tab order.
|
|
141
|
+
|
|
142
|
+
Arrow discovery now uses substring matching: `화살표` / `arrow` finds directional, double, diagonal, long, hook, harpoon and equilibrium arrows. There are 31 arrow symbols and 117 catalog symbols in total. Exact spellings rank ahead of partial matches, including case-sensitive LaTeX names. All additions share parsing, export, suggestions and the symbol browser.
|
|
143
|
+
|
|
144
|
+
Arrow punctuation shortcuts: `-` offers subtraction first, then arrow alternatives. `->` offers `→` first, followed by all 31 arrow symbols, including left/up/down/diagonal and equilibrium directions. Select a candidate to convert; ordinary typing such as `x-2` stays unchanged. Longer triggers such as `<->` and `-+` retain their own matches.
|
|
145
|
+
|
|
146
|
+
## Norm fences (workspace)
|
|
147
|
+
|
|
148
|
+
Type `norm`, `노름`, `||` or `‖` and choose Norm. Enter the body and use Tab to continue outside. The same action wraps a selected expression. `\lVert x\rVert`, `\left\|x\right\|`, `\left\Vert x\right\Vert` and scalable Unicode double bars import as a one-slot `norm` node. Export canonicalizes to `\left\Vert x\right\Vert` (command-separating spaces may be included). Mixed scalable ends retain generic `fenced` metadata with `‖` as a valid physical end. Missing closing delimiters fail atomically. This represents notation; it does not calculate a vector norm.
|
|
149
|
+
|
|
150
|
+
## Triple and contour integrals (workspace)
|
|
151
|
+
|
|
152
|
+
| Input | Model | Slots / behavior |
|
|
153
|
+
| --- | --- | --- |
|
|
154
|
+
| `\iiint_a^b{f}` | `tripleIntegral` | `[lower, upper, body]` |
|
|
155
|
+
| `\oint_C{f}` | `contourIntegral` | `[lower, upper, body]`; absent upper stays empty |
|
|
156
|
+
|
|
157
|
+
Search `iiint` / `삼중적분` / `∭`, or `oint` / `폐곡선적분` / `∮`. Tab visits lower, upper and body. Backspace after the structure unwraps its contents; Undo restores it. Both accept and preserve `\limits` for stacked bounds; default editing places bounds alongside the slanted glyph. Unbraced input consumes one body atom, as for existing integrals. `\nolimits` is supported in the current workspace. These are editable notation, not integration or path analysis. Contour glyphs use the bundled KaTeX Size2-Regular U+222E directly, with its native ring and slant. No pseudo-element strokes are added.
|
|
158
|
+
|
|
159
|
+
## Brace annotations (workspace)
|
|
160
|
+
|
|
161
|
+
| Input | Model | Slots |
|
|
162
|
+
| --- | --- | --- |
|
|
163
|
+
| `\overbrace{a+b}^{n}` | `overbrace` | `[annotation, body]` |
|
|
164
|
+
| `\underbrace{a+b}_{n}` | `underbrace` | `[annotation, body]` |
|
|
165
|
+
|
|
166
|
+
Type `overbrace` / `위중괄호` or `underbrace` / `아래중괄호`. The annotation is edited first; Tab moves into the body. Wrapping a selection preserves it in the body and focuses the empty annotation. Both slots allow nested math. The brace stretches across the body/annotation container. Backspace immediately after the structure unwraps its contents; Undo restores the structure.
|
|
167
|
+
|
|
168
|
+
The parser accepts a bare brace body and creates an empty annotation. Export always includes the corresponding `^{…}` or `_{…}`, including an empty annotation. Repeated annotation markers fail. An opposite-side script is handled as an outer ordinary script, not a second brace annotation. Slot order is annotation then body even for underbraces; this matches overset/underset. This workspace addition retains document version 1; older consumers must reject unknown structure kinds during validation.
|
|
169
|
+
|
|
170
|
+
## Additional accents (workspace)
|
|
171
|
+
|
|
172
|
+
| Syntax | Model / appearance | Search |
|
|
173
|
+
| --- | --- | --- |
|
|
174
|
+
| `\tilde{x}` | `tilde`, fixed-width centered wave | `tilde`, `물결악센트` |
|
|
175
|
+
| `\bar{x}` | `bar`, short centered line | `bar`, `짧은윗줄` |
|
|
176
|
+
| `\dot{x}` | `dot`, one centered dot | `dot`, `위점` |
|
|
177
|
+
| `\ddot{x}` | `ddot`, two dots | `ddot`, `두점` |
|
|
178
|
+
| `\widehat{AB}` | `widehat`, body-width hat | `widehat`, `넓은모자` |
|
|
179
|
+
| `\widetilde{AB}` | `widetilde`, body-width wave | `widetilde`, `넓은물결` |
|
|
180
|
+
|
|
181
|
+
Each is a structure with a unique `id` and exactly one MathRow in `slots: [body]`. Empty and nested bodies are supported, including scripts and fractions. Import preserves the command spelling; export emits the same command with a braced body. Selection wrapping retains the original expression. Tab continues outside; Backspace after the wrapper preserves its body, and Undo restores it. `dot` can also match a multiplication symbol: choose Dot accent explicitly or search `위점`. `bar` remains distinct from the existing body-width `overline`. These additions are in 0.2.0 and do not evaluate derivatives or estimates.
|
|
182
|
+
|
|
183
|
+
## Limit variants and placement (workspace)
|
|
184
|
+
|
|
185
|
+
`\limsup_{n}{x}` and `\liminf_{n}{x}` use `limsup` / `liminf` structures with exactly `[condition, body]` rows. Search `limsup` / `상극한` or `liminf` / `하극한`; Tab moves from condition to body. They do not evaluate sequence limits.
|
|
186
|
+
|
|
187
|
+
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.
|
|
188
|
+
|
|
189
|
+
Placement is currently selected through imported LaTeX/model metadata, not a dedicated toolbar switch. Imported side conditions remain editable; normal limit suggestions use default placement. This is 0.2.0 functionality.
|
|
190
|
+
|
|
191
|
+
## Fine mathematical spacing (workspace)
|
|
192
|
+
|
|
193
|
+
| LaTeX | Node type | Width | Suggestion search |
|
|
194
|
+
| --- | --- | --- | --- |
|
|
195
|
+
| `\,` | `thinSpace` | 3mu / 1⁄6em | `thinspace`, `얇은간격` |
|
|
196
|
+
| `\:` | `mediumSpace` | 4mu / 2⁄9em | `mediumspace`, `중간간격` |
|
|
197
|
+
| `\;` | `thickSpace` | 5mu / 5⁄18em | `thickspace`, `두꺼운간격` |
|
|
198
|
+
| `\!` | `negativeThinSpace` | −3mu / −1⁄6em | `negativethinspace`, `간격줄이기` |
|
|
199
|
+
|
|
200
|
+
All four nodes have a unique ID and `slots: []`, like quad/qquad. Import/export preserve the exact command; ordinary source whitespace is still normalized. Insertion resumes immediately after the spacer. Backspace removes it and Undo restores it. Negative spacing uses a zero-width node with negative inline-end margin, not an overlay that intercepts pointer input. Click the adjoining text to edit; the spacer has no text slot. Plain punctuation remains literal and is not a spacing trigger.
|
|
201
|
+
|
|
202
|
+
Editor dimensions scale in script/limit slots. These are explicit gaps added to the editor's own token clearance, not a complete TeX math-glue or script-style suppression engine. Arbitrary dimensions (`\hspace`, `\kern`) and rubber-glue stretch/shrink remain unsupported. This is 0.2.0 functionality.
|
|
203
|
+
|
|
204
|
+
### KaTeX 0.16.28 limit-name preview compatibility
|
|
205
|
+
|
|
206
|
+
This KaTeX version expands limsup/liminf through starred operator names, whose HTML display layout can ignore explicit nolimits. The demo uses the following rendering-only definitions so conditions agree with the editor (default stacked, explicit nolimits beside the name):
|
|
207
|
+
|
|
208
|
+
```js
|
|
209
|
+
const macros = {
|
|
210
|
+
'\\limsup': String.raw`\mathop{\mathrm{lim\,sup}}\limits`,
|
|
211
|
+
'\\liminf': String.raw`\mathop{\mathrm{lim\,inf}}\limits`,
|
|
212
|
+
};
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Pass these as the KaTeX `macros` option when using this renderer with the editor's default stacked layout. They do not change saved JSON or exported LaTeX. They also keep default bounds stacked in inline previews, matching this editor's current limit layout rather than TeX's automatic inline-style choice. The package itself does not require KaTeX.
|
|
216
|
+
|
|
217
|
+
## Explicit sizes (0.2.0)
|
|
218
|
+
|
|
219
|
+
`\dfrac`, `\tfrac`, `\dbinom` and `\tbinom` can be imported and edited without losing their size choice on export. Type `dfrac`, `tfrac`, `dbinom` or `tbinom` and select the matching suggestion, then edit the two slots with Tab. See [JSON size mapping](LATEX-MODEL.md#explicit-fraction-and-binomial-sizes--workspace). General `\displaystyle` and `\textstyle` declarations remain unsupported.
|
|
220
|
+
|
|
221
|
+
## Mathematical alphabets — 0.2.0
|
|
222
|
+
|
|
223
|
+
| Input | Model kind | Editable slots | Intended glyph coverage |
|
|
224
|
+
| --- | --- | --- | --- |
|
|
225
|
+
| `\mathbf{Ax+2}` | `bold` | One math body | Bold upright Latin letters and numerals |
|
|
226
|
+
| `\mathcal{ABC}` | `calligraphic` | One math body | Calligraphic Latin capitals |
|
|
227
|
+
| `\mathbb{ABH}` | `blackboard` | One math body | Double-struck Latin capitals |
|
|
228
|
+
|
|
229
|
+
Type `mathbf`, `mathcal` or `mathbb` and select the suggestion, or import the LaTeX command. These structures can also wrap a selected expression. Their bodies remain math rows: fractions, scripts and nested font groups remain editable. Export preserves the scoped command. Existing single `\mathbb{N}`, `Z`, `Q`, `R`, `C` imports retain the previous Unicode-symbol normalization; multi-letter inputs use a `blackboard` structure.
|
|
230
|
+
|
|
231
|
+
The editor bundles KaTeX Main Bold, Caligraphic and AMS font faces with the existing MIT license. Decorative faces are limited to Latin capitals; other characters use fallback glyphs and are not claimed to match every KaTeX alphabet substitution. Semantic token colors remain visible. This does not add `\boldsymbol`, `\mathfrak`, arbitrary font declarations or mixed math inside literal `\text`.
|
|
232
|
+
|
|
233
|
+
## Labeled arrows — 0.2.0
|
|
234
|
+
|
|
235
|
+
| LaTeX | Model kind | `slots[0]` | `slots[1]` |
|
|
236
|
+
| --- | --- | --- | --- |
|
|
237
|
+
| `\xrightarrow[below]{above}` | `xrightarrow` | Upper label | Lower label |
|
|
238
|
+
| `\xleftarrow[below]{above}` | `xleftarrow` | Upper label | Lower label |
|
|
239
|
+
|
|
240
|
+
Both slots are math rows, including an empty lower row when the optional argument is absent. The exporter omits `[below]` when the lower label is empty, and always emits the upper `{above}` argument. Nested fractions and scripts stay editable. An unfinished optional bracket rejects the complete import without applying a partial document.
|
|
241
|
+
|
|
242
|
+
Type `xrightarrow`, `xleftarrow`, or search for “labeled arrow” / “설명화살표” in suggestions. Enter applies the candidate; edit the upper label, then Tab to the lower label. The shaft expands to fit the longer label while its arrowhead keeps a fixed size. Empty slots retain an editing affordance. This is a dedicated two-label arrow, distinct from ordinary arrow symbols and generic `overset` annotations. Other extensible arrow commands (`\xleftrightarrow`, harpoons, etc.) remain unsupported.
|
|
243
|
+
|
|
244
|
+
## Unnumbered equation wrapper — workspace
|
|
245
|
+
|
|
246
|
+
`\begin{equation*} ... \end{equation*}` imports its body into the existing root math row. It creates no new node kind and adds no suggestion item. Export emits the body without the environment wrapper. Nested supported structures remain editable. Missing/mismatched endings and unsupported commands fail atomically.
|
|
247
|
+
|
|
248
|
+
Numbered `equation`, `\tag` and `\label` are not supported: the model cannot preserve numbering or references. Use `equation*` only when formula-only import is intended. `align`, `split` and `array` remain open.
|
package/LATEX-MODEL.md
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
# LaTeX to JSON model mapping
|
|
2
|
+
|
|
3
|
+
See the [JSON model specification](JSON-MODEL.md) for required fields, exact slot order, invariants and persistence limits.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
This is the conversion reference for the **0.2.0 loader**. Read [LaTeX support](LATEX-SCOPE.md) for accepted syntax, exclusions and limits. This document explains the JSON produced by `parseLatex`, not KaTeX's internal tree.
|
|
7
|
+
|
|
8
|
+
## Data model at a glance
|
|
9
|
+
|
|
10
|
+
| JSON object | Fields | Meaning |
|
|
11
|
+
|---|---|---|
|
|
12
|
+
| `MathDocument` | `version: 1`, `root`, optional `additionalLines` | One formula document with one or more top-level rows |
|
|
13
|
+
| `MathRow` | `id`, `children` | Ordered sequence of text and structures; also used for every editable slot |
|
|
14
|
+
| `MathText` | `type: "text"`, `id`, `text` | Literal characters, including normalized symbol glyphs |
|
|
15
|
+
| Ordinary structure | `type`, `id`, `slots` | Structure-specific ordered rows |
|
|
16
|
+
| Matrix | `type: "matrix"`, `id`, `slots`, `columns`, `environment` | Rectangular cells in row-major order with delimiter style |
|
|
17
|
+
| Equation grid | `type: "aligned"` or `"cases"`, `id`, `slots`, `columns: 2` | Two cells per visual row |
|
|
18
|
+
|
|
19
|
+
Every row starts and ends with a text node. Structures have text boundaries on both sides, even when the text is empty. These empty strings provide editable positions before, after and between structures; they are not visible spaces and must not be removed from persisted documents.
|
|
20
|
+
|
|
21
|
+
IDs address rows and caret positions. Each import creates fresh IDs. The JSON examples below replace generated IDs with short labels for readability.
|
|
22
|
+
|
|
23
|
+
## Syntax-to-node table
|
|
24
|
+
|
|
25
|
+
`row("x")` below is shorthand for a real `MathRow` containing one `MathText`. It is explanatory notation, not a JSON field or serialized function.
|
|
26
|
+
|
|
27
|
+
| LaTeX input | JSON node / document field | Ordered slot meaning | Canonical export |
|
|
28
|
+
|---|---|---|---|
|
|
29
|
+
| `abc123` | `text`, `text: "abc123"` | No slots | `abc123` |
|
|
30
|
+
| `\alpha + \beta` | `text`, `text: "α+β"` | Symbols become catalog glyphs | `\alpha +\beta ` |
|
|
31
|
+
| `\mathbb{R}` or `\mathbb R` | `text`, `text: "ℝ"` | Blackboard set symbol | `\mathbb{R} ` |
|
|
32
|
+
| `\neq` | `text`, `text: "≠"` | Alias normalizes to one glyph | `\ne ` |
|
|
33
|
+
| `\text{if x > 0}` | `textGroup` | `[0]` literal-only row | `\text{if x > 0}` |
|
|
34
|
+
| `\sin`, `\operatorname{custom}` | `operatorName` | `[0]` editable literal name; argument is a sibling | `\sin `, `\operatorname{custom}` |
|
|
35
|
+
| `\frac{a}{b}` | `fraction` | `slots[0]` numerator; `[1]` denominator | `\frac{a}{b}` |
|
|
36
|
+
| `\sqrt{x}` | `root` | `[0]` radicand | `\sqrt{x}` |
|
|
37
|
+
| `\\lim_{x\\to 0}{x}` | `limit` | `[0]` approach condition; `[1]` body | `\\lim_{x\\to 0}{x}` |
|
|
38
|
+
| `\\binom{n}{k}` | `binomial` | `[0]` upper term; `[1]` lower term | `\\binom{n}{k}` |
|
|
39
|
+
| `\sqrt[3]{x}` | `indexedRoot` | `[0]` index; `[1]` radicand | `\sqrt[3]{x}` |
|
|
40
|
+
| `\vec{x}`, `\hat{x}`, `\overline{AB}` | `vec`, `hat`, `overline` | `[0]` editable body | Same command with the exported body |
|
|
41
|
+
| `\geqslant`, `\leqslant` | `text` containing `⩾` or `⩽` | No slots | Original command preserved |
|
|
42
|
+
| `(a+b)^2` | `superscript` with a `parentheses` base | Entire balanced parenthesis is the base | `{\left(a+b\right)}^{2}` |
|
|
43
|
+
| `x^2`, `x^{2}` | `superscript` | `[0]` base; `[1]` exponent | `{x}^{2}` |
|
|
44
|
+
| `x_i`, `x_{i}` | `subscript` | `[0]` base; `[1]` subscript | `{x}_{i}` |
|
|
45
|
+
| `x_i^2`, `x^2_i` | `scripts` | `[0]` shared base; `[1]` subscript; `[2]` superscript | `{x}_{i}^{2}` |
|
|
46
|
+
| `{x_i}^{2}` | `superscript` containing `subscript` in its base | Outer base contains the entire inner structure | `{{x}_{i}}^{2}` |
|
|
47
|
+
| `\left(x\right)` | `parentheses` | `[0]` enclosed row | `\left(x\right)` |
|
|
48
|
+
| `\left[x\right]` | `brackets` | `[0]` enclosed row | `\left[x\right]` |
|
|
49
|
+
| `\left\vert x\right\vert` | `absolute` | `[0]` enclosed row | `\left\vert x\right\vert` normalizes to literal vertical delimiters after left/right |
|
|
50
|
+
| `\sum_{i=1}^{n}{x}` | `sum` | `[0]` lower limit; `[1]` upper limit; `[2]` body | `\sum_{i=1}^{n}{x}` |
|
|
51
|
+
| `\prod_{i=1}^{n}{x}` | `product` | `[0]` lower; `[1]` upper; `[2]` body | `\prod_{i=1}^{n}{x}` |
|
|
52
|
+
| `\int_{0}^{1}{x}` | `integral` | `[0]` lower; `[1]` upper; `[2]` body | `\int_{0}^{1}{x}` |
|
|
53
|
+
| `\begin{bmatrix}a&b\\c&d\end{bmatrix}` | `matrix`, `columns: 2`, `environment: "bmatrix"` | `[a, b, c, d]`, each cell a row | Same environment, normalized separators |
|
|
54
|
+
| `\begin{aligned}a&=b\\c&=d\end{aligned}` | `aligned`, `columns: 2` | `[a, =b, c, =d]`; equals signs remain text | Same environment |
|
|
55
|
+
| `\begin{cases}x&x>0\\0&x=0\end{cases}` | `cases`, `columns: 2` | `[value1, condition1, value2, condition2]` | Same environment |
|
|
56
|
+
| `\begin{gathered}a\\b\end{gathered}` | `root: row("a")`, `additionalLines: [row("b")]` | No `gathered` structure node | `gathered` when there is more than one top-level row |
|
|
57
|
+
| `{}^{\circ}` | `text`, `text: "°"` | Degree catalog glyph | `{}^{\circ} ` |
|
|
58
|
+
| `\{x\}` | `text`, `text: "{x}"` | Escaped braces are visible characters | `\{x\}` |
|
|
59
|
+
| `{a+b}` | Contents flattened into the containing row | Grouping alone does not create visible parentheses | `a+b` |
|
|
60
|
+
| `$x$`, `\(x\)` | Same document as `x` | Outer wrapper is not saved in the model | `x` |
|
|
61
|
+
|
|
62
|
+
All six matrix environments share the `matrix` node: `matrix`, `pmatrix`, `bmatrix`, `Bmatrix`, `vmatrix`, `Vmatrix`. Only the `environment` field changes.
|
|
63
|
+
|
|
64
|
+
## A complete fraction example
|
|
65
|
+
|
|
66
|
+
Input:
|
|
67
|
+
|
|
68
|
+
```latex
|
|
69
|
+
\frac{a}{b}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Actual parser output shape, with IDs relabeled:
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"version": 1,
|
|
77
|
+
"root": {
|
|
78
|
+
"id": "root",
|
|
79
|
+
"children": [
|
|
80
|
+
{ "type": "text", "id": "before", "text": "" },
|
|
81
|
+
{
|
|
82
|
+
"type": "fraction",
|
|
83
|
+
"id": "fraction",
|
|
84
|
+
"slots": [
|
|
85
|
+
{
|
|
86
|
+
"id": "numerator-row",
|
|
87
|
+
"children": [{ "type": "text", "id": "numerator-text", "text": "a" }]
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"id": "denominator-row",
|
|
91
|
+
"children": [{ "type": "text", "id": "denominator-text", "text": "b" }]
|
|
92
|
+
}
|
|
93
|
+
]
|
|
94
|
+
},
|
|
95
|
+
{ "type": "text", "id": "after", "text": "" }
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
The root boundaries allow typing before and after the fraction. The numerator and denominator each have their own row and text address. Editing the numerator changes `slots[0].children[0].text`; the exporter recursively reads those slots. There is no hidden LaTeX string inside the fraction node.
|
|
102
|
+
|
|
103
|
+
## Binding and nested structures
|
|
104
|
+
|
|
105
|
+
| Input | Result | Why |
|
|
106
|
+
|---|---|---|
|
|
107
|
+
| `ab^2` | Text `a`, then a superscript whose base is `b` | An unbraced base is one atom |
|
|
108
|
+
| `{ab}^2` | One superscript whose base row contains text `ab` | Braces collect the base |
|
|
109
|
+
| `\sqrt{x^2}` | Root → radicand row → superscript | Each slot can contain another structure |
|
|
110
|
+
| `{x_i}^{2}` | Superscript → base row → subscript | Explicit nesting is preserved |
|
|
111
|
+
| `x_i_i` | Failure, no document | Repeated scripts require explicit grouping |
|
|
112
|
+
|
|
113
|
+
A row can contain several structures. For example, `\frac{a}{b}+x^2` has the sequence `empty text → fraction → text "+" → superscript → empty text`. Text nodes between structures can hold operators and other ordinary characters.
|
|
114
|
+
|
|
115
|
+
## Matrix and line addressing
|
|
116
|
+
|
|
117
|
+
For a matrix with `columns: C`, cell `(rowIndex, columnIndex)` is `slots[rowIndex * C + columnIndex]`. Indices are zero-based.
|
|
118
|
+
|
|
119
|
+
| Cell in a 2×2 matrix | Slot index | Example text |
|
|
120
|
+
|---|---|---|
|
|
121
|
+
| First row, first column | `slots[0]` | `a` |
|
|
122
|
+
| First row, second column | `slots[1]` | `b` |
|
|
123
|
+
| Second row, first column | `slots[2]` | `c` |
|
|
124
|
+
| Second row, second column | `slots[3]` | `d` |
|
|
125
|
+
|
|
126
|
+
A blank cell is still a row containing an empty text node. Matrix and aligned rows must have consistent cell counts. A cases row may omit its condition; the loader adds an empty condition cell. `aligned` and `cases` use the same indexing with exactly two columns. Top-level `gathered` lines instead become `root` and `additionalLines`; line numbers are UI-only.
|
|
127
|
+
|
|
128
|
+
## What is normalized, and what is not stored
|
|
129
|
+
|
|
130
|
+
| Concern | Behavior |
|
|
131
|
+
|---|---|
|
|
132
|
+
| Variables, numbers, symbols | All are stored in `MathText.text`. Token colors/roles are derived by the renderer, not separate variable/constant AST nodes |
|
|
133
|
+
| Spaces and comments | Ordinary LaTeX formatting whitespace/comments are discarded; an explicit escaped space becomes a text space |
|
|
134
|
+
| Command aliases | Different accepted spellings map to the same glyph/structure and export canonically |
|
|
135
|
+
| Invisible braces | Group the argument/base; no standalone brace node is stored |
|
|
136
|
+
| Original source | `result.source` preserves it for the caller; `MathDocument` does not store it |
|
|
137
|
+
| Selection and undo | Belong to editor state/session, not the document JSON |
|
|
138
|
+
| Mathematical meaning | This is a presentation tree, not a computer-algebra AST; no evaluation, simplification or variable binding |
|
|
139
|
+
| Unsupported commands | No opaque or partial node is created; the entire import fails with source offsets |
|
|
140
|
+
|
|
141
|
+
## Product integration rule
|
|
142
|
+
|
|
143
|
+
Parse once through `/core`; do not create Note-specific or framework-specific LaTeX mappings. Use `session.importLatex` or the rich React import handle for undoable replacement. Save a validated `MathDocument` and derive LaTeX with `toLatex`. If a host also stores source, changing it directly must invalidate stale structure.
|
|
144
|
+
|
|
145
|
+
The mapping is guarded by symbol/template fixtures and all nested pairs of supported structure kinds. A new model node must add its slot contract, importer, exporter and editor tests together. See [implementation](IMPLEMENTATION.md), [support](SUPPORT.md) and [validation](VALIDATION.md).
|
|
146
|
+
|
|
147
|
+
### Spacing, explicit limits and upright math (workspace)
|
|
148
|
+
|
|
149
|
+
| Input | Model / export policy |
|
|
150
|
+
| --- | --- |
|
|
151
|
+
| `\quad`, `\qquad` | Zero-slot spacing structures, one/two em; original command preserved |
|
|
152
|
+
| `\sum\limits_{i=1}^n`, `\prod\limits`, `\int\limits`, `\lim\limits` | Operator with `limits: true`; explicit directive preserved |
|
|
153
|
+
| `\mathrm{dx}` | One-slot `roman` math group; same command exported |
|
|
154
|
+
| `{\rm dx}` | Scoped upright declaration; normalizes to `\mathrm{dx}` |
|
|
155
|
+
|
|
156
|
+
Type `quad` / `qquad` (or `간격` / `큰간격`) for an explicit gap. The caret resumes after the gap; Backspace there removes it and Undo restores it. Type `mathrm` / `직립체` for an editable upright group. Math inside a roman group keeps semantic colors and structure editing. It is not a literal text group.
|
|
157
|
+
|
|
158
|
+
`\limits` is accepted immediately after the supported operator, before its scripts. Arbitrary TeX dimensions (`\hspace`, `\kern`) and other font declarations remain unsupported. These additions are included in 0.2.0.
|
|
159
|
+
|
|
160
|
+
## Additional fences and annotations (workspace)
|
|
161
|
+
|
|
162
|
+
| Input | Model | Editing |
|
|
163
|
+
| --- | --- | --- |
|
|
164
|
+
| `\left\{x\right\}` | `braces`, one body slot | Search `braces` or `중괄호` |
|
|
165
|
+
| `\langle u,v\rangle` or `\left\langle u,v\right\rangle` | `angle`, one body slot | Search `angle`, `내적` or `꺾쇠괄호` |
|
|
166
|
+
| `\left(a,b\right]` | `openClosed`, one body slot | Search `openclosed` or `열린닫힌구간` |
|
|
167
|
+
| `\left[a,b\right)` | `closedOpen`, one body slot | Search `closedopen` or `닫힌열린구간` |
|
|
168
|
+
| Other `\left…\right…` pairs, including `\left.x\right|` | `fenced`, one body slot and independent `left`/`right` | Imported ends are preserved; `.` denotes an invisible end |
|
|
169
|
+
| `\overset{a}{b}` | `overset`, `[annotation, body]` | Search `overset` or `위주석`; Tab moves from annotation to body |
|
|
170
|
+
| `\underset{a}{b}` | `underset`, `[annotation, body]` | Search `underset` or `아래주석`; Tab follows model order, even though the annotation is below |
|
|
171
|
+
|
|
172
|
+
Select an expression and choose a fence or annotation in the regular suggestion menu. Fences wrap the expression and resume after it. Annotations keep the selected expression in the body and focus the empty annotation slot. Nested fractions, scripts and other editable structures are allowed in both annotation slots. Backspace after a structure removes its wrapper while preserving its content; Undo restores it.
|
|
173
|
+
|
|
174
|
+
All structured fences scale with their contents. Short angle notation normalizes to scalable `\left\langle…\right\rangle` on export. Supported physical ends are `(`, `)`, `[`, `]`, `{`, `}`, `⟨`, `⟩`, `|` and `.`. Plain punctuation stays literal unless imported with a structural command. Double norm bars, `\big`/`\Big` remain unsupported; brace annotations are implemented in the workspace.
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
### Double integrals (workspace)
|
|
178
|
+
|
|
179
|
+
`\iint_R f(x,y)` imports as `doubleIntegral` with exactly three slots: `[lower/domain, upper, body]`, matching integral navigation. Missing bounds remain editable empty slots. `\iint\limits` preserves the explicit placement directive. Export uses `\iint_{lower}^{upper}{body}`. Search `iint`, `이중적분` or `∬` to insert; Tab visits the domain, upper bound and body in order. The reported expression with `\rm dx \rm dy`, `\xi`, `\eta` and `\text{Area}` is covered by import/round-trip and browser editing fixtures. This is notation support, not numerical integration. Triple and contour integrals are now implemented in the workspace; see the section below.
|
|
180
|
+
|
|
181
|
+
### Norm node (workspace)
|
|
182
|
+
|
|
183
|
+
| Field / input | Contract |
|
|
184
|
+
| --- | --- |
|
|
185
|
+
| `type` | `"norm"` |
|
|
186
|
+
| `id` | Unique structure ID |
|
|
187
|
+
| `slots` | Exactly one MathRow: `[body]`; nested math and empty content allowed |
|
|
188
|
+
| LaTeX aliases | `\lVert…\rVert`, `\left\|…\right\|`, `\left\Vert…\right\Vert` |
|
|
189
|
+
| Canonical export | `\left\Vert …\right\Vert ` |
|
|
190
|
+
| Generic fence metadata | `"‖"` is also a valid independent `left` / `right` value for `fenced` |
|
|
191
|
+
|
|
192
|
+
The document version remains 1. Older package builds do not understand this workspace node; validate saved documents against the consuming package's supported kinds.
|
|
193
|
+
|
|
194
|
+
## Triple and contour integrals (workspace)
|
|
195
|
+
|
|
196
|
+
| Input | Model | Slots / behavior |
|
|
197
|
+
| --- | --- | --- |
|
|
198
|
+
| `\iiint_a^b{f}` | `tripleIntegral` | `[lower, upper, body]` |
|
|
199
|
+
| `\oint_C{f}` | `contourIntegral` | `[lower, upper, body]`; absent upper stays empty |
|
|
200
|
+
|
|
201
|
+
Search `iiint` / `삼중적분` / `∭`, or `oint` / `폐곡선적분` / `∮`. Tab visits lower, upper and body. Backspace after the structure unwraps its contents; Undo restores it. Both accept and preserve `\limits` for stacked bounds; default editing places bounds alongside the slanted glyph. Unbraced input consumes one body atom, as for existing integrals. `\nolimits` is supported in the current workspace. These are editable notation, not integration or path analysis. Contour glyphs use the bundled KaTeX Size2-Regular U+222E directly, with its native ring and slant. No pseudo-element strokes are added.
|
|
202
|
+
|
|
203
|
+
## Brace annotations (workspace)
|
|
204
|
+
|
|
205
|
+
| Input | Model | Slots |
|
|
206
|
+
| --- | --- | --- |
|
|
207
|
+
| `\overbrace{a+b}^{n}` | `overbrace` | `[annotation, body]` |
|
|
208
|
+
| `\underbrace{a+b}_{n}` | `underbrace` | `[annotation, body]` |
|
|
209
|
+
|
|
210
|
+
Type `overbrace` / `위중괄호` or `underbrace` / `아래중괄호`. The annotation is edited first; Tab moves into the body. Wrapping a selection preserves it in the body and focuses the empty annotation. Both slots allow nested math. The brace stretches across the body/annotation container. Backspace immediately after the structure unwraps its contents; Undo restores the structure.
|
|
211
|
+
|
|
212
|
+
The parser accepts a bare brace body and creates an empty annotation. Export always includes the corresponding `^{…}` or `_{…}`, including an empty annotation. Repeated annotation markers fail. An opposite-side script is handled as an outer ordinary script, not a second brace annotation. Slot order is annotation then body even for underbraces; this matches overset/underset. This workspace addition retains document version 1; older consumers must reject unknown structure kinds during validation.
|
|
213
|
+
|
|
214
|
+
## Additional accents (workspace)
|
|
215
|
+
|
|
216
|
+
| Syntax | Model / appearance | Search |
|
|
217
|
+
| --- | --- | --- |
|
|
218
|
+
| `\tilde{x}` | `tilde`, fixed-width centered wave | `tilde`, `물결악센트` |
|
|
219
|
+
| `\bar{x}` | `bar`, short centered line | `bar`, `짧은윗줄` |
|
|
220
|
+
| `\dot{x}` | `dot`, one centered dot | `dot`, `위점` |
|
|
221
|
+
| `\ddot{x}` | `ddot`, two dots | `ddot`, `두점` |
|
|
222
|
+
| `\widehat{AB}` | `widehat`, body-width hat | `widehat`, `넓은모자` |
|
|
223
|
+
| `\widetilde{AB}` | `widetilde`, body-width wave | `widetilde`, `넓은물결` |
|
|
224
|
+
|
|
225
|
+
Each is a structure with a unique `id` and exactly one MathRow in `slots: [body]`. Empty and nested bodies are supported, including scripts and fractions. Import preserves the command spelling; export emits the same command with a braced body. Selection wrapping retains the original expression. Tab continues outside; Backspace after the wrapper preserves its body, and Undo restores it. `dot` can also match a multiplication symbol: choose Dot accent explicitly or search `위점`. `bar` remains distinct from the existing body-width `overline`. These additions are in 0.2.0 and do not evaluate derivatives or estimates.
|
|
226
|
+
|
|
227
|
+
## Limit variants and placement (workspace)
|
|
228
|
+
|
|
229
|
+
`\limsup_{n}{x}` and `\liminf_{n}{x}` use `limsup` / `liminf` structures with exactly `[condition, body]` rows. Search `limsup` / `상극한` or `liminf` / `하극한`; Tab moves from condition to body. They do not evaluate sequence limits.
|
|
230
|
+
|
|
231
|
+
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.
|
|
232
|
+
|
|
233
|
+
Placement is currently selected through imported LaTeX/model metadata, not a dedicated toolbar switch. Imported side conditions remain editable; normal limit suggestions use default placement. This is 0.2.0 functionality.
|
|
234
|
+
|
|
235
|
+
## Fine mathematical spacing (workspace)
|
|
236
|
+
|
|
237
|
+
| LaTeX | Node type | Width | Suggestion search |
|
|
238
|
+
| --- | --- | --- | --- |
|
|
239
|
+
| `\,` | `thinSpace` | 3mu / 1⁄6em | `thinspace`, `얇은간격` |
|
|
240
|
+
| `\:` | `mediumSpace` | 4mu / 2⁄9em | `mediumspace`, `중간간격` |
|
|
241
|
+
| `\;` | `thickSpace` | 5mu / 5⁄18em | `thickspace`, `두꺼운간격` |
|
|
242
|
+
| `\!` | `negativeThinSpace` | −3mu / −1⁄6em | `negativethinspace`, `간격줄이기` |
|
|
243
|
+
|
|
244
|
+
All four nodes have a unique ID and `slots: []`, like quad/qquad. Import/export preserve the exact command; ordinary source whitespace is still normalized. Insertion resumes immediately after the spacer. Backspace removes it and Undo restores it. Negative spacing uses a zero-width node with negative inline-end margin, not an overlay that intercepts pointer input. Click the adjoining text to edit; the spacer has no text slot. Plain punctuation remains literal and is not a spacing trigger.
|
|
245
|
+
|
|
246
|
+
Editor dimensions scale in script/limit slots. These are explicit gaps added to the editor's own token clearance, not a complete TeX math-glue or script-style suppression engine. Arbitrary dimensions (`\hspace`, `\kern`) and rubber-glue stretch/shrink remain unsupported. This is 0.2.0 functionality.
|
|
247
|
+
|
|
248
|
+
## Explicit fraction and binomial sizes — workspace
|
|
249
|
+
|
|
250
|
+
| LaTeX | JSON `type` | `mathStyle` | Slots |
|
|
251
|
+
| --- | --- | --- | --- |
|
|
252
|
+
| `\frac{a}{b}` | `fraction` | Omitted | Numerator, denominator |
|
|
253
|
+
| `\dfrac{a}{b}` | `fraction` | `"display"` | Numerator, denominator |
|
|
254
|
+
| `\tfrac{a}{b}` | `fraction` | `"text"` | Numerator, denominator |
|
|
255
|
+
| `\binom{n}{k}` | `binomial` | Omitted | Upper term, lower term |
|
|
256
|
+
| `\dbinom{n}{k}` | `binomial` | `"display"` | Upper term, lower term |
|
|
257
|
+
| `\tbinom{n}{k}` | `binomial` | `"text"` | Upper term, lower term |
|
|
258
|
+
|
|
259
|
+
The parser, validated JSON, copy/paste and exporter preserve this optional field. It is valid only on `fraction` and `binomial`; other values or node kinds are rejected. Omission retains the ordinary structure behavior. Nested explicit sizes override the enclosing explicit size.
|
|
260
|
+
|
|
261
|
+
Both editing surfaces use larger display operands (22 px) and smaller text operands (16 px), retaining editable scripts and slots. This is a bounded editing presentation, not a complete TeX style cascade; `\displaystyle`, `\textstyle` and script-style declarations remain unsupported. KaTeX controls the final exported formula's typesetting.
|
|
262
|
+
|
|
263
|
+
## Mathematical alphabets — 0.2.0
|
|
264
|
+
|
|
265
|
+
| Input | Model kind | Editable slots | Intended glyph coverage |
|
|
266
|
+
| --- | --- | --- | --- |
|
|
267
|
+
| `\mathbf{Ax+2}` | `bold` | One math body | Bold upright Latin letters and numerals |
|
|
268
|
+
| `\mathcal{ABC}` | `calligraphic` | One math body | Calligraphic Latin capitals |
|
|
269
|
+
| `\mathbb{ABH}` | `blackboard` | One math body | Double-struck Latin capitals |
|
|
270
|
+
|
|
271
|
+
Type `mathbf`, `mathcal` or `mathbb` and select the suggestion, or import the LaTeX command. These structures can also wrap a selected expression. Their bodies remain math rows: fractions, scripts and nested font groups remain editable. Export preserves the scoped command. Existing single `\mathbb{N}`, `Z`, `Q`, `R`, `C` imports retain the previous Unicode-symbol normalization; multi-letter inputs use a `blackboard` structure.
|
|
272
|
+
|
|
273
|
+
The editor bundles KaTeX Main Bold, Caligraphic and AMS font faces with the existing MIT license. Decorative faces are limited to Latin capitals; other characters use fallback glyphs and are not claimed to match every KaTeX alphabet substitution. Semantic token colors remain visible. This does not add `\boldsymbol`, `\mathfrak`, arbitrary font declarations or mixed math inside literal `\text`.
|
|
274
|
+
|
|
275
|
+
## Labeled arrows — 0.2.0
|
|
276
|
+
|
|
277
|
+
| LaTeX | Model kind | `slots[0]` | `slots[1]` |
|
|
278
|
+
| --- | --- | --- | --- |
|
|
279
|
+
| `\xrightarrow[below]{above}` | `xrightarrow` | Upper label | Lower label |
|
|
280
|
+
| `\xleftarrow[below]{above}` | `xleftarrow` | Upper label | Lower label |
|
|
281
|
+
|
|
282
|
+
Both slots are math rows, including an empty lower row when the optional argument is absent. The exporter omits `[below]` when the lower label is empty, and always emits the upper `{above}` argument. Nested fractions and scripts stay editable. An unfinished optional bracket rejects the complete import without applying a partial document.
|
|
283
|
+
|
|
284
|
+
Type `xrightarrow`, `xleftarrow`, or search for “labeled arrow” / “설명화살표” in suggestions. Enter applies the candidate; edit the upper label, then Tab to the lower label. The shaft expands to fit the longer label while its arrowhead keeps a fixed size. Empty slots retain an editing affordance. This is a dedicated two-label arrow, distinct from ordinary arrow symbols and generic `overset` annotations. Other extensible arrow commands (`\xleftrightarrow`, harpoons, etc.) remain unsupported.
|
|
285
|
+
|
|
286
|
+
## Unnumbered equation wrapper — workspace
|
|
287
|
+
|
|
288
|
+
`\begin{equation*} ... \end{equation*}` imports its body into the existing root math row. It creates no new node kind and adds no suggestion item. Export emits the body without the environment wrapper. Nested supported structures remain editable. Missing/mismatched endings and unsupported commands fail atomically.
|
|
289
|
+
|
|
290
|
+
Numbered `equation`, `\tag` and `\label` are not supported: the model cannot preserve numbering or references. Use `equation*` only when formula-only import is intended. `align`, `split` and `array` remain open.
|