import { Handler } from '/csspageweaver/lib/paged.esm.js'; export default class beforeAll extends Handler { constructor(chunker, polisher, caller) { super(chunker, polisher, caller); } beforeParsed(content){ thesis(content); wrapChapterAndIntro(content); } } function wrapChapterAndIntro(content){ // Wrap h1 and following content in .chapter sections const sectionContent = content.querySelector('#section__content'); if (sectionContent) { const h1s = sectionContent.querySelectorAll(':scope > h1'); h1s.forEach(h1 => { // Create chapter section const chapter = document.createElement('section'); chapter.classList.add('chapter'); // Insert chapter before h1 h1.parentNode.insertBefore(chapter, h1); // Move h1 into chapter chapter.appendChild(h1); // Move following siblings until next h1 or end let nextElement = chapter.nextElementSibling; while (nextElement && nextElement.tagName.toLowerCase() !== 'h1') { const current = nextElement; nextElement = nextElement.nextElementSibling; chapter.appendChild(current); } let divEnd = document.createElement('div'); divEnd.classList.add("chapter-end"); // need to avoid to add new page chapter.appendChild(divEnd); }); // Wrap content between h1 and h2 in .intro if chapter doesn't contain .p-these const chapters = sectionContent.querySelectorAll('.chapter'); chapters.forEach(chapter => { if (chapter.querySelector('.p-these')) { // Case 1: Chapter has thesis chapter.classList.add('has-thesis'); } else { const h1 = chapter.querySelector('h1'); if (h1) { // Calculate chapter content length excluding notes const chapterClone = chapter.cloneNode(true); // Remove notes (common note selectors) chapterClone.querySelectorAll('.note, .footnote, .sidenote, aside, [role="note"]').forEach(note => note.remove()); const contentLength = chapterClone.textContent.trim().length; const intro = document.createElement('div'); intro.classList.add('intro'); if (contentLength < 5000) { // Case 2: Short chapter, wrap all content after h1 h1.parentNode.insertBefore(intro, h1.nextSibling); let current = intro.nextSibling; while (current) { const next = current.nextSibling; intro.appendChild(current); current = next; } chapter.classList.add('has-only-intro'); } else { const nextHeading = chapter.querySelector('h2, h3, h4, h5, h6'); if (nextHeading) { // Case 3: Has heading, wrap all content between h1 and that heading h1.parentNode.insertBefore(intro, h1.nextSibling); let current = intro.nextSibling; while (current && current !== nextHeading) { const next = current.nextSibling; intro.appendChild(current); current = next; } chapter.classList.add('has-intro'); } else { // Case 4: No heading, wrap first ol[type="1"] and first p after h1 h1.parentNode.insertBefore(intro, h1.nextSibling); let foundOl = false; let foundP = false; let current = intro.nextSibling; while (current && (!foundOl || !foundP)) { const next = current.nextSibling; // Skip text nodes (whitespace) if (current.nodeType !== 1) { current = next; continue; } const isOlType1 = current.tagName.toLowerCase() === 'ol' && current.getAttribute('type') === '1'; const isP = current.tagName.toLowerCase() === 'p'; if (isOlType1 && !foundOl) { intro.appendChild(current); foundOl = true; current = next; } else if (isP && !foundP) { intro.appendChild(current); foundP = true; current = next; } else if (!isOlType1 && !isP) { break; } else { current = next; } } if (intro.children.length > 0) { chapter.classList.add('has-intro-1-paragraph'); } } } } } }); } } function thesis(content){ const strongs = content.querySelectorAll('strong'); strongs.forEach(strong => { if (/^these\s+\d+/i.test(strong.textContent.trim())) { const parent = strong.closest('p'); if (parent) { const thesisDiv = document.createElement('div'); thesisDiv.classList.add('thesis-title'); const thesisP = document.createElement('p'); thesisP.textContent = strong.textContent; thesisDiv.appendChild(thesisP); parent.parentNode.insertBefore(thesisDiv, parent); strong.remove(); parent.classList.add('p-these'); } } }); const theseParas = content.querySelectorAll('.p-these'); theseParas.forEach(p => { let next = p.nextElementSibling; while (next && next.tagName.toLowerCase() === 'ol') { next = next.nextElementSibling; } if (!next || !next.classList.contains('p-these')) { p.classList.add('p-these-last'); } }); }