rehype-mathjax
Advanced tools
Comparing version 4.0.3 to 5.0.0
@@ -1,8 +0,2 @@ | ||
export default rehypeMathJaxBrowser | ||
export type Options = import('./lib/create-plugin').Options | ||
declare const rehypeMathJaxBrowser: ( | ||
this: import('unified').Processor<void, import('hast').Root, void, void>, | ||
options?: void | import('./lib/create-plugin.js').Options | undefined | ||
) => | ||
| void | ||
| import('unified').Transformer<import('hast').Root, import('hast').Root> | ||
export { default } from "./lib/browser.js"; | ||
export type Options = import('./lib/create-plugin.js').Options; |
/** | ||
* @typedef {import('./lib/create-plugin').Options} Options | ||
* @typedef {import('./lib/create-plugin.js').Options} Options | ||
*/ | ||
import {createPlugin} from './lib/create-plugin.js' | ||
const rehypeMathJaxBrowser = createPlugin((options) => { | ||
const tex = options.tex || {} | ||
const display = tex.displayMath || [['\\[', '\\]']] | ||
const inline = tex.inlineMath || [['\\(', '\\)']] | ||
return { | ||
render(node, options) { | ||
const delimiters = (options.display ? display : inline)[0] | ||
node.children.unshift({type: 'text', value: delimiters[0]}) | ||
node.children.push({type: 'text', value: delimiters[1]}) | ||
} | ||
} | ||
}) | ||
export default rehypeMathJaxBrowser | ||
export {default} from './lib/browser.js' |
@@ -1,8 +0,2 @@ | ||
export default rehypeMathJaxCHtml | ||
export type Options = import('./lib/create-plugin').Options | ||
declare const rehypeMathJaxCHtml: ( | ||
this: import('unified').Processor<void, import('hast').Root, void, void>, | ||
options?: void | import('./lib/create-plugin.js').Options | undefined | ||
) => | ||
| void | ||
| import('unified').Transformer<import('hast').Root, import('hast').Root> | ||
export { default } from "./lib/chtml.js"; | ||
export type Options = import('./lib/create-plugin.js').Options; |
18
chtml.js
/** | ||
* @typedef {import('./lib/create-plugin').Options} Options | ||
* @typedef {import('./lib/create-plugin.js').Options} Options | ||
*/ | ||
import {CHTML} from 'mathjax-full/js/output/chtml.js' | ||
import {createRenderer} from './lib/create-renderer.js' | ||
import {createPlugin} from './lib/create-plugin.js' | ||
const rehypeMathJaxCHtml = createPlugin((options) => { | ||
if (!options.chtml || !options.chtml.fontURL) { | ||
throw new Error( | ||
'rehype-mathjax: missing `fontURL` in options, which must be set to a URL to reach MathJaX fonts' | ||
) | ||
} | ||
return createRenderer(options, new CHTML(options.chtml)) | ||
}) | ||
export default rehypeMathJaxCHtml | ||
export {default} from './lib/chtml.js' |
/** | ||
* Create a plugin. | ||
* | ||
* @param {CreateRenderer} createRenderer | ||
* Create a renderer. | ||
* @returns | ||
* Plugin. | ||
*/ | ||
export function createPlugin( | ||
createRenderer: CreateRenderer | ||
): ( | ||
this: import('unified').Processor<void, import('hast').Root, void, void>, | ||
options?: void | Options | undefined | ||
) => | ||
| void | ||
| import('unified').Transformer<import('hast').Root, import('hast').Root> | ||
export type Root = import('hast').Root | ||
export type Element = import('hast').Element | ||
export function createPlugin(createRenderer: CreateRenderer): (options?: Readonly<Options> | null | undefined) => (tree: Root) => undefined; | ||
export type Element = import('hast').Element; | ||
export type ElementContent = import('hast').ElementContent; | ||
export type Root = import('hast').Root; | ||
/** | ||
* Create a renderer. | ||
*/ | ||
export type CreateRenderer = (options: Readonly<Options>) => Renderer; | ||
/** | ||
* Format an error. | ||
*/ | ||
export type FormatError = (jax: any, error: any) => string; | ||
/** | ||
* Configuration for input tex math. | ||
* <http://docs.mathjax.org/en/latest/options/input/tex.html#the-configuration-block> | ||
*/ | ||
export type InputTexOptions = { | ||
/** | ||
* URL for use with links to tags, when there is a `<base>` tag in effect | ||
* (optional). | ||
*/ | ||
baseURL?: string | null | undefined; | ||
/** | ||
* Pattern for recognizing numbers (optional). | ||
*/ | ||
digits?: RegExp | null | undefined; | ||
/** | ||
* Start/end delimiter pairs for display math (optional). | ||
*/ | ||
displayMath?: ReadonlyArray<MathNotation> | null | undefined; | ||
/** | ||
* Function called when TeX syntax errors occur (optional). | ||
*/ | ||
formatError?: FormatError | null | undefined; | ||
/** | ||
* Start/end delimiter pairs for in-line math (optional). | ||
*/ | ||
inlineMath?: ReadonlyArray<MathNotation> | null | undefined; | ||
/** | ||
* Max size for the internal TeX string (5K) (optional). | ||
*/ | ||
maxBuffer?: number | null | undefined; | ||
/** | ||
* Max number of macro substitutions per expression (optional). | ||
*/ | ||
maxMacros?: number | null | undefined; | ||
/** | ||
* Extensions to use (optional). | ||
*/ | ||
packages?: ReadonlyArray<string> | null | undefined; | ||
/** | ||
* Process `\begin{xxx}...\end{xxx}` outside math mode (optional). | ||
*/ | ||
processEnvironments?: boolean | null | undefined; | ||
/** | ||
* Use `\$` to produce a literal dollar sign (optional). | ||
*/ | ||
processEscapes?: boolean | null | undefined; | ||
/** | ||
* Process `\ref{...}` outside of math mode (optional). | ||
*/ | ||
processRefs?: boolean | null | undefined; | ||
/** | ||
* Amount to indent tags (optional). | ||
*/ | ||
tagIndent?: string | null | undefined; | ||
/** | ||
* Side for `\tag` macros (optional). | ||
*/ | ||
tagSide?: 'left' | 'right' | null | undefined; | ||
/** | ||
* Optional. | ||
*/ | ||
tags?: 'all' | 'ams' | 'none' | null | undefined; | ||
/** | ||
* Use label name rather than tag for ids (optional). | ||
*/ | ||
useLabelIds?: boolean | null | undefined; | ||
}; | ||
/** | ||
* Markers to use for math. | ||
* See: <http://docs.mathjax.org/en/latest/options/input/tex.html#the-configuration-block> | ||
*/ | ||
export type MathNotation = [string, string] | ||
export type MathNotation = [string, string]; | ||
/** | ||
* <http://docs.mathjax.org/en/latest/options/output/svg.html#the-configuration-block> | ||
* Configuration. | ||
* | ||
* ###### Notes | ||
* | ||
* When using `rehype-mathjax/browser`, only `options.tex.displayMath` and | ||
* `options.tex.inlineMath` are used. | ||
* That plugin will use the first delimiter pair in those fields to wrap | ||
* math. | ||
* Then you need to load MathJax yourself on the client and start it with the | ||
* same markers. | ||
* You can pass other options on the client. | ||
* | ||
* When using `rehype-mathjax/chtml`, `options.chtml.fontURL` is required. | ||
* For example: | ||
* | ||
* ```js | ||
* // … | ||
* .use(rehypeMathjaxChtml, { | ||
* chtml: { | ||
* fontURL: 'https://cdn.jsdelivr.net/npm/mathjax@3/es5/output/chtml/fonts/woff-v2' | ||
* } | ||
* }) | ||
* // … | ||
* ``` | ||
*/ | ||
export type OutputSvgOptions = { | ||
scale?: number | undefined | ||
minScale?: number | undefined | ||
mtextInheritFont?: boolean | undefined | ||
merrorInheritFont?: boolean | undefined | ||
mathmlSpacing?: boolean | undefined | ||
skipAttributes?: Record<string, boolean> | undefined | ||
exFactor?: number | undefined | ||
displayAlign?: 'left' | 'center' | 'right' | undefined | ||
displayIndent?: string | undefined | ||
fontCache?: 'local' | 'global' | undefined | ||
localID?: string | null | undefined | ||
internalSpeechTitles?: boolean | undefined | ||
titleID?: number | undefined | ||
} | ||
export type Options = { | ||
/** | ||
* Configuration for the output, when CHTML (optional). | ||
*/ | ||
chtml?: Readonly<OutputCHtmlOptions> | null | undefined; | ||
/** | ||
* Configuration for the output, when SVG (optional). | ||
*/ | ||
svg?: Readonly<OutputSvgOptions> | null | undefined; | ||
/** | ||
* Configuration for the input TeX (optional). | ||
*/ | ||
tex?: Readonly<InputTexOptions> | null | undefined; | ||
}; | ||
/** | ||
* Configuration for output CHTML. | ||
* <http://docs.mathjax.org/en/latest/options/output/chtml.html#the-configuration-block> | ||
*/ | ||
export type OutputCHtmlOptions = { | ||
scale?: number | undefined | ||
minScale?: number | undefined | ||
matchFontHeight?: boolean | undefined | ||
mtextInheritFont?: boolean | undefined | ||
merrorInheritFont?: boolean | undefined | ||
mathmlSpacing?: boolean | undefined | ||
skipAttributes?: Record<string, boolean> | undefined | ||
exFactor?: number | undefined | ||
displayAlign?: 'left' | 'center' | 'right' | undefined | ||
displayIndent?: string | undefined | ||
fontURL: string | ||
adaptiveCSS?: boolean | undefined | ||
} | ||
/** | ||
* `true` means only produce CSS that is used in the processed equations (optional). | ||
*/ | ||
adaptiveCSS?: boolean | null | undefined; | ||
/** | ||
* Default for indentalign when set to `'auto'` (optional). | ||
*/ | ||
displayAlign?: 'center' | 'left' | 'right' | null | undefined; | ||
/** | ||
* Default for indentshift when set to `'auto'` (optional). | ||
*/ | ||
displayIndent?: string | null | undefined; | ||
/** | ||
* Default size of ex in em units (optional). | ||
*/ | ||
exFactor?: number | null | undefined; | ||
/** | ||
* The URL where the fonts are found (**required**). | ||
*/ | ||
fontURL: string; | ||
/** | ||
* `true` to match ex-height of surrounding font (optional). | ||
*/ | ||
matchFontHeight?: boolean | null | undefined; | ||
/** | ||
* `true` for MathML spacing rules, false for TeX rules (optional). | ||
*/ | ||
mathmlSpacing?: boolean | null | undefined; | ||
/** | ||
* `true` to make merror text use surrounding font (optional). | ||
*/ | ||
merrorInheritFont?: boolean | null | undefined; | ||
/** | ||
* Smallest scaling factor to use (optional). | ||
*/ | ||
minScale?: number | null | undefined; | ||
/** | ||
* `true` to make mtext elements use surrounding font (optional). | ||
*/ | ||
mtextInheritFont?: boolean | null | undefined; | ||
/** | ||
* Global scaling factor for all expressions (optional). | ||
*/ | ||
scale?: number | null | undefined; | ||
/** | ||
* RFDa and other attributes NOT to copy to the output (optional). | ||
*/ | ||
skipAttributes?: Readonly<Record<string, boolean>> | null | undefined; | ||
}; | ||
/** | ||
* <http://docs.mathjax.org/en/latest/options/input/tex.html#the-configuration-block> | ||
* Configuration for output SVG. | ||
* <http://docs.mathjax.org/en/latest/options/output/svg.html#the-configuration-block> | ||
*/ | ||
export type InputTexOptions = { | ||
packages?: string[] | undefined | ||
inlineMath?: MathNotation[] | undefined | ||
displayMath?: MathNotation[] | undefined | ||
processEscapes?: boolean | undefined | ||
processEnvironments?: boolean | undefined | ||
processRefs?: boolean | undefined | ||
digits?: RegExp | undefined | ||
tags?: 'none' | 'ams' | 'all' | undefined | ||
tagSide?: 'left' | 'right' | undefined | ||
tagIndent?: string | undefined | ||
useLabelIds?: boolean | undefined | ||
multlineWidth?: string | undefined | ||
maxMacros?: number | undefined | ||
maxBuffer?: number | undefined | ||
baseURL?: string | undefined | ||
formatError?: ((jax: any, error: any) => string) | undefined | ||
} | ||
export type OutputSvgOptions = { | ||
/** | ||
* Default for indentalign when set to `'auto'` (optional). | ||
*/ | ||
displayAlign?: 'center' | 'left' | 'right' | null | undefined; | ||
/** | ||
* Default for indentshift when set to `'auto'` (optional). | ||
*/ | ||
displayIndent?: string | null | undefined; | ||
/** | ||
* Default size of ex in em units (optional). | ||
*/ | ||
exFactor?: number | null | undefined; | ||
/** | ||
* Or `'global'` or `'none'` (optional). | ||
*/ | ||
fontCache?: 'global' | 'local' | 'none' | null | undefined; | ||
/** | ||
* Insert `<title>` tags with speech content (optional). | ||
*/ | ||
internalSpeechTitles?: boolean | null | undefined; | ||
/** | ||
* ID to use for local font cache, for single equation processing (optional). | ||
*/ | ||
localID?: string | null | undefined; | ||
/** | ||
* `true` for MathML spacing rules, `false` for TeX rules (optional). | ||
*/ | ||
mathmlSpacing?: boolean | null | undefined; | ||
/** | ||
* `true` to make merror text use surrounding font (optional). | ||
*/ | ||
merrorInheritFont?: boolean | null | undefined; | ||
/** | ||
* Smallest scaling factor to use (optional). | ||
*/ | ||
minScale?: number | null | undefined; | ||
/** | ||
* `true` to make mtext elements use surrounding font (optional). | ||
*/ | ||
mtextInheritFont?: boolean | null | undefined; | ||
/** | ||
* Global scaling factor for all expressions (optional). | ||
*/ | ||
scale?: number | null | undefined; | ||
/** | ||
* RFDa and other attributes *not* to copy to the output (optional). | ||
*/ | ||
skipAttributes?: Readonly<Record<string, boolean>> | null | undefined; | ||
/** | ||
* Initial ID number to use for `aria-labeledby` titles (optional). | ||
*/ | ||
titleID?: number | null | undefined; | ||
}; | ||
/** | ||
* Render a math node. | ||
*/ | ||
export type Render = (value: string, options: Readonly<RenderOptions>) => Array<ElementContent>; | ||
/** | ||
* Configuration. | ||
*/ | ||
export type Options = { | ||
/** | ||
* Configuration for the input TeX. | ||
*/ | ||
tex?: InputTexOptions | undefined | ||
/** | ||
* Configuration for the output (when CHTML). | ||
*/ | ||
chtml?: OutputCHtmlOptions | undefined | ||
/** | ||
* Configuration for the output (when SVG). | ||
*/ | ||
svg?: OutputSvgOptions | undefined | ||
} | ||
export type RenderOptions = { | ||
/** | ||
* Whether to render display math. | ||
*/ | ||
display: boolean; | ||
}; | ||
/** | ||
* Renderer. | ||
*/ | ||
export type Renderer = { | ||
render: ( | ||
node: Element, | ||
options: { | ||
display: boolean | ||
} | ||
) => void | ||
styleSheet?: (() => Element) | undefined | ||
} | ||
export type CreateRenderer = (options: Options) => Renderer | ||
/** | ||
* Render a math node. | ||
*/ | ||
render: Render; | ||
/** | ||
* Render a style sheet (optional). | ||
*/ | ||
styleSheet?: StyleSheet | null | undefined; | ||
}; | ||
/** | ||
* Render a style sheet. | ||
*/ | ||
export type StyleSheet = () => Element; |
/** | ||
* @typedef {import('hast').Element} Element | ||
* @typedef {import('hast').ElementContent} ElementContent | ||
* @typedef {import('hast').Root} Root | ||
* @typedef {import('hast').Element} Element | ||
*/ | ||
/** | ||
* @callback CreateRenderer | ||
* Create a renderer. | ||
* @param {Readonly<Options>} options | ||
* Configuration. | ||
* @returns {Renderer} | ||
* Rendeder. | ||
* | ||
* @callback FormatError | ||
* Format an error. | ||
* @param {any} jax | ||
* MathJax object. | ||
* @param {any} error | ||
* Error. | ||
* @returns {string} | ||
* Formatted error. | ||
* | ||
* @typedef InputTexOptions | ||
* Configuration for input tex math. | ||
* <http://docs.mathjax.org/en/latest/options/input/tex.html#the-configuration-block> | ||
* @property {string | null | undefined} [baseURL] | ||
* URL for use with links to tags, when there is a `<base>` tag in effect | ||
* (optional). | ||
* @property {RegExp | null | undefined} [digits] | ||
* Pattern for recognizing numbers (optional). | ||
* @property {ReadonlyArray<MathNotation> | null | undefined} [displayMath] | ||
* Start/end delimiter pairs for display math (optional). | ||
* @property {FormatError | null | undefined} [formatError] | ||
* Function called when TeX syntax errors occur (optional). | ||
* @property {ReadonlyArray<MathNotation> | null | undefined} [inlineMath] | ||
* Start/end delimiter pairs for in-line math (optional). | ||
* @property {number | null | undefined} [maxBuffer] | ||
* Max size for the internal TeX string (5K) (optional). | ||
* @property {number | null | undefined} [maxMacros] | ||
* Max number of macro substitutions per expression (optional). | ||
* @property {ReadonlyArray<string> | null | undefined} [packages] | ||
* Extensions to use (optional). | ||
* @property {boolean | null | undefined} [processEnvironments] | ||
* Process `\begin{xxx}...\end{xxx}` outside math mode (optional). | ||
* @property {boolean | null | undefined} [processEscapes] | ||
* Use `\$` to produce a literal dollar sign (optional). | ||
* @property {boolean | null | undefined} [processRefs] | ||
* Process `\ref{...}` outside of math mode (optional). | ||
* @property {string | null | undefined} [tagIndent] | ||
* Amount to indent tags (optional). | ||
* @property {'left' | 'right' | null | undefined} [tagSide] | ||
* Side for `\tag` macros (optional). | ||
* @property {'all' | 'ams' | 'none' | null | undefined} [tags] | ||
* Optional. | ||
* @property {boolean | null | undefined} [useLabelIds] | ||
* Use label name rather than tag for ids (optional). | ||
* | ||
* @typedef {[string, string]} MathNotation | ||
@@ -9,103 +63,208 @@ * Markers to use for math. | ||
* | ||
* @typedef OutputSvgOptions | ||
* <http://docs.mathjax.org/en/latest/options/output/svg.html#the-configuration-block> | ||
* @property {number} [scale] | ||
* @property {number} [minScale] | ||
* @property {boolean} [mtextInheritFont] | ||
* @property {boolean} [merrorInheritFont] | ||
* @property {boolean} [mathmlSpacing] | ||
* @property {Record<string, boolean>} [skipAttributes] | ||
* @property {number} [exFactor] | ||
* @property {'left'|'center'|'right'} [displayAlign] | ||
* @property {string} [displayIndent] | ||
* @property {'local'|'global'} [fontCache] | ||
* @property {string|null} [localID] | ||
* @property {boolean} [internalSpeechTitles] | ||
* @property {number} [titleID] | ||
* @typedef Options | ||
* Configuration. | ||
* | ||
* ###### Notes | ||
* | ||
* When using `rehype-mathjax/browser`, only `options.tex.displayMath` and | ||
* `options.tex.inlineMath` are used. | ||
* That plugin will use the first delimiter pair in those fields to wrap | ||
* math. | ||
* Then you need to load MathJax yourself on the client and start it with the | ||
* same markers. | ||
* You can pass other options on the client. | ||
* | ||
* When using `rehype-mathjax/chtml`, `options.chtml.fontURL` is required. | ||
* For example: | ||
* | ||
* ```js | ||
* // … | ||
* .use(rehypeMathjaxChtml, { | ||
* chtml: { | ||
* fontURL: 'https://cdn.jsdelivr.net/npm/mathjax@3/es5/output/chtml/fonts/woff-v2' | ||
* } | ||
* }) | ||
* // … | ||
* ``` | ||
* @property {Readonly<OutputCHtmlOptions> | null | undefined} [chtml] | ||
* Configuration for the output, when CHTML (optional). | ||
* @property {Readonly<OutputSvgOptions> | null | undefined} [svg] | ||
* Configuration for the output, when SVG (optional). | ||
* @property {Readonly<InputTexOptions> | null | undefined} [tex] | ||
* Configuration for the input TeX (optional). | ||
* | ||
* @typedef OutputCHtmlOptions | ||
* Configuration for output CHTML. | ||
* <http://docs.mathjax.org/en/latest/options/output/chtml.html#the-configuration-block> | ||
* @property {number} [scale] | ||
* @property {number} [minScale] | ||
* @property {boolean} [matchFontHeight] | ||
* @property {boolean} [mtextInheritFont] | ||
* @property {boolean} [merrorInheritFont] | ||
* @property {boolean} [mathmlSpacing] | ||
* @property {Record<string, boolean>} [skipAttributes] | ||
* @property {number} [exFactor] | ||
* @property {'left'|'center'|'right'} [displayAlign] | ||
* @property {string} [displayIndent] | ||
* @property {boolean | null | undefined} [adaptiveCSS] | ||
* `true` means only produce CSS that is used in the processed equations (optional). | ||
* @property {'center' | 'left' | 'right' | null | undefined} [displayAlign] | ||
* Default for indentalign when set to `'auto'` (optional). | ||
* @property {string | null | undefined} [displayIndent] | ||
* Default for indentshift when set to `'auto'` (optional). | ||
* @property {number | null | undefined} [exFactor] | ||
* Default size of ex in em units (optional). | ||
* @property {string} fontURL | ||
* @property {boolean} [adaptiveCSS] | ||
* The URL where the fonts are found (**required**). | ||
* @property {boolean | null | undefined} [matchFontHeight] | ||
* `true` to match ex-height of surrounding font (optional). | ||
* @property {boolean | null | undefined} [mathmlSpacing] | ||
* `true` for MathML spacing rules, false for TeX rules (optional). | ||
* @property {boolean | null | undefined} [merrorInheritFont] | ||
* `true` to make merror text use surrounding font (optional). | ||
* @property {number | null | undefined} [minScale] | ||
* Smallest scaling factor to use (optional). | ||
* @property {boolean | null | undefined} [mtextInheritFont] | ||
* `true` to make mtext elements use surrounding font (optional). | ||
* @property {number | null | undefined} [scale] | ||
* Global scaling factor for all expressions (optional). | ||
* @property {Readonly<Record<string, boolean>> | null | undefined} [skipAttributes] | ||
* RFDa and other attributes NOT to copy to the output (optional). | ||
* | ||
* @typedef InputTexOptions | ||
* <http://docs.mathjax.org/en/latest/options/input/tex.html#the-configuration-block> | ||
* @property {string[]} [packages] | ||
* @property {MathNotation[]} [inlineMath] | ||
* @property {MathNotation[]} [displayMath] | ||
* @property {boolean} [processEscapes] | ||
* @property {boolean} [processEnvironments] | ||
* @property {boolean} [processRefs] | ||
* @property {RegExp} [digits] | ||
* @property {'none'|'ams'|'all'} [tags] | ||
* @property {'left'|'right'} [tagSide] | ||
* @property {string} [tagIndent] | ||
* @property {boolean} [useLabelIds] | ||
* @property {string} [multlineWidth] | ||
* @property {number} [maxMacros] | ||
* @property {number} [maxBuffer] | ||
* @property {string} [baseURL] | ||
* @property {(jax: any, error: any) => string} [formatError] | ||
* @typedef OutputSvgOptions | ||
* Configuration for output SVG. | ||
* <http://docs.mathjax.org/en/latest/options/output/svg.html#the-configuration-block> | ||
* @property {'center' | 'left' | 'right' | null | undefined} [displayAlign] | ||
* Default for indentalign when set to `'auto'` (optional). | ||
* @property {string | null | undefined} [displayIndent] | ||
* Default for indentshift when set to `'auto'` (optional). | ||
* @property {number | null | undefined} [exFactor] | ||
* Default size of ex in em units (optional). | ||
* @property {'global' | 'local' | 'none' | null | undefined} [fontCache] | ||
* Or `'global'` or `'none'` (optional). | ||
* @property {boolean | null | undefined} [internalSpeechTitles] | ||
* Insert `<title>` tags with speech content (optional). | ||
* @property {string | null | undefined} [localID] | ||
* ID to use for local font cache, for single equation processing (optional). | ||
* @property {boolean | null | undefined} [mathmlSpacing] | ||
* `true` for MathML spacing rules, `false` for TeX rules (optional). | ||
* @property {boolean | null | undefined} [merrorInheritFont] | ||
* `true` to make merror text use surrounding font (optional). | ||
* @property {number | null | undefined} [minScale] | ||
* Smallest scaling factor to use (optional). | ||
* @property {boolean | null | undefined} [mtextInheritFont] | ||
* `true` to make mtext elements use surrounding font (optional). | ||
* @property {number | null | undefined} [scale] | ||
* Global scaling factor for all expressions (optional). | ||
* @property {Readonly<Record<string, boolean>> | null | undefined} [skipAttributes] | ||
* RFDa and other attributes *not* to copy to the output (optional). | ||
* @property {number | null | undefined} [titleID] | ||
* Initial ID number to use for `aria-labeledby` titles (optional). | ||
* | ||
* @typedef Options | ||
* @callback Render | ||
* Render a math node. | ||
* @param {string} value | ||
* Math value. | ||
* @param {Readonly<RenderOptions>} options | ||
* Configuration. | ||
* @property {InputTexOptions} [tex] | ||
* Configuration for the input TeX. | ||
* @property {OutputCHtmlOptions} [chtml] | ||
* Configuration for the output (when CHTML). | ||
* @property {OutputSvgOptions} [svg] | ||
* Configuration for the output (when SVG). | ||
* @returns {Array<ElementContent>} | ||
* Content. | ||
* | ||
* @typedef RenderOptions | ||
* Configuration. | ||
* @property {boolean} display | ||
* Whether to render display math. | ||
* | ||
* @typedef Renderer | ||
* @property {(node: Element, options: {display: boolean}) => void} render | ||
* @property {() => Element} [styleSheet] | ||
* Renderer. | ||
* @property {Render} render | ||
* Render a math node. | ||
* @property {StyleSheet | null | undefined} [styleSheet] | ||
* Render a style sheet (optional). | ||
* | ||
* @callback CreateRenderer | ||
* @param {Options} options | ||
* @returns {Renderer} | ||
* @callback StyleSheet | ||
* Render a style sheet. | ||
* @returns {Element} | ||
* Style sheet. | ||
*/ | ||
import {visit, SKIP} from 'unist-util-visit' | ||
import {toText} from 'hast-util-to-text' | ||
import {SKIP, visitParents} from 'unist-util-visit-parents' | ||
/** @type {Readonly<Options>} */ | ||
const emptyOptions = {} | ||
/** @type {ReadonlyArray<unknown>} */ | ||
const emptyClasses = [] | ||
/** | ||
* Create a plugin. | ||
* | ||
* @param {CreateRenderer} createRenderer | ||
* Create a renderer. | ||
* @returns | ||
* Plugin. | ||
*/ | ||
export function createPlugin(createRenderer) { | ||
/** @type {import('unified').Plugin<[Options?]|void[], Root>} */ | ||
return (options = {}) => | ||
(tree) => { | ||
const renderer = createRenderer(options) | ||
/** | ||
* Plugin. | ||
* | ||
* @param {Readonly<Options> | null | undefined} [options] | ||
* Configuration (optional). | ||
* @returns | ||
* Transform. | ||
*/ | ||
return function (options) { | ||
/** | ||
* Transform. | ||
* | ||
* @param {Root} tree | ||
* Tree. | ||
* @returns {undefined} | ||
* Nothing. | ||
*/ | ||
return function (tree) { | ||
const renderer = createRenderer(options || emptyOptions) | ||
let found = false | ||
/** @type {Root|Element} */ | ||
/** @type {Element | Root} */ | ||
let context = tree | ||
visit(tree, 'element', (node) => { | ||
const classes = | ||
node.properties && Array.isArray(node.properties.className) | ||
? node.properties.className | ||
: [] | ||
const inline = classes.includes('math-inline') | ||
const display = classes.includes('math-display') | ||
visitParents(tree, 'element', function (element, parents) { | ||
const classes = Array.isArray(element.properties.className) | ||
? element.properties.className | ||
: emptyClasses | ||
// This class can be generated from markdown with ` ```math `. | ||
const languageMath = classes.includes('language-math') | ||
// This class is used by `remark-math` for flow math (block, `$$\nmath\n$$`). | ||
const mathDisplay = classes.includes('math-display') | ||
// This class is used by `remark-math` for text math (inline, `$math$`). | ||
const mathInline = classes.includes('math-inline') | ||
let display = mathDisplay | ||
if (node.tagName === 'head') { | ||
context = node | ||
// Find `<head>`. | ||
if (element.tagName === 'head') { | ||
context = element | ||
} | ||
if (!inline && !display) { | ||
// Any class is fine. | ||
if (!languageMath && !mathDisplay && !mathInline) { | ||
return | ||
} | ||
let parent = parents[parents.length - 1] | ||
let scope = element | ||
// If this was generated with ` ```math `, replace the `<pre>` and use | ||
// display. | ||
if ( | ||
element.tagName === 'code' && | ||
languageMath && | ||
parent && | ||
parent.type === 'element' && | ||
parent.tagName === 'pre' | ||
) { | ||
scope = parent | ||
parent = parents[parents.length - 2] | ||
display = true | ||
} | ||
/* c8 ignore next -- verbose to test. */ | ||
if (!parent) return | ||
found = true | ||
renderer.render(node, {display}) | ||
const text = toText(scope, {whitespace: 'pre'}) | ||
const result = renderer.render(text, {display}) | ||
const index = parent.children.indexOf(scope) | ||
parent.children.splice(index, 1, ...result) | ||
return SKIP | ||
@@ -118,2 +277,3 @@ }) | ||
} | ||
} | ||
} |
/** | ||
* Create a renderer. | ||
* | ||
* @param {Options} options | ||
* Configuration. | ||
* @param {OutputJax} output | ||
* Output jax. | ||
* @returns {Renderer} | ||
* Rendeder. | ||
*/ | ||
export function createRenderer( | ||
options: Options, | ||
output: import('mathjax-full/js/core/OutputJax').OutputJax< | ||
HTMLElement, | ||
Text, | ||
Document | ||
> | ||
): Renderer | ||
export type Element = import('hast').Element | ||
export type OutputJax = import('mathjax-full/js/core/OutputJax').OutputJax< | ||
HTMLElement, | ||
Text, | ||
Document | ||
> | ||
export type MathDocument = | ||
import('mathjax-full/js/core/MathDocument.js').MathDocument< | ||
HTMLElement, | ||
Text, | ||
Document | ||
> | ||
export type TeX_ = import('mathjax-full/js/input/tex.js').TeX< | ||
HTMLElement, | ||
Text, | ||
Document | ||
> | ||
export type Options = import('./create-plugin.js').Options | ||
export type Renderer = import('./create-plugin.js').Renderer | ||
export function createRenderer(options: Options, output: import("mathjax-full/js/core/OutputJax.js").OutputJax<HTMLElement, Text, Document>): Renderer; | ||
export type Element = import('hast').Element; | ||
export type MathDocument = import('mathjax-full/js/core/MathDocument.js').MathDocument<HTMLElement, Text, Document>; | ||
export type OutputJax = import('mathjax-full/js/core/OutputJax.js').OutputJax<HTMLElement, Text, Document>; | ||
export type Options = import('./create-plugin.js').Options; | ||
export type Renderer = import('./create-plugin.js').Renderer; |
/** | ||
* @typedef {import('hast').Element} Element | ||
* @typedef {import('mathjax-full/js/core/OutputJax').OutputJax<HTMLElement, Text, Document>} OutputJax | ||
* @typedef {import('mathjax-full/js/core/MathDocument.js').MathDocument<HTMLElement, Text, Document>} MathDocument | ||
* @typedef {import('mathjax-full/js/input/tex.js').TeX<HTMLElement, Text, Document>} TeX_ | ||
* @typedef {import('mathjax-full/js/core/OutputJax.js').OutputJax<HTMLElement, Text, Document>} OutputJax | ||
* @typedef {import('./create-plugin.js').Options} Options | ||
@@ -10,13 +9,12 @@ * @typedef {import('./create-plugin.js').Renderer} Renderer | ||
import {mathjax} from 'mathjax-full/js/mathjax.js' | ||
import {fromDom} from 'hast-util-from-dom' | ||
import {RegisterHTMLHandler} from 'mathjax-full/js/handlers/html.js' | ||
import {TeX} from 'mathjax-full/js/input/tex.js' | ||
import {AllPackages} from 'mathjax-full/js/input/tex/AllPackages.js' | ||
import {fromDom} from 'hast-util-from-dom' | ||
import {toText} from 'hast-util-to-text' | ||
import {createAdaptor} from './create-adaptor.js' | ||
import {mathjax} from 'mathjax-full/js/mathjax.js' | ||
import {createAdapter} from '#create-adapter' | ||
const adaptor = createAdaptor() | ||
const adapter = createAdapter() | ||
// To do next major: Keep resultant HTML handler from `register(adaptor)` to | ||
// To do next major: Keep resultant HTML handler from `register(adapter)` to | ||
// allow registering the `AssistiveMmlHandler` as in this demo: | ||
@@ -32,11 +30,16 @@ // <https://github.com/mathjax/MathJax-demos-node/tree/master/direct> | ||
/* eslint-disable-next-line new-cap */ | ||
RegisterHTMLHandler(adaptor) | ||
RegisterHTMLHandler(adapter) | ||
/** | ||
* Create a renderer. | ||
* | ||
* @param {Options} options | ||
* Configuration. | ||
* @param {OutputJax} output | ||
* Output jax. | ||
* @returns {Renderer} | ||
* Rendeder. | ||
*/ | ||
export function createRenderer(options, output) { | ||
const input = new TeX(Object.assign({packages: AllPackages}, options.tex)) | ||
const input = new TeX({packages: AllPackages, ...options.tex}) | ||
/** @type {MathDocument} */ | ||
@@ -46,13 +49,11 @@ const doc = mathjax.document('', {InputJax: input, OutputJax: output}) | ||
return { | ||
render(node, options) { | ||
const domNode = fromDom( | ||
// @ts-expect-error: assume mathml nodes can be handled by | ||
// `hast-util-from-dom`. | ||
doc.convert(toText(node, {whitespace: 'pre'}), options) | ||
) | ||
// @ts-expect-error: `fromDom` returns an element for a given element. | ||
node.children = [domNode] | ||
render(value, options) { | ||
// Cast as this practically results in `HTMLElement`. | ||
const domNode = /** @type {HTMLElement} */ (doc.convert(value, options)) | ||
// Cast as `HTMLElement` results in an `Element`. | ||
const hastNode = /** @type {Element} */ (fromDom(domNode)) | ||
return [hastNode] | ||
}, | ||
styleSheet() { | ||
const value = adaptor.textContent(output.styleSheet(doc)) | ||
const value = adapter.textContent(output.styleSheet(doc)) | ||
@@ -59,0 +60,0 @@ return { |
{ | ||
"name": "rehype-mathjax", | ||
"version": "4.0.3", | ||
"version": "5.0.0", | ||
"description": "rehype plugin to transform inline and block math with MathJax", | ||
"license": "MIT", | ||
"keywords": [ | ||
"unified", | ||
"remark", | ||
"rehype", | ||
"rehype-plugin", | ||
"plugin", | ||
"mdast", | ||
"markdown", | ||
"hast", | ||
"html", | ||
"latex", | ||
"markdown", | ||
"math", | ||
"mathjax", | ||
"latex", | ||
"tex" | ||
"mdast", | ||
"plugin", | ||
"rehype", | ||
"rehype-plugin", | ||
"remark", | ||
"tex", | ||
"unified" | ||
], | ||
@@ -34,4 +34,17 @@ "repository": "https://github.com/remarkjs/remark-math/tree/main/packages/rehype-mathjax", | ||
"type": "module", | ||
"main": "index.js", | ||
"types": "index.d.ts", | ||
"exports": { | ||
".": "./svg.js", | ||
"./browser": "./browser.js", | ||
"./chtml": "./chtml.js", | ||
"./svg": "./svg.js" | ||
}, | ||
"imports": { | ||
"#create-adapter": { | ||
"deno": "./lib/create-adapter.default.js", | ||
"react-native": "./lib/create-adapter.default.js", | ||
"worker": "./lib/create-adapter.default.js", | ||
"browser": "./lib/create-adapter.browser.js", | ||
"default": "./lib/create-adapter.default.js" | ||
} | ||
}, | ||
"files": [ | ||
@@ -43,41 +56,29 @@ "lib/", | ||
"chtml.js", | ||
"index.d.ts", | ||
"index.js", | ||
"svg.d.ts", | ||
"svg.js" | ||
], | ||
"browser": { | ||
"./lib/create-adaptor.js": "./lib/create-adaptor.browser.js" | ||
}, | ||
"dependencies": { | ||
"@types/hast": "^2.0.0", | ||
"@types/hast": "^3.0.0", | ||
"@types/mathjax": "^0.0.37", | ||
"hast-util-from-dom": "^4.0.0", | ||
"hast-util-to-text": "^3.1.0", | ||
"jsdom": "^20.0.0", | ||
"hast-util-from-dom": "^5.0.0", | ||
"hast-util-to-text": "^4.0.0", | ||
"jsdom": "^22.0.0", | ||
"mathjax-full": "^3.0.0", | ||
"unified": "^10.0.0", | ||
"unist-util-visit": "^4.0.0" | ||
"unified": "^11.0.0", | ||
"unist-util-visit-parents": "^6.0.0" | ||
}, | ||
"devDependencies": { | ||
"@types/jsdom": "^20.0.0" | ||
"@types/jsdom": "^21.0.0" | ||
}, | ||
"scripts": { | ||
"build": "rimraf \"lib/**/*.d.ts\" \"test/**/*.d.ts\" \"*.d.ts\" && tsc && type-coverage", | ||
"test-api": "node --conditions development test/index.js", | ||
"test": "npm run build && npm run test-api" | ||
}, | ||
"xo": false, | ||
"typeCoverage": { | ||
"atLeast": 100, | ||
"detail": true, | ||
"strict": true, | ||
"ignoreCatch": true, | ||
"#": "needed `any`s", | ||
"ignoreFiles": [ | ||
"lib/create-plugin.d.ts", | ||
"lib/create-renderer.d.ts", | ||
"lib/create-renderer.js" | ||
] | ||
"xo": { | ||
"prettier": true, | ||
"rules": { | ||
"n/file-extension-in-import": "off", | ||
"unicorn/prefer-at": "off" | ||
} | ||
} | ||
} |
285
readme.md
@@ -11,4 +11,4 @@ # rehype-mathjax | ||
**[rehype][]** plugin to render `<span class=math-inline>` and | ||
`<div class=math-display>` with [MathJax][]. | ||
**[rehype][]** plugin to render elements with a `language-math` class with | ||
[MathJax][]. | ||
@@ -22,5 +22,7 @@ ## Contents | ||
* [API](#api) | ||
* [`unified().use(rehypeMathjaxSvg[, options])`](#unifieduserehypemathjaxsvg-options) | ||
* [`unified().use(rehypeMathjax[, options])`](#unifieduserehypemathjax-options) | ||
* [`Options`](#options) | ||
* [Markdown](#markdown) | ||
* [HTML](#html) | ||
* [CSS](#css) | ||
* [Syntax tree](#syntax-tree) | ||
* [Types](#types) | ||
@@ -36,11 +38,5 @@ * [Compatibility](#compatibility) | ||
This package is a [unified][] ([rehype][]) plugin to render math. | ||
You can combine it with [`remark-math`][remark-math] for math in markdown or add | ||
`math-inline` and `math-display` classes in HTML. | ||
You can add classes to HTML elements, use fenced code in markdown, or combine | ||
with [`remark-math`][remark-math] for a `$C$` syntax extension. | ||
**unified** is a project that transforms content with abstract syntax trees | ||
(ASTs). | ||
**rehype** adds support for HTML to unified. | ||
**hast** is the HTML AST that rehype uses. | ||
This is a rehype plugin that transforms hast. | ||
## When should I use this? | ||
@@ -51,9 +47,9 @@ | ||
A different plugin, [`rehype-katex`][rehype-katex], is similar but uses | ||
[KaTeX][] instead. | ||
A different plugin, [`rehype-katex`][rehype-katex], does the same but with | ||
[KaTeX][]. | ||
## Install | ||
This package is [ESM only](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c). | ||
In Node.js (version 12.20+, 14.14+, or 16.0+), install with [npm][]: | ||
This package is [ESM only][esm]. | ||
In Node.js (version 16+), install with [npm][]: | ||
@@ -67,3 +63,3 @@ ```sh | ||
```js | ||
import rehypeMathjax from 'https://esm.sh/rehype-mathjax@4' | ||
import rehypeMathjax from 'https://esm.sh/rehype-mathjax@5' | ||
``` | ||
@@ -75,3 +71,3 @@ | ||
<script type="module"> | ||
import rehypeMathjax from 'https://esm.sh/rehype-mathjax@4?bundle' | ||
import rehypeMathjax from 'https://esm.sh/rehype-mathjax@5?bundle' | ||
</script> | ||
@@ -82,23 +78,22 @@ ``` | ||
Say we have the following file `example.html`: | ||
Say our document `input.html` contains: | ||
```html | ||
<p> | ||
Lift(<span class="math math-inline">L</span>) can be determined by Lift Coefficient | ||
(<span class="math math-inline">C_L</span>) like the following equation. | ||
Lift(<code class="language-math">L</code>) can be determined by Lift Coefficient | ||
(<code class="language-math">C_L</code>) like the following equation. | ||
</p> | ||
<div class="math math-display"> | ||
<pre><code class="language-math"> | ||
L = \frac{1}{2} \rho v^2 S C_L | ||
</div> | ||
</code></pre> | ||
``` | ||
And our module `example.js` looks as follows: | ||
…and our module `example.js` contains: | ||
```js | ||
import {read} from 'to-vfile' | ||
import {unified} from 'unified' | ||
import rehypeMathjax from 'rehype-mathjax' | ||
import rehypeParse from 'rehype-parse' | ||
import rehypeMathjax from 'rehype-mathjax' | ||
import rehypeStringify from 'rehype-stringify' | ||
import {read, write} from 'to-vfile' | ||
import {unified} from 'unified' | ||
@@ -109,16 +104,16 @@ const file = await unified() | ||
.use(rehypeStringify) | ||
.process(await read('example.html')) | ||
.process(await read('input.html')) | ||
console.log(String(file)) | ||
file.basename = 'output.html' | ||
await write(file) | ||
``` | ||
Now running `node example.js` yields: | ||
…then running `node example.js` creates an `output.html` with: | ||
```html | ||
<p> | ||
Lift(<span class="math math-inline"><mjx-container class="MathJax" jax="SVG"><!--…--></mjx-container></span>) can be determined by Lift Coefficient | ||
(<span class="math math-inline"><mjx-container class="MathJax" jax="SVG"><!--…--></mjx-container></span>) like the following equation. | ||
Lift(<mjx-container class="MathJax" jax="SVG"><!--…--></mjx-container>) can be determined by Lift Coefficient | ||
(<mjx-container class="MathJax" jax="SVG"><!--…--></mjx-container>) like the following equation. | ||
</p> | ||
<div class="math math-display"><mjx-container class="MathJax" jax="SVG" display="true"><!--…--></mjx-container></div> | ||
<mjx-container class="MathJax" jax="SVG" display="true"><!--…--></mjx-container> | ||
<style> | ||
@@ -132,57 +127,61 @@ mjx-container[jax="SVG"] { | ||
…open `output.html` in a browser to see the rendered math. | ||
## API | ||
This package exports no identifiers. | ||
The default export is `rehypeMathjaxSvg`. | ||
This package has an export map with several entries for plugins using different | ||
strategies: | ||
### `unified().use(rehypeMathjaxSvg[, options])` | ||
* `rehype-mathjax/browser` — browser (±1kb) | ||
* `rehype-mathjax/chtml` — [CHTML][mathjax-chtml] (±154kb) | ||
* `rehype-mathjax/svg` — [SVG][mathjax-svg] (±566kb) | ||
* `rehype-mathjax` — same as SVG | ||
Transform `<span class="math-inline">` and `<div class="math-display">` with | ||
[MathJax][]. | ||
Each module exports the plugin [`rehypeMathjax`][api-rehype-mathjax] as | ||
the default export. | ||
This package includes three plugins, split out because MathJax targets have a | ||
big memory and bundle size footprint: SVG, CHTML, and browser: | ||
### `unified().use(rehypeMathjax[, options])` | ||
###### SVG | ||
Render elements with a `language-math` (or `math-display`, `math-inline`) | ||
class with [MathJax][]. | ||
Render math as [SVG][mathjax-svg] | ||
(`import rehypeMathjaxSvg from 'rehype-mathjax/svg.js'`, default). | ||
About 566kb minzipped. | ||
###### Parameters | ||
###### CHTML | ||
* `options` ([`Options`][api-options], typically optional) | ||
— configuration | ||
Render math as [CHTML][mathjax-chtml] | ||
(`import rehypeMathjaxChtml from 'rehype-mathjax/chtml.js'`). | ||
About 154kb minzipped. | ||
Needs a `fontURL` to be passed. | ||
###### Returns | ||
###### Browser | ||
Transform ([`Transformer`][unified-transformer]). | ||
Tiny wrapper that expects MathJax to do work client side | ||
(`import rehypeMathjaxBrowser from 'rehype-mathjax/browser.js'`). | ||
About 1kb minzipped. | ||
### `Options` | ||
Uses `options.displayMath` (default: `['\\[', '\\]']`) for display math and | ||
`options.inlineMath` (default: `['\\(', '\\)']`) for inline math. | ||
Configuration (TypeScript type). | ||
You need to load MathJax on the client yourself and start it with corresponding | ||
markers. | ||
Options are not passed to MathJax: do that yourself on the client. | ||
###### Fields | ||
#### `options` | ||
* `chtml` (`unknown`, optional) | ||
— configuration for the output, when CHTML; | ||
see [*CommonHTML Output Processor Options* on | ||
`mathjax.org`][mathjax-chtml-options] | ||
* `svg` (`unknown`, optional) | ||
— configuration for the output, when SVG; | ||
see [*SVG Output Processor Options* on | ||
`mathjax.org`][mathjax-svg-options] | ||
* `tex` (`unknown`, optional) | ||
— configuration for the input TeX; | ||
see [*TeX Input Processor Options* on | ||
`mathjax.org`][mathjax-tex-options] | ||
All options, except when using the browser plugin, are passed to | ||
[MathJax][mathjax-options]. | ||
###### Notes | ||
#### `options.tex` | ||
When using `rehype-mathjax/browser`, only `options.tex.displayMath` and | ||
`options.tex.inlineMath` are used. | ||
That plugin will use the first delimiter pair in those fields to wrap | ||
math. | ||
Then you need to load MathJax yourself on the client and start it with the | ||
same markers. | ||
You can pass other options on the client. | ||
These options are passed to the [TeX input processor][mathjax-tex-options]. | ||
The browser plugin uses the first delimiter pair in `tex.displayMath` and | ||
`tex.inlineMath` to instead wrap math. | ||
#### `options.chtml` | ||
These options are passed to the [CommonHTML output | ||
processor][mathjax-chtml-options]. | ||
Passing `fontURL` is required! | ||
When using `rehype-mathjax/chtml`, `options.chtml.fontURL` is required. | ||
For example: | ||
@@ -200,6 +199,22 @@ | ||
#### `options.svg` | ||
## Markdown | ||
These options are passed to the [SVG output processor][mathjax-svg-options]. | ||
This plugin supports the syntax extension enabled by | ||
[`remark-math`][remark-math]. | ||
It also supports math generated by using fenced code: | ||
````markdown | ||
```math | ||
C_L | ||
``` | ||
```` | ||
## HTML | ||
The content of any element with a `language-math`, `math-inline`, or | ||
`math-display` class is transformed. | ||
The elements are replaced by what MathJax renders. | ||
Either a `math-display` class or using `<pre><code class="language-math">` will | ||
result in “display” math: math that is a centered block on its own line. | ||
## CSS | ||
@@ -209,19 +224,17 @@ | ||
## Syntax tree | ||
This plugin transforms elements with a class name of either `math-inline` and/or | ||
`math-display`. | ||
## Types | ||
This package is fully typed with [TypeScript][]. | ||
An extra `Options` type is exported, which models the accepted options. | ||
It exports the additional type [`Options`][api-options]. | ||
## Compatibility | ||
Projects maintained by the unified collective are compatible with all maintained | ||
Projects maintained by the unified collective are compatible with maintained | ||
versions of Node.js. | ||
As of now, that is Node.js 12.20+, 14.14+, and 16.0+. | ||
Our projects sometimes work with older versions, but this is not guaranteed. | ||
When we cut a new major release, we drop support for unmaintained versions of | ||
Node. | ||
This means we try to keep the current release line, `rehype-mathjax@^5`, | ||
compatible with Node.js 16. | ||
This plugin works with unified version 6+ and rehype version 4+. | ||
@@ -231,36 +244,36 @@ | ||
Using `rehype-mathjax` should be safe assuming that you trust MathJax. | ||
Any vulnerability in it could open you to a [cross-site scripting (XSS)][xss] | ||
attack. | ||
Always be wary of user input and use [`rehype-sanitize`][rehype-sanitize]. | ||
Assuming you trust MathJax, using `rehype-mathjax` is safe. | ||
A vulnerability in it could open you to a | ||
[cross-site scripting (XSS)][wiki-xss] attack. | ||
Be wary of user input and use [`rehype-sanitize`][rehype-sanitize]. | ||
When you don’t trust user content but do trust MathKax, you can allow the | ||
classes added by `remark-math` while disallowing anything else in the | ||
`rehype-sanitize` schema, and run `rehype-katex` afterwards. | ||
Like so: | ||
When you don’t trust user content but do trust MathJax, run `rehype-mathjax` | ||
*after* `rehype-sanitize`: | ||
```js | ||
import rehypeSanitize, {defaultSchema} from 'rehype-stringify' | ||
import rehypeMathjax from 'rehype-mathjax' | ||
import rehypeSanitize, {defaultSchema} from 'rehype-sanitize' | ||
import rehypeStringify from 'rehype-stringify' | ||
import remarkMath from 'remark-math' | ||
import remarkParse from 'remark-parse' | ||
import remarkRehype from 'remark-rehype' | ||
import {unified} from 'unified' | ||
const mathSanitizeSchema = { | ||
...defaultSchema, | ||
attributes: { | ||
...defaultSchema.attributes, | ||
div: [ | ||
...defaultSchema.attributes.div, | ||
['className', 'math', 'math-display'] | ||
], | ||
span: [ | ||
['className', 'math', 'math-inline'] | ||
] | ||
} | ||
} | ||
const file = await unified() | ||
.use(remarkParse) | ||
.use(remarkMath) | ||
.use(remarkRehype) | ||
.use(rehypeSanitize, { | ||
...defaultSchema, | ||
attributes: { | ||
...defaultSchema.attributes, | ||
// The `language-*` regex is allowed by default. | ||
code: [['className', /^language-./, 'math-inline', 'math-display']] | ||
} | ||
}) | ||
.use(rehypeMathjax) | ||
.use(rehypeStringify) | ||
.process('$C$') | ||
// … | ||
unified() | ||
// … | ||
.use(rehypeSanitize, mathSanitizeSchema) | ||
.use(rehypeMathjax) | ||
// … | ||
console.log(String(file)) | ||
``` | ||
@@ -309,5 +322,5 @@ | ||
[size-badge]: https://img.shields.io/bundlephobia/minzip/rehype-mathjax.svg | ||
[size-badge]: https://img.shields.io/bundlejs/size/rehype-mathjax | ||
[size]: https://bundlephobia.com/result?p=rehype-mathjax | ||
[size]: https://bundlejs.com/?q=rehype-mathjax | ||
@@ -326,2 +339,4 @@ [sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg | ||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c | ||
[esmsh]: https://esm.sh | ||
@@ -331,7 +346,7 @@ | ||
[contributing]: https://github.com/remarkjs/.github/blob/HEAD/contributing.md | ||
[contributing]: https://github.com/remarkjs/.github/blob/main/contributing.md | ||
[support]: https://github.com/remarkjs/.github/blob/HEAD/support.md | ||
[support]: https://github.com/remarkjs/.github/blob/main/support.md | ||
[coc]: https://github.com/remarkjs/.github/blob/HEAD/code-of-conduct.md | ||
[coc]: https://github.com/remarkjs/.github/blob/main/code-of-conduct.md | ||
@@ -342,30 +357,34 @@ [license]: https://github.com/remarkjs/remark-math/blob/main/license | ||
[rehype]: https://github.com/rehypejs/rehype | ||
[katex]: https://github.com/Khan/KaTeX | ||
[unified]: https://github.com/unifiedjs/unified | ||
[mathjax-svg]: http://docs.mathjax.org/en/latest/output/svg.html | ||
[xss]: https://en.wikipedia.org/wiki/Cross-site_scripting | ||
[mathjax-chtml]: http://docs.mathjax.org/en/latest/output/html.html | ||
[typescript]: https://www.typescriptlang.org | ||
[mathjax-tex-options]: http://docs.mathjax.org/en/latest/options/input/tex.html | ||
[mathjax-svg-options]: http://docs.mathjax.org/en/latest/options/output/svg.html | ||
[mathjax-chtml-options]: http://docs.mathjax.org/en/latest/options/output/chtml.html | ||
[rehype]: https://github.com/rehypejs/rehype | ||
[rehype-sanitize]: https://github.com/rehypejs/rehype-sanitize | ||
[mathjax]: https://mathjax.org/ | ||
[typescript]: https://www.typescriptlang.org | ||
[mathjax-options]: http://docs.mathjax.org/en/latest/options/ | ||
[unified]: https://github.com/unifiedjs/unified | ||
[mathjax-svg]: http://docs.mathjax.org/en/latest/output/svg.html | ||
[unified-transformer]: https://github.com/unifiedjs/unified#transformer | ||
[mathjax-chtml]: http://docs.mathjax.org/en/latest/output/html.html | ||
[wiki-xss]: https://en.wikipedia.org/wiki/Cross-site_scripting | ||
[mathjax-tex-options]: http://docs.mathjax.org/en/latest/options/input/tex.html | ||
[mathjax]: https://mathjax.org/ | ||
[mathjax-svg-options]: http://docs.mathjax.org/en/latest/options/output/svg.html | ||
[remark-math]: ../remark-math/ | ||
[mathjax-chtml-options]: http://docs.mathjax.org/en/latest/options/output/chtml.html | ||
[rehype-katex]: ../rehype-katex/ | ||
[katex]: https://github.com/Khan/KaTeX | ||
[api-options]: #options | ||
[remark-math]: ../remark-math | ||
[rehype-katex]: ../rehype-katex | ||
[api-rehype-mathjax]: #unifieduserehypemathjax-options |
10
svg.d.ts
@@ -1,8 +0,2 @@ | ||
export default rehypeMathJaxSvg | ||
export type Options = import('./lib/create-plugin.js').Options | ||
declare const rehypeMathJaxSvg: ( | ||
this: import('unified').Processor<void, import('hast').Root, void, void>, | ||
options?: void | import('./lib/create-plugin.js').Options | undefined | ||
) => | ||
| void | ||
| import('unified').Transformer<import('hast').Root, import('hast').Root> | ||
export { default } from "./lib/svg.js"; | ||
export type Options = import('./lib/create-plugin.js').Options; |
10
svg.js
@@ -5,10 +5,2 @@ /** | ||
import {SVG} from 'mathjax-full/js/output/svg.js' | ||
import {createRenderer} from './lib/create-renderer.js' | ||
import {createPlugin} from './lib/create-plugin.js' | ||
const rehypeMathJaxSvg = createPlugin((options) => | ||
createRenderer(options, new SVG(options.svg)) | ||
) | ||
export default rehypeMathJaxSvg | ||
export {default} from './lib/svg.js' |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
38180
22
737
375
1
+ Added@types/hast@3.0.4(transitive)
+ Added@types/unist@3.0.3(transitive)
+ Addedcssstyle@3.0.0(transitive)
+ Addeddata-urls@4.0.0(transitive)
+ Addeddequal@2.0.3(transitive)
+ Addeddevlop@1.1.0(transitive)
+ Addedhast-util-from-dom@5.0.0(transitive)
+ Addedhast-util-is-element@3.0.0(transitive)
+ Addedhast-util-parse-selector@4.0.0(transitive)
+ Addedhast-util-to-text@4.0.2(transitive)
+ Addedhastscript@8.0.0(transitive)
+ Addedjsdom@22.1.0(transitive)
+ Addedrrweb-cssom@0.6.0(transitive)
+ Addedtr46@4.1.1(transitive)
+ Addedunified@11.0.5(transitive)
+ Addedunist-util-find-after@5.0.0(transitive)
+ Addedunist-util-is@6.0.0(transitive)
+ Addedunist-util-stringify-position@4.0.0(transitive)
+ Addedunist-util-visit-parents@6.0.1(transitive)
+ Addedvfile@6.0.3(transitive)
+ Addedvfile-message@4.0.2(transitive)
+ Addedwhatwg-url@12.0.1(transitive)
- Removedunist-util-visit@^4.0.0
- Removed@types/hast@2.3.10(transitive)
- Removed@types/unist@2.0.11(transitive)
- Removedacorn@8.12.1(transitive)
- Removedacorn-globals@7.0.1(transitive)
- Removedacorn-walk@8.3.4(transitive)
- Removedcssom@0.3.80.5.0(transitive)
- Removedcssstyle@2.3.0(transitive)
- Removeddata-urls@3.0.2(transitive)
- Removedescodegen@2.1.0(transitive)
- Removedesprima@4.0.1(transitive)
- Removedestraverse@5.3.0(transitive)
- Removedesutils@2.0.3(transitive)
- Removedhast-util-from-dom@4.2.0(transitive)
- Removedhast-util-is-element@2.1.3(transitive)
- Removedhast-util-parse-selector@3.1.1(transitive)
- Removedhast-util-to-text@3.1.2(transitive)
- Removedhastscript@7.2.0(transitive)
- Removedis-buffer@2.0.5(transitive)
- Removedjsdom@20.0.3(transitive)
- Removedsource-map@0.6.1(transitive)
- Removedtr46@3.0.0(transitive)
- Removedunified@10.1.2(transitive)
- Removedunist-util-find-after@4.0.1(transitive)
- Removedunist-util-is@5.2.1(transitive)
- Removedunist-util-stringify-position@3.0.3(transitive)
- Removedunist-util-visit@4.1.2(transitive)
- Removedunist-util-visit-parents@5.1.3(transitive)
- Removedvfile@5.3.7(transitive)
- Removedvfile-message@3.1.4(transitive)
- Removedwhatwg-url@11.0.0(transitive)
Updated@types/hast@^3.0.0
Updatedhast-util-from-dom@^5.0.0
Updatedhast-util-to-text@^4.0.0
Updatedjsdom@^22.0.0
Updatedunified@^11.0.0