@xiee/utils
Version:
Miscellaneous tools and utilities to manipulate HTML pages
54 lines (51 loc) • 2.29 kB
JavaScript
// support \ref \eqref \label for KaTeX, based on https://github.com/KaTeX/KaTeX/issues/2003
(d => {
renderMathInElement(d.body, {
strict: false, throwOnError: false,
trust: context => ['\\href', '\\htmlId', '\\htmlClass'].includes(context.command),
macros: {
'\\eqref': '\\htmlClass{ktx-eqref}{\\href{###1}{(\\text{#1})}}',
'\\ref': '\\htmlClass{ktx-ref}{\\href{###1}{\\text{#1}}}',
'\\label': '\\htmlClass{ktx-label}{\\htmlId{#1}{}}'
}
});
function $(s, el = d) { return el.querySelector(s); }
function $$(s, el = d) { return el.querySelectorAll(s); }
const xrefs = $$('.katex:has(:is(.ktx-ref, .ktx-eqref))');
if (!xrefs.length) return;
const M = {}; // map equation labels to numbers
let n = 0;
// scan all display expressions for labels and tags
$$('.katex-display').forEach(el => {
const s = '.ktx-label > [id]', lab = $(s, el);
if (!lab) return; // no labels found
// find the common ancestor of all labels and the label of each row of equation
const ids = [...$$(':scope > [style]', lab.offsetParent.parentNode)].map(el => {
return $(s, el)?.id || '';
});
// find all tags
const tags = [...$$('.tag > .vlist-t > .vlist-r > .vlist > [style]', el)].map(tag => {
// if tag is automatically generated by CSS counter, we have to compute it
// manually because there is no way to access CSS counters from JS
return $('.eqn-num', tag) ? `(${++n})` : tag.innerText.trim();
});
if (ids.length === tags.length) {
ids.forEach((id, i) => id && (M[id] = tags[i]));
} else {
console.warn('labels and tags differ in length in ', el, ids, tags);
}
});
// resolve innerText of cross-ref links
function resolveRefLink(a, paren) {
const id = a.getAttribute('href').replace(/^#/, ''), tag = M[id];
a.innerText = tag ? (paren ? tag : tag.replace(/^\(|\)$/g, '')) : '???';
a.classList.add(`cross-ref-eq${paren ? 'n' : ''}`);
}
xrefs.forEach(el => {
const a = $('a', el);
if (!a) return;
const paren = a.parentNode.classList.contains('ktx-eqref'), p = el.parentNode;
p.after(a); p.remove(); // remove KaTeX's HTML for links to make their style consistent with surrounding text
resolveRefLink(a, paren);
});
})(document);