diff --git a/plugins/tiddlywiki/katex/styles.tid b/plugins/tiddlywiki/katex/styles.tid index afb328887..165d91a6b 100644 --- a/plugins/tiddlywiki/katex/styles.tid +++ b/plugins/tiddlywiki/katex/styles.tid @@ -19,6 +19,26 @@ tags: [[$:/tags/Stylesheet]] counter-reset: katexEqnNo; } +/* Replace \eqref placeholder with generated eqnum */ + +.katex-eqref [data-katex-eqnum] > * { + display: none; +} + +.katex-eqref [data-katex-eqnum]::after { + content: attr(data-katex-eqnum); +} + +/* Emulate tiddlylink style but w/o decorating the parentheses */ + +.katex-eqref a { + text-decoration: none; +} + +.katex-eqref a:hover .enclosing { + text-decoration: underline; +} + /* Avoid TW5's max-width: 100% */ .katex svg { diff --git a/plugins/tiddlywiki/katex/wrapper.js b/plugins/tiddlywiki/katex/wrapper.js index 05b820749..3c3c56c5b 100644 --- a/plugins/tiddlywiki/katex/wrapper.js +++ b/plugins/tiddlywiki/katex/wrapper.js @@ -13,7 +13,11 @@ var katex = require("$:/plugins/tiddlywiki/katex/katex.min.js"), chemParse = require("$:/plugins/tiddlywiki/katex/mhchem.min.js"), Widget = require("$:/core/modules/widgets/widget.js").widget; -katex.macros = {}; +katex.macros = { + '\\label': '\\htmlClass{katex-label}{\\htmlId{###1}{}}', + '\\eqref': '\\htmlClass{katex-eqref}{\\href{#####1}{(\\htmlData{katex-label=#1}{\\text{#1}})}}', +}; + katex.updateMacros = function() { var tiddlers = $tw.wiki.getTiddlersWithTag("$:/tags/KaTeX/Macro"), regex = /#\d/g, // Remove the arguments like #1#2 @@ -54,6 +58,9 @@ KaTeXWidget.prototype.render = function(parent,nextSibling) { // Render it into a span var span = this.document.createElement("span"), options = {throwOnError: false, displayMode: displayMode, macros: katex.macros}; + options.trust = function (ctx) { + return ctx.command == '\\href' || ctx.command == '\\htmlClass' || ctx.command == '\\htmlData' || ctx.command == '\\htmlId' && ctx.id[0] == '#'; + }; try { if(!this.document.isTiddlyWikiFakeDom) { katex.render(text,span,options); @@ -64,9 +71,34 @@ KaTeXWidget.prototype.render = function(parent,nextSibling) { span.className = "tc-error"; span.textContent = ex; } + // rewrite identifiers to make them unique + var tiddlerFrame = parent.closest('.tc-tiddler-frame'); + var safeTitle = tiddlerFrame.dataset.tiddlerTitle.replaceAll(/\s+/g, ''); + $tw.utils.each(span.querySelectorAll('.katex-label [id^="#"]'), function (element) { + var safeId = element.id.replaceAll(/\s+/g, '~'); + element.setAttribute('id', '#' + safeTitle + safeId); + element.classList.add('katex-label' + safeId); + }); + $tw.utils.each(span.querySelectorAll('.katex-eqref [href^="##"]'), function (element) { + element.href = '##' + safeTitle + element.getAttribute('href').substring(1).replaceAll(/\s+/g, '~'); + }); // Insert it into the DOM parent.insertBefore(span,nextSibling); this.domNodes.push(span); + // compute data-katex-eqnum attributes on elements made by \eqref + $tw.utils.each(tiddlerFrame.querySelectorAll('.katex-eqref [data-katex-label]:not([data-katex-eqnum])'), function (element) { + // find a unique matching element made by \label (or quit) + var katexLabels = tiddlerFrame.getElementsByClassName('katex-label#' + element.dataset.katexLabel.replaceAll(/\s+/g, '~')); + if (katexLabels.length != 1) return; + // everything is a and the span holding a row doesn't even have a class + var katexRow = katexLabels[0].closest('.vlist > *'); + var katexPos = Array.prototype.indexOf.call(katexRow.parentElement.children, katexRow); // which row has the label + var katexEqn = katexRow.closest('.katex-html').querySelectorAll('.tag .eqn-num')[katexPos]; // which eqn num corresponds + if (!tiddlerFrame._katex_eqn_num_elements) { + tiddlerFrame._katex_eqn_num_elements = tiddlerFrame.getElementsByClassName('eqn-num'); + } + element.dataset.katexEqnum = 1 + Array.prototype.indexOf.call(tiddlerFrame._katex_eqn_num_elements, katexEqn); + }); }; /* @@ -85,7 +117,7 @@ KaTeXWidget.prototype.refresh = function(changedTiddlers) { this.refreshSelf(); return true; } else { - return false; + return false; } };