aboutsummaryrefslogtreecommitdiff
path: root/page.js
diff options
context:
space:
mode:
authorRadu <radu@pml4t.net>2023-11-22 18:33:44 -0500
committerRadu <radu@pml4t.net>2023-11-22 22:15:41 -0500
commit3e4feb710a88ec81c5476e762cb1c0cd02da18c8 (patch)
treee06e16346b5a8b82beef88c3b26d07389e09e36b /page.js
Bodge together LaTeX and code support
Diffstat (limited to 'page.js')
-rw-r--r--page.js103
1 files changed, 103 insertions, 0 deletions
diff --git a/page.js b/page.js
new file mode 100644
index 0000000..ab04f66
--- /dev/null
+++ b/page.js
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+"use strict";
+
+console.log("ASAP: Loaded");
+
+const msgListCb = new MutationObserver(handleMsgList);
+msgListCb.observe(document.body, {
+ childList: true,
+ subtree: true,
+});
+handleMsgList();
+
+function handleMsgList() {
+ const list = document.querySelector(".message-list");
+ if (list) {
+ console.log("ASAP: Found message list");
+ msgListCb.disconnect();
+ const msgCb = new MutationObserver(handleMsg);
+ msgCb.observe(list, { childList: true, subtree: true });
+ handleMsg();
+ }
+}
+
+function handleMsg() {
+ const texts = document.querySelectorAll(".message-parts-container:not(.zbyffrly-done), .parent-text:not(.zbyffrly-done)")
+ texts.forEach((text) => {
+ text.classList.add("zbyffrly-done");
+
+ // Split up between text and code bits
+ const blockBits = text.firstChild.textContent.split(/(?:^|\n)```/);
+ const msgOut = document.createElement("div");
+ for (let i = 0; i < blockBits.length; i++) {
+ let block = blockBits[i];
+ if (i & 1) {
+ const newlineIdx = block.indexOf("\n");
+ const lang = block.slice(0, newlineIdx);
+ const code = block.slice(newlineIdx + 1);
+
+ const preEl = document.createElement("pre");
+ const codeEl = document.createElement("code");
+ if (lang) codeEl.classList.add("language-" + lang);
+ codeEl.appendChild(document.createTextNode(code));
+ hljs.highlightElement(codeEl);
+ preEl.appendChild(codeEl);
+
+ msgOut.appendChild(preEl);
+ } else {
+ block = block[0] == "\n" ? block.slice(1) : block;
+ const inlineBits = block.split("`");
+ for (let i = 0; i < inlineBits.length; i++) {
+ let inlineEl;
+ if (i & 1) {
+ inlineEl = document.createElement("code");
+ inlineEl.innerText = inlineBits[i];
+ if (inlineBits[i + 1]?.startsWith("{:.")) {
+ const closingBrace = inlineBits[i + 1].indexOf("}");
+ if (closingBrace !== -1) {
+ const lang = inlineBits[i + 1].slice(3, closingBrace);
+ inlineBits[i + 1] = inlineBits[i + 1].slice(closingBrace + 1);
+ inlineEl.classList.add("language-" + lang);
+ }
+ }
+ hljs.highlightElement(inlineEl);
+ } else {
+ if (inlineBits[i] === "\xa0") continue;
+ inlineEl = document.createElement("span");
+ inlineEl.innerText = inlineBits[i];
+ renderTex(inlineEl);
+ }
+ msgOut.appendChild(inlineEl);
+ }
+ }
+ }
+
+ if (msgOut.children.length > 1) text.replaceChild(msgOut, text.firstChild);
+ else renderTex(text);
+ });
+}
+
+function renderTex(el) {
+ renderMathInElement(el, {
+ output: "mathml", // HTML output is broken in Pronto
+ delimiters: [
+ { left: "$$", right: "$$", display: true },
+ { left: "$", right: "$", display: false },
+ { left: "\\(", right: "\\)", display: false },
+ { left: "\\begin{equation}", right: "\\end{equation}", display: true },
+ { left: "\\begin{align}", right: "\\end{align}", display: true },
+ { left: "\\begin{alignat}", right: "\\end{alignat}", display: true },
+ { left: "\\begin{gather}", right: "\\end{gather}", display: true },
+ { left: "\\begin{CD}", right: "\\end{CD}", display: true },
+ { left: "\\[", right: "\\]", display: true }
+ ],
+ errorCallback: (msg) => {
+ console.error("ASAP: KaTeX:", msg);
+ const span = document.createElement("span");
+ span.innerText = msg;
+ span.style.color = "red";
+ el.prepend(span);
+ },
+ });
+}