diff options
Diffstat (limited to 'static/toc.js')
| -rw-r--r-- | static/toc.js | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/static/toc.js b/static/toc.js new file mode 100644 index 0000000..950533e --- /dev/null +++ b/static/toc.js @@ -0,0 +1,52 @@ +/** + * Table of Contents - Gera sumário automático de headings + */ + +document.addEventListener('DOMContentLoaded', () => { + const prose = document.getElementById('prose'); + const tocNav = document.getElementById('toc-nav'); + const tocList = document.getElementById('toc-list'); + + if (!prose || !tocNav || !tocList) return; + + const headings = prose.querySelectorAll('h2, h3'); + if (!headings.length) return; + + const used = new Set(); + + headings.forEach((h) => { + // Gerar ID único baseado no texto + let base = h.textContent + .trim() + .normalize('NFD') + .replace(/[\u0300-\u036f]/g, '') + .toLowerCase() + .replace(/[^a-z0-9]+/g, '-') + .replace(/^-+|-+$/g, ''); + + let id = base || 'sec'; + let i = 2; + while (used.has(id)) id = base + '-' + i++; + + h.id = id; + used.add(id); + + // Criar item no sumário + const li = document.createElement('li'); + li.className = 'toc-' + h.tagName.toLowerCase(); + + const a = document.createElement('a'); + a.href = '#' + id; + a.textContent = h.textContent; + a.addEventListener('click', (e) => { + e.preventDefault(); + h.scrollIntoView({ behavior: 'smooth', block: 'start' }); + }); + + li.appendChild(a); + tocList.appendChild(li); + }); + + // Mostrar sumário se houver conteúdo + tocNav.style.display = ''; +}); |
