diff --git a/src/extensions/outliner/client.mjs b/src/extensions/outliner/client.mjs index 5bf52c9..fe26044 100644 --- a/src/extensions/outliner/client.mjs +++ b/src/extensions/outliner/client.mjs @@ -11,6 +11,10 @@ export default async (api, db) => { const { html, debounce, addMutationListener, addPanelView } = api, behavior = (await db.get("smoothScrolling")) ? "smooth" : "auto", scroller = ".notion-frame > .notion-scroller", + equation = ".notion-text-equation-token", + annotation = (await db.get("equationRendering")) + ? ".katex-html" + : ".katex-mathml annotation", page = ".notion-page-content", headings = [ ".notion-header-block", @@ -69,18 +73,30 @@ export default async (api, db) => { for (let i = 0; i < headings.length; i++) if ($heading.matches(headings[i])) return i + 1; }, + getHeadingTitle = ($heading) => { + if (!$heading.innerText) return "Untitled"; + let title = ""; + for (const node of $heading.querySelector("h2, h3, h4").childNodes) { + if (node.nodeType === 3) title += node.textContent; + else if (node.matches(equation)) { + // https://github.com/notion-enhancer/repo/issues/39 + const $katex = node.querySelector(annotation); + title += $katex.textContent; + } else title += node.innerText; + } + return title; + }, updateHeadings = debounce(() => { $toc.innerHTML = ""; if (!$page) return; const $frag = document.createDocumentFragment(); for (const $heading of getHeadings()) { - const title = $heading.innerText, - indent = getHeadingLevel($heading); - if (!title) continue; - const $h = html`<${Heading} indent=${indent} onclick=${() => { - const $scroller = document.querySelector(scroller); - $scroller.scrollTo({ top: $heading.offsetTop - 24, behavior }); - }}>${title}

`; + const $h = html`<${Heading} + indent=${getHeadingLevel($heading)} + onclick=${() => { + const $scroller = document.querySelector(scroller); + $scroller.scrollTo({ top: $heading.offsetTop - 24, behavior }); + }}>${getHeadingTitle($heading)}

`; $frag.append($h); } $toc.append($frag); @@ -89,4 +105,5 @@ export default async (api, db) => { const semanticHeadings = '[class$="header-block"] :is(h2, h3, h4)'; addMutationListener(`${page} ${semanticHeadings}`, updateHeadings); addMutationListener(`${page}, ${scroller}`, updatePage, false); + updatePage(); }; diff --git a/src/extensions/outliner/mod.json b/src/extensions/outliner/mod.json index 6ebc5e5..866efc8 100644 --- a/src/extensions/outliner/mod.json +++ b/src/extensions/outliner/mod.json @@ -23,6 +23,12 @@ "key": "smoothScrolling", "description": "Animates scrolling to a heading smoothly. Disable this to jump to a heading instantly when clicking it in the Outliner's table of contents.", "value": true + }, + { + "type": "toggle", + "key": "equationRendering", + "description": "Attempts to render special symbols from inline equations in headings. Note that position- and size-based formatting will be lost when displaying equations in the Outliner's table of contents. Disable this to display the raw TeX equation instead.", + "value": true } ], "clientScripts": ["client.mjs"]