# Math Plugin for Jodit PRO

The plugin inserts mathematical formulas written in LaTeX or MathML. MathJax renders them to SVG, and the SVG is stored in the document as a block or an inline element. The formula source stays in the `data-jodit-math` attribute, so the user can open it again and edit it. The result does not depend on MathJax or on any stylesheet: every SVG carries its own glyph outlines and renders wherever the HTML is shown.

## Features

- The "Insert equation" button in the `insert` toolbar group. A click opens the dialog for a block equation, the arrow opens a list with "Block equation" and "Inline equation".
- The `insertMath` command with an optional display mode.
- A dialog with LaTeX and MathML tabs, a list of popular formulas, a palette of common symbols, a source textarea and a live preview. Ctrl+Enter or Cmd+Enter saves.
- Rendering errors show up under the preview, and a formula with an error is not inserted.
- Appearance controls in the preview corner: background, text and border colors (each with a reset to none) and, for block formulas, left, center or right alignment plus a "Wrap text" switch that floats a left or right formula so the text flows around it, as with images. The result is written as inline style on the element.
- Block formulas are `figure` elements, so the standard Jodit resizer resizes them. The width is stored in the data and the SVG scales with the figure, keeping its ratio.
- A click on a formula opens a popup with the edit and delete buttons. A double click opens the dialog. The dialog for an existing formula has a delete button too.
- Formulas that arrive with the initial value are recognized on load. A formula with data but no SVG is rendered on load, so a backend can insert formulas without MathJax.
- MathJax loads on first use from `math.mathJaxUrl`. A MathJax that the page already loaded is reused.

## Installation

The plugin is included in the fat build. With the slim build enable it manually:

```js
Jodit.make('#editor', {
	extraPlugins: ['math']
});
```

## HTML structure

A block formula is a `<div>`, an inline one is a `<span>`:

```html
<div
	class="jodit-math jodit-math_block"
	contenteditable="false"
	data-jodit-math='{"format":"latex","display":"block","source":"x^2 + y^2 = r^2"}'
>
	<svg
		xmlns="http://www.w3.org/2000/svg"
		width="12ex"
		height="2.5ex"
		viewBox="…"
		role="img"
		aria-label="x^2 + y^2 = r^2"
	>
		…
	</svg>
</div>

<p>
	Energy:
	<span
		class="jodit-math"
		contenteditable="false"
		data-jodit-math='{"format":"latex","display":"inline","source":"E = mc^2"}'
		><svg …></svg
	></span>
</p>
```

The SVG uses `ex` units and `currentColor`, so it follows the font size and the text color around it. Remove the `data-jodit-math` attribute if the formula should not be editable anymore.

## Data format

```ts
interface IMathData {
	format: 'latex' | 'mathml';
	display: 'block' | 'inline';
	source: string;
	background?: string; // card color, '' means none
	textColor?: string; // formula color, '' inherits the text color
	borderColor?: string; // 1px border, '' means none
	align?: 'left' | 'center' | 'right'; // block formulas only
	wrap?: boolean; // float a left or right formula so the text wraps around it
	width?: number; // px, set by the resizer; the SVG scales to it
}
```

Colors, alignment and width are written as inline style on the element. A block formula is as wide as its content (`width: fit-content`) and is placed with margins, so the resize handles hug the formula; after resizing the width is a pixel value. A background or a border adds padding and rounded corners.

MathML without a `<math>` root is wrapped into one before rendering.

## Options

### math.className

- Type: `string`
- Default: `'jodit-math'`

The class of the formula element. Block formulas get `<className>_block` as well.

### math.mathJaxUrl

- Type: `string`
- Default: `'https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-svg.js'`

The MathJax 3 bundle with TeX and MathML input and SVG output. The plugin loads it on first use. If `window.MathJax` already provides `tex2svg`, nothing is loaded. When the plugin loads MathJax itself it sets `svg.fontCache` to `local`, which keeps every SVG self-contained.

```js
Jodit.make('#editor', {
	math: {
		mathJaxUrl: '/static/mathjax/tex-mml-svg.js'
	}
});
```

### math.defaultFormat

- Type: `'latex' | 'mathml'`
- Default: `'latex'`

The tab selected for a new formula.

### math.defaultDisplay

- Type: `'block' | 'inline'`
- Default: `'block'`

The display mode used by the toolbar button and by `insertMath` without an argument.

### math.defaultBackground / math.defaultTextColor / math.defaultBorderColor

- Type: `string`
- Default: `''` / `''` / `''`

Colors of a new formula. Empty strings mean no background, the surrounding text color and no border.

### math.defaultAlign

- Type: `'left' | 'center' | 'right'`
- Default: `'center'`

Alignment of a new block formula.

### math.defaultWrap

- Type: `boolean`
- Default: `false`

Whether a new left or right formula floats with the text wrapping around it. Has no effect on centered formulas.

### math.allowChangeBackground / math.allowChangeTextColor / math.allowChangeBorderColor / math.allowChangeAlign / math.allowChangeWrap

- Type: `boolean`
- Default: `true`

Each flag shows or hides one control in the preview corner of the dialog. The wrap switch also needs `allowChangeAlign`. With all five `false` the corner is empty and every formula uses the defaults.

```js
Jodit.make('#editor', {
	math: {
		allowChangeBackground: false,
		allowChangeBorderColor: false
	}
});
```

### math.symbols

- Type: `Array<{ label: string; latex: string; mathml: string }>`
- Default: 53 symbols in five groups: fractions, roots, powers, indices, accents and brackets; sums, products, integrals, limits and derivatives; relations and arrows; sets and logic; Greek letters and ħ

The palette above the source field. A click inserts the LaTeX or MathML snippet, depending on the active tab, at the caret.

```js
Jodit.make('#editor', {
	math: {
		symbols: [
			{ label: '→', latex: '\\to', mathml: '<mo>→</mo>' },
			{ label: 'ℝ', latex: '\\mathbb{R}', mathml: '<mi>ℝ</mi>' }
		]
	}
});
```

### math.templates

- Type: `Array<{ title: string; latex: string; mathml: string }>`
- Default: ten formulas: the quadratic formula, the Pythagorean theorem, Euler's identity, mass–energy equivalence, the derivative as a limit, the Gaussian integral, the sum of the first n integers, the binomial theorem, the normal distribution and a 2×2 matrix

The "Templates" list next to the format tabs. Choosing an entry replaces the source with the formula in the active format and renders the preview. An empty array hides the list.

```js
Jodit.make('#editor', {
	math: {
		templates: [
			{
				title: "Ohm's law",
				latex: 'U = I R',
				mathml: '<mi>U</mi><mo>=</mo><mi>I</mi><mi>R</mi>'
			}
		]
	}
});
```

### math.popup

- Type: `Array<IControlType | string>`
- Default: `['mathEdit', 'mathRemove']`

The buttons of the popup that opens on a click on a formula. An empty array disables the popup.

### math.dialog

- Type: `{ width: number; height: number }`
- Default: `{ width: 620, height: 700 }`

The size of the dialog in pixels.

### allowResizeTags

The plugin adds `figure` to the core `allowResizeTags` set so block formulas get the resize handles. If you override `allowResizeTags` in your config and still want resizable formulas, include `'figure'` in your set.

## Controls

| Name         | Description                                                                  |
| ------------ | ---------------------------------------------------------------------------- |
| `math`       | Toolbar button. Click: a block formula. Arrow: a list with block and inline. |
| `mathEdit`   | Popup button. Opens the dialog for the clicked formula.                      |
| `mathRemove` | Popup button. Removes the clicked formula.                                   |

## Commands and events

```js
// open the dialog for a new block formula at the caret
editor.execCommand('insertMath');

// open the dialog for a new inline formula
editor.execCommand('insertMath', false, 'inline');

// open the dialog for a new formula, or for an existing formula element
editor.e.fire('openMathEditor');
editor.e.fire('openMathEditor', null, 'inline');
editor.e.fire('openMathEditor', element);

// remove a formula element
editor.e.fire('removeMath', element);

// true while the dialog is opened
editor.e.fire('isMathEditorOpened');
```

## Styling

Inside the editor the `.jodit-wysiwyg .jodit-math` rule adds `cursor: pointer`, and `.jodit-math_block` gets a vertical margin. Alignment, colors and width are inline styles, so they also apply outside the editor.

## Dependencies

- The plugin requires the `license` plugin from Jodit PRO.
- MathJax 3 is loaded at runtime from `math.mathJaxUrl`; it is not bundled.
- The `tune-block` plugin shows its grip handle for block formulas because they are `figure` elements, and the core `resizer` plugin provides the resize handles. Both are optional.
