Skip to content

Commit

Permalink
rehype-mathjax: change options to match mathjax
Browse files Browse the repository at this point in the history
Previously, output options for SVG and CHTML were set on the main options
object.
MathJax itself puts them in separate fields.
Similarly, the “browser” plugin supported `inlineMath` and `displayMath` option
fields that were close to `tex.inlineMath` and `tex.displayMath`.

We now match MathJax’ option format:

```diff
-  .use(rehypeMathJaxChtml, {fontURL: 'place/to/fonts'})
+  .use(rehypeMathJaxChtml, {chtml: {fontURL: 'place/to/fonts'}})
```

```diff
-  .use(rehypeMathJaxSvg, {scale: 1})
+  .use(rehypeMathJaxSvg, {svg: {scale: 1}})
```

Note that `inlineMath` and `displayMath` are now lists of pairs, instead of
a single pair!

```diff
-  .use(rehypeMathJaxBrowser, {inlineMath: ['\\(', '\\)']})
+  .use(rehypeMathJaxBrowser, {tex: {inlineMath: [['\\(', '\\)']]}})
```
  • Loading branch information
wooorm committed Aug 9, 2021
1 parent 6899b07 commit c6fc7a0
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 134 deletions.
42 changes: 13 additions & 29 deletions packages/rehype-mathjax/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,23 @@
* @typedef {import('hast').Root} Root
* @typedef {import('hast').Element} Element
* @typedef {import('./lib/create-plugin').MathNotation} MathNotation
* @typedef {import('./lib/create-plugin').BrowserOptions} Options
* @typedef {import('./lib/create-plugin').Options} Options
*/

import {createPlugin} from './lib/create-plugin.js'

const rehypeMathJaxBrowser =
/** @type {import('unified').Plugin<[Options?]|void[], Root>} */ (
createPlugin(
// To do next major: Make `options` match the format of MathJax options
// `{tex: ...}`
(_, options) => {
/** @type {MathNotation} */
let display = ['\\[', '\\]']
/** @type {MathNotation} */
let inline = ['\\(', '\\)']
const rehypeMathJaxBrowser = createPlugin((options) => {
const tex = options.tex || {}
const display = tex.displayMath || [['\\[', '\\]']]
const inline = tex.inlineMath || [['\\(', '\\)']]

if ('displayMath' in options && options.displayMath) {
display = options.displayMath
}

if ('inlineMath' in options && options.inlineMath) {
inline = options.inlineMath
}

return {
render(node, options) {
const delimiters = options.display ? display : inline
node.children.unshift({type: 'text', value: delimiters[0]})
node.children.push({type: 'text', value: delimiters[1]})
}
}
}
)
)
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
21 changes: 11 additions & 10 deletions packages/rehype-mathjax/chtml.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
/**
* @typedef {import('hast').Root} Root
* @typedef {import('./lib/create-plugin').CHtmlOptions} Options
* @typedef {import('mathjax-full/js/output/chtml.js').CHTML<HTMLElement, Text, Document>} CHTML_
* @typedef {import('./lib/create-plugin').Options} Options
*/

import {createOutputChtml} from './lib/create-output-chtml.js'
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 =
/** @type {import('unified').Plugin<[Options?]|void[], Root>} */
(
createPlugin(
(inputOptions, outputOptions) =>
createRenderer(inputOptions, createOutputChtml(outputOptions)),
true
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
15 changes: 0 additions & 15 deletions packages/rehype-mathjax/lib/create-input.js

This file was deleted.

14 changes: 0 additions & 14 deletions packages/rehype-mathjax/lib/create-output-chtml.js

This file was deleted.

14 changes: 0 additions & 14 deletions packages/rehype-mathjax/lib/create-output-svg.js

This file was deleted.

47 changes: 15 additions & 32 deletions packages/rehype-mathjax/lib/create-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,7 @@
* Markers to use for math.
* See: <http://docs.mathjax.org/en/latest/options/input/tex.html#the-configuration-block>
*
* @typedef BrowserOptions
* Configuration.
* @property {MathNotation} [displayMath]
* Markers to use for blocks.
* @property {MathNotation} [inlineMath]
* Markers to use for inlines.
*
* @typedef MathJaxSvgOptions
* @typedef OutputSvgOptions
* <http://docs.mathjax.org/en/latest/options/output/svg.html#the-configuration-block>
* @property {number} [scale]
* @property {number} [minScale]
Expand All @@ -29,7 +22,7 @@
* @property {boolean} [internalSpeechTitles]
* @property {number} [titleID]
*
* @typedef MathJaxCHtmlOptions
* @typedef OutputCHtmlOptions
* <http://docs.mathjax.org/en/latest/options/output/chtml.html#the-configuration-block>
* @property {number} [scale]
* @property {number} [minScale]
Expand All @@ -44,7 +37,7 @@
* @property {string} fontURL
* @property {boolean} [adaptiveCSS]
*
* @typedef MathJaxInputTexOptions
* @typedef InputTexOptions
* <http://docs.mathjax.org/en/latest/options/input/tex.html#the-configuration-block>
* @property {string[]} [packages]
* @property {MathNotation[]} [inlineMath]
Expand All @@ -63,47 +56,37 @@
* @property {string} [baseURL]
* @property {(jax: any, error: any) => string} [formatError]
*
* @typedef {MathJaxCHtmlOptions & {tex?: MathJaxInputTexOptions}} CHtmlOptions
* @typedef {MathJaxSvgOptions & {tex?: MathJaxInputTexOptions}} SvgOptions
*
* @typedef {BrowserOptions|CHtmlOptions|SvgOptions} Options
* @typedef 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).
*
* @typedef Renderer
* @property {(node: Element, options: {display: boolean}) => void} render
* @property {() => Element} [styleSheet]
*
* @callback CreateRenderer
* @param {MathJaxInputTexOptions} inputOptions
* @param {MathJaxCHtmlOptions|MathJaxSvgOptions|BrowserOptions} outputOptions
* @param {Options} options
* @returns {Renderer}
*/

import {visit, SKIP} from 'unist-util-visit'

// To do next major: Remove `chtml` and `browser` flags once all the options use
// the same format.

/**
* @param {CreateRenderer} createRenderer
* @param {boolean} [chtml=false]
*/
export function createPlugin(createRenderer, chtml) {
export function createPlugin(createRenderer) {
/** @type {import('unified').Plugin<[Options?]|void[], Root>} */
return (options = {}) => {
if (chtml && (!('fontURL' in options) || !options.fontURL)) {
throw new Error(
'rehype-mathjax: missing `fontURL` in options, which must be set to a URL to reach MathJaX fonts'
)
}

// @ts-expect-error: hush.
const {tex, ...outputOptions} = options

return (tree) => {
const renderer = createRenderer(tex || {}, outputOptions)
const renderer = createRenderer(options)
let found = false
/** @type {Root|Element} */
let context = tree
let found = false

visit(tree, 'element', (node) => {
const classes =
Expand Down
14 changes: 9 additions & 5 deletions packages/rehype-mathjax/lib/create-renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@
* @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('./create-plugin.js').CreateRenderer} CreateRenderer
* @typedef {import('mathjax-full/js/input/tex.js').TeX<HTMLElement, Text, Document>} TeX_
* @typedef {import('./create-plugin.js').Options} Options
* @typedef {import('./create-plugin.js').Renderer} Renderer
*/

import {mathjax} from 'mathjax-full/js/mathjax.js'
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 {createInput} from './create-input.js'
import {createAdaptor} from './create-adaptor.js'

const adaptor = createAdaptor()
Expand All @@ -28,11 +31,12 @@ const adaptor = createAdaptor()
RegisterHTMLHandler(adaptor)

/**
* @type {CreateRenderer}
* @param {Options} options
* @param {OutputJax} output
* @returns {Renderer}
*/
export function createRenderer(inputOptions, output) {
const input = createInput(inputOptions)
export function createRenderer(options, output) {
const input = new TeX(Object.assign({packages: AllPackages}, options.tex))
/** @type {MathDocument} */
const doc = mathjax.document('', {InputJax: input, OutputJax: output})

Expand Down
17 changes: 16 additions & 1 deletion packages/rehype-mathjax/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,22 @@ Options are not passed to MathJax: do that yourself on the client.

All options, except when using the browser plugin, are passed to
[MathJax][mathjax-options].
Specifically, they are passed to the chosen output processor.

#### `options.tex`

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!

#### `options.svg`

These options are passed to the [SVG output processor][mathjax-svg-options].

## Security

Expand Down Expand Up @@ -208,3 +219,7 @@ abide by its terms.
[mathjax-chtml]: http://docs.mathjax.org/en/latest/output/html.html

[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
15 changes: 6 additions & 9 deletions packages/rehype-mathjax/svg.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
/**
* @typedef {import('hast').Root} Root
* @typedef {import('./lib/create-plugin').SvgOptions} Options
* @typedef {import('mathjax-full/js/output/svg.js').SVG<HTMLElement, Text, Document>} SVG_
* @typedef {import('./lib/create-plugin.js').Options} Options
*/

import {createOutputSvg} from './lib/create-output-svg.js'
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 =
/** @type {import('unified').Plugin<[Options?]|void[], Root>} */
(
createPlugin((inputOptions, outputOptions) =>
createRenderer(inputOptions, createOutputSvg(outputOptions))
)
)
const rehypeMathJaxSvg = createPlugin((options) =>
createRenderer(options, new SVG(options.svg))
)

export default rehypeMathJaxSvg
20 changes: 15 additions & 5 deletions packages/rehype-mathjax/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ test('rehype-mathjax', (t) => {

t.throws(
() => {
unified().use(rehypeMathJaxChtml).freeze()
unified()
.use(rehypeParse, {fragment: true})
.use(rehypeMathJaxChtml)
.use(rehypeStringify)
.processSync(readSync({dirname: fixtures, basename: 'small.html'}))
.toString()
},
/rehype-mathjax: missing `fontURL` in options/,
'should crash for CHTML w/o `fontURL`'
Expand All @@ -36,7 +41,7 @@ test('rehype-mathjax', (t) => {
t.equal(
unified()
.use(rehypeParse, {fragment: true})
.use(rehypeMathJaxChtml, {fontURL: 'place/to/fonts'})
.use(rehypeMathJaxChtml, {chtml: {fontURL: 'place/to/fonts'}})
.use(rehypeStringify)
.processSync(readSync({dirname: fixtures, basename: 'small.html'}))
.toString(),
Expand Down Expand Up @@ -105,8 +110,10 @@ test('rehype-mathjax', (t) => {
unified()
.use(rehypeParse, {fragment: true})
.use(rehypeMathJaxBrowser, {
inlineMath: ['$', '$'],
displayMath: ['$$', '$$']
tex: {
inlineMath: [['$', '$']],
displayMath: [['$$', '$$']]
}
})
.use(rehypeStringify)
.processSync(readSync({dirname: fixtures, basename: 'small.html'}))
Expand Down Expand Up @@ -165,7 +172,10 @@ test('rehype-mathjax', (t) => {
t.equal(
unified()
.use(rehypeParse, {fragment: true})
.use(rehypeMathJaxChtml, {fontURL: 'place/to/fonts', tex: {tags: 'ams'}})
.use(rehypeMathJaxChtml, {
chtml: {fontURL: 'place/to/fonts'},
tex: {tags: 'ams'}
})
.use(rehypeStringify)
.processSync(
readSync({
Expand Down

0 comments on commit c6fc7a0

Please sign in to comment.