70 lines
1.8 KiB
TypeScript
70 lines
1.8 KiB
TypeScript
|
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);
|
||
|
});
|
||
|
}
|
||
|
}
|