erl-mathtextx-editor 0.3.1 → 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.
- package/CHANGELOG.md +108 -0
- package/README.md +14 -1
- package/dist/{CellPropertiesDialogImpl-5bzEkaTt.js → CellPropertiesDialogImpl-NSTfG9SA.js} +1 -1
- package/dist/ContentViewer-LqSkiQjT.js +161 -0
- package/dist/ImageInsertDialog-DDxR_Cah.js +331 -0
- package/dist/{InsertTableDialogImpl-B2GUzYNY.js → InsertTableDialogImpl-DrW9QTDd.js} +1 -1
- package/dist/{LinkDialogImpl-CPjj0CkY.js → LinkDialogImpl-BXjhfEiE.js} +1 -1
- package/dist/MathTextXEditor.d.ts +1 -1
- package/dist/{TablePropertiesDialogImpl-BLbhyfA0.js → TablePropertiesDialogImpl-C2eqgZMa.js} +1 -1
- package/dist/{TableTemplatesDialogImpl-BQZTGw_Y.js → TableTemplatesDialogImpl-B2DJBmzm.js} +1 -1
- package/dist/assets/erl-mathtextx-editor.css +1 -1
- package/dist/assets/viewer.css +1 -1
- package/dist/components/UploadErrorDebugPanel.d.ts +6 -0
- package/dist/erl-mathtextx-editor.js +50 -28
- package/dist/erl-mathtextx-editor.umd.cjs +470 -200
- package/dist/export-deps-Tu2DJTcR.js +14815 -0
- package/dist/{index-CI4oNSUc.js → index-CvLezwrJ.js} +1 -1
- package/dist/{index-Bq8NKSwD.js → index-D1pCAIcb.js} +6239 -4221
- package/dist/index-D7oo0rd0.js +14235 -0
- package/dist/index.d.ts +11 -1
- package/dist/index.es-UDhZ1Ncp.js +5632 -0
- package/dist/jszip.min-I9rjwvpP.js +2341 -0
- package/dist/math/MathInputModeContext.d.ts +7 -0
- package/dist/math/TemplatePanel.d.ts +4 -1
- package/dist/math/mathFieldFontStyles.d.ts +7 -0
- package/dist/math/mathFieldSpaceKey.d.ts +10 -0
- package/dist/{tiptap-K3rU-Wjn.js → tiptap-BiWGiMFj.js} +27 -27
- package/dist/toolbar/MainToolbar.d.ts +3 -1
- package/dist/toolbar/MathToolbar.d.ts +9 -2
- package/dist/types/index.d.ts +18 -5
- package/dist/utils/docxImporter.d.ts +1 -0
- package/dist/utils/docxOmmlPreprocess.d.ts +12 -0
- package/dist/utils/imageFileValidation.d.ts +14 -0
- package/dist/utils/isLatexContent.d.ts +5 -0
- package/dist/utils/mathMlToLatex.d.ts +4 -0
- package/dist/utils/microsoftMathPaste.d.ts +43 -0
- package/dist/utils/ommlToLatex.d.ts +11 -0
- package/dist/utils/reuploadImagesInHTML.d.ts +9 -0
- package/dist/utils/sanitizeConfig.d.ts +11 -0
- package/dist/utils/unicodeMathToLatex.d.ts +24 -0
- package/dist/utils/uploadError.d.ts +8 -0
- package/dist/{viewer-deps-BDYoL2Ts.js → viewer-deps-_HnWniSt.js} +5 -0
- package/dist/viewer.js +1 -1
- package/package.json +23 -10
- package/dist/ContentViewer-RijJ5nlJ.js +0 -45
- package/dist/ImageInsertDialog-Dcg6kdLb.js +0 -240
- package/dist/components/__tests__/WordCount.test.d.ts +0 -1
- package/dist/core/__tests__/serializer.test.d.ts +0 -1
- package/dist/index-elIws1oE.js +0 -16549
- package/dist/viewer-styles.d.ts +0 -1
- 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, {
|
|
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 =
|
|
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" ?
|
|
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] =
|
|
12814
|
-
return Kg(() => t.watch(n.editor), [n.editor, t]),
|
|
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 =
|
|
12955
|
+
const t = Ed(n);
|
|
12956
12956
|
t.current = n;
|
|
12957
|
-
const [r] =
|
|
12958
|
-
return
|
|
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 =
|
|
12963
|
+
const Yg = Ka({
|
|
12964
12964
|
editor: null
|
|
12965
12965
|
});
|
|
12966
12966
|
Yg.Consumer;
|
|
12967
|
-
const Iu =
|
|
12967
|
+
const Iu = Ka({
|
|
12968
12968
|
onDragStart: void 0
|
|
12969
|
-
}), Qg = () =>
|
|
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:
|
|
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 =
|
|
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
|
-
|
|
19081
|
-
|
|
19082
|
-
|
|
19083
|
-
|
|
19084
|
-
|
|
19085
|
-
|
|
19086
|
-
|
|
19087
|
-
|
|
19088
|
-
|
|
19089
|
-
|
|
19090
|
-
|
|
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
|
-
|
|
19093
|
-
|
|
19094
|
-
|
|
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 {};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -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,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;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type UploadErrorDebug = Record<string, unknown>;
|
|
2
|
+
export declare class UploadError extends Error {
|
|
3
|
+
readonly debug: UploadErrorDebug;
|
|
4
|
+
constructor(message: string, debug?: UploadErrorDebug);
|
|
5
|
+
}
|
|
6
|
+
export declare function getUploadErrorDebug(error: unknown): UploadErrorDebug | null;
|
|
7
|
+
export declare function formatUploadErrorDebug(debug: UploadErrorDebug): string;
|
|
8
|
+
export declare function logUploadError(context: string, error: unknown): UploadErrorDebug | null;
|
|
@@ -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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "erl-mathtextx-editor",
|
|
3
|
-
"version": "0.3.
|
|
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
|
-
"
|
|
17
|
-
"
|
|
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
|
|
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
|
-
};
|