aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--index.html68
-rw-r--r--styles.css40
2 files changed, 104 insertions, 4 deletions
diff --git a/index.html b/index.html
index b227cc0..3f11cd9 100644
--- a/index.html
+++ b/index.html
@@ -30,6 +30,7 @@
</script>
<div id="themeButton" style="display: none">
<button id="themeToggle">🌙</button>
+ <a href="#table-of-contents"><button id="goBackUp">⤴</button></a>
</div>
<script>
@@ -180,10 +181,15 @@
}
class TempoParser {
- constructor(rawText) {
+ constructor(rawText, symbols = {}) {
this.lines = rawText.replace(/\r\n/g, '\n').replace(/\r/g, '\n').split('\n')
this.tokens = []
this.defs = new Set()
+ this.symbols = symbols
+ this.reverseSymbols = {}
+ for (const [name, sym] of Object.entries(symbols)) {
+ this.reverseSymbols[sym] = name
+ }
}
tokenize() {
@@ -279,9 +285,53 @@
render() {
let html = ''
+
+ let tocItems = []
+ for (const token of this.tokens) {
+ if (token.type === 'definition') {
+ let line = token.header.substring(4).trim()
+ let name = ''
+ const firstTick = line.indexOf('`')
+ const lastTick = line.lastIndexOf('`')
+ if (firstTick !== -1 && lastTick !== -1 && lastTick > firstTick) {
+ name = line.substring(0, firstTick).trim()
+ } else {
+ name = line
+ }
+
+ const actualName = token.description.split('\n')[0].replace(/:/g, '')
+
+ if (this.reverseSymbols[name]) {
+ tocItems.push({
+ symbol: name,
+ name: actualName,
+ id: `def-${this.reverseSymbols[name].replace(/\s+/g, '-')}`
+ })
+ }
+ }
+ }
+
+ let tocHtml = ''
+ tocItems = tocItems.sort((a, b) => a.name.localeCompare(b.name))
+ if (tocItems.length > 0) {
+ tocHtml = `<div id="table-of-contents" style="display: grid; grid-template-columns: repeat(16, auto); gap: 0.5rem; width: fit-content; margin-bottom: 2rem; border: 1px solid var(--border); padding: 10px; border-radius: 5px;">`
+ const tocItemNames = tocItems.map(e => e.id)
+ for (const itemName of [...new Set(tocItemNames)]) {
+ const item = tocItems.find(e => e.id === itemName)
+ tocHtml += `<a class="table-item" href="#${item.id}" title="${item.name}">${item.symbol}</a>`
+ }
+ tocHtml += `</div>`
+ }
+ let tocInserted = false
let i = 0
for (const token of this.tokens) {
+ // Inject TOC before the first H2
+ if (!tocInserted && tocHtml && token.type === 'header' && token.level === 2) {
+ html += tocHtml
+ tocInserted = true
+ }
+
if (token.type === 'header') {
html += `<h${token.level}>${parseInline(token.text)}</h${token.level}>`
}
@@ -306,6 +356,12 @@
i++
}
+
+ // If no h2 found, prepend it (or append to whatever was rendered)
+ if (!tocInserted && tocHtml) {
+ html = tocHtml + html
+ }
+
return html
}
@@ -339,10 +395,16 @@
name = line
}
+ // Determine ID for TOC linking
+ let idAttr = ''
+ if (this.reverseSymbols[name]) {
+ idAttr = ` id="def-${this.reverseSymbols[name].replace(/\s+/g, '-')}"`
+ }
+
const descHtml = parseInline(token.description).replace(/\n/g, '<br>').replace(/ /g, '&nbsp;&nbsp;')
const deftext = escapeHTML(code)
- return `<block>
+ return `<block${idAttr}>
<header>
<div class='header-left'>
<span>def</span>
@@ -417,7 +479,7 @@
text = text.replace(/((^|\n)<!> *)/g, (e) => e.replace(/<!> */g, ''))
text = applySymbols(text, symbols)
- const parser = new TempoParser(text)
+ const parser = new TempoParser(text, symbols) // Passed symbols here
parser.tokenize()
const html = parser.render().replace(/{{dict_size}}/g, `<b>${parser.defs.size - 1}</b>`)
diff --git a/styles.css b/styles.css
index bdd0a6b..ca9fc63 100644
--- a/styles.css
+++ b/styles.css
@@ -111,10 +111,31 @@ body.dark-mode {
background-color: var(--code-bg-faint);
}
+#goBackUp {
+ position: fixed;
+ top: 70px;
+ right: 20px;
+ padding: 8px 16px;
+ background-color: var(--code-bg);
+ border: 1px solid var(--border);
+ cursor: pointer;
+ font-family: 'Roboto Mono', monospace;
+ font-size: 1.2rem;
+ border-radius: 4px;
+ z-index: 1000;
+ transition: 0.5s background-color;
+ color: var(--text);
+ font-weight: bold;
+}
+
+#goBackUp:hover {
+ background-color: var(--code-bg-faint);
+}
+
a {
/* text-decoration: none; */
color: var(--link);
- transition: 0.5s color;
+ transition: 0.5s background-color, 0.5s color !important;
}
a:hover {
@@ -173,6 +194,23 @@ b {
text-shadow: 0 0 2px var(--text);
}
+.table-item {
+ border-radius: 6px;
+ background-color: var(--code-bg);
+ transition: 0.5s background-color;
+
+ text-decoration: none;
+ font-size: 1.5em;
+ padding: 5px 8px;
+ text-align: center;
+ color: inherit;
+ display: block;
+}
+
+.table-item:hover {
+ background-color: var(--code-bg-faint);
+}
+
pre code {
background-color: transparent;
padding: 0;