toc.js (1335B)
1 /** 2 * Table of Contents - Gera sumário automático de headings 3 */ 4 5 document.addEventListener('DOMContentLoaded', () => { 6 const prose = document.getElementById('prose'); 7 const tocNav = document.getElementById('toc-nav'); 8 const tocList = document.getElementById('toc-list'); 9 10 if (!prose || !tocNav || !tocList) return; 11 12 const headings = prose.querySelectorAll('h2, h3'); 13 if (!headings.length) return; 14 15 const used = new Set(); 16 17 headings.forEach((h) => { 18 // Gerar ID único baseado no texto 19 let base = h.textContent 20 .trim() 21 .normalize('NFD') 22 .replace(/[\u0300-\u036f]/g, '') 23 .toLowerCase() 24 .replace(/[^a-z0-9]+/g, '-') 25 .replace(/^-+|-+$/g, ''); 26 27 let id = base || 'sec'; 28 let i = 2; 29 while (used.has(id)) id = base + '-' + i++; 30 31 h.id = id; 32 used.add(id); 33 34 // Criar item no sumário 35 const li = document.createElement('li'); 36 li.className = 'toc-' + h.tagName.toLowerCase(); 37 38 const a = document.createElement('a'); 39 a.href = '#' + id; 40 a.textContent = h.textContent; 41 a.addEventListener('click', (e) => { 42 e.preventDefault(); 43 h.scrollIntoView({ behavior: 'smooth', block: 'start' }); 44 }); 45 46 li.appendChild(a); 47 tocList.appendChild(li); 48 }); 49 50 // Mostrar sumário se houver conteúdo 51 tocNav.style.display = ''; 52 });