erl-mathtextx-editor 0.3.2 → 0.3.6

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 (49) hide show
  1. package/CHANGELOG.md +88 -0
  2. package/README.md +14 -1
  3. package/dist/{CellPropertiesDialogImpl-CgRJUUSC.js → CellPropertiesDialogImpl-NSTfG9SA.js} +1 -1
  4. package/dist/ContentViewer-LqSkiQjT.js +161 -0
  5. package/dist/ImageInsertDialog-DDxR_Cah.js +331 -0
  6. package/dist/{InsertTableDialogImpl-CWM11lNz.js → InsertTableDialogImpl-DrW9QTDd.js} +1 -1
  7. package/dist/{LinkDialogImpl-DrEasmBM.js → LinkDialogImpl-BXjhfEiE.js} +1 -1
  8. package/dist/MathTextXEditor.d.ts +1 -1
  9. package/dist/{TablePropertiesDialogImpl-BPcKuKCT.js → TablePropertiesDialogImpl-C2eqgZMa.js} +1 -1
  10. package/dist/{TableTemplatesDialogImpl-DYrlbe5p.js → TableTemplatesDialogImpl-B2DJBmzm.js} +1 -1
  11. package/dist/assets/erl-mathtextx-editor.css +1 -1
  12. package/dist/assets/viewer.css +1 -1
  13. package/dist/erl-mathtextx-editor.js +45 -27
  14. package/dist/erl-mathtextx-editor.umd.cjs +470 -200
  15. package/dist/export-deps-Tu2DJTcR.js +14815 -0
  16. package/dist/{index-DYrjnSa6.js → index-CvLezwrJ.js} +1 -1
  17. package/dist/{index-CHqs4QOj.js → index-D1pCAIcb.js} +6260 -4294
  18. package/dist/index-D7oo0rd0.js +14235 -0
  19. package/dist/index.d.ts +9 -1
  20. package/dist/index.es-UDhZ1Ncp.js +5632 -0
  21. package/dist/jszip.min-I9rjwvpP.js +2341 -0
  22. package/dist/math/MathInputModeContext.d.ts +7 -0
  23. package/dist/math/TemplatePanel.d.ts +4 -1
  24. package/dist/math/mathFieldFontStyles.d.ts +7 -0
  25. package/dist/math/mathFieldSpaceKey.d.ts +10 -0
  26. package/dist/{tiptap-K3rU-Wjn.js → tiptap-BiWGiMFj.js} +27 -27
  27. package/dist/toolbar/MainToolbar.d.ts +3 -1
  28. package/dist/toolbar/MathToolbar.d.ts +9 -2
  29. package/dist/types/index.d.ts +18 -5
  30. package/dist/utils/docxImporter.d.ts +1 -0
  31. package/dist/utils/docxOmmlPreprocess.d.ts +12 -0
  32. package/dist/utils/imageFileValidation.d.ts +14 -0
  33. package/dist/utils/isLatexContent.d.ts +5 -0
  34. package/dist/utils/mathMlToLatex.d.ts +4 -0
  35. package/dist/utils/microsoftMathPaste.d.ts +43 -0
  36. package/dist/utils/ommlToLatex.d.ts +11 -0
  37. package/dist/utils/reuploadImagesInHTML.d.ts +9 -0
  38. package/dist/utils/sanitizeConfig.d.ts +11 -0
  39. package/dist/utils/unicodeMathToLatex.d.ts +24 -0
  40. package/dist/{viewer-deps-BDYoL2Ts.js → viewer-deps-_HnWniSt.js} +5 -0
  41. package/dist/viewer.js +1 -1
  42. package/package.json +23 -10
  43. package/dist/ContentViewer-RijJ5nlJ.js +0 -45
  44. package/dist/ImageInsertDialog-DbUscLs1.js +0 -244
  45. package/dist/components/__tests__/WordCount.test.d.ts +0 -1
  46. package/dist/core/__tests__/serializer.test.d.ts +0 -1
  47. package/dist/index-CVlS1KL8.js +0 -16549
  48. package/dist/viewer-styles.d.ts +0 -1
  49. package/dist/viewer-styles.js +0 -1
@@ -0,0 +1,7 @@
1
+ import { MathInputMode } from '../types';
2
+ export declare const MATH_INPUT_MODE_STORAGE_KEY = "mtx-math-input-mode";
3
+ export declare const MathInputModeContext: import('react').Context<MathInputMode>;
4
+ export declare function useMathInputMode(): MathInputMode;
5
+ export declare function isValidMathInputMode(value: unknown): value is MathInputMode;
6
+ export declare function readStoredMathInputMode(): MathInputMode | null;
7
+ export declare function storeMathInputMode(mode: MathInputMode): void;
@@ -1,5 +1,8 @@
1
+ import { EducationLevel } from '../types';
1
2
  export interface TemplatePanelProps {
2
3
  onInsert: (latex: string) => void;
3
4
  onClose: () => void;
5
+ /** Restrict / preselect education level filter */
6
+ educationLevel?: EducationLevel;
4
7
  }
5
- export declare function TemplatePanel({ onInsert, onClose }: TemplatePanelProps): import("react/jsx-runtime").JSX.Element;
8
+ export declare function TemplatePanel({ onInsert, onClose, educationLevel }: TemplatePanelProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,7 @@
1
+ /** Primary Arabic text font for math fields and KaTeX output */
2
+ export declare const ADOBE_NASKH_FONT_FAMILY = "Adobe Naskh Medium";
3
+ export declare const ADOBE_NASKH_FONT_STACK = "'Adobe Naskh Medium', 'Adobe Naskh', 'Noto Naskh Arabic', 'Amiri', 'Traditional Arabic', serif";
4
+ /** CSS injected into MathLive shadow roots (global editor.css does not apply there). */
5
+ export declare const MATHFIELD_CUSTOM_FONT_CSS = "\n.mt-font-arabic {\n font-family: 'Adobe Naskh Medium', 'Adobe Naskh', 'Noto Naskh Arabic', 'Amiri', 'Traditional Arabic', serif !important;\n font-weight: 500;\n direction: rtl;\n unicode-bidi: embed;\n}\n";
6
+ /** Inject Arabic / custom font classes into a math-field shadow DOM. */
7
+ export declare function injectMathFieldFontStyles(mathField: HTMLElement): void;
@@ -0,0 +1,10 @@
1
+ type MathFieldSpaceTarget = {
2
+ executeCommand?: (command: any) => void;
3
+ value?: string;
4
+ };
5
+ /**
6
+ * Map Space → thin space (\,) in math mode. Ignores key repeat (held spacebar).
7
+ */
8
+ export declare function handleMathFieldSpaceKey(evt: Event, mathField: MathFieldSpaceTarget, onValueChange?: (value: string) => void): boolean;
9
+ export declare const MATHFIELD_SPACE_LATEX = "\\,";
10
+ export {};
@@ -1,4 +1,4 @@
1
- import ie, { createRef as Ed, memo as Md, createElement as Td, createContext as ja, version as qo, useContext as Od, useRef as Ad, useState as Wa, useDebugValue as Ua, useEffect as Ka, forwardRef as Nd, useLayoutEffect as vd } from "react";
1
+ import ie, { useRef as Ed, useState as ja, useDebugValue as Wa, useEffect as Ua, createRef as Md, memo as Td, createElement as Od, forwardRef as Ad, createContext as Ka, useLayoutEffect as Nd, version as qo, useContext as vd } from "react";
2
2
  import Rd, { flushSync as Dd } from "react-dom";
3
3
  function fe(n) {
4
4
  this.content = n;
@@ -12607,7 +12607,7 @@ class Hg extends ie.Component {
12607
12607
  );
12608
12608
  }
12609
12609
  }
12610
- const $g = Nd((n, e) => {
12610
+ const $g = Ad((n, e) => {
12611
12611
  const t = ie.useMemo(() => Math.floor(Math.random() * 4294967295).toString(), [n.editor]);
12612
12612
  return ie.createElement(Hg, {
12613
12613
  key: t,
@@ -12769,7 +12769,7 @@ function Wg() {
12769
12769
  }
12770
12770
  process.env.NODE_ENV === "production" ? _i.exports = jg() : _i.exports = Wg();
12771
12771
  var Ug = _i.exports;
12772
- const Kg = typeof window < "u" ? vd : Ka;
12772
+ const Kg = typeof window < "u" ? Nd : Ua;
12773
12773
  class qg {
12774
12774
  constructor(e) {
12775
12775
  this.transactionNumber = 0, this.lastTransactionNumber = 0, this.subscribers = /* @__PURE__ */ new Set(), this.editor = e, this.lastSnapshot = { editor: e, transactionNumber: 0 }, this.getSnapshot = this.getSnapshot.bind(this), this.getServerSnapshot = this.getServerSnapshot.bind(this), this.watch = this.watch.bind(this), this.subscribe = this.subscribe.bind(this);
@@ -12810,8 +12810,8 @@ class qg {
12810
12810
  }
12811
12811
  function Jg(n) {
12812
12812
  var e;
12813
- const [t] = Wa(() => new qg(n.editor)), r = Ug.useSyncExternalStoreWithSelector(t.subscribe, t.getSnapshot, t.getServerSnapshot, n.selector, (e = n.equalityFn) !== null && e !== void 0 ? e : Vg);
12814
- return Kg(() => t.watch(n.editor), [n.editor, t]), Ua(r), r;
12813
+ const [t] = ja(() => new qg(n.editor)), r = Ug.useSyncExternalStoreWithSelector(t.subscribe, t.getSnapshot, t.getServerSnapshot, n.selector, (e = n.equalityFn) !== null && e !== void 0 ? e : Vg);
12814
+ return Kg(() => t.watch(n.editor), [n.editor, t]), Wa(r), r;
12815
12815
  }
12816
12816
  const sa = process.env.NODE_ENV !== "production", Hi = typeof window > "u", Gg = Hi || !!(typeof window < "u" && window.next);
12817
12817
  class To {
@@ -12952,21 +12952,21 @@ class To {
12952
12952
  }
12953
12953
  }
12954
12954
  function tS(n = {}, e = []) {
12955
- const t = Ad(n);
12955
+ const t = Ed(n);
12956
12956
  t.current = n;
12957
- const [r] = Wa(() => new To(t)), s = Rs.useSyncExternalStore(r.subscribe, r.getEditor, r.getServerSnapshot);
12958
- return Ua(s), Ka(r.onRender(e)), Jg({
12957
+ const [r] = ja(() => new To(t)), s = Rs.useSyncExternalStore(r.subscribe, r.getEditor, r.getServerSnapshot);
12958
+ return Wa(s), Ua(r.onRender(e)), Jg({
12959
12959
  editor: s,
12960
12960
  selector: ({ transactionNumber: i }) => n.shouldRerenderOnTransaction === !1 ? null : n.immediatelyRender && i === 0 ? 0 : i + 1
12961
12961
  }), s;
12962
12962
  }
12963
- const Yg = ja({
12963
+ const Yg = Ka({
12964
12964
  editor: null
12965
12965
  });
12966
12966
  Yg.Consumer;
12967
- const Iu = ja({
12967
+ const Iu = Ka({
12968
12968
  onDragStart: void 0
12969
- }), Qg = () => Od(Iu), nS = ie.forwardRef((n, e) => {
12969
+ }), Qg = () => vd(Iu), nS = ie.forwardRef((n, e) => {
12970
12970
  const { onDragStart: t } = Qg(), r = n.as || "div";
12971
12971
  return (
12972
12972
  // @ts-ignore
@@ -13077,7 +13077,7 @@ class ny extends Rg {
13077
13077
  getPos: () => this.getPos(),
13078
13078
  updateAttributes: (c = {}) => this.updateAttributes(c),
13079
13079
  deleteNode: () => this.deleteNode(),
13080
- ref: Ed()
13080
+ ref: Md()
13081
13081
  };
13082
13082
  if (!this.component.displayName) {
13083
13083
  const c = (u) => u.charAt(0).toUpperCase() + u.substring(1);
@@ -13085,7 +13085,7 @@ class ny extends Rg {
13085
13085
  }
13086
13086
  const s = { onDragStart: this.onDragStart.bind(this), nodeViewContentRef: (c) => {
13087
13087
  c && this.contentDOMElement && c.firstChild !== this.contentDOMElement && (c.hasAttribute("data-node-view-wrapper") && c.removeAttribute("data-node-view-wrapper"), c.appendChild(this.contentDOMElement));
13088
- } }, i = this.component, o = Md((c) => ie.createElement(Iu.Provider, { value: s }, Td(i, c)));
13088
+ } }, i = this.component, o = Td((c) => ie.createElement(Iu.Provider, { value: s }, Od(i, c)));
13089
13089
  o.displayName = "ReactNodeView";
13090
13090
  let l = this.node.isInline ? "span" : "div";
13091
13091
  this.options.as && (l = this.options.as);
@@ -19077,21 +19077,21 @@ export {
19077
19077
  I as T,
19078
19078
  iS as U,
19079
19079
  ee as a,
19080
- hS as b,
19081
- mS as c,
19082
- gS as d,
19083
- Eb as e,
19084
- lS as f,
19085
- bS as g,
19086
- CS as h,
19087
- pS as i,
19088
- sS as j,
19089
- ES as k,
19090
- cS as l,
19080
+ lS as b,
19081
+ bS as c,
19082
+ CS as d,
19083
+ pS as e,
19084
+ sS as f,
19085
+ ES as g,
19086
+ cS as h,
19087
+ aS as i,
19088
+ wS as j,
19089
+ dS as k,
19090
+ mS as l,
19091
19091
  j as m,
19092
- aS as n,
19093
- wS as o,
19094
- dS as p,
19092
+ gS as n,
19093
+ hS as o,
19094
+ Eb as p,
19095
19095
  eS as q,
19096
19096
  tS as u
19097
19097
  };
@@ -1,9 +1,11 @@
1
1
  import { default as React } from 'react';
2
2
  import { Editor } from '@tiptap/react';
3
- import { ToolbarMode } from '../types';
3
+ import { ToolbarItem, ToolbarMode } from '../types';
4
4
  interface MainToolbarProps {
5
5
  editor: Editor | null;
6
6
  toolbarMode?: ToolbarMode;
7
+ /** When set, only tools mapped to these items are shown */
8
+ toolbar?: ToolbarItem[];
7
9
  onInsertMath?: (tab?: string) => void;
8
10
  onInsertBlockMath?: () => void;
9
11
  onInsertImage?: () => void;
@@ -1,9 +1,16 @@
1
- import { ToolbarMode } from '../types';
1
+ import { MathInputMode, MathToolbarItem, ToolbarMode } from '../types';
2
2
  interface MathToolbarProps {
3
3
  onInsertLatex: (latex: string) => void;
4
4
  onToggleSymbols: () => void;
5
5
  onToggleTemplates?: () => void;
6
6
  mode?: ToolbarMode;
7
+ /** When set, only matching formula buttons / panels are shown */
8
+ items?: MathToolbarItem[];
9
+ /** Word-like Conversions mode */
10
+ mathInputMode?: MathInputMode;
11
+ onMathInputModeChange?: (mode: MathInputMode) => void;
12
+ onConvertToMath?: () => void;
13
+ onConvertToLatexText?: () => void;
7
14
  }
8
- export declare function MathToolbar({ onInsertLatex, onToggleSymbols, onToggleTemplates, mode }: MathToolbarProps): import("react/jsx-runtime").JSX.Element;
15
+ export declare function MathToolbar({ onInsertLatex, onToggleSymbols, onToggleTemplates, mode, items, mathInputMode, onMathInputModeChange, onConvertToMath, onConvertToLatexText, }: MathToolbarProps): import("react/jsx-runtime").JSX.Element;
9
16
  export {};
@@ -9,11 +9,17 @@ export type EducationLevel = 'sd' | 'smp' | 'sma' | 'all';
9
9
  export type OutputFormat = 'html' | 'json';
10
10
  /** Toolbar density mode */
11
11
  export type ToolbarMode = 'basic' | 'advanced' | 'olimpiade';
12
+ /**
13
+ * Word-like math input / paste interpretation mode.
14
+ * UI exposes `latex` (default, also accepts Unicode/OMML) and `text`.
15
+ * `unicode` remains for API/back-compat only.
16
+ */
17
+ export type MathInputMode = 'latex' | 'unicode' | 'text';
12
18
  /** Main editor props */
13
19
  export interface MathTextXEditorProps {
14
20
  /** Initial content (HTML string or TipTap JSON) */
15
21
  content?: string;
16
- /** Called when content changes — returns HTML string */
22
+ /** Called when content changes — returns HTML string (or JSON string when outputFormat is `json`) */
17
23
  onChange?: (html: string) => void;
18
24
  /** Called when user triggers save (Ctrl+S) */
19
25
  onSave?: (html: string) => void;
@@ -21,16 +27,23 @@ export interface MathTextXEditorProps {
21
27
  editable?: boolean;
22
28
  /** Placeholder text when editor is empty */
23
29
  placeholder?: string;
24
- /** Which toolbar items to show */
30
+ /** Which toolbar items to show (filters MainToolbar buttons) */
25
31
  toolbar?: ToolbarItem[];
26
32
  /** Preset toolbar density mode */
27
33
  toolbarMode?: ToolbarMode;
28
34
  /** Which math toolbar items to show */
29
35
  mathToolbar?: MathToolbarItem[];
30
- /** Education level for formula templates */
36
+ /** Education level for formula templates (filters TemplatePanel) */
31
37
  templates?: EducationLevel;
32
- /** Output format */
38
+ /** Output format for onChange / onSave (`html` default, or TipTap `json` string) */
33
39
  outputFormat?: OutputFormat;
40
+ /**
41
+ * Word-like paste/input interpretation: `latex` (default), `unicode`, or `text`.
42
+ * When omitted, uses last saved preference or `latex`.
43
+ */
44
+ mathInputMode?: MathInputMode;
45
+ /** Called when the user changes the Conversions mode toggle */
46
+ onMathInputModeChange?: (mode: MathInputMode) => void;
34
47
  /** Custom class name for the editor container */
35
48
  className?: string;
36
49
  /** Minimum height of the editor */
@@ -41,7 +54,7 @@ export interface MathTextXEditorProps {
41
54
  autoFocus?: boolean;
42
55
  /** Image upload handler — return the URL of the uploaded image */
43
56
  onImageUpload?: (file: File) => Promise<string>;
44
- /** Transform HTML before pasting — e.g. re-upload images in pasted content */
57
+ /** Transform HTML before pasting — e.g. re-upload images in pasted content. Overrides default re-upload when set. */
45
58
  onBeforePasteHTML?: (html: string) => Promise<string>;
46
59
  /** Table styling mode: 'custom' uses mtx-table CSS themes, 'native' uses plain TipTap/ProseMirror table */
47
60
  tableStyle?: 'custom' | 'native';
@@ -9,6 +9,7 @@ export interface DocxImportResult {
9
9
  /**
10
10
  * Convert a .docx File to clean HTML via mammoth.js.
11
11
  *
12
+ * OMML equations are converted to LaTeX math spans before mammoth runs.
12
13
  * Images embedded in the .docx are extracted and returned separately
13
14
  * so they can be re-uploaded by the host application.
14
15
  */
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Pre-process DOCX so OMML equations become markers mammoth can keep as text,
3
+ * then post-process HTML into mtx math spans.
4
+ */
5
+ /**
6
+ * Unzip DOCX, convert OMML in word/*.xml to text markers, re-zip.
7
+ */
8
+ export declare function preprocessDocxOmml(arrayBuffer: ArrayBuffer): Promise<ArrayBuffer>;
9
+ /**
10
+ * Replace MTX math markers left in mammoth HTML with math node spans.
11
+ */
12
+ export declare function rewriteDocxMathMarkers(html: string): string;
@@ -0,0 +1,14 @@
1
+ export type ImageValidationResult = {
2
+ valid: true;
3
+ } | {
4
+ valid: false;
5
+ error: string;
6
+ };
7
+ /**
8
+ * Validate image MIME, size, and magic-byte signature (including WebP RIFF+WEBP).
9
+ */
10
+ export declare function validateImageFile(file: File): Promise<ImageValidationResult>;
11
+ /**
12
+ * Check whether a URL is safe to insert as an image src (http/https only).
13
+ */
14
+ export declare function isSafeImageUrl(raw: string): boolean;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Detect if pasted text looks like LaTeX content.
3
+ * Checks for common LaTeX delimiters and commands.
4
+ */
5
+ export declare function isLatexContent(text: string): boolean;
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Convert MathML string to LaTeX using MathLive (browser-only, lazy-loaded).
3
+ */
4
+ export declare function mathMlToLatex(mathml: string): Promise<string | null>;
@@ -0,0 +1,43 @@
1
+ import { MathInputMode } from '../types';
2
+ export type ResolvedMathPaste = {
3
+ latex: string;
4
+ /** Prefer block math node when true */
5
+ display: 'inline' | 'block';
6
+ source: 'latex' | 'mathml' | 'unicode' | 'omml';
7
+ };
8
+ /**
9
+ * True when clipboard carries *structured* math (OMML / MathML / LaTeX) that
10
+ * should win over Word's equation image snapshot.
11
+ *
12
+ * Unicode Math alone does **not** qualify — Word's Unicode equations are often
13
+ * best kept as the clipboard image (linear Unicode text is lossy / incomplete).
14
+ */
15
+ export declare function clipboardHasMathContent(clipboard: DataTransfer | null | undefined): boolean;
16
+ /**
17
+ * Strip common LaTeX delimiters and detect block vs inline.
18
+ */
19
+ export declare function normalizeLatexSource(raw: string): {
20
+ latex: string;
21
+ display: 'inline' | 'block';
22
+ };
23
+ /**
24
+ * Resolve clipboard / plain text into LaTeX for math nodes.
25
+ * `mode` gates which detection paths run (Word-like Conversions).
26
+ * - latex: LaTeX MIME / plain LaTeX / TeX annotations only
27
+ * - unicode: Unicode / OMML / MathML (plus explicit text/latex MIME)
28
+ * - text: always null (caller inserts plain text)
29
+ */
30
+ export declare function resolveMicrosoftMathPaste(clipboard: DataTransfer | null | undefined, mode?: MathInputMode): Promise<ResolvedMathPaste | null>;
31
+ /**
32
+ * Resolve a plain string (selection / Convert) into LaTeX using the active mode.
33
+ */
34
+ export declare function resolveMathText(text: string, mode?: MathInputMode): ResolvedMathPaste | null;
35
+ /**
36
+ * Re-normalize latex already stored on a math node (Convert on selection).
37
+ */
38
+ export declare function normalizeExistingMathLatex(latex: string): string;
39
+ /**
40
+ * Replace MathML / OMML / Unicode-math-looking runs in Office HTML with mtx math spans.
41
+ * Call BEFORE namespace stripping so `<math>` and `<m:oMath>` survive.
42
+ */
43
+ export declare function rewriteOfficeHtmlMath(html: string): Promise<string>;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Convert Office Math Markup Language (OMML) fragments to LaTeX.
3
+ * Covers common Word equation structures used in education content.
4
+ */
5
+ /**
6
+ * Parse an OMML XML/HTML string and return LaTeX.
7
+ * Accepts a full `<m:oMath>` / `<m:oMathPara>` fragment or inner OMML.
8
+ */
9
+ export declare function ommlToLatex(omml: string): string | null;
10
+ /** True when HTML/XML contains OMML math. */
11
+ export declare function hasOmml(html: string): boolean;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Re-upload images found in HTML (paste / Office) via a host upload callback.
3
+ * Handles data-URI and http(s) srcs; leaves failures unchanged.
4
+ */
5
+ /**
6
+ * Find `<img src>` values, upload via `onImageUpload`, replace with returned URLs.
7
+ * Skips blob: URLs and already-same results. Failures leave the original src.
8
+ */
9
+ export declare function reuploadImagesInHTML(html: string, onImageUpload: (file: File) => Promise<string>): Promise<string>;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Shared DOMPurify allowlists for editor input, paste, and viewer output.
3
+ * Keep these in sync so XSS policy is consistent across surfaces.
4
+ */
5
+ export declare const SANITIZE_ALLOWED_TAGS: string[];
6
+ export declare const SANITIZE_ALLOWED_ATTR: string[];
7
+ export declare const SANITIZE_OPTIONS: {
8
+ ALLOWED_TAGS: string[];
9
+ ALLOWED_ATTR: string[];
10
+ ALLOW_DATA_ATTR: true;
11
+ };
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Convert Microsoft Word-style Unicode math characters to LaTeX.
3
+ * Covers Mathematical Alphanumeric Symbols, super/subscripts, operators,
4
+ * and linear UnicodeMath build-up (`1/2√2` → `\frac{1}{2}\sqrt{2}`).
5
+ */
6
+ /**
7
+ * True when text looks like Unicode math / Word linear math, not normal prose.
8
+ */
9
+ export declare function isUnicodeMathContent(text: string): boolean;
10
+ /**
11
+ * Build up Word/UnicodeMath linear forms into structured LaTeX.
12
+ * e.g. `1/2√2` → `\frac{1}{2}\sqrt{2}`, `Q_enc/ε_0` → `\frac{Q_{enc}}{\varepsilon_0}`
13
+ */
14
+ export declare function buildUpLinearMath(input: string): string;
15
+ /**
16
+ * Insert a space after a known LaTeX control word when the next char would be
17
+ * glued into the command name. e.g. `\timesE` → `\times E`, `\partialB` → `\partial B`.
18
+ * Uses longest-match words so `\int` is not split as `\in` + `t`.
19
+ */
20
+ export declare function separateLatexControlWords(input: string): string;
21
+ /**
22
+ * Convert Unicode math text to a LaTeX string suitable for MathLive / mathInline.
23
+ */
24
+ export declare function unicodeMathToLatex(text: string): string;
@@ -12135,6 +12135,10 @@ function ii() {
12135
12135
  }, e;
12136
12136
  }
12137
12137
  var Ts = ii();
12138
+ const As = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
12139
+ __proto__: null,
12140
+ default: Ts
12141
+ }, Symbol.toStringTag, { value: "Module" }));
12138
12142
  ta.__defineMacro("\\ce", function(r) {
12139
12143
  return si(r.consumeArgs(1)[0], "ce");
12140
12144
  });
@@ -14441,6 +14445,7 @@ var t0 = {
14441
14445
  }
14442
14446
  };
14443
14447
  export {
14448
+ As as a,
14444
14449
  ta as k,
14445
14450
  Ts as p
14446
14451
  };
package/dist/viewer.js CHANGED
@@ -1,4 +1,4 @@
1
- import { C as r } from "./ContentViewer-RijJ5nlJ.js";
1
+ import { C as r } from "./ContentViewer-LqSkiQjT.js";
2
2
  export {
3
3
  r as ContentViewer
4
4
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "erl-mathtextx-editor",
3
- "version": "0.3.2",
3
+ "version": "0.3.6",
4
4
  "description": "Visual math editor component for solutest.id — CKEditor replacement with zero-LaTeX approach",
5
5
  "type": "module",
6
6
  "main": "./dist/erl-mathtextx-editor.umd.cjs",
@@ -8,17 +8,20 @@
8
8
  "types": "./dist/index.d.ts",
9
9
  "exports": {
10
10
  ".": {
11
+ "types": "./dist/index.d.ts",
11
12
  "import": "./dist/erl-mathtextx-editor.js",
12
- "require": "./dist/erl-mathtextx-editor.umd.cjs",
13
- "types": "./dist/index.d.ts"
13
+ "require": "./dist/erl-mathtextx-editor.umd.cjs"
14
14
  },
15
15
  "./viewer": {
16
- "import": "./dist/viewer.js",
17
- "types": "./dist/viewer.d.ts"
16
+ "types": "./dist/viewer.d.ts",
17
+ "import": "./dist/viewer.js"
18
18
  },
19
19
  "./styles": "./dist/assets/erl-mathtextx-editor.css",
20
- "./viewer/styles": "./dist/viewer-styles.js"
20
+ "./viewer/styles": "./dist/assets/viewer.css"
21
21
  },
22
+ "sideEffects": [
23
+ "**/*.css"
24
+ ],
22
25
  "files": [
23
26
  "dist",
24
27
  "README.md",
@@ -32,7 +35,9 @@
32
35
  "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
33
36
  "test": "vitest",
34
37
  "test:run": "vitest run",
35
- "test:coverage": "vitest run --coverage"
38
+ "test:coverage": "vitest run --coverage",
39
+ "prepack": "npm run test:run && npm run build",
40
+ "pack:check": "npm pack --dry-run --ignore-scripts"
36
41
  },
37
42
  "peerDependencies": {
38
43
  "react": "^18.0.0 || ^19.0.0",
@@ -67,6 +72,7 @@
67
72
  "function-plot": "^1.25.3",
68
73
  "html2canvas": "^1.4.1",
69
74
  "jspdf": "^4.1.0",
75
+ "jszip": "^3.10.1",
70
76
  "katex": "^0.16.33",
71
77
  "lowlight": "^3.3.0",
72
78
  "mammoth": "^1.12.0",
@@ -76,6 +82,7 @@
76
82
  "@eslint/js": "^9.39.2",
77
83
  "@fullhuman/postcss-purgecss": "^8.0.0",
78
84
  "@types/dompurify": "^3.0.5",
85
+ "@types/jszip": "^3.4.0",
79
86
  "@types/react": "^18.2.0",
80
87
  "@types/react-dom": "^18.2.0",
81
88
  "@typescript-eslint/eslint-plugin": "^8.56.0",
@@ -101,12 +108,16 @@
101
108
  "author": "Erlangga Team",
102
109
  "repository": {
103
110
  "type": "git",
104
- "url": "git+https://github.com/erlangga/richtext-editor-research.git"
111
+ "url": "git+https://github.com/erlangga/richtext-editor-research.git",
112
+ "directory": "packages/editor"
105
113
  },
106
- "homepage": "https://github.com/erlangga/richtext-editor-research#readme",
114
+ "homepage": "https://github.com/erlangga/richtext-editor-research/tree/main/packages/editor#readme",
107
115
  "bugs": {
108
116
  "url": "https://github.com/erlangga/richtext-editor-research/issues"
109
117
  },
118
+ "engines": {
119
+ "node": ">=18"
120
+ },
110
121
  "publishConfig": {
111
122
  "access": "public",
112
123
  "registry": "https://registry.npmjs.org/"
@@ -118,6 +129,8 @@
118
129
  "wysiwyg",
119
130
  "ckeditor-replacement",
120
131
  "solutest",
121
- "react"
132
+ "react",
133
+ "katex",
134
+ "rich-text-editor"
122
135
  ]
123
136
  }
@@ -1,45 +0,0 @@
1
- import { jsx as a } from "react/jsx-runtime";
2
- import { useRef as o, useMemo as i, useEffect as m } from "react";
3
- import { p as s, k as l } from "./viewer-deps-BDYoL2Ts.js";
4
- function c(t) {
5
- if (t.querySelector(".katex")) return;
6
- const e = t.getAttribute("data-latex") || t.getAttribute("latex");
7
- if (!e) return;
8
- const r = t.classList.contains("mtx-math-block");
9
- try {
10
- l.render(e, t, {
11
- throwOnError: !1,
12
- displayMode: r,
13
- output: "htmlAndMathml"
14
- });
15
- } catch {
16
- t.textContent = r ? `$$${e}$$` : `$${e}$`;
17
- }
18
- }
19
- function x({ content: t, className: e }) {
20
- const r = o(null), n = i(
21
- () => s.sanitize(t, {
22
- ADD_TAGS: ["math-field", "span", "div"],
23
- ADD_ATTR: ["data-latex", "latex", "data-type", "data-mathml"],
24
- FORBID_TAGS: ["script", "style", "iframe", "object", "embed"],
25
- FORBID_ATTR: ["onerror", "onload", "onclick", "onmouseover", "onmouseout", "onfocus", "onblur"]
26
- }),
27
- [t]
28
- );
29
- return m(() => {
30
- if (!r.current) return;
31
- r.current.querySelectorAll(
32
- '.mtx-math-inline, .mtx-math-block, [data-type="math-inline"], [data-type="math-block"]'
33
- ).forEach(c);
34
- }, [n]), /* @__PURE__ */ a(
35
- "div",
36
- {
37
- ref: r,
38
- className: `mtx-content-viewer${e ? ` ${e}` : ""}`,
39
- dangerouslySetInnerHTML: { __html: n }
40
- }
41
- );
42
- }
43
- export {
44
- x as C
45
- };