@barocss/math-editor 0.2.0 → 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 +51 -1
- package/EMBEDDING.md +4 -0
- package/IMPLEMENTATION.md +27 -2
- package/JSON-MODEL.md +1 -0
- package/LATEX-GUIDE.md +13 -0
- package/LATEX-SCOPE.md +2 -2
- package/LICENSE +1 -3
- package/README.md +150 -36
- package/ROADMAP.md +96 -10
- package/STYLING.md +157 -0
- package/SUPPORT.md +29 -11
- package/VALIDATION.md +117 -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 +527 -126
- 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 +28 -2
- package/dist/locales/en.json +28 -2
- package/dist/locales/ko.js +28 -2
- package/dist/locales/ko.json +28 -2
- 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 +300 -44
- 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 +4 -1
- package/dist/range.js +57 -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 +103 -13
- 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/dist/session.d.ts
CHANGED
|
@@ -1,14 +1,24 @@
|
|
|
1
|
+
import { type MathPresentationChange } from './presentation.js';
|
|
2
|
+
import { type MathPreferences } from './preferences.js';
|
|
3
|
+
import { type LatexInsertionResult } from './latex-insertion.js';
|
|
1
4
|
import { type LatexParseResult } from './latex.js';
|
|
2
5
|
import { type MathDocument, type MathState, type MathCaret, type StructureKind } from './model.js';
|
|
3
6
|
import { type MathRange, type MathFragment } from './range.js';
|
|
4
7
|
import type { MathLocale } from './i18n.js';
|
|
8
|
+
import { type MathMatrixRange, type MathMatrixFragment } from './matrix-range.js';
|
|
5
9
|
export type MathEditorMode = 'block' | 'inline';
|
|
6
10
|
export interface MathSessionOptions {
|
|
11
|
+
/** UI-only preference store. Supply one store to share it across editors. */
|
|
12
|
+
preferences?: MathPreferences;
|
|
7
13
|
document?: MathDocument;
|
|
8
14
|
mode?: MathEditorMode;
|
|
9
15
|
locale?: MathLocale;
|
|
10
16
|
}
|
|
11
17
|
export type MathCommand = {
|
|
18
|
+
type: 'presentation';
|
|
19
|
+
id: string;
|
|
20
|
+
change: MathPresentationChange;
|
|
21
|
+
} | {
|
|
12
22
|
type: 'text';
|
|
13
23
|
value: string;
|
|
14
24
|
} | {
|
|
@@ -23,10 +33,18 @@ export type MathCommand = {
|
|
|
23
33
|
type: 'undo';
|
|
24
34
|
} | {
|
|
25
35
|
type: 'redo';
|
|
36
|
+
} | {
|
|
37
|
+
type: 'matrix-select';
|
|
38
|
+
all?: boolean;
|
|
39
|
+
} | {
|
|
40
|
+
type: 'matrix-transpose';
|
|
41
|
+
} | {
|
|
42
|
+
type: 'matrix-clear';
|
|
26
43
|
};
|
|
27
44
|
export interface MathSessionSnapshot {
|
|
28
45
|
state: MathState;
|
|
29
46
|
range?: MathRange;
|
|
47
|
+
matrixRange?: MathMatrixRange;
|
|
30
48
|
locale: MathLocale;
|
|
31
49
|
mode: MathEditorMode;
|
|
32
50
|
canUndo: boolean;
|
|
@@ -35,14 +53,26 @@ export interface MathSessionSnapshot {
|
|
|
35
53
|
}
|
|
36
54
|
/** Framework-free session. Snapshots are copies; consumers cannot mutate history. */
|
|
37
55
|
export declare function createMathSession(options?: MathSessionOptions): {
|
|
56
|
+
preferences: {
|
|
57
|
+
getSnapshot: () => import("./preferences.js").MathPreferencesSnapshot;
|
|
58
|
+
record(id: string): void;
|
|
59
|
+
toggleFavorite(id: string): void;
|
|
60
|
+
clearRecent(): void;
|
|
61
|
+
subscribe(listener: () => void): () => void;
|
|
62
|
+
};
|
|
38
63
|
getSnapshot: () => MathSessionSnapshot;
|
|
39
64
|
subscribe(listener: (snapshot: MathSessionSnapshot, documentChanged: boolean) => void): () => void;
|
|
40
65
|
apply: (next: MathState) => boolean;
|
|
41
66
|
select(caret: MathCaret): void;
|
|
42
67
|
selectRange(next?: MathRange): void;
|
|
43
|
-
|
|
68
|
+
selectMatrixRange(next?: MathMatrixRange): boolean;
|
|
69
|
+
copyMatrix(): MathMatrixFragment | undefined;
|
|
70
|
+
pasteMatrix(fragment: MathMatrixFragment): boolean;
|
|
71
|
+
configure(next: Omit<MathSessionOptions, "document" | "preferences">): void;
|
|
44
72
|
/** Atomic replacement in the existing history. Syntax/policy failures emit no changes. */
|
|
45
73
|
importLatex(source: string): LatexParseResult;
|
|
74
|
+
/** Explicit LaTeX paste replaces only the current range and creates one Undo entry. */
|
|
75
|
+
pasteLatex(source: string): LatexInsertionResult;
|
|
46
76
|
load(document: MathDocument): void;
|
|
47
77
|
copy(): MathFragment | undefined;
|
|
48
78
|
paste(fragment: MathFragment): boolean;
|
|
@@ -50,4 +80,3 @@ export declare function createMathSession(options?: MathSessionOptions): {
|
|
|
50
80
|
destroy(): void;
|
|
51
81
|
};
|
|
52
82
|
export type MathSession = ReturnType<typeof createMathSession>;
|
|
53
|
-
//# sourceMappingURL=session.d.ts.map
|
package/dist/session.js
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
|
+
import { setMathPresentation } from './presentation.js';
|
|
2
|
+
import { createMathPreferences } from './preferences.js';
|
|
3
|
+
import { insertLatex } from './latex-insertion.js';
|
|
1
4
|
import { parseLatex } from './latex.js';
|
|
2
5
|
import { commit, createHistory, initialState, insertStructure, toLatex, row, undo, redo, } from './model.js';
|
|
3
6
|
import { copyRange, pasteFragment, wrapRange, wrappingKinds, } from './range.js';
|
|
4
7
|
import { insertTemplate } from './templates.js';
|
|
5
8
|
import { splitLine } from './lines.js';
|
|
9
|
+
import { activeMatrix } from './matrix.js';
|
|
10
|
+
import { clearMatrixRange, copyMatrixRange, focusMatrixCell, matrixFragment, pasteMatrixFragment, resolveMatrixRange, transposeMatrix, } from './matrix-range.js';
|
|
6
11
|
/** Framework-free session. Snapshots are copies; consumers cannot mutate history. */
|
|
7
12
|
export function createMathSession(options = {}) {
|
|
8
13
|
let history = createHistory(initialState(options.document ? structuredClone(options.document) : undefined));
|
|
9
|
-
let mode = options.mode ?? 'block', locale = options.locale ?? 'ko', range;
|
|
14
|
+
let mode = options.mode ?? 'block', locale = options.locale ?? 'ko', range, matrixRange;
|
|
10
15
|
const listeners = new Set();
|
|
11
16
|
const valid = (document) => mode !== 'inline' || !document.additionalLines?.length;
|
|
12
17
|
if (!valid(history.present.document))
|
|
@@ -14,6 +19,7 @@ export function createMathSession(options = {}) {
|
|
|
14
19
|
const getSnapshot = () => ({
|
|
15
20
|
state: structuredClone(history.present),
|
|
16
21
|
range: range && structuredClone(range),
|
|
22
|
+
matrixRange: matrixRange && structuredClone(matrixRange),
|
|
17
23
|
locale,
|
|
18
24
|
mode,
|
|
19
25
|
canUndo: !!history.past.length,
|
|
@@ -32,12 +38,16 @@ export function createMathSession(options = {}) {
|
|
|
32
38
|
history = changed
|
|
33
39
|
? commit(history, next)
|
|
34
40
|
: { ...history, present: { ...history.present, caret: next.caret } };
|
|
35
|
-
if (changed)
|
|
41
|
+
if (changed) {
|
|
36
42
|
range = undefined;
|
|
43
|
+
matrixRange = undefined;
|
|
44
|
+
}
|
|
37
45
|
emit(changed);
|
|
38
46
|
return true;
|
|
39
47
|
};
|
|
48
|
+
const preferences = options.preferences ?? createMathPreferences();
|
|
40
49
|
return {
|
|
50
|
+
preferences,
|
|
41
51
|
getSnapshot,
|
|
42
52
|
subscribe(listener) {
|
|
43
53
|
listeners.add(listener);
|
|
@@ -52,12 +62,34 @@ export function createMathSession(options = {}) {
|
|
|
52
62
|
present: { ...history.present, caret: { ...caret } },
|
|
53
63
|
};
|
|
54
64
|
range = undefined;
|
|
65
|
+
matrixRange = undefined;
|
|
55
66
|
emit(false);
|
|
56
67
|
},
|
|
57
68
|
selectRange(next) {
|
|
69
|
+
matrixRange = undefined;
|
|
58
70
|
range = next && structuredClone(next);
|
|
59
71
|
emit(false);
|
|
60
72
|
},
|
|
73
|
+
selectMatrixRange(next) {
|
|
74
|
+
if (next && !resolveMatrixRange(history.present.document, next))
|
|
75
|
+
return false;
|
|
76
|
+
matrixRange = next && structuredClone(next);
|
|
77
|
+
range = undefined;
|
|
78
|
+
if (next)
|
|
79
|
+
history = {
|
|
80
|
+
...history,
|
|
81
|
+
present: focusMatrixCell(history.present, next.matrixId, next.focus),
|
|
82
|
+
};
|
|
83
|
+
emit(false);
|
|
84
|
+
return true;
|
|
85
|
+
},
|
|
86
|
+
copyMatrix() {
|
|
87
|
+
return matrixRange ? copyMatrixRange(history.present.document, matrixRange) : undefined;
|
|
88
|
+
},
|
|
89
|
+
pasteMatrix(fragment) {
|
|
90
|
+
const next = pasteMatrixFragment(history.present, fragment, matrixRange);
|
|
91
|
+
return next !== history.present && apply(next);
|
|
92
|
+
},
|
|
61
93
|
configure(next) {
|
|
62
94
|
const targetMode = next.mode ?? mode;
|
|
63
95
|
if (targetMode === 'inline' && history.present.document.additionalLines?.length)
|
|
@@ -73,17 +105,44 @@ export function createMathSession(options = {}) {
|
|
|
73
105
|
apply(initialState(result.document));
|
|
74
106
|
return result;
|
|
75
107
|
},
|
|
108
|
+
/** Explicit LaTeX paste replaces only the current range and creates one Undo entry. */
|
|
109
|
+
pasteLatex(source) {
|
|
110
|
+
if (matrixRange)
|
|
111
|
+
return {
|
|
112
|
+
ok: false,
|
|
113
|
+
source,
|
|
114
|
+
diagnostics: [
|
|
115
|
+
{
|
|
116
|
+
code: 'unsupported-structure',
|
|
117
|
+
message: 'Select one insertion point before pasting LaTeX.',
|
|
118
|
+
start: 0,
|
|
119
|
+
end: source.length,
|
|
120
|
+
},
|
|
121
|
+
],
|
|
122
|
+
};
|
|
123
|
+
const result = insertLatex(history.present, source, range, { multiline: mode !== 'inline' });
|
|
124
|
+
if (result.ok)
|
|
125
|
+
apply(result.state);
|
|
126
|
+
return result;
|
|
127
|
+
},
|
|
76
128
|
load(document) {
|
|
77
129
|
if (!valid(document))
|
|
78
130
|
throw new Error('Inline mode requires a single top-level row.');
|
|
79
131
|
history = createHistory(initialState(structuredClone(document)));
|
|
80
132
|
range = undefined;
|
|
133
|
+
matrixRange = undefined;
|
|
81
134
|
emit(true);
|
|
82
135
|
},
|
|
83
136
|
copy() {
|
|
137
|
+
if (matrixRange) {
|
|
138
|
+
const fragment = copyMatrixRange(history.present.document, matrixRange);
|
|
139
|
+
return fragment && matrixFragment(fragment);
|
|
140
|
+
}
|
|
84
141
|
return range ? copyRange(history.present.document, range) : undefined;
|
|
85
142
|
},
|
|
86
143
|
paste(fragment) {
|
|
144
|
+
if (matrixRange)
|
|
145
|
+
return false;
|
|
87
146
|
return apply(pasteFragment(history.present, fragment, range));
|
|
88
147
|
},
|
|
89
148
|
execute(command) {
|
|
@@ -96,19 +155,62 @@ export function createMathSession(options = {}) {
|
|
|
96
155
|
const changed = next.present.document !== state.document;
|
|
97
156
|
history = next;
|
|
98
157
|
range = undefined;
|
|
158
|
+
matrixRange = undefined;
|
|
99
159
|
emit(changed);
|
|
100
160
|
return changed;
|
|
101
161
|
}
|
|
102
|
-
if (command.type === '
|
|
103
|
-
|
|
162
|
+
if (command.type === 'presentation') {
|
|
163
|
+
if (range || matrixRange)
|
|
164
|
+
return false;
|
|
165
|
+
const next = setMathPresentation(state, command.id, command.change);
|
|
166
|
+
return next !== state && apply(next);
|
|
167
|
+
}
|
|
168
|
+
if (command.type === 'matrix-select') {
|
|
169
|
+
const context = activeMatrix(state);
|
|
170
|
+
if (!context)
|
|
171
|
+
return false;
|
|
172
|
+
matrixRange = {
|
|
173
|
+
matrixId: context.matrix.id,
|
|
174
|
+
anchor: command.all ? 0 : context.cell,
|
|
175
|
+
focus: command.all ? context.matrix.slots.length - 1 : context.cell,
|
|
176
|
+
};
|
|
177
|
+
range = undefined;
|
|
178
|
+
history = {
|
|
179
|
+
...history,
|
|
180
|
+
present: focusMatrixCell(state, matrixRange.matrixId, matrixRange.focus),
|
|
181
|
+
};
|
|
182
|
+
emit(false);
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
185
|
+
if (command.type === 'matrix-transpose') {
|
|
186
|
+
const next = transposeMatrix(state, matrixRange?.matrixId);
|
|
187
|
+
return next !== state && apply(next);
|
|
188
|
+
}
|
|
189
|
+
if (command.type === 'matrix-clear')
|
|
190
|
+
return !!matrixRange && apply(clearMatrixRange(state, matrixRange));
|
|
191
|
+
if (matrixRange)
|
|
192
|
+
return (command.type === 'text' &&
|
|
193
|
+
!command.value.includes('\n') &&
|
|
194
|
+
!command.value.includes('\r') &&
|
|
195
|
+
apply(clearMatrixRange(state, matrixRange, command.value)));
|
|
196
|
+
if (command.type === 'text') {
|
|
197
|
+
const inserted = apply(pasteFragment(state, {
|
|
104
198
|
version: 1,
|
|
105
199
|
rows: command.value
|
|
106
200
|
.replace(/\r\n?/g, '\n')
|
|
107
201
|
.split('\n')
|
|
108
202
|
.map((value) => row(value)),
|
|
109
203
|
}, range));
|
|
110
|
-
|
|
111
|
-
|
|
204
|
+
if (inserted)
|
|
205
|
+
preferences.record(`symbol-${command.value}`);
|
|
206
|
+
return inserted;
|
|
207
|
+
}
|
|
208
|
+
if (command.type === 'template') {
|
|
209
|
+
const inserted = apply(insertTemplate(state, command.id, range));
|
|
210
|
+
if (inserted)
|
|
211
|
+
preferences.record(`template-${command.id}`);
|
|
212
|
+
return inserted;
|
|
213
|
+
}
|
|
112
214
|
if (command.type === 'newline')
|
|
113
215
|
return mode === 'inline' ? false : apply(splitLine(state));
|
|
114
216
|
if (range)
|
|
@@ -121,4 +223,3 @@ export function createMathSession(options = {}) {
|
|
|
121
223
|
},
|
|
122
224
|
};
|
|
123
225
|
}
|
|
124
|
-
//# sourceMappingURL=session.js.map
|
package/dist/solid.d.ts
CHANGED
package/dist/solid.js
CHANGED
package/dist/suggestions.d.ts
CHANGED
|
@@ -7,7 +7,11 @@ export interface MathSuggestion {
|
|
|
7
7
|
mathStyle?: 'display' | 'text';
|
|
8
8
|
templateId?: string;
|
|
9
9
|
identity?: boolean;
|
|
10
|
+
/** Fill each matrix cell with an editable zero. */
|
|
11
|
+
zero?: boolean;
|
|
12
|
+
/** Row count; matrices are square unless matrixColumns is supplied. */
|
|
10
13
|
matrixSize?: number;
|
|
14
|
+
matrixColumns?: number;
|
|
11
15
|
id: string;
|
|
12
16
|
/** Catalog entries hold message keys; findSuggestions returns localized display text. */
|
|
13
17
|
label: string;
|
|
@@ -28,4 +32,3 @@ export declare function findSuggestions(text: string, caret: number, locale?: Ma
|
|
|
28
32
|
candidates: MathSuggestion[];
|
|
29
33
|
};
|
|
30
34
|
export declare function acceptSuggestion(state: MathState, query: string, candidate: MathSuggestion): MathState;
|
|
31
|
-
//# sourceMappingURL=suggestions.d.ts.map
|
package/dist/suggestions.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { mathLocaleAliases, translate, } from './i18n.js';
|
|
2
2
|
import { insertTemplate, mathTemplates } from './templates.js';
|
|
3
|
-
import { insertIdentityMatrix, insertMatrix } from './matrix.js';
|
|
3
|
+
import { activeMatrix, insertIdentityMatrix, insertMatrix, MATRIX_MAX_SIZE } from './matrix.js';
|
|
4
4
|
import { insertStructure, namedFunctions, moveCaret, setText, textNodes, } from './model.js';
|
|
5
5
|
import { mathSymbols } from './symbols.js';
|
|
6
|
+
import { wrappingKinds } from './range.js';
|
|
6
7
|
const structure = (kind, glyph, label, aliases, triggers, detail) => ({
|
|
7
8
|
id: kind,
|
|
8
9
|
kind,
|
|
@@ -15,7 +16,7 @@ const structure = (kind, glyph, label, aliases, triggers, detail) => ({
|
|
|
15
16
|
export const mathStructures = [
|
|
16
17
|
structure('matrix', '[▦]', 'structure.matrix', ['matrix', '행렬', 'vector', '벡터'], [], 'structure.matrixDetail'),
|
|
17
18
|
structure('aligned', '≡', 'structure.aligned', ['aligned', 'align', '정렬', '등호'], [], 'structure.alignedDetail'),
|
|
18
|
-
structure('cases', '{', 'structure.cases', ['cases', 'case', '조건', '구간'], [], 'structure.casesDetail'),
|
|
19
|
+
structure('cases', '{', 'structure.cases', ['cases', 'case', '조건', '구간'], ['{'], 'structure.casesDetail'),
|
|
19
20
|
structure('fraction', 'a/b', 'structure.fraction', ['frac', 'fraction', 'division'], ['/'], 'structure.fractionDetail'),
|
|
20
21
|
structure('root', '√', 'structure.root', ['sqrt', 'root'], ['√'], 'structure.rootDetail'),
|
|
21
22
|
structure('indexedRoot', 'ⁿ√', 'structure.indexedRoot', ['nthroot', 'nroot', '제곱근'], [], 'structure.indexedRootDetail'),
|
|
@@ -129,14 +130,58 @@ const catalog = [
|
|
|
129
130
|
})),
|
|
130
131
|
];
|
|
131
132
|
const triggers = [...new Set(catalog.flatMap((c) => c.triggers))].sort((a, b) => b.length - a.length);
|
|
133
|
+
/** Generate only the requested size, with identity matrices reserved for square shapes. */
|
|
134
|
+
function matrixDimensionSuggestions(rows, columns) {
|
|
135
|
+
const sizeId = rows === columns ? String(rows) : `${rows}x${columns}`;
|
|
136
|
+
const dimensions = { rows, columns };
|
|
137
|
+
const empty = {
|
|
138
|
+
...mathStructures[0],
|
|
139
|
+
id: `matrix-${sizeId}`,
|
|
140
|
+
label: 'matrix.size',
|
|
141
|
+
labelParameters: dimensions,
|
|
142
|
+
detail: 'grid.dimensions',
|
|
143
|
+
detailParameters: dimensions,
|
|
144
|
+
matrixSize: rows,
|
|
145
|
+
matrixColumns: columns,
|
|
146
|
+
};
|
|
147
|
+
const candidates = [empty];
|
|
148
|
+
if (rows === columns) {
|
|
149
|
+
candidates.push({
|
|
150
|
+
...empty,
|
|
151
|
+
id: `identity-${sizeId}`,
|
|
152
|
+
glyph: 'I',
|
|
153
|
+
label: 'matrix.identity',
|
|
154
|
+
detail: 'matrix.identityDetail',
|
|
155
|
+
identity: true,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
candidates.push({
|
|
159
|
+
...empty,
|
|
160
|
+
id: `template-zero-${sizeId}`,
|
|
161
|
+
glyph: '0',
|
|
162
|
+
label: 'matrix.zero',
|
|
163
|
+
zero: true,
|
|
164
|
+
});
|
|
165
|
+
return candidates;
|
|
166
|
+
}
|
|
132
167
|
export function findSuggestions(text, caret, locale = 'ko') {
|
|
133
168
|
const before = text.slice(0, caret);
|
|
169
|
+
// Size shortcuts are complete tokens, not the tail of a number or identifier.
|
|
170
|
+
// They remain ordinary text until the user accepts a matrix candidate.
|
|
171
|
+
const dimensionMatch = /^[\p{L}\p{M}\p{N}_.]/u.test(text.slice(caret))
|
|
172
|
+
? null
|
|
173
|
+
: before.match(/(?<![\p{L}\p{M}\p{N}_.\\])([1-9]\d?)[xX×]([1-9]\d?)$/u);
|
|
174
|
+
const dimension = dimensionMatch &&
|
|
175
|
+
Number(dimensionMatch[1]) <= MATRIX_MAX_SIZE &&
|
|
176
|
+
Number(dimensionMatch[2]) <= MATRIX_MAX_SIZE
|
|
177
|
+
? dimensionMatch
|
|
178
|
+
: null;
|
|
134
179
|
// Recognize the longest symbolic spelling first: E/ must never become a fraction query.
|
|
135
180
|
const trigger = triggers.find((t) => before.endsWith(t) &&
|
|
136
181
|
(t.length > 1 || !/[A-Za-z]/.test(t) || !/[\p{L}\p{N}]/u.test(before.at(-2) ?? '')));
|
|
137
182
|
const word = before.match(/(?:\\)?[\p{L}\p{M}]+$/u)?.[0];
|
|
138
183
|
const operand = before.match(/(?:\d+(?:\.\d+)?|[\p{L}\p{M}]+)$/u)?.[0];
|
|
139
|
-
const query = trigger ?? word ?? operand ?? '';
|
|
184
|
+
const query = dimension?.[0] ?? trigger ?? word ?? operand ?? '';
|
|
140
185
|
if (!query)
|
|
141
186
|
return { query: '', candidates: [] };
|
|
142
187
|
const name = query.replace(/^\\/, '');
|
|
@@ -160,12 +205,16 @@ export function findSuggestions(text, caret, locale = 'ko') {
|
|
|
160
205
|
return 3;
|
|
161
206
|
return 4;
|
|
162
207
|
};
|
|
163
|
-
const candidates =
|
|
164
|
-
?
|
|
165
|
-
:
|
|
166
|
-
?
|
|
167
|
-
:
|
|
208
|
+
const candidates = dimension
|
|
209
|
+
? matrixDimensionSuggestions(Number(dimension[1]), Number(dimension[2]))
|
|
210
|
+
: trigger
|
|
211
|
+
? catalog.filter((item) => item.triggers.includes(trigger))
|
|
212
|
+
: /^\d+(?:\.\d+)?$/.test(name)
|
|
213
|
+
? []
|
|
214
|
+
: catalog.filter((item) => names(item).some((value) => normalize(value).includes(needle)));
|
|
168
215
|
candidates.sort((a, b) => {
|
|
216
|
+
if (dimension)
|
|
217
|
+
return 0;
|
|
169
218
|
if (trigger === '-' || trigger === '->') {
|
|
170
219
|
const preferred = trigger === '-' ? ['−', '→'] : ['→'];
|
|
171
220
|
const order = (item) => {
|
|
@@ -175,6 +224,8 @@ export function findSuggestions(text, caret, locale = 'ko') {
|
|
|
175
224
|
if (order(a) !== order(b))
|
|
176
225
|
return order(a) - order(b);
|
|
177
226
|
}
|
|
227
|
+
if (trigger === '{')
|
|
228
|
+
return Number(b.kind === 'braces') - Number(a.kind === 'braces');
|
|
178
229
|
if (trigger === '_')
|
|
179
230
|
return Number(b.kind === 'subscript') - Number(a.kind === 'subscript');
|
|
180
231
|
if (!trigger && rank(a) !== rank(b))
|
|
@@ -214,6 +265,16 @@ export function findSuggestions(text, caret, locale = 'ko') {
|
|
|
214
265
|
});
|
|
215
266
|
}
|
|
216
267
|
}
|
|
268
|
+
// A partial name after a coefficient is an operand (4ab), not an "absolute"
|
|
269
|
+
// command. Keep explicit commands such as 4abs and \\abs working as before.
|
|
270
|
+
if (!trigger && /^\p{L}+$/u.test(query) && /\d$/.test(before.slice(0, -query.length))) {
|
|
271
|
+
for (let index = 0; index < candidates.length; index++) {
|
|
272
|
+
const item = candidates[index];
|
|
273
|
+
if (item.kind && wrappingKinds.some((kind) => kind === item.kind) && rank(item) >= 3) {
|
|
274
|
+
candidates[index] = { ...item, wrapOperand: true, detail: 'suggestion.wrapOperand' };
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
217
278
|
return {
|
|
218
279
|
query,
|
|
219
280
|
candidates: candidates.map((item) => ({
|
|
@@ -228,6 +289,13 @@ export function acceptSuggestion(state, query, candidate) {
|
|
|
228
289
|
const start = state.caret.start - query.length;
|
|
229
290
|
if (!node || start < 0 || node.text.slice(start, state.caret.start) !== query)
|
|
230
291
|
return state;
|
|
292
|
+
if (candidate.matrixSize !== undefined) {
|
|
293
|
+
const rows = candidate.matrixSize;
|
|
294
|
+
const columns = candidate.matrixColumns ?? rows;
|
|
295
|
+
if (![rows, columns].every((size) => Number.isInteger(size) && size >= 1 && size <= MATRIX_MAX_SIZE) ||
|
|
296
|
+
(candidate.identity && rows !== columns))
|
|
297
|
+
return state;
|
|
298
|
+
}
|
|
231
299
|
if (candidate.wrapOperand && candidate.kind) {
|
|
232
300
|
const selected = { ...state, caret: { ...state.caret, start, end: state.caret.start } };
|
|
233
301
|
const wrapped = insertStructure(selected, candidate.kind);
|
|
@@ -251,12 +319,34 @@ export function acceptSuggestion(state, query, candidate) {
|
|
|
251
319
|
const inserted = insertStructure(next, 'operatorName');
|
|
252
320
|
return moveCaret(setText(inserted, candidate.operatorName, candidate.operatorName.length), 1);
|
|
253
321
|
}
|
|
254
|
-
if (candidate.templateId)
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
322
|
+
if (candidate.templateId) {
|
|
323
|
+
const inserted = insertTemplate(next, candidate.templateId);
|
|
324
|
+
if (!candidate.templateId.startsWith('zero-') || inserted === next)
|
|
325
|
+
return inserted;
|
|
326
|
+
// Matrix suggestions start cell editing, including populated zero templates.
|
|
327
|
+
// Pasting a template otherwise leaves the caret after its last structure.
|
|
328
|
+
const matrix = activeMatrix(moveCaret(inserted, -1))?.matrix;
|
|
329
|
+
const first = matrix?.slots[0].children[0];
|
|
330
|
+
return first?.type === 'text'
|
|
331
|
+
? { ...inserted, caret: { id: first.id, start: 0, end: 0 } }
|
|
332
|
+
: inserted;
|
|
333
|
+
}
|
|
334
|
+
if (candidate.matrixSize) {
|
|
335
|
+
const inserted = candidate.identity
|
|
336
|
+
? insertIdentityMatrix(next, candidate.matrixSize)
|
|
337
|
+
: insertMatrix(next, candidate.matrixSize, candidate.matrixColumns);
|
|
338
|
+
if (inserted === next)
|
|
339
|
+
return state;
|
|
340
|
+
if (candidate.zero) {
|
|
341
|
+
activeMatrix(inserted)?.matrix.slots.forEach((cell) => {
|
|
342
|
+
const first = cell.children[0];
|
|
343
|
+
if (first.type === 'text')
|
|
344
|
+
first.text = '0';
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
return inserted;
|
|
348
|
+
}
|
|
258
349
|
return candidate.kind
|
|
259
350
|
? insertStructure(next, candidate.kind, ['fraction', 'binomial', 'superscript', 'subscript'].includes(candidate.kind), candidate.mathStyle)
|
|
260
351
|
: next;
|
|
261
352
|
}
|
|
262
|
-
//# sourceMappingURL=suggestions.js.map
|
package/dist/svelte.d.ts
CHANGED
|
@@ -2,4 +2,3 @@ import type { Action } from 'svelte/action';
|
|
|
2
2
|
import { type DOMMathEditorOptions } from './dom.js';
|
|
3
3
|
/** Svelte action: <div use:mathEditor={options} />. */
|
|
4
4
|
export declare const mathEditor: Action<HTMLElement, DOMMathEditorOptions | undefined>;
|
|
5
|
-
//# sourceMappingURL=svelte.d.ts.map
|
package/dist/svelte.js
CHANGED
package/dist/symbol-browser.d.ts
CHANGED
package/dist/symbol-browser.js
CHANGED
|
@@ -29,4 +29,3 @@ export function SymbolBrowser({ locale, onInsert, onClose, }) {
|
|
|
29
29
|
}
|
|
30
30
|
}, children: [_jsxs("div", { className: "me-symbol-browser-heading", children: [_jsxs("strong", { children: [t('symbols.title'), ' ', _jsxs("small", { children: [matches.length, " / ", mathSymbols.length] })] }), _jsx("button", { type: "button", onClick: onClose, children: t('common.close') })] }), _jsxs("label", { className: "me-symbol-search", children: [t('symbols.search'), _jsx("input", { ref: search, type: "search", value: query, onChange: (event) => setQuery(event.target.value), placeholder: t('symbols.searchPlaceholder') })] }), _jsx("p", { className: "me-symbol-help", children: t('symbols.help') }), _jsx("div", { className: "me-symbol-grid", children: matches.map(([glyph, label]) => (_jsxs("button", { type: "button", "aria-label": `${glyph} — ${t(label)}`, title: `${translate('en', label)} / ${translate('ko', label)}`, onClick: () => onInsert(glyph), children: [_jsx("span", { className: "me-symbol-glyph", "aria-hidden": "true", children: glyph }), _jsx("span", { children: t(label) })] }, glyph))) }), !matches.length && _jsx("p", { role: "status", children: t('symbols.noMatches') })] }));
|
|
31
31
|
}
|
|
32
|
-
//# sourceMappingURL=symbol-browser.js.map
|
package/dist/symbols.d.ts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
1
|
/** One catalog powers discovery and LaTeX export. */
|
|
2
2
|
export declare const mathSymbols: readonly [readonly ["↑", "symbol.upArrow", "uparrow arrow 화살표", "- ->", "\\uparrow"], readonly ["↕", "symbol.upDownArrow", "updownarrow arrow 화살표", "- ->", "\\updownarrow"], readonly ["⇐", "symbol.doubleLeftArrow", "Leftarrow arrow 화살표", "- ->", "\\Leftarrow"], readonly ["⇑", "symbol.doubleUpArrow", "Uparrow arrow 화살표", "- ->", "\\Uparrow"], readonly ["⇓", "symbol.doubleDownArrow", "Downarrow arrow 화살표", "- ->", "\\Downarrow"], readonly ["⇕", "symbol.doubleUpDownArrow", "Updownarrow arrow 화살표", "- ->", "\\Updownarrow"], readonly ["↗", "symbol.northEastArrow", "nearrow arrow 화살표", "- ->", "\\nearrow"], readonly ["↘", "symbol.southEastArrow", "searrow arrow 화살표", "- ->", "\\searrow"], readonly ["↙", "symbol.southWestArrow", "swarrow arrow 화살표", "- ->", "\\swarrow"], readonly ["↖", "symbol.northWestArrow", "nwarrow arrow 화살표", "- ->", "\\nwarrow"], readonly ["⟶", "symbol.longRightArrow", "longrightarrow arrow 화살표", "- ->", "\\longrightarrow"], readonly ["⟵", "symbol.longLeftArrow", "longleftarrow arrow 화살표", "- ->", "\\longleftarrow"], readonly ["⟷", "symbol.longLeftRightArrow", "longleftrightarrow arrow 화살표", "-", "\\longleftrightarrow"], readonly ["⟹", "symbol.longDoubleRightArrow", "Longrightarrow arrow 화살표", "- ->", "\\Longrightarrow"], readonly ["⟸", "symbol.longDoubleLeftArrow", "Longleftarrow arrow 화살표", "- ->", "\\Longleftarrow"], readonly ["⟺", "symbol.longDoubleLeftRightArrow", "Longleftrightarrow arrow 화살표", "", "\\Longleftrightarrow"], readonly ["↪", "symbol.hookRightArrow", "hookrightarrow arrow 화살표", "- ->", "\\hookrightarrow"], readonly ["↩", "symbol.hookLeftArrow", "hookleftarrow arrow 화살표", "- ->", "\\hookleftarrow"], readonly ["⇀", "symbol.rightHarpoonUp", "rightharpoonup arrow 화살표", "- ->", "\\rightharpoonup"], readonly ["↼", "symbol.leftHarpoonUp", "leftharpoonup arrow 화살표", "- ->", "\\leftharpoonup"], readonly ["⇁", "symbol.rightHarpoonDown", "rightharpoondown arrow 화살표", "- ->", "\\rightharpoondown"], readonly ["↽", "symbol.leftHarpoonDown", "leftharpoondown arrow 화살표", "- ->", "\\leftharpoondown"], readonly ["⇌", "symbol.rightLeftHarpoons", "rightleftharpoons arrow 화살표", "- ->", "\\rightleftharpoons"], readonly ["⇋", "symbol.leftRightHarpoons", "leftrightharpoons arrow 화살표", "- ->", "\\leftrightharpoons"], readonly ["↓", "symbol.downArrow", "downarrow down 아래화살표 아래쪽화살표", "- ->", "\\downarrow"], readonly ["⩾", "symbol.greaterOrEqualSlanted", "geqslant", "", "\\geqslant"], readonly ["⩽", "symbol.lessOrEqualSlanted", "leqslant", "", "\\leqslant"], readonly ["∋", "symbol.contains", "ni contains", "", "\\ni"], readonly ["⊃", "symbol.superset", "supset superset", "", "\\supset"], readonly ["⊇", "symbol.supersetOrEqual", "supseteq", "", "\\supseteq"], readonly ["⊈", "symbol.notSubsetOrEqual", "nsubseteq", "", "\\nsubseteq"], readonly ["∖", "symbol.setDifference", "setminus difference", "", "\\setminus"], readonly ["ℕ", "symbol.naturals", "naturals natural", "", "\\mathbb{N}"], readonly ["ℤ", "symbol.integers", "integers integer", "", "\\mathbb{Z}"], readonly ["ℚ", "symbol.rationals", "rationals rational", "", "\\mathbb{Q}"], readonly ["ℝ", "symbol.reals", "reals real", "", "\\mathbb{R}"], readonly ["ℂ", "symbol.complexes", "complexes complex", "", "\\mathbb{C}"], readonly ["⊥", "symbol.perpendicular", "perp perpendicular", "", "\\perp"], readonly ["∥", "symbol.parallel", "parallel", "", "\\parallel"], readonly ["≅", "symbol.congruent", "cong congruent", "", "\\cong"], readonly ["∼", "symbol.similar", "sim similar", "", "\\sim"], readonly ["↦", "symbol.mapsTo", "mapsto maps arrow 화살표", "|-> - ->", "\\mapsto"], readonly ["…", "symbol.ellipsis", "ldots ellipsis", "", "\\ldots"], readonly ["⋯", "symbol.centeredDots", "cdots", "", "\\cdots"], readonly ["⋮", "symbol.verticalDots", "vdots", "", "\\vdots"], readonly ["⋱", "symbol.diagonalDots", "ddots", "", "\\ddots"], readonly ["°", "symbol.degree", "degree degrees 각도", "", "{}^{\\circ}"], readonly ["∠", "symbol.angle", "angle", "", "\\angle"], readonly ["+", "symbol.plus", "plus sum", "+", "+"], readonly ["−", "symbol.minus", "minus", "-", "-"], readonly ["±", "symbol.plusMinus", "plusminus sum", "+- +", "\\pm"], readonly ["∓", "symbol.minusPlus", "minusplus", "-+ -", "\\mp"], readonly ["×", "symbol.times", "times multiply", "*", "\\times"], readonly ["·", "symbol.dot", "dot multiply", "*", "\\cdot"], readonly ["÷", "symbol.divide", "divide division", "/", "\\div"], readonly ["=", "symbol.equal", "equal", "=", "="], readonly ["≠", "symbol.notEqual", "neq unequal", "!= /= =", "\\ne"], readonly ["≈", "symbol.approximatelyEqual", "approx", "~ ~~ =", "\\approx"], readonly ["≡", "symbol.equivalent", "equiv", "=== =", "\\equiv"], readonly ["<", "symbol.lessThan", "less", "<", "<"], readonly [">", "symbol.greaterThan", "greater", ">", ">"], readonly ["≤", "symbol.lessOrEqual", "leq less", "<= <- <", "\\le"], readonly ["≥", "symbol.greaterOrEqual", "geq greater", ">= >- >", "\\ge"], readonly ["∝", "symbol.proportional", "proportional", "~", "\\propto"], readonly ["→", "symbol.rightArrow", "rightarrow arrow", "-> -", "\\to"], readonly ["←", "symbol.leftArrow", "leftarrow arrow", "<- < - ->", "\\leftarrow"], readonly ["↔", "symbol.leftRightArrow", "leftrightarrow arrow", "<-> - ->", "\\leftrightarrow"], readonly ["⇒", "symbol.implies", "implies arrow 화살표", "=> = - ->", "\\Rightarrow"], readonly ["⇔", "symbol.iff", "iff arrow 화살표", "<=> - ->", "\\Leftrightarrow"], readonly ["∈", "symbol.elementOf", "in element", "E", "\\in"], readonly ["∉", "symbol.notElementOf", "notin element", "E/", "\\notin"], readonly ["∀", "symbol.forAll", "forall", "A", "\\forall"], readonly ["∃", "symbol.exists", "exists", "E", "\\exists"], readonly ["∪", "symbol.union", "union", "U", "\\cup"], readonly ["∩", "symbol.intersection", "intersection", "", "\\cap"], readonly ["⊂", "symbol.subset", "subset", "<", "\\subset"], readonly ["⊆", "symbol.subsetOrEqual", "subseteq", "<=", "\\subseteq"], readonly ["∅", "symbol.emptySet", "emptyset", "", "\\emptyset"], readonly ["∞", "symbol.infinity", "infinity infty", "", "\\infty"], readonly ["∂", "symbol.partialDerivative", "partial derivative", "", "\\partial"], readonly ["∇", "symbol.nabla", "nabla gradient", "", "\\nabla"], readonly ["∧", "symbol.logicalAnd", "and wedge", "^", "\\wedge"], readonly ["∨", "symbol.logicalOr", "or vee", "", "\\vee"], readonly ["¬", "symbol.logicalNot", "not neg", "!", "\\neg"], readonly ["α", "symbol.alpha", "alpha", "", "\\alpha"], readonly ["β", "symbol.beta", "beta", "", "\\beta"], readonly ["γ", "symbol.gamma", "gamma", "", "\\gamma"], readonly ["δ", "symbol.delta", "delta", "", "\\delta"], readonly ["ε", "symbol.epsilon", "epsilon", "", "\\epsilon"], readonly ["ζ", "symbol.zeta", "zeta", "", "\\zeta"], readonly ["η", "symbol.eta", "eta", "", "\\eta"], readonly ["θ", "symbol.theta", "theta", "", "\\theta"], readonly ["ι", "symbol.iota", "iota", "", "\\iota"], readonly ["κ", "symbol.kappa", "kappa", "", "\\kappa"], readonly ["λ", "symbol.lambda", "lambda", "", "\\lambda"], readonly ["μ", "symbol.mu", "mu", "", "\\mu"], readonly ["ν", "symbol.nu", "nu", "", "\\nu"], readonly ["ξ", "symbol.xi", "xi", "", "\\xi"], readonly ["π", "symbol.pi", "pi", "", "\\pi"], readonly ["ρ", "symbol.rho", "rho", "", "\\rho"], readonly ["σ", "symbol.sigma", "sigma", "", "\\sigma"], readonly ["τ", "symbol.tau", "tau", "", "\\tau"], readonly ["υ", "symbol.upsilon", "upsilon", "", "\\upsilon"], readonly ["φ", "symbol.phi", "phi", "", "\\phi"], readonly ["χ", "symbol.chi", "chi", "", "\\chi"], readonly ["ψ", "symbol.psi", "psi", "", "\\psi"], readonly ["ω", "symbol.omega", "omega", "", "\\omega"], readonly ["Γ", "symbol.upperGamma", "Gamma", "", "\\Gamma"], readonly ["Δ", "symbol.upperDelta", "Delta", "", "\\Delta"], readonly ["Θ", "symbol.upperTheta", "Theta", "", "\\Theta"], readonly ["Λ", "symbol.upperLambda", "Lambda", "", "\\Lambda"], readonly ["Ξ", "symbol.upperXi", "Xi", "", "\\Xi"], readonly ["Π", "symbol.upperPi", "Pi", "", "\\Pi"], readonly ["Σ", "symbol.upperSigma", "Sigma", "", "\\Sigma"], readonly ["Φ", "symbol.upperPhi", "Phi", "", "\\Phi"], readonly ["Ψ", "symbol.upperPsi", "Psi", "", "\\Psi"], readonly ["Ω", "symbol.upperOmega", "Omega", "", "\\Omega"]];
|
|
3
|
-
//# sourceMappingURL=symbols.d.ts.map
|
package/dist/symbols.js
CHANGED
package/dist/templates.d.ts
CHANGED
|
@@ -13,4 +13,3 @@ export declare const mathTemplates: MathTemplate[];
|
|
|
13
13
|
/** Each call creates independent, editable nodes; templates are not opaque LaTeX. */
|
|
14
14
|
export declare function createTemplate(id: string): MathFragment | undefined;
|
|
15
15
|
export declare function insertTemplate(state: MathState, id: string, range?: MathRange): MathState;
|
|
16
|
-
//# sourceMappingURL=templates.d.ts.map
|
package/dist/templates.js
CHANGED
package/dist/tokens.d.ts
CHANGED
|
@@ -8,4 +8,3 @@ export interface MathToken {
|
|
|
8
8
|
/** Lexical input units, not inferred mathematical definitions (e and c remain variables). */
|
|
9
9
|
export declare function tokenizeMathText(text: string): MathToken[];
|
|
10
10
|
export declare function tokenIndexAt(tokens: MathToken[], offset: number, affinity?: 'forward' | 'backward'): number;
|
|
11
|
-
//# sourceMappingURL=tokens.d.ts.map
|
package/dist/tokens.js
CHANGED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type MathCaret, type MathState } from './model.js';
|
|
2
|
+
import type { MathPoint } from './range.js';
|
|
3
|
+
type VerticalPoint = MathPoint & Pick<MathCaret, 'affinity'>;
|
|
4
|
+
/** Viewport coordinates of a rendered insertion point, including either side of a token boundary. */
|
|
5
|
+
export type MathCaretGeometry = (point: VerticalPoint) => {
|
|
6
|
+
x: number;
|
|
7
|
+
y: number;
|
|
8
|
+
} | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Move through the nearest vertical structure, then enclosing grids and equation lines.
|
|
11
|
+
* Geometry is optional so the same operation works in headless sessions and either renderer.
|
|
12
|
+
* Native text selections and literal text retain their own arrow-key behavior.
|
|
13
|
+
*/
|
|
14
|
+
export declare function moveVertical(state: MathState, direction: -1 | 1, geometry?: MathCaretGeometry): MathState;
|
|
15
|
+
export {};
|