site/node_modules/micromark-extension-math/dev/lib/html.js
2024-10-14 08:09:33 +02:00

94 lines
2.4 KiB
JavaScript

/**
* @typedef {import('katex').KatexOptions} KatexOptions
* @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension
*/
/**
* @typedef {Omit<KatexOptions, 'displayMode'>} Options
* Configuration for HTML output.
*
* > 👉 **Note**: passed to `katex.renderToString`.
* > `displayMode` is overwritten by this plugin, to `false` for math in
* > text (inline), and `true` for math in flow (block).
*/
import katex from 'katex'
/** @type {import('katex')['default']['renderToString']} */
// @ts-expect-error: types are incorrect.
const renderToString = katex.renderToString
/**
* Create an extension for `micromark` to support math when serializing to
* HTML.
*
* > 👉 **Note**: this uses KaTeX to render math.
*
* @param {Options | null | undefined} [options={}]
* Configuration (default: `{}`).
* @returns {HtmlExtension}
* Extension for `micromark` that can be passed in `htmlExtensions`, to
* support math when serializing to HTML.
*/
export function mathHtml(options) {
return {
enter: {
mathFlow() {
this.lineEndingIfNeeded()
this.tag('<div class="math math-display">')
},
mathFlowFenceMeta() {
this.buffer()
},
mathText() {
// Double?
this.tag('<span class="math math-inline">')
this.buffer()
}
},
exit: {
mathFlow() {
const value = this.resume()
this.tag(math(value.replace(/(?:\r?\n|\r)$/, ''), true))
this.tag('</div>')
this.setData('mathFlowOpen')
this.setData('slurpOneLineEnding')
},
mathFlowFence() {
// After the first fence.
if (!this.getData('mathFlowOpen')) {
this.setData('mathFlowOpen', true)
this.setData('slurpOneLineEnding', true)
this.buffer()
}
},
mathFlowFenceMeta() {
this.resume()
},
mathFlowValue(token) {
this.raw(this.sliceSerialize(token))
},
mathText() {
const value = this.resume()
this.tag(math(value, false))
this.tag('</span>')
},
mathTextData(token) {
this.raw(this.sliceSerialize(token))
}
}
}
/**
* @param {string} value
* Math text.
* @param {boolean} displayMode
* Whether the math is in display mode.
* @returns {string}
* HTML.
*/
function math(value, displayMode) {
return renderToString(value, {...options, displayMode})
}
}