wrap intro + add chapterEnd

This commit is contained in:
Julie Blanc 2026-04-21 15:40:30 +02:00
parent 07047d97ea
commit 0d56ca3d0d
10 changed files with 217 additions and 158 deletions

View file

@ -11,7 +11,9 @@ $indent: 10mm;
$unit: calc($content-w/7);
:root{
--unit: #{$unit};
// --content-w: #{$content-w};
// --unit: calc(var(--content-w)/7);
--unit: 80px;
}
@ -139,15 +141,6 @@ $unit: calc($content-w/7);
}
#section__content{
break-before: right;
}
.page-break{
break-before: page;
}
#section__content h1 .h1-count{
@ -159,19 +152,8 @@ $unit: calc($content-w/7);
}
.chapter{
break-before: left;
}
.intro{
color: red;
page: chapter;
break-before: page;
}
// #section__content{
// break-before: left;
// }
// #section__content h1:first-of-type{
// break-before: right;
// }

View file

@ -12,6 +12,7 @@
position: absolute;
top: 0;
left: 0;
color: blue;
// color: red;
}

View file

@ -17,11 +17,8 @@ ol[type="1"]{
ol[type="1"].ol-clone{
break-before: column;
break-after: avoid;
top: 0;
left: calc($content-w/2 + $gap/2)
.intro ol[type="1"]{
left: 0px;
}

View file

@ -61,16 +61,6 @@ blockquote p{
padding-left: 2mm;
}
// blockquote u{
// text-decoration: none;
// text-transform: uppercase;
// font-size: var(--fs-small);
// color: red;
// }
// u{
// color: red;
// }
ul{
@ -79,6 +69,9 @@ ul{
// THESE --------------------------------------------------
.p-these{
font-weight: 500;
margin-bottom: calc(var(--baseline)*0.5);
@ -97,3 +90,29 @@ ul{
margin-bottom: calc(var(--baseline)*1);
}
// INTRO --------------------------------------------------
.has-intro-1-paragraph .intro,
.has-intro .intro{
break-after: right;
}
.intro{
color: red;
p{
font-size: var(--fs-intro);
padding-left: calc(var(--unit)*1);
line-height: 1.4;
}
}
.chapter-end{
width: 20px;
height: 20px;
background-color: green;
}

View file

@ -16,18 +16,21 @@
// }
h1{
// break-before: page;
break-after: page;
position: absolute;
left: 0;
top: 0;
// break-before: page;
// break-after: page;
// position: absolute;
// left: 0;
// top: 0;
height: $content-h;
// background-color: red;
display: flex;
flex-direction: column;
justify-content: space-between;
// display: none;
}

View file

@ -4,8 +4,9 @@
--font-quote: 'Louize', sans-serif;
--font-sans: 'Basis Grotesque Pro', sans-serif;
--font-size: 12px;
--fs-medium: 15px;
--fs-medium: 15px;
--fs-small: 9.8px;
--fs-intro: 16.5px;
--baseline: 18px;
--indent: 26px;
--fs-num: 12px;

View file

@ -7,6 +7,7 @@
--font-size: 12px;
--fs-medium: 15px;
--fs-small: 9.8px;
--fs-intro: 16.5px;
--baseline: 18px;
--indent: 26px;
--fs-num: 12px;
@ -33,7 +34,7 @@ body {
}
:root {
--unit: 20.2857142857mm;
--unit: 80px;
}
@media print {
@ -235,16 +236,6 @@ body {
}
}
}
#section__content {
-moz-column-break-before: right;
break-before: right;
}
.page-break {
-moz-column-break-before: page;
break-before: page;
}
#section__content h1 .h1-count {
string-set: chapterCount content(text);
}
@ -254,12 +245,9 @@ body {
}
.chapter {
-moz-column-break-before: left;
break-before: left;
}
.intro {
color: red;
page: chapter;
-moz-column-break-before: page;
break-before: page;
}
sup {
@ -333,6 +321,27 @@ ul {
margin-bottom: calc(var(--baseline) * 1);
}
.has-intro-1-paragraph .intro,
.has-intro .intro {
-moz-column-break-after: right;
break-after: right;
}
.intro {
color: red;
}
.intro p {
font-size: var(--fs-intro);
padding-left: calc(var(--unit) * 1);
line-height: 1.4;
}
.chapter-end {
width: 20px;
height: 20px;
background-color: green;
}
[data-id=section__content] {
position: relative;
}
@ -351,21 +360,11 @@ ol[type="1"]::after {
opacity: 0.5;
}
ol[type="1"].ol-clone {
-moz-column-break-before: column;
break-before: column;
-moz-column-break-after: avoid;
break-after: avoid;
top: 0;
left: 73mm;
.intro ol[type="1"] {
left: 0px;
}
#section__content h1 {
-moz-column-break-after: page;
break-after: page;
position: absolute;
left: 0;
top: 0;
height: 215mm;
display: flex;
flex-direction: column;
@ -525,6 +524,7 @@ ol[type="1"].ol-clone {
position: absolute;
top: 0;
left: 0;
color: blue;
}
.body-note {

File diff suppressed because one or more lines are too long

View file

@ -57,6 +57,10 @@ export default class addPagesNotes extends Handler {
if (prevPage) {
let content = prevPage.querySelector('[data-id="section__content"]');
let contentId = prevPage.querySelector('#section__content');
let titleH1 = prevPage.querySelector('h1');
if(titleH1){
container.classList.add('container-note-first');
}
if(content){
content.appendChild(container);
}else if(contentId){
@ -71,19 +75,22 @@ export default class addPagesNotes extends Handler {
// create blank left page
// create blank left page
if (
page.element.classList.contains('pagedjs_right_page') &&
page.element.querySelector('[data-id="section__content"]') &&
!pageElement.querySelector('.before-h1')
page.element.classList.contains('pagedjs_chapter_page')
) {
// Check if previous page is not end chapter
let pageEnd = pageElement.querySelector(".chapter-end");
let notesPage = chunker.addPage();
notesPage.element.classList.add('page-notes');
if (!pageEnd) {
let notesPage = chunker.addPage();
notesPage.element.classList.add('page-notes');
// Make margin boxes visible (hasContent is set during polishing, which skips added pages)
notesPage.element.querySelector('.pagedjs_margin-bottom-left')?.classList.add('hasContent');
notesPage.element.querySelector('.pagedjs_margin-bottom-center')?.classList.add('hasContent');
// Make margin boxes visible (hasContent is set during polishing, which skips added pages)
notesPage.element.querySelector('.pagedjs_margin-bottom-left')?.classList.add('hasContent');
notesPage.element.querySelector('.pagedjs_margin-bottom-center')?.classList.add('hasContent');
}
}
}
}

View file

@ -9,82 +9,8 @@ export default class beforeAll extends Handler {
thesis(content);
// for break
// let headings = content.querySelectorAll('#section__content h1');
// headings.forEach(function (h1) {
// let div = document.createElement('div');
// div.classList.add('before-h1');
// h1.insertAdjacentElement('beforebegin', div);
// });
// 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);
}
});
// 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');
const nextHeading = chapter.querySelector('h2, h3, h4, h5, h6');
if (h1) {
const intro = document.createElement('div');
intro.classList.add('intro');
if (nextHeading) {
// Case 2: 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 3: No heading, wrap only the first paragraph after h1
let current = h1.nextSibling;
while (current && current.tagName.toLowerCase() !== 'p') {
current = current.nextSibling;
}
if (current) {
current.parentNode.insertBefore(intro, current);
intro.appendChild(current);
chapter.classList.add('has-intro-1-paragraph');
}
}
}
}
});
}
wrapChapterAndIntro(content);
}
@ -92,6 +18,129 @@ export default class beforeAll extends Handler {
}
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 => {