walter-boente_book-collection/js/beforeAll.js
2026-04-21 15:40:30 +02:00

173 lines
No EOL
6.5 KiB
JavaScript

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');
}
});
}