@barocss/math-editor 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/ADAPTERS.md +170 -0
  2. package/CHANGELOG.md +13 -0
  3. package/EMBEDDING.md +95 -0
  4. package/IMPLEMENTATION.md +111 -0
  5. package/LATEX-SCOPE.md +7 -0
  6. package/LICENSE +23 -0
  7. package/LOCALIZATION.md +97 -0
  8. package/README.md +151 -0
  9. package/RELEASING.md +31 -0
  10. package/ROADMAP.md +102 -0
  11. package/SUPPORT.md +160 -0
  12. package/SYMBOLS.md +96 -0
  13. package/VALIDATION.md +85 -0
  14. package/dist/core.d.ts +11 -0
  15. package/dist/core.d.ts.map +1 -0
  16. package/dist/core.js +11 -0
  17. package/dist/core.js.map +1 -0
  18. package/dist/dom/elements.d.ts +3 -0
  19. package/dist/dom/elements.d.ts.map +1 -0
  20. package/dist/dom/elements.js +9 -0
  21. package/dist/dom/elements.js.map +1 -0
  22. package/dist/dom/toolbar.d.ts +11 -0
  23. package/dist/dom/toolbar.d.ts.map +1 -0
  24. package/dist/dom/toolbar.js +46 -0
  25. package/dist/dom/toolbar.js.map +1 -0
  26. package/dist/dom.d.ts +32 -0
  27. package/dist/dom.d.ts.map +1 -0
  28. package/dist/dom.js +581 -0
  29. package/dist/dom.js.map +1 -0
  30. package/dist/editor-labels.d.ts +9 -0
  31. package/dist/editor-labels.d.ts.map +1 -0
  32. package/dist/editor-labels.js +31 -0
  33. package/dist/editor-labels.js.map +1 -0
  34. package/dist/enter-policy.d.ts +11 -0
  35. package/dist/enter-policy.d.ts.map +1 -0
  36. package/dist/enter-policy.js +13 -0
  37. package/dist/enter-policy.js.map +1 -0
  38. package/dist/i18n.d.ts +20 -0
  39. package/dist/i18n.d.ts.map +1 -0
  40. package/dist/i18n.js +58 -0
  41. package/dist/i18n.js.map +1 -0
  42. package/dist/index.d.ts +12 -0
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +12 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/lines.d.ts +7 -0
  47. package/dist/lines.d.ts.map +1 -0
  48. package/dist/lines.js +51 -0
  49. package/dist/lines.js.map +1 -0
  50. package/dist/locales/en.js +214 -0
  51. package/dist/locales/en.json +213 -0
  52. package/dist/locales/ko.js +214 -0
  53. package/dist/locales/ko.json +213 -0
  54. package/dist/math-editor-toolbar.d.ts +24 -0
  55. package/dist/math-editor-toolbar.d.ts.map +1 -0
  56. package/dist/math-editor-toolbar.js +21 -0
  57. package/dist/math-editor-toolbar.js.map +1 -0
  58. package/dist/math-editor.d.ts +23 -0
  59. package/dist/math-editor.d.ts.map +1 -0
  60. package/dist/math-editor.js +692 -0
  61. package/dist/math-editor.js.map +1 -0
  62. package/dist/matrix.d.ts +29 -0
  63. package/dist/matrix.d.ts.map +1 -0
  64. package/dist/matrix.js +125 -0
  65. package/dist/matrix.js.map +1 -0
  66. package/dist/model.d.ts +74 -0
  67. package/dist/model.d.ts.map +1 -0
  68. package/dist/model.js +262 -0
  69. package/dist/model.js.map +1 -0
  70. package/dist/outputs.d.ts +13 -0
  71. package/dist/outputs.d.ts.map +1 -0
  72. package/dist/outputs.js +61 -0
  73. package/dist/outputs.js.map +1 -0
  74. package/dist/range.d.ts +30 -0
  75. package/dist/range.d.ts.map +1 -0
  76. package/dist/range.js +275 -0
  77. package/dist/range.js.map +1 -0
  78. package/dist/react.d.ts +11 -0
  79. package/dist/react.d.ts.map +1 -0
  80. package/dist/react.js +20 -0
  81. package/dist/react.js.map +1 -0
  82. package/dist/session.d.ts +50 -0
  83. package/dist/session.d.ts.map +1 -0
  84. package/dist/session.js +116 -0
  85. package/dist/session.js.map +1 -0
  86. package/dist/solid.d.ts +12 -0
  87. package/dist/solid.d.ts.map +1 -0
  88. package/dist/solid.js +9 -0
  89. package/dist/solid.js.map +1 -0
  90. package/dist/suggestions.d.ts +27 -0
  91. package/dist/suggestions.d.ts.map +1 -0
  92. package/dist/suggestions.js +125 -0
  93. package/dist/suggestions.js.map +1 -0
  94. package/dist/svelte.d.ts +5 -0
  95. package/dist/svelte.d.ts.map +1 -0
  96. package/dist/svelte.js +14 -0
  97. package/dist/svelte.js.map +1 -0
  98. package/dist/symbol-browser.d.ts +8 -0
  99. package/dist/symbol-browser.d.ts.map +1 -0
  100. package/dist/symbol-browser.js +32 -0
  101. package/dist/symbol-browser.js.map +1 -0
  102. package/dist/symbols.d.ts +3 -0
  103. package/dist/symbols.d.ts.map +1 -0
  104. package/dist/symbols.js +94 -0
  105. package/dist/symbols.js.map +1 -0
  106. package/dist/templates.d.ts +16 -0
  107. package/dist/templates.d.ts.map +1 -0
  108. package/dist/templates.js +86 -0
  109. package/dist/templates.js.map +1 -0
  110. package/dist/tokens.d.ts +11 -0
  111. package/dist/tokens.d.ts.map +1 -0
  112. package/dist/tokens.js +24 -0
  113. package/dist/tokens.js.map +1 -0
  114. package/dist/vue.d.ts +5 -0
  115. package/dist/vue.d.ts.map +1 -0
  116. package/dist/vue.js +16 -0
  117. package/dist/vue.js.map +1 -0
  118. package/dist/web-component.d.ts +10 -0
  119. package/dist/web-component.d.ts.map +1 -0
  120. package/dist/web-component.js +67 -0
  121. package/dist/web-component.js.map +1 -0
  122. package/package.json +124 -0
  123. package/src/style.css +781 -0
@@ -0,0 +1,31 @@
1
+ import { translate } from './i18n.js';
2
+ const slotLabels = {
3
+ matrix: [],
4
+ aligned: [],
5
+ cases: [],
6
+ fraction: ['slot.numerator', 'slot.denominator'],
7
+ root: ['slot.radicand'],
8
+ superscript: ['slot.base', 'structure.superscript'],
9
+ subscript: ['slot.base', 'structure.subscript'],
10
+ parentheses: ['slot.parentheses'],
11
+ brackets: ['slot.brackets'],
12
+ absolute: ['slot.absolute'],
13
+ sum: ['slot.lowerLimit', 'slot.upperLimit', 'slot.expression'],
14
+ product: ['slot.lowerLimit', 'slot.upperLimit', 'slot.expression'],
15
+ integral: ['slot.lowerLimit', 'slot.upperLimit', 'slot.integrand'],
16
+ };
17
+ /** Build display paths from message keys; callers pass already localized parent paths. */
18
+ export function createEditorLabels(locale) {
19
+ return {
20
+ line: (index) => index === 0
21
+ ? translate(locale, 'expression.label')
22
+ : translate(locale, 'expression.line', { line: index + 1 }),
23
+ slot: (parent, kind, index) => `${parent} / ${translate(locale, slotLabels[kind][index])}`,
24
+ grid: (parent, kind, index, columns) => `${parent} / ${translate(locale, 'grid.cell', {
25
+ kind: translate(locale, kind === 'aligned' ? 'grid.alignedLabel' : `structure.${kind}`),
26
+ row: Math.floor(index / columns) + 1,
27
+ column: (index % columns) + 1,
28
+ })}`,
29
+ };
30
+ }
31
+ //# sourceMappingURL=editor-labels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor-labels.js","sourceRoot":"","sources":["../src/editor-labels.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAmB,MAAM,WAAW,CAAC;AAGvD,MAAM,UAAU,GAAoC;IAClD,MAAM,EAAE,EAAE;IACV,OAAO,EAAE,EAAE;IACX,KAAK,EAAE,EAAE;IACT,QAAQ,EAAE,CAAC,gBAAgB,EAAE,kBAAkB,CAAC;IAChD,IAAI,EAAE,CAAC,eAAe,CAAC;IACvB,WAAW,EAAE,CAAC,WAAW,EAAE,uBAAuB,CAAC;IACnD,SAAS,EAAE,CAAC,WAAW,EAAE,qBAAqB,CAAC;IAC/C,WAAW,EAAE,CAAC,kBAAkB,CAAC;IACjC,QAAQ,EAAE,CAAC,eAAe,CAAC;IAC3B,QAAQ,EAAE,CAAC,eAAe,CAAC;IAC3B,GAAG,EAAE,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,CAAC;IAC9D,OAAO,EAAE,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,CAAC;IAClE,QAAQ,EAAE,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB,CAAC;CACnE,CAAC;AAEF,0FAA0F;AAC1F,MAAM,UAAU,kBAAkB,CAAC,MAAkB;IACnD,OAAO;QACL,IAAI,EAAE,CAAC,KAAa,EAAE,EAAE,CACtB,KAAK,KAAK,CAAC;YACT,CAAC,CAAC,SAAS,CAAC,MAAM,EAAE,kBAAkB,CAAC;YACvC,CAAC,CAAC,SAAS,CAAC,MAAM,EAAE,iBAAiB,EAAE,EAAE,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,CAAC;QAC/D,IAAI,EAAE,CAAC,MAAc,EAAE,IAAmB,EAAE,KAAa,EAAE,EAAE,CAC3D,GAAG,MAAM,MAAM,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;QAC7D,IAAI,EAAE,CAAC,MAAc,EAAE,IAAoC,EAAE,KAAa,EAAE,OAAe,EAAE,EAAE,CAC7F,GAAG,MAAM,MAAM,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE;YAC5C,IAAI,EAAE,SAAS,CAAC,MAAM,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,aAAa,IAAI,EAAE,CAAC;YACvF,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC;YACpC,MAAM,EAAE,CAAC,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC;SAC9B,CAAC,EAAE;KACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { MathEditorMode } from './session.js';
2
+ export interface MathEnterContext {
3
+ mode: MathEditorMode;
4
+ behavior?: 'newline' | 'commit';
5
+ shiftKey: boolean;
6
+ hasSuggestion: boolean;
7
+ gridKind?: 'matrix' | 'aligned' | 'cases';
8
+ }
9
+ /** Keep host completion separate from internal grid editing and suggestion acceptance. */
10
+ export declare function mathEnterAction(context: MathEnterContext): 'suggestion' | 'grid-row' | 'commit' | 'newline' | 'none';
11
+ //# sourceMappingURL=enter-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enter-policy.d.ts","sourceRoot":"","sources":["../src/enter-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,cAAc,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC;CAC3C;AAED,0FAA0F;AAC1F,wBAAgB,eAAe,CAC7B,OAAO,EAAE,gBAAgB,GACxB,YAAY,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAM3D"}
@@ -0,0 +1,13 @@
1
+ /** Keep host completion separate from internal grid editing and suggestion acceptance. */
2
+ export function mathEnterAction(context) {
3
+ if (context.hasSuggestion && !context.shiftKey)
4
+ return 'suggestion';
5
+ if (context.gridKind && context.shiftKey)
6
+ return 'grid-row';
7
+ if (context.mode === 'inline' || context.behavior === 'commit')
8
+ return 'commit';
9
+ if (context.gridKind)
10
+ return context.gridKind === 'matrix' ? 'none' : 'grid-row';
11
+ return 'newline';
12
+ }
13
+ //# sourceMappingURL=enter-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enter-policy.js","sourceRoot":"","sources":["../src/enter-policy.ts"],"names":[],"mappings":"AAUA,0FAA0F;AAC1F,MAAM,UAAU,eAAe,CAC7B,OAAyB;IAEzB,IAAI,OAAO,CAAC,aAAa,IAAI,CAAC,OAAO,CAAC,QAAQ;QAAE,OAAO,YAAY,CAAC;IACpE,IAAI,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ;QAAE,OAAO,UAAU,CAAC;IAC5D,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAChF,IAAI,OAAO,CAAC,QAAQ;QAAE,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC;IACjF,OAAO,SAAS,CAAC;AACnB,CAAC"}
package/dist/i18n.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ export type MathLocale = 'ko' | 'en' | (string & {});
2
+ export type MathMessageParameters = Readonly<Record<string, string | number>>;
3
+ export interface MathLocaleDefinition {
4
+ messages: Readonly<Record<string, string>>;
5
+ /** Search aliases keyed by suggestion ID, e.g. fraction or symbol-α. */
6
+ aliases?: Readonly<Record<string, readonly string[]>>;
7
+ direction?: 'ltr' | 'rtl';
8
+ }
9
+ /** JSON imports infer string for direction; registration validates and narrows it. */
10
+ export type MathLocaleConfiguration = Omit<MathLocaleDefinition, 'direction'> & {
11
+ direction?: string;
12
+ };
13
+ /** Register a JSON-compatible language pack before mounting; never translate formula content. */
14
+ export declare function registerMathLocale(locale: string, definition: MathLocaleConfiguration): void;
15
+ export declare const mathLocaleDirection: (locale: string) => "ltr" | "rtl";
16
+ export declare const mathLocaleAliases: (locale: string, id: string) => readonly string[];
17
+ /** A small dictionary resolver: lookup, fallback and named interpolation. No rendering or fetching. */
18
+ export declare function translate(locale: MathLocale, key: string, parameters?: MathMessageParameters): string;
19
+ export declare const mathEnglishMessages: Readonly<Record<string, string>>;
20
+ //# sourceMappingURL=i18n.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AACrD,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC;AAC9E,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3C,wEAAwE;IACxE,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC;IACtD,SAAS,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;CAC3B;AACD,sFAAsF;AACtF,MAAM,MAAM,uBAAuB,GAAG,IAAI,CAAC,oBAAoB,EAAE,WAAW,CAAC,GAAG;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AASF,iGAAiG;AACjG,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,uBAAuB,GAAG,IAAI,CAkB5F;AAkBD,eAAO,MAAM,mBAAmB,GAAI,QAAQ,MAAM,KAAG,KAAK,GAAG,KACW,CAAC;AACzE,eAAO,MAAM,iBAAiB,GAAI,QAAQ,MAAM,EAAE,IAAI,MAAM,KAAG,SAAS,MAAM,EAE7E,CAAC;AAEF,uGAAuG;AACvG,wBAAgB,SAAS,CACvB,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE,MAAM,EACX,UAAU,GAAE,qBAA0B,GACrC,MAAM,CAMR;AAMD,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAE/D,CAAC"}
package/dist/i18n.js ADDED
@@ -0,0 +1,58 @@
1
+ import english from './locales/en.js';
2
+ import korean from './locales/ko.js';
3
+ const builtins = {
4
+ en: english,
5
+ ko: korean,
6
+ };
7
+ const locales = new Map();
8
+ const normalize = (locale) => locale.trim().toLowerCase();
9
+ /** Register a JSON-compatible language pack before mounting; never translate formula content. */
10
+ export function registerMathLocale(locale, definition) {
11
+ const tag = normalize(locale);
12
+ const direction = definition.direction;
13
+ if (direction !== undefined && direction !== 'ltr' && direction !== 'rtl') {
14
+ throw new Error('Locale direction must be ltr or rtl.');
15
+ }
16
+ if (!tag || Object.hasOwn(builtins, tag))
17
+ throw new Error('Use a custom language tag; built-in ko/en cannot be replaced.');
18
+ locales.set(tag, {
19
+ ...definition,
20
+ direction,
21
+ messages: { ...definition.messages },
22
+ aliases: definition.aliases &&
23
+ Object.fromEntries(Object.entries(definition.aliases).map(([id, values]) => [id, [...values]])),
24
+ });
25
+ }
26
+ /** Exact locale overrides base locale; missing entries fall back to English. */
27
+ function definitions(locale) {
28
+ const tag = normalize(locale), base = tag.split('-')[0];
29
+ return [
30
+ ...new Set([
31
+ locales.get(tag),
32
+ Object.hasOwn(builtins, tag) ? builtins[tag] : undefined,
33
+ locales.get(base),
34
+ Object.hasOwn(builtins, base) ? builtins[base] : undefined,
35
+ builtins.en,
36
+ ].filter((item) => !!item)),
37
+ ];
38
+ }
39
+ export const mathLocaleDirection = (locale) => definitions(locale).find((item) => item.direction)?.direction ?? 'ltr';
40
+ export const mathLocaleAliases = (locale, id) => [
41
+ ...new Set(definitions(locale).flatMap((item) => item.aliases?.[id] ?? [])),
42
+ ];
43
+ /** A small dictionary resolver: lookup, fallback and named interpolation. No rendering or fetching. */
44
+ export function translate(locale, key, parameters = {}) {
45
+ for (const definition of definitions(locale)) {
46
+ const template = Object.hasOwn(definition.messages, key) ? definition.messages[key] : undefined;
47
+ if (template !== undefined)
48
+ return interpolate(template, parameters);
49
+ }
50
+ return key;
51
+ }
52
+ function interpolate(template, parameters) {
53
+ return template.replace(/\{([\w]+)\}/g, (placeholder, name) => Object.hasOwn(parameters, name) ? String(parameters[name]) : placeholder);
54
+ }
55
+ export const mathEnglishMessages = Object.freeze({
56
+ ...english.messages,
57
+ });
58
+ //# sourceMappingURL=i18n.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"i18n.js","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export * from './model.js';
2
+ export { MathEditor, type MathEditorProps } from './math-editor.js';
3
+ export { findSuggestions, acceptSuggestion, mathStructures, type MathSuggestion, } from './suggestions.js';
4
+ export * from './matrix.js';
5
+ export * from './lines.js';
6
+ export * from './tokens.js';
7
+ export * from './range.js';
8
+ export * from './i18n.js';
9
+ export * from './session.js';
10
+ export * from './templates.js';
11
+ export { mathSymbols } from './symbols.js';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,KAAK,cAAc,GACpB,MAAM,kBAAkB,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ export * from './model.js';
2
+ export { MathEditor } from './math-editor.js';
3
+ export { findSuggestions, acceptSuggestion, mathStructures, } from './suggestions.js';
4
+ export * from './matrix.js';
5
+ export * from './lines.js';
6
+ export * from './tokens.js';
7
+ export * from './range.js';
8
+ export * from './i18n.js';
9
+ export * from './session.js';
10
+ export * from './templates.js';
11
+ export { mathSymbols } from './symbols.js';
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAwB,MAAM,kBAAkB,CAAC;AACpE,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,cAAc,GAEf,MAAM,kBAAkB,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { type MathState } from './model.js';
2
+ /** Split only at a document-level text slot; nested structures retain their own editing rules. */
3
+ export declare function splitLine(state: MathState): MathState;
4
+ /** Backspace at the start of a top-level line merges it with the previous line. */
5
+ export declare function joinPreviousLine(state: MathState): MathState;
6
+ export declare function moveLineVertical(state: MathState, direction: -1 | 1): MathState;
7
+ //# sourceMappingURL=lines.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lines.d.ts","sourceRoot":"","sources":["../src/lines.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0C,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAEpF,kGAAkG;AAClG,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,CAmBrD;AAED,mFAAmF;AACnF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,CAkB5D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,SAAS,CAS/E"}
package/dist/lines.js ADDED
@@ -0,0 +1,51 @@
1
+ import { documentRows, row, textNode, textNodes } from './model.js';
2
+ /** Split only at a document-level text slot; nested structures retain their own editing rules. */
3
+ export function splitLine(state) {
4
+ const document = structuredClone(state.document), lines = documentRows(document);
5
+ const index = lines.findIndex((line) => line.children.some((node) => node.type === 'text' && node.id === state.caret.id));
6
+ if (index < 0)
7
+ return state;
8
+ const line = lines[index], at = line.children.findIndex((node) => node.id === state.caret.id);
9
+ const node = line.children[at];
10
+ if (node.type !== 'text')
11
+ return state;
12
+ const tail = textNode(node.text.slice(state.caret.end)), next = row();
13
+ next.children = [tail, ...line.children.slice(at + 1)];
14
+ node.text = node.text.slice(0, state.caret.start);
15
+ line.children = line.children.slice(0, at + 1);
16
+ lines.splice(index + 1, 0, next);
17
+ document.additionalLines = lines.slice(1);
18
+ return { document, caret: { id: tail.id, start: 0, end: 0 } };
19
+ }
20
+ /** Backspace at the start of a top-level line merges it with the previous line. */
21
+ export function joinPreviousLine(state) {
22
+ if (state.caret.start !== 0 || state.caret.end !== 0)
23
+ return state;
24
+ const document = structuredClone(state.document), lines = documentRows(document);
25
+ const index = lines.findIndex((line) => line.children[0].id === state.caret.id);
26
+ if (index < 1)
27
+ return state;
28
+ const previous = lines[index - 1], current = lines[index];
29
+ const tail = previous.children.at(-1), head = current.children[0];
30
+ if (tail.type !== 'text' || head.type !== 'text')
31
+ return state;
32
+ const offset = tail.text.length;
33
+ tail.text += head.text;
34
+ previous.children.push(...current.children.slice(1));
35
+ lines.splice(index, 1);
36
+ if (lines.length > 1)
37
+ document.additionalLines = lines.slice(1);
38
+ else
39
+ delete document.additionalLines;
40
+ return { document, caret: { id: tail.id, start: offset, end: offset } };
41
+ }
42
+ export function moveLineVertical(state, direction) {
43
+ const lines = documentRows(state.document);
44
+ const index = lines.findIndex((line) => line.children.some((node) => node.type === 'text' && node.id === state.caret.id));
45
+ if (index < 0 || !lines[index + direction])
46
+ return state;
47
+ const target = textNodes({ version: 1, root: lines[index + direction] })[0];
48
+ const offset = Math.min(state.caret.start, target.text.length);
49
+ return { ...state, caret: { id: target.id, start: offset, end: offset } };
50
+ }
51
+ //# sourceMappingURL=lines.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lines.js","sourceRoot":"","sources":["../src/lines.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,214 @@
1
+ // Generated from en.json; edit src/locales/en.json.
2
+ export default {
3
+ "direction": "ltr",
4
+ "messages": {
5
+ "symbol.plusMinus": "Plus or minus",
6
+ "symbol.minusPlus": "Minus or plus",
7
+ "symbol.notEqual": "Not equal",
8
+ "symbol.approximatelyEqual": "Approximately equal",
9
+ "symbol.equivalent": "Equivalent",
10
+ "symbol.lessThan": "Less than",
11
+ "symbol.greaterThan": "Greater than",
12
+ "symbol.lessOrEqual": "Less than or equal",
13
+ "symbol.greaterOrEqual": "Greater than or equal",
14
+ "symbol.rightArrow": "Right arrow",
15
+ "symbol.leftArrow": "Left arrow",
16
+ "symbol.leftRightArrow": "Left-right arrow",
17
+ "symbol.iff": "If and only if",
18
+ "symbol.elementOf": "Element of",
19
+ "symbol.notElementOf": "Not an element of",
20
+ "symbol.forAll": "For all",
21
+ "symbol.exists": "There exists",
22
+ "symbol.subsetOrEqual": "Subset or equal",
23
+ "symbol.emptySet": "Empty set",
24
+ "symbol.partialDerivative": "Partial derivative",
25
+ "symbol.logicalAnd": "Logical and",
26
+ "symbol.logicalOr": "Logical or",
27
+ "symbol.logicalNot": "Logical not",
28
+ "symbols.title": "All symbols",
29
+ "common.close": "Close",
30
+ "symbols.search": "Search symbols",
31
+ "symbols.searchPlaceholder": "Search by symbol, English, Korean or LaTeX",
32
+ "symbols.help": "Choose a symbol to insert at the last caret position or replace the selection.",
33
+ "symbols.noMatches": "No matching symbols.",
34
+ "editor.label": "Math editor",
35
+ "expression.label": "Expression",
36
+ "toolbar.label": "Math tools",
37
+ "selection.surface": "Math selection area",
38
+ "structure.fraction": "Fraction",
39
+ "structure.root": "Square root",
40
+ "structure.superscript": "Exponent",
41
+ "structure.subscript": "Subscript",
42
+ "structure.parentheses": "Parentheses",
43
+ "structure.brackets": "Brackets",
44
+ "structure.absolute": "Absolute value",
45
+ "structure.sum": "Sum",
46
+ "structure.product": "Product",
47
+ "structure.integral": "Integral",
48
+ "structure.matrix": "Matrix",
49
+ "structure.aligned": "Aligned equations",
50
+ "grid.alignedLabel": "Aligned equations",
51
+ "structure.cases": "Cases",
52
+ "slot.numerator": "Numerator",
53
+ "slot.denominator": "Denominator",
54
+ "slot.radicand": "Radicand",
55
+ "slot.base": "Base",
56
+ "slot.parentheses": "Inside parentheses",
57
+ "slot.brackets": "Inside brackets",
58
+ "slot.absolute": "Inside absolute value",
59
+ "slot.lowerLimit": "Lower limit",
60
+ "slot.upperLimit": "Upper limit",
61
+ "slot.expression": "Expression",
62
+ "slot.integrand": "Integrand",
63
+ "token.variable": "Variable",
64
+ "token.constant": "Numeric constant",
65
+ "token.symbol": "Symbol",
66
+ "token.space": "Space",
67
+ "token.empty": "Empty slot",
68
+ "token.composing": "Composing",
69
+ "token.legend": "Token kinds",
70
+ "history.undo": "Undo",
71
+ "history.redo": "Redo",
72
+ "matrix.preset": "Matrix preset",
73
+ "matrix.presetPlaceholder": "Matrix size ▾",
74
+ "matrix.edit": "Edit matrix",
75
+ "grid.editRows": "Edit equation rows",
76
+ "matrix.delimiters": "Matrix delimiters",
77
+ "delimiter.none": "No delimiters",
78
+ "delimiter.parentheses": "( ) Parentheses",
79
+ "delimiter.brackets": "[ ] Brackets",
80
+ "delimiter.braces": "{ } Braces",
81
+ "delimiter.bars": "| | Bars",
82
+ "delimiter.doubleBars": "‖ ‖ Double bars",
83
+ "grid.addRow": "Add row",
84
+ "grid.deleteRow": "Delete row",
85
+ "grid.addColumn": "Add column",
86
+ "grid.deleteColumn": "Delete column",
87
+ "grid.deleteRowShortcut": "Delete row: Alt(⌥)+Shift+↑",
88
+ "grid.deleteColumnShortcut": "Delete column: Alt(⌥)+Shift+←",
89
+ "clipboard.cut": "Selected math cut.",
90
+ "clipboard.copied": "Selected math copied as structure and LaTeX.",
91
+ "clipboard.pasted": "Pasted.",
92
+ "clipboard.multilineRejected": "Paste multiple lines into a top-level expression row.",
93
+ "editor.interactionHint": "Click to edit · Drag to select · Esc to preview",
94
+ "grid.selectionHint": "Structure selected · Backspace/Delete to remove · Esc to cancel",
95
+ "selection.toolbar": "Wrap selected math",
96
+ "selection.highlighted": "Wrap highlighted range",
97
+ "selection.singleRowRequired": "Select a range within one row.",
98
+ "suggestion.label": "Math suggestions",
99
+ "suggestion.composing": "Composing · Choose after committing",
100
+ "suggestion.keyboardHint": "↑ ↓ to choose · Enter to apply",
101
+ "suggestion.imeHint": "Suggestion preview · Enter and arrows are reserved for the IME",
102
+ "suggestion.keepSource": "Keep typing, or use Space / Esc to keep the source",
103
+ "matrix.keyboardHint": "Shift+Enter add row · Shift+Space add column · Alt(⌥)+Shift+↑ delete row · Alt(⌥)+Shift+← delete column",
104
+ "aligned.inputHint": "Left: left-hand side · Right: start with =",
105
+ "cases.inputHint": "Left: expression · Right: condition",
106
+ "grid.keyboardHint": "Enter add row · Alt(⌥)+Shift+↑ delete row",
107
+ "structure.matrixDetail": "2×2 matrix · Editable rows and columns",
108
+ "structure.alignedDetail": "Two rows with aligned left and right sides",
109
+ "structure.casesDetail": "Write expressions alongside conditions",
110
+ "structure.fractionDetail": "Edit numerator and denominator",
111
+ "structure.rootDetail": "Edit inside a square root",
112
+ "structure.superscriptDetail": "Write a superscript",
113
+ "structure.subscriptDetail": "Write a subscript",
114
+ "structure.parenthesesDetail": "Write inside parentheses",
115
+ "structure.bracketsDetail": "Write inside brackets",
116
+ "structure.absoluteDetail": "Write inside absolute value",
117
+ "structure.limitsDetail": "Lower limit, upper limit and expression",
118
+ "structure.integralDetail": "Lower limit, upper limit and integrand",
119
+ "suggestion.insertSymbol": "Insert symbol",
120
+ "matrix.identityDetail": "Diagonal ones, zeros elsewhere",
121
+ "aligned.leftHint": "Left: left-hand side",
122
+ "aligned.rightHint": "Right: start with =",
123
+ "cases.leftHint": "Left: expression",
124
+ "cases.rightHint": "Right: condition",
125
+ "grid.enterAddRow": "Enter add row",
126
+ "grid.altDeleteRow": "Alt(⌥)+Shift+↑ delete row",
127
+ "symbol.naturals": "Natural numbers",
128
+ "symbol.integers": "Integers",
129
+ "symbol.rationals": "Rational numbers",
130
+ "symbol.reals": "Real numbers",
131
+ "symbol.complexes": "Complex numbers",
132
+ "symbol.contains": "Contains as an element",
133
+ "symbol.superset": "Superset",
134
+ "symbol.supersetOrEqual": "Superset or equal",
135
+ "symbol.notSubsetOrEqual": "Not a subset or equal",
136
+ "symbol.setDifference": "Set difference",
137
+ "symbol.perpendicular": "Perpendicular",
138
+ "symbol.parallel": "Parallel",
139
+ "symbol.congruent": "Congruent",
140
+ "symbol.similar": "Similar",
141
+ "symbol.mapsTo": "Maps to",
142
+ "symbol.ellipsis": "Ellipsis",
143
+ "symbol.centeredDots": "Centered dots",
144
+ "symbol.verticalDots": "Vertical dots",
145
+ "symbol.diagonalDots": "Diagonal dots",
146
+ "template.label": "Math templates",
147
+ "template.placeholder": "Templates ▾",
148
+ "template.detail": "Editable math template",
149
+ "template.quadratic": "Quadratic formula",
150
+ "template.pythagorean": "Pythagorean theorem",
151
+ "symbol.degree": "Degree",
152
+ "symbol.angle": "Angle",
153
+ "symbol.plus": "Plus",
154
+ "symbol.minus": "Minus",
155
+ "symbol.times": "Times",
156
+ "symbol.dot": "Dot",
157
+ "symbol.divide": "Divide",
158
+ "symbol.equal": "Equal",
159
+ "symbol.proportional": "Proportional",
160
+ "symbol.implies": "Implies",
161
+ "symbol.union": "Union",
162
+ "symbol.intersection": "Intersection",
163
+ "symbol.subset": "Subset",
164
+ "symbol.infinity": "Infinity",
165
+ "symbol.nabla": "Nabla",
166
+ "symbol.alpha": "Alpha",
167
+ "symbol.beta": "Beta",
168
+ "symbol.gamma": "Gamma",
169
+ "symbol.delta": "Delta",
170
+ "symbol.epsilon": "Epsilon",
171
+ "symbol.zeta": "Zeta",
172
+ "symbol.eta": "Eta",
173
+ "symbol.theta": "Theta",
174
+ "symbol.iota": "Iota",
175
+ "symbol.kappa": "Kappa",
176
+ "symbol.lambda": "Lambda",
177
+ "symbol.mu": "Mu",
178
+ "symbol.nu": "Nu",
179
+ "symbol.xi": "Xi",
180
+ "symbol.pi": "Pi",
181
+ "symbol.rho": "Rho",
182
+ "symbol.sigma": "Sigma",
183
+ "symbol.tau": "Tau",
184
+ "symbol.upsilon": "Upsilon",
185
+ "symbol.phi": "Phi",
186
+ "symbol.chi": "Chi",
187
+ "symbol.psi": "Psi",
188
+ "symbol.omega": "Omega",
189
+ "symbol.upperGamma": "Uppercase Gamma",
190
+ "symbol.upperDelta": "Uppercase Delta",
191
+ "symbol.upperTheta": "Uppercase Theta",
192
+ "symbol.upperLambda": "Uppercase Lambda",
193
+ "symbol.upperXi": "Uppercase Xi",
194
+ "symbol.upperPi": "Uppercase Pi",
195
+ "symbol.upperSigma": "Uppercase Sigma",
196
+ "symbol.upperPhi": "Uppercase Phi",
197
+ "symbol.upperPsi": "Uppercase Psi",
198
+ "symbol.upperOmega": "Uppercase Omega",
199
+ "matrix.editableDimensions": "Editable rows and columns",
200
+ "expression.line": "Expression line {line}",
201
+ "suggestion.create": "Create from “{query}”",
202
+ "grid.cell": "{kind} row {row} column {column}",
203
+ "grid.position": "Row {row}, column {column}",
204
+ "grid.dimensions": "{rows} rows, {columns} columns · Editable rows and columns",
205
+ "selection.wrap": "Wrap selection: {kind}",
206
+ "matrix.size": "Matrix {rows}×{columns}",
207
+ "matrix.identity": "Identity {rows}×{columns} matrix",
208
+ "matrix.insert": "Insert {rows}×{columns} matrix",
209
+ "matrix.insertIdentity": "Insert identity {rows}×{columns} matrix",
210
+ "matrix.zero": "Zero matrix {rows}×{columns}",
211
+ "matrix.vector": "Column vector {rows}"
212
+ },
213
+ "aliases": {}
214
+ };