deno.land / x / lume@v2.1.4 / deps / katex-auto-render / auto-render.ts
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108import { katex, KatexOptions } from "../../deps/katex.ts";import splitAtDelimiters from "./splitAtDelimiters.js";
/* Note: optionsCopy is mutated by this method. If it is ever exposed in the * API, we should copy it before mutating. */const renderMathInText = function ( document: Document, text: string, optionsCopy: KatexOptions,) { const data = splitAtDelimiters(text, optionsCopy.delimiters); if (data.length === 1 && data[0].type === 'text') { // There is no formula in the text. // Let's return null which means there is no need to replace // the current text node with a new one. return null; }
const fragment = document.createDocumentFragment();
for (let i = 0; i < data.length; i++) { if (data[i].type === "text") { fragment.appendChild(document.createTextNode(data[i].data)); } else { const span = document.createElement("span"); let math = data[i].data; // Override any display mode defined in the settings with that // defined by the text itself optionsCopy.displayMode = data[i].display; if (optionsCopy.preProcess) { math = optionsCopy.preProcess(math); } const rendered = katex.renderToString( math, optionsCopy, ); const div = document.createElement("div"); div.innerHTML = rendered.trim();
span.appendChild(div.firstChild!); fragment.appendChild(span); } }
return fragment;};
function renderElem(elem: Element, optionsCopy: KatexOptions) { for (let i = 0; i < elem.childNodes.length; i++) { const childNode = elem.childNodes[i]; if (childNode.nodeType === 3) { // Text node let textContentConcat = childNode.textContent || ""; let sibling = childNode.nextSibling; let nSiblings = 0; while (sibling && (sibling.nodeType === 3)) { textContentConcat += sibling.textContent; sibling = sibling.nextSibling; nSiblings++; } const frag = renderMathInText( elem.ownerDocument!, textContentConcat, optionsCopy, ); if (frag) { // Remove extra text nodes for (let j = 0; j < nSiblings; j++) { childNode.nextSibling?.remove(); } i += frag.childNodes.length - 1; elem.replaceChild(frag, childNode); } else { // If the concatenated text does not contain math // the siblings will not either i += nSiblings; } } else if (childNode.nodeType === 1) { // Element node const el = childNode as Element; const className = " " + el.className + " "; const shouldRender = optionsCopy.ignoredTags!.indexOf( el.nodeName.toLowerCase(), ) === -1 && optionsCopy.ignoredClasses!.every( (x) => className.indexOf(" " + x + " ") === -1, );
if (shouldRender) { renderElem(el, optionsCopy); } } // Otherwise, it's something else, and ignore it. }}
export function renderMathInElement( elem: Element | undefined, options: KatexOptions,) { if (!elem) { throw new Error("No element provided to render"); }
renderElem(elem, Object.assign({}, options));}
Version Info