import { Plugin, loadMathJax, finishRenderMath, renderMath } from 'obsidian'; function convertLink(link : HTMLElement) { const linkText = link.textContent?.trim(); if (linkText?.contains('$')) { // Each section of text between unescaped $ signs // Fallback to empty list if null, as this happens when input is empty const sections = mathSplit(linkText); let isMath = false; link.innerText = ''; for (let i = 0; i < sections.length; i++) { if (isMath) { link.createSpan().replaceWith(renderMath(sections[i], false)); } else { link.createSpan().innerText += sections[i]; } isMath = !isMath; } finishRenderMath(); } } // Splits at math delimeters, handling escapes properly // Returns an array of alternating normal text and math text function mathSplit(input : string) : string[] { let output = ['']; let backslashes = 0; for (let i = 0; i < input.length; i++) { let curr = input[i]; if (curr == '\\') { backslashes++; } else { for (let j = 0; j < Math.ceil(backslashes / 2); j++) { output[output.length - 1] = output[output.length - 1] + "\\"; } if (curr == '$' && backslashes % 2 == 0) { output.push(''); } else { output[output.length - 1] = output[output.length - 1] + curr; } backslashes = 0; } } return output; } export default class MathJaxWikiLinks extends Plugin { async onload() { await loadMathJax(); this.registerMarkdownPostProcessor((element, context) => { element.querySelectorAll('.internal-link').forEach(convertLink); }); } }