create .intro modify + push to bottom

This commit is contained in:
Julie Blanc 2026-05-27 18:18:39 +02:00
parent c0a42e125b
commit 3495b49eed
4 changed files with 127 additions and 101 deletions

View file

@ -21,7 +21,8 @@
"hook": [
"/js/beforeAll.js",
"/js/counters.js",
"/js/addPagesNotes.js"
"/js/addPagesNotes.js",
"/js/afterAll.js"
]
}

View file

@ -35,7 +35,6 @@ export default class addPagesNotes extends Handler {
marker.textContent = counter + ". ";
note.prepend(marker);
});
console.log(chapter)
});

46
js/afterAll.js Normal file
View file

@ -0,0 +1,46 @@
import { Handler } from '/csspageweaver/lib/paged.esm.js';
export default class afterAll extends Handler {
constructor(chunker, polisher, caller) {
super(chunker, polisher, caller);
}
// PUSHINTRODUCTION&THESISTOBOTTOM
afterPageLayout(pageElement, page, breakToken){
pushIntroAndThesis(pageElement);
}
}
function pushIntroAndThesis(pageElement){
let intro = pageElement.querySelector('.intro');
let pageContent = pageElement.querySelector('.pagedjs_page_content');
console.log(intro);
if(intro && pageContent){
let introBottom = intro.getBoundingClientRect().bottom;
let pageContentBottom = pageContent.getBoundingClientRect().bottom;
let gap = pageContentBottom - introBottom;
gap = gap - 22; // snap on baseline
intro.style.paddingTop = gap + "px";
}
let thesisList = pageElement.querySelectorAll('.thesis');
if(thesisList.length > 0 && pageContent){
let lastThesis = thesisList[thesisList.length - 1];
let firstThesis = thesisList[0];
let lastThesisBottom = lastThesis.getBoundingClientRect().bottom;
let pageContentBottom = pageContent.getBoundingClientRect().bottom;
let gap = pageContentBottom - lastThesisBottom;
gap = gap - 4; // snap on baseline
firstThesis.style.marginTop = gap + "px";
}
}

View file

@ -22,30 +22,30 @@ export default class beforeAll extends Handler {
// PUSHINTRODUCTION&THESISTOBOTTOM
afterPageLayout(pageElement, page, breakToken){
let intro = pageElement.querySelector('.intro');
let pageContent = pageElement.querySelector('.pagedjs_page_content');
// afterPageLayout(pageElement, page, breakToken){
// let intro = pageElement.querySelector('.intro');
// let pageContent = pageElement.querySelector('.pagedjs_page_content');
if(intro && pageContent){
let introBottom = intro.getBoundingClientRect().bottom;
let pageContentBottom = pageContent.getBoundingClientRect().bottom;
let gap = pageContentBottom - introBottom;
gap = gap - 22; // snap on baseline
intro.style.paddingTop = gap + "px";
}
// if(intro && pageContent){
// let introBottom = intro.getBoundingClientRect().bottom;
// let pageContentBottom = pageContent.getBoundingClientRect().bottom;
// let gap = pageContentBottom - introBottom;
// gap = gap - 22; // snap on baseline
// intro.style.paddingTop = gap + "px";
// }
let thesisList = pageElement.querySelectorAll('.thesis');
if(thesisList.length > 0 && pageContent){
let lastThesis = thesisList[thesisList.length - 1];
let firstThesis = thesisList[0];
let lastThesisBottom = lastThesis.getBoundingClientRect().bottom;
let pageContentBottom = pageContent.getBoundingClientRect().bottom;
let gap = pageContentBottom - lastThesisBottom;
gap = gap - 4; // snap on baseline
firstThesis.style.marginTop = gap + "px";
}
// let thesisList = pageElement.querySelectorAll('.thesis');
// if(thesisList.length > 0 && pageContent){
// let lastThesis = thesisList[thesisList.length - 1];
// let firstThesis = thesisList[0];
// let lastThesisBottom = lastThesis.getBoundingClientRect().bottom;
// let pageContentBottom = pageContent.getBoundingClientRect().bottom;
// let gap = pageContentBottom - lastThesisBottom;
// gap = gap - 4; // snap on baseline
// firstThesis.style.marginTop = gap + "px";
// }
}
// }
@ -228,90 +228,70 @@ function wrapChapterAndIntro(content){
// Wrap content between h1 and h2 in .intro if chapter doesn't contain .thesis
const chapters = sectionContent.querySelectorAll('.chapter');
chapters.forEach(chapter => {
if (chapter.querySelector('.thesis')) {
// Case 1: Chapter has thesis
const h1 = chapter.querySelector('h1');
if (!h1) return;
const chapterClone = chapter.cloneNode(true);
chapterClone.querySelectorAll('.note, .footnote, .sidenote, aside, [role="note"]').forEach(n => n.remove());
const contentLength = chapterClone.textContent.trim().length;
const chapterStart = chapter.querySelector('.chapter-start');
const chapterEnd = chapter.querySelector('.chapter-end');
const anchor = chapterStart ? chapterStart.nextSibling : h1.nextSibling;
const intro = document.createElement('div');
intro.classList.add('intro');
if (contentLength < 5000) {
// Cas 1 : chapitre court → tout le contenu dans .intro
anchor.parentNode.insertBefore(intro, anchor);
let current = intro.nextSibling;
while (current && current !== chapterEnd) {
const next = current.nextSibling;
intro.appendChild(current);
current = next;
}
chapter.classList.add('has-intro-only');
} else if (chapter.querySelector('.thesis')) {
// Cas 2 : a une thèse → pas d'intro
chapter.classList.add('has-thesis');
} else if (chapter.querySelector('h2')) {
// Cas 3 : pas de thèse, a un h2 → wrap jusqu'au premier h2
const nextHeading = chapter.querySelector('h2');
anchor.parentNode.insertBefore(intro, anchor);
let current = intro.nextSibling;
while (current && current !== nextHeading) {
const next = current.nextSibling;
intro.appendChild(current);
current = next;
}
chapter.classList.add('has-intro');
} 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-intro-only');
// Cas 4 : ni thèse ni h2 → 4 premiers paragraphes (avec ol[type="1"] précédents)
anchor.parentNode.insertBefore(intro, anchor);
let pCount = 0;
let current = anchor;
while (current && pCount < 4) {
const next = current.nextSibling;
if (current.nodeType !== 1) { current = next; continue; }
const tag = current.tagName.toLowerCase();
const isOl = tag === 'ol' && current.getAttribute('type') === '1';
const isBodyText = tag === 'div' && current.getAttribute('data-custom-style') === 'Body Text';
if (isOl || isBodyText) {
intro.appendChild(current);
if (isBodyText) pCount++;
} 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');
}
}
break;
}
current = next;
}
if (intro.children.length > 0) {
chapter.classList.add('has-intro-1-paragraph');
}
}
});