@ajinkya.kr/omnimath-editor
v1.0.0
Published
Framework-agnostic mathematical document and diagram editor
Readme
OmniMath Editor
OmniMath Editor is a framework-agnostic, premium WYSIWYG mathematical document and vector sketch editor inspired by Mathcha. It compiles to an extremely lightweight (~75KB minified) distribution bundle with zero heavy runtime dependencies, resolving KaTeX rendering asynchronously from a CDN.
Suitable for integration into any modern web project: React, Angular, Vue, Svelte, or Plain JavaScript/HTML.
🌟 Key Features
- Mixed WYSIWYG Document Editor: Compose standard paragraphs, lists, headers, and code side-by-side with mathematical equations.
- Live KaTeX Formula Renderer: Mathematical notation updates in real-time. Click any equation to edit its LaTeX source inside a popover editor.
- Symbol Palettes: Sidebar filled with clickable Greek letters, calculus symbols, logic operators, brackets, arrows, and matrices.
- Vector Diagram Canvas: Drag and draw vector lines, arrow connectors, rectangles, circles, triangles, and freehand pen drawings. Drag handles allow easy resizing and translating.
- Mathematical Function Plotter: Plot standard curves (like
sin(x)orx^2) or import CSV/JSON coordinates files or API URL endpoints. Includes automatic axis bounds scaling. - Draggable Canvas Math Labels & Images: Upload image assets (converted to Base64) or link URL graphics to sketch boards, overlaying KaTeX mathematical labels.
- Checklists: Functional checkboxes styled with strikethroughs. Checkbox states serialize inside the HTML output data.
- Distraction-Free Fullscreen Layout: Toggle distraction-free mode to expand the workspace across the screen.
📦 Installation
Install the package via npm:
npm install omnimath-editor🚀 Quick Start
1. Plain HTML / Vanilla JavaScript
Load the stylesheets and scripts directly:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>OmniMath Integration</title>
<!-- Load the stylesheet -->
<link rel="stylesheet" href="node_modules/omnimath-editor/dist/omnimath-editor.css">
</head>
<body>
<!-- Container for the Editor -->
<div id="editor-container" style="height: 600px; width: 100%;"></div>
<!-- Load the script -->
<script src="node_modules/omnimath-editor/dist/omnimath-editor.umd.js"></script>
<script>
const container = document.getElementById('editor-container');
const editor = new OmniMathEditor(container, {
theme: 'dark', // 'dark' or 'light'
onChange: (data) => {
console.log('Saved document HTML:', data.html);
console.log('LaTeX code:', editor.exportLaTeX());
}
});
</script>
</body>
</html>2. React Integration
Use a useEffect hook to instantiate and dispose of the editor:
import React, { useEffect, useRef } from 'react';
import 'omnimath-editor/dist/omnimath-editor.css';
import { OmniMathEditor } from 'omnimath-editor';
export const MathEditor = ({ initialData, onChange }) => {
const containerRef = useRef(null);
const editorRef = useRef(null);
useEffect(() => {
if (containerRef.current) {
editorRef.current = new OmniMathEditor(containerRef.current, {
theme: 'dark',
initialHTML: initialData?.html,
initialDrawing: initialData?.drawing,
onChange: (data) => {
if (onChange) onChange(data);
}
});
}
return () => {
if (containerRef.current) {
containerRef.current.innerHTML = '';
}
};
}, []);
return <div ref={containerRef} style={{ height: '650px', width: '100%' }} />;
};3. Angular Integration
Map component life-cycle events to the editor:
import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild, OnDestroy } from '@angular/core';
import { OmniMathEditor } from 'omnimath-editor';
@Component({
selector: 'app-math-editor',
template: '<div #editorContainer style="height: 650px; width: 100%;"></div>'
})
export class MathEditorComponent implements OnInit, OnDestroy {
@ViewChild('editorContainer', { static: true }) container!: ElementRef;
@Input() initialData: any;
@Output() dataChange = new EventEmitter<any>();
private editor: any;
ngOnInit() {
this.editor = new OmniMathEditor(this.container.nativeElement, {
theme: 'dark',
initialHTML: this.initialData?.html,
initialDrawing: this.initialData?.drawing,
onChange: (data: any) => {
this.dataChange.emit(data);
}
});
}
ngOnDestroy() {
this.container.nativeElement.innerHTML = '';
}
}🛠️ API Reference
When you create an instance const editor = new OmniMathEditor(container, options), the following methods are exposed:
editor.getData()
Returns a JSON object containing the document text editor state and the drawing board canvas paths:
{
"html": "...document text HTML...",
"drawing": {
"svg": "...drawing canvas elements innerHTML...",
"labels": [
{ "x": "150px", "y": "100px", "latex": "\\theta" }
]
}
}editor.setData(data)
Restores document and drawing states from a previously saved JSON payload.
editor.exportLaTeX()
Parses the structured document and returns a raw LaTeX-formatted string.
editor.exportSVG()
Returns a clean, standalone, vector-graphic SVG string representation of the Sketch Board (with grid lines removed and embedded LaTeX annotations parsed into SVG text nodes).
🎨 Theme Customization
You can customize the styling by overriding variables in your application stylesheet:
.omnimath-editor {
--om-bg-primary: #0a0e17; /* Background */
--om-accent: #3b82f6; /* Accent color */
--om-border: #2e3b4e; /* Panel borders */
--om-radius-lg: 8px; /* Frame border-radius */
}📄 License
This project is licensed under the MIT License.
