/** * @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 }); } }