add functioning TOC links

This commit is contained in:
evilchili 2025-12-25 12:09:32 -08:00
parent 995e75d3e2
commit ff78d55b8e
4 changed files with 54 additions and 32 deletions

View File

@ -22,9 +22,9 @@
<div class='content'> <div class='content'>
<main> <main>
{% for message in g.messages %} {% for message in g.messages %}
<article class="alert"> <dialog class="alert">
{{ message }} {{ message }}
</article> </dialog>
{% endfor %} {% endfor %}
{% block content %}{% endblock %} {% block content %}{% endblock %}
</main> </main>

View File

@ -4,7 +4,7 @@
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div id='froghat'>{{ page.body }}</div> <article id='froghat'>{{ page.body }}</article>
{% endblock %} {% endblock %}

View File

@ -279,7 +279,7 @@ div.macro {
display: inline; display: inline;
} }
div[data-macro-name="toc"] { [data-macro-name="toc"] {
display: inline; display: inline;
float: left; float: left;
border-radius: 5px; border-radius: 5px;
@ -290,43 +290,52 @@ div[data-macro-name="toc"] {
padding: 0ch 2ch; padding: 0ch 2ch;
} }
div[data-macro-name="toc"] ul { [data-macro-name="toc"] ul {
box-sizing: border-box; box-sizing: border-box;
list-style: none; list-style: none;
padding-left: 2ch; padding-left: 0ch;
font-weight: normal; font-weight: normal;
margin-left: 0px; margin-left: 0px;
} }
div[data-macro-name="toc"] > ul:first-child { [data-macro-name="toc"] ul ul {
padding-left: 0ch;
margin-left: 0px;
}
div[data-macro-name="toc"] > ul:first-child > li {
padding-left: 0ch;
margin-left: 0px;
}
div[data-macro-name="toc"] > ul:first-child > li {
font-weight: bold;
}
div[data-macro-name="toc"] > ul > li {
font-weight: bold;
}
div[data-macro-name="toc"] > ul > li {
padding-left: 2ch; padding-left: 2ch;
} }
div[data-macro-name="toc"] a { [data-macro-name="toc"] > ul:first-child {
padding-left: 0ch;
margin-left: 0px;
}
[data-macro-name="toc"] > ul:first-child > li {
padding-left: 0ch;
margin-left: 0px;
}
[data-macro-name="toc"] > ul:first-child > li {
font-weight: bold;
}
[data-macro-name="toc"] > ul > li {
font-weight: bold;
}
[data-macro-name="toc"] > ul > li {
padding-left: 0ch;
}
[data-macro-name="toc"] a {
display: block; display: block;
width: 100%; width: 100%;
} }
div[data-macro-name="toc"] a:hover { [data-macro-name="toc"] a:hover {
background: #CCC; background: #CCC;
} }
[data-macro-name="toc"] .header {
font-size: var(--default-font-size);
width: fit-content;
margin: 2ch auto 0 auto;
}
#froghat { #froghat {
display: none; display: none;

View File

@ -243,9 +243,6 @@ class MacroPlugin extends FroghatPlugin {
macros = { macros = {
// image: {} // image: {}
// toc {}
// widget {}
//
style: { style: {
inline: false, inline: false,
toHTML: (token, node) => { toHTML: (token, node) => {
@ -272,9 +269,9 @@ class MacroPlugin extends FroghatPlugin {
}, },
toc: { toc: {
inline: true, inline: true,
element: 'div', element: 'aside',
toHTML: (token, node) => { toHTML: (token, node) => {
return node + "</div>"; return node + "</aside>";
}, },
postprocess: (html) => { postprocess: (html) => {
const subList = (depth) => { const subList = (depth) => {
@ -284,9 +281,10 @@ class MacroPlugin extends FroghatPlugin {
return li; return li;
}; };
var tocIndex = 0;
const buf = document.createElement('div'); const buf = document.createElement('div');
buf.innerHTML = html; buf.innerHTML = html;
const tocElement =
buf.querySelectorAll('[data-macro-name="toc"]').forEach(tocElement => { buf.querySelectorAll('[data-macro-name="toc"]').forEach(tocElement => {
var params = { var params = {
@ -296,6 +294,11 @@ class MacroPlugin extends FroghatPlugin {
const headings = buf.querySelectorAll("h2, h3, h4, h5, h6"); const headings = buf.querySelectorAll("h2, h3, h4, h5, h6");
var header = document.createElement("h2");
header.className = 'header';
header.textContent = 'Table of Contents';
tocElement.prepend(header);
const toc = document.createElement("ul"); const toc = document.createElement("ul");
toc.setAttribute('role', 'list'); toc.setAttribute('role', 'list');
@ -311,7 +314,8 @@ class MacroPlugin extends FroghatPlugin {
} }
var index = document.createElement("li"); var index = document.createElement("li");
index.innerHTML = '<a href="#h">' + heading.innerHTML + "</a>"; var ref = camelCase(heading.textContent).join("");
index.innerHTML = `<a href="#${heading.id}">${heading.textContent}</a>`;
var list = null; var list = null;
if (depth > lastDepth) { if (depth > lastDepth) {
@ -441,6 +445,15 @@ class MacroPlugin extends FroghatPlugin {
const plugin = this; const plugin = this;
this.editor.marked.use({ this.editor.marked.use({
extensions: [
{
name: 'heading',
renderer(token) {
var ref = camelCase(token.text).join("");
return `<h${token.depth} id='${ref}'>${token.text}</h${token.depth}>`;
}
},
],
hooks: { hooks: {
preprocess: (source) => { preprocess: (source) => {
const matched = source.matchAll(plugin.multilinePattern); const matched = source.matchAll(plugin.multilinePattern);