/** * @import {HtmlOptions as Options} from 'micromark-extension-math' * @import {HtmlExtension} from 'micromark-util-types' */ import katex from 'katex' 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('
') }, mathFlowFenceMeta() { this.buffer() }, mathText() { // Double? this.tag('') this.buffer() } }, exit: { mathFlow() { const value = this.resume() this.tag(math(value.replace(/(?:\r?\n|\r)$/, ''), true)) this.tag('
') 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('') }, 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}) } }