Compare commits

...
Sign in to create a new pull request.

17 commits
main ... mini-1

Author SHA1 Message Date
Julie Blanc
c705823784 bleed mark 2026-04-22 17:50:32 +02:00
Julie Blanc
c801320c31 styles paragraphes 2026-04-22 17:43:29 +02:00
Julie Blanc
cd2a9e554d add counters to toc level-1 2026-04-22 10:47:47 +02:00
Julie Blanc
5cd734966e move list of abrr 2026-04-22 10:43:53 +02:00
Julie Blanc
ed5d47184d thesis align bottom 2026-04-21 23:28:03 +02:00
Julie Blanc
725306418d intro bottom 2026-04-21 23:05:59 +02:00
Julie Blanc
9ef96b6897 wrap thesis 2026-04-21 16:37:59 +02:00
Julie Blanc
626ba00ba8 ol satrt in html 2026-04-21 16:18:44 +02:00
Julie Blanc
0d56ca3d0d wrap intro + add chapterEnd 2026-04-21 15:40:30 +02:00
Julie Blanc
07047d97ea add intro and chapter wrapper 2026-04-21 13:52:57 +02:00
Julie Blanc
92b92a1146 titles 2026-04-17 18:06:54 +02:00
Julie Blanc
5b1113c988 title same page notes 2026-04-16 18:15:07 +02:00
Julie Blanc
656e58b0f4 style-note 2026-04-16 17:44:10 +02:00
Julie Blanc
bc2c5ffccb style notes 2026-04-16 17:42:46 +02:00
Julie Blanc
1d747cc77b move note to prev page 2026-04-16 16:00:53 +02:00
Julie Blanc
d57050caeb add blank page 2026-04-16 10:35:30 +02:00
Julie Blanc
fa738ed605 grid column 2026-04-16 09:42:55 +02:00
34 changed files with 919 additions and 2228 deletions

View file

@ -1,54 +0,0 @@
// INUTILE
@page {
@footnote {
float: bottom;
footnote-policy: auto;
}
}
.pagedjs_footnote_content{
padding-top: calc(var(--baseline)*1);
}
.inline-note {
float: footnote;
footnote-policy: auto;
font-size: var(--fs-small);
line-height: calc(var(--baseline)*0.8);
padding-left: var(--indent);
position: relative;
font-weight: 600;
&::marker{
display: none;
content: "";
}
}
[data-counter-note]{
&::before{
content: attr(data-counter-note) ".";
position: absolute;
left: 0px;
}
}
.inline-note::after{
font-family: var(--font);
font-size: var(--fs-small);
line-height: 0;
position: relative;
top: -3px;
font-variant-position: normal!important;
}
blockquote .inline-note{
font-variant-position: normal!important;
}

View file

@ -1,13 +1,23 @@
$width: 176mm;
$height: 240mm;
$top: 6mm;
$bottom: 20mm;
$inside: 12mm;
$outside: 6mm;
$top: 10mm;
$bottom: 19mm;
$inside: 20mm;
$outside: 14mm;
$content-h: calc($height - $top - $bottom - 1mm);
$content-w: calc($width - $inside - $outside);
$gap: 4mm;
$indent: 10mm;
$unit: calc($content-w/7);
:root{
// --content-w: #{$content-w};
--unit: calc(#{$content-w}/7);
// --unit: 80px;
--margin-box: -13px;
}
@media print {
@ -15,30 +25,31 @@ $indent: 10mm;
size: $width $height;
margin-top: $top;
margin-bottom: $bottom;
// bleed: 6mm;
// marks: crop;
bleed: 6mm;
marks: crop;
}
@page:left {
margin-left: $outside;
margin-right: $inside;
// background-image: url("/images/layout-2_3.png");
// background-size: 100% 100%;
@bottom-left {
content: counter(page);
font-family: var(--font-sans);
font-size: var(--fs-num);
font-weight: 500;
text-align: left;
width: $indent;
position: relative;
top: var(--margin-box);
}
@bottom-center {
content: "Höchstpersönlichkeit";
font-family: var(--font-sans);
font-size: var(--fs-num);
font-weight: 500;
text-align: left;
position: relative;
top: var(--margin-box);
}
}
@ -46,31 +57,48 @@ $indent: 10mm;
margin-left: $inside;
margin-right: $outside;
// background-image: url('/images/layout-1_2.png');
// background-size: 100% 100%;
@bottom-left {
content: string(chapterCount);
font-family: var(--font-sans);
font-size: var(--fs-num);
font-weight: 500;
text-align: left;
width: $indent;
width: calc(var(--unit)*3);
padding-left: calc(var(--unit)*2);
position: relative;
top: var(--margin-box);
}
@bottom-center {
content: string(chapter);
font-family: var(--font-sans);
font-size: var(--fs-num);
font-weight: 500;
text-align: left;
position: relative;
top: var(--margin-box);
width: calc(var(--unit)*3.5);
}
@bottom-right {
content: counter(page);
font-family: var(--font-sans);
font-size: var(--fs-num);
font-weight: 500;
text-align: right;
position: relative;
top: var(--margin-box);
}
}
@page:first {
@page chapter:first {
@top-left-corner { content: none; }
@top-left { content: none; }
@top-center { content: none; }
@ -107,54 +135,12 @@ $indent: 10mm;
@bottom-right-corner { content: none; }
}
@page chapter {
margin-left: $outside;
margin-right: $outside;
@top-left-corner { content: none; }
@top-left { content: none; }
@top-center { content: none; }
@top-right { content: none; }
@top-right-corner { content: none; }
@left-top { content: none; }
@left-middle { content: none; }
@left-bottom { content: none; }
@right-top { content: none; }
@right-middle { content: none; }
@right-bottom { content: none; }
@bottom-left-corner { content: none; }
@bottom-left { content: none; }
@bottom-center { content: none; }
@bottom-right { content: none; }
@bottom-right-corner { content: none; }
}
}
#section__content{
break-before: right;
}
.page-break{
break-before: page;
}
#section__content{
columns: 2;
column-gap: $gap;
column-fill: auto;
}
// Title chapter
#section__content h1{
break-before: left;
break-after: page;
page: chapter;
}
#section__content h1 .h1-count{
string-set: chapterCount content(text);
}
@ -164,3 +150,9 @@ $indent: 10mm;
}
.chapter{
page: chapter;
break-before: page;
}

View file

@ -1,9 +1,27 @@
.container-following-note{
font-family: var(--font-sans);
.pagedjs_page_content{
position: relative;
}
.container-note{
padding-left: calc(var(--unit)*2);
}
.page-with-h1 .before-h1,
.container-note-first{
position: absolute;
top: 0;
left: 0;
}
.body-note{
display: block;
font-family: var(--font-sans);
font-size: var(--fs-small);
line-height: calc(var(--baseline)*0.75);
position: relative;
margin-top: 2px;
// margin-top: calc(var(--baseline)*0.25);
hyphens: auto;
@ -12,24 +30,21 @@
hyphenate-limit-zone: 8%;
word-spacing: -0.004em;
text-align: justify;
// color: #999;
}
.body_note{
// padding-left: calc(var(--indent)*1);
// position: relative;
.note_marker{
font-weight: bold;
}
.following-note_marker::after{
content: ". "
}
.following-note_call{
font-family: var(--font-sans);
.note_call{
font-family: var(--font-sans);
font-size: var(--fs-small);
font-weight: normal;
line-height: 1;
position: relative;
top: -4px;
}

View file

@ -4,30 +4,24 @@
ol[type="1"]{
list-style-type: none;
position: relative;
break-after: avoid;
width: $indent;
position: absolute;
display: flex;
align-items: center;
justify-content: center;
&::after{
content: attr(start);
display: block;
position: absolute;
font-size: var(--fs-small);
opacity: 0.5;
}
left: calc(var(--unit)*1);
display: block;
font-size: var(--fs-small);
opacity: 0.5;
// &::after{
// content: attr(start)!important;
// display: block;
// font-size: var(--fs-small);
// opacity: 0.5;
// }
}
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

@ -22,8 +22,12 @@ p{
text-align: justify;
orphans: 2;
widows: 2;
margin-left: $indent;
// padding-left: $indent*0.2;
position: relative;
top: -2px;
padding-left: calc(var(--unit)*2);
}
p, li{
@ -47,19 +51,16 @@ p, li{
blockquote{
font-family: var(--font-quote);
// font-family: var(--font-quote);
border-left: 0.5px solid black;
margin-left: calc(var(--unit)*2);
}
// blockquote u{
// text-decoration: none;
// text-transform: uppercase;
// font-size: var(--fs-small);
// color: red;
// }
blockquote p{
padding-left: 2mm;
}
// u{
// color: red;
// }
ul{
@ -68,21 +69,65 @@ ul{
.p-these{
// ol, p, h4, h5, h6{
// display: none;
// }
// THESE --------------------------------------------------
.thesis{
break-inside: avoid;
}
.thesis-title{
width: 100%;
display: flex;
gap: 1ch;
}
.thesis-line{
width: 100%;
height: 8px;
background-color: black;
position: relative;
top: 3px;
}
.thesis-title p{
flex-shrink: 0;
text-transform: uppercase;
font-weight: 500;
margin-bottom: calc(var(--baseline)*0.5);
strong{
text-transform: uppercase;
display: inline-block;
min-width: $indent*2;
font-weight: bold;
font-size: var(--fs-small);
letter-spacing: 0.05rem;
font-size: 0.9em;
letter-spacing: 0.01rem;
}
.thesis p{
display: block;
}
.thesis + .thesis{
margin-top: calc(var(--baseline)*1);
}
// INTRO --------------------------------------------------
.has-intro-1-paragraph .intro,
.has-intro .intro{
break-after: right;
}
.intro{
p{
font-size: var(--fs-intro);
padding-left: calc(var(--unit)*1);
line-height: 23px;
display: block;
}
}
.p-these-last{
margin-bottom: calc(var(--baseline)*1);
}

View file

@ -1,20 +1,33 @@
#section__content{
// margin-left: 28mm;
h1{
column-span: all;
height: $content-h;
}
.h1-count::after{
content: "."
}
.h1-count{
margin-bottom: 1em;
}
min-height: $content-h;
display: flex;
flex-direction: column;
justify-content: space-between;
&[data-split-from]{
color: red;
position: absolute;
}
}
h2, h3, h4, h5, h6 {
&::before{
content: attr(data-counter);
content: attr(data-counter) ". ";
}
}
@ -64,19 +77,10 @@
h1{
font-weight: 200;
font-size: 115px;
font-size: 105px;
line-height: 0.9;
hyphens: auto;
break-inside: avoid;
display: flex;
flex-direction: column;
justify-content: space-between;
text-align: center;
hyphenate-limit-chars: 12 4 3;
span{
@ -93,56 +97,67 @@
font-size: 22px;
font-weight: 200;
text-transform: uppercase;
text-align: center;
text-align: left;
line-height: calc(var(--baseline)*1.4);
margin-top: 4mm;
padding-bottom: 4mm;
margin-top: 6mm;
padding-bottom: 6mm;
hyphens: auto;
margin-left: calc(var(--unit)*1);
padding-left: calc(var(--unit)*0.5);
position: relative;
max-width: calc(var(--unit)*5);
text-wrap: balance;
// background-color: red;
&::before{
display: block;
position: absolute;
left: 0;
}
// &::after{
// content: '';
// display: block;
// width: 100%;
// border-bottom: 1px solid currentColor;
// position: relative;
// top: calc(var(--baseline)*-2.5);
// opacity: 0.2;
// }
}
h3{
font-weight: 500;
font-size: 1em;
line-height: calc(var(--baseline)*0.75);
font-size: var(--fs-medium);
line-height: 1.1;
padding-left: calc(var(--unit)*1);
margin-left: calc(var(--unit)*2);
padding-left: calc(var(--unit)*0.5);
position: relative;
margin-top: 4mm;
padding-bottom: 4mm;
padding-left: $indent;
text-align: center;
margin-top: 6mm;
padding-bottom: 6mm;
margin-right: 8mm;
&::before{
display: block;
position: absolute;
left: 0;
}
}
h4{
font-weight: 500;
font-weight: normal;
font-size: 1em;
line-height: calc(var(--baseline)*0.75);
line-height: var(--baseline);
position: relative;
margin-top: calc(var(--baseline)*1);
padding-bottom: calc(var(--baseline)*0.5);
padding-left: $indent*2;
margin-top: 6mm;
padding-bottom: 6mm;
margin-right: 20mm;
text-decoration: 0.5px underline;
text-underline-offset: 3px;
margin-left: calc(var(--unit)*2);
padding-left: calc(var(--unit)*0.5);
&::before{
display: block;
position: absolute;
left: $indent;
left: 0;
// left: calc(var(--unit)*1);
text-decoration: none;
}
}
@ -150,13 +165,14 @@
h5{
font-weight: normal;
font-size: 1em;
line-height: calc(var(--baseline)*0.75);
line-height: calc(var(--baseline)*1);
position: relative;
top: -2px;
margin-top: calc(var(--baseline)*1);
padding-bottom: calc(var(--baseline)*0.25);
padding-left: $indent;
margin-left: calc(var(--unit)*3);
padding-left: calc(var(--unit)*0.5);
text-indent: $indent;
&::before{
display: block;
position: absolute;
@ -167,16 +183,17 @@
h6{
font-weight: normal;
font-size: 1em;
line-height: calc(var(--baseline)*0.75);
position: relative;
line-height: calc(var(--baseline)*1);
margin-top: calc(var(--baseline)*1);
padding-left: $indent;
text-indent: $indent;
margin-left: calc(var(--unit)*2);
// padding-left: calc(var(--unit)*0.5);
// color: red;
position: relative;
top: -2px;
&::before{
display: block;
position: absolute;
left: 0;
// display: block;
// position: absolute;
// left: 0;
}
}
@ -186,7 +203,9 @@
}
[data-id="section__content"][data-split-from] > :first-child {
[data-id="section__content"] > .chapter h2:first-child,
[data-id="section__content"] > .chapter h3:first-child,
[data-id="section__content"] > .chapter h4:first-child {
margin-top: 0;
}

View file

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

View file

@ -5,10 +5,12 @@
--font-quote: 'Louize', sans-serif;
--font-sans: 'Basis Grotesque Pro', sans-serif;
--font-size: 12px;
--fs-medium: 15px;
--fs-small: 9.8px;
--fs-intro: 16.5px;
--baseline: 18px;
--indent: 26px;
--fs-num: 12px;
--fs-num: 11px;
}
* {
@ -31,53 +33,77 @@ body {
line-height: var(--baseline);
}
:root {
--unit: calc(142mm/7);
--margin-box: -13px;
}
@media print {
@page {
size: 176mm 240mm;
margin-top: 6mm;
margin-bottom: 20mm;
margin-top: 10mm;
margin-bottom: 19mm;
bleed: 6mm;
marks: crop;
}
@page :left {
margin-left: 6mm;
margin-right: 12mm;
margin-left: 14mm;
margin-right: 20mm;
@bottom-left {
content: counter(page);
font-family: var(--font-sans);
font-size: var(--fs-num);
font-weight: 500;
text-align: left;
width: 10mm;
position: relative;
top: var(--margin-box);
}
@bottom-center {
content: "Höchstpersönlichkeit";
font-family: var(--font-sans);
font-size: var(--fs-num);
font-weight: 500;
text-align: left;
position: relative;
top: var(--margin-box);
}
}
@page :right {
margin-left: 12mm;
margin-right: 6mm;
margin-left: 20mm;
margin-right: 14mm;
@bottom-left {
content: string(chapterCount);
font-family: var(--font-sans);
font-size: var(--fs-num);
font-weight: 500;
text-align: left;
width: 10mm;
width: calc(var(--unit) * 3);
padding-left: calc(var(--unit) * 2);
position: relative;
top: var(--margin-box);
}
@bottom-center {
content: string(chapter);
font-family: var(--font-sans);
font-size: var(--fs-num);
font-weight: 500;
text-align: left;
position: relative;
top: var(--margin-box);
width: calc(var(--unit) * 3.5);
}
@bottom-right {
content: counter(page);
font-family: var(--font-sans);
font-size: var(--fs-num);
font-weight: 500;
text-align: right;
position: relative;
top: var(--margin-box);
}
}
@page :first {
@page chapter:first {
@top-left-corner {
content: none;
}
@ -177,86 +203,7 @@ body {
content: none;
}
}
@page chapter {
margin-left: 6mm;
margin-right: 6mm;
@top-left-corner {
content: none;
}
@top-left {
content: none;
}
@top-center {
content: none;
}
@top-right {
content: none;
}
@top-right-corner {
content: none;
}
@left-top {
content: none;
}
@left-middle {
content: none;
}
@left-bottom {
content: none;
}
@right-top {
content: none;
}
@right-middle {
content: none;
}
@right-bottom {
content: none;
}
@bottom-left-corner {
content: none;
}
@bottom-left {
content: none;
}
@bottom-center {
content: none;
}
@bottom-right {
content: none;
}
@bottom-right-corner {
content: none;
}
}
}
#section__content {
-moz-column-break-before: right;
break-before: right;
}
.page-break {
-moz-column-break-before: page;
break-before: page;
}
#section__content {
-moz-columns: 2;
columns: 2;
-moz-column-gap: 4mm;
column-gap: 4mm;
-moz-column-fill: auto;
column-fill: auto;
}
#section__content h1 {
-moz-column-break-before: left;
break-before: left;
-moz-column-break-after: page;
break-after: page;
page: chapter;
}
#section__content h1 .h1-count {
string-set: chapterCount content(text);
}
@ -265,6 +212,12 @@ body {
string-set: chapter content(text);
}
.chapter {
page: chapter;
-moz-column-break-before: page;
break-before: page;
}
sup {
line-height: 0;
}
@ -287,7 +240,9 @@ p {
text-align: justify;
orphans: 2;
widows: 2;
margin-left: 10mm;
position: relative;
top: -2px;
padding-left: calc(var(--unit) * 2);
}
p, li {
@ -305,28 +260,64 @@ p, li {
}
blockquote {
font-family: var(--font-quote);
border-left: 0.5px solid black;
margin-left: calc(var(--unit) * 2);
}
blockquote p {
padding-left: 2mm;
}
ul {
color: red;
}
.p-these {
font-weight: 500;
margin-bottom: calc(var(--baseline) * 0.5);
}
.p-these strong {
text-transform: uppercase;
display: inline-block;
min-width: 20mm;
font-weight: bold;
font-size: var(--fs-small);
letter-spacing: 0.05rem;
.thesis {
-moz-column-break-inside: avoid;
break-inside: avoid;
}
.p-these-last {
margin-bottom: calc(var(--baseline) * 1);
.thesis-title {
width: 100%;
display: flex;
gap: 1ch;
}
.thesis-line {
width: 100%;
height: 8px;
background-color: black;
position: relative;
top: 3px;
}
.thesis-title p {
flex-shrink: 0;
text-transform: uppercase;
font-weight: 500;
font-size: 0.9em;
letter-spacing: 0.01rem;
}
.thesis p {
display: block;
}
.thesis + .thesis {
margin-top: calc(var(--baseline) * 1);
}
.has-intro-1-paragraph .intro,
.has-intro .intro {
-moz-column-break-after: right;
break-after: right;
}
.intro p {
font-size: var(--fs-intro);
padding-left: calc(var(--unit) * 1);
line-height: 23px;
display: block;
}
[data-id=section__content] {
@ -335,39 +326,37 @@ ul {
ol[type="1"] {
list-style-type: none;
position: relative;
-moz-column-break-after: avoid;
break-after: avoid;
width: 10mm;
position: absolute;
display: flex;
align-items: center;
justify-content: center;
}
ol[type="1"]::after {
content: attr(start);
left: calc(var(--unit) * 1);
display: block;
position: absolute;
font-size: var(--fs-small);
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: 81mm;
.intro ol[type="1"] {
left: 0px;
}
#section__content h1 .h1-count::after {
content: ".";
}
#section__content h1 .h1-count {
margin-bottom: 1em;
}
#section__content h1 {
-moz-column-span: all;
column-span: all;
height: 213mm;
min-height: 210mm;
display: flex;
flex-direction: column;
justify-content: space-between;
}
#section__content h1[data-split-from] {
color: red;
position: absolute;
}
#section__content h2::before, #section__content h3::before, #section__content h4::before, #section__content h5::before, #section__content h6::before {
content: attr(data-counter);
content: attr(data-counter) ". ";
}
#section__content h2, #section__content h3, #section__content h4 {
-moz-column-break-inside: avoid;
@ -407,15 +396,10 @@ ol[type="1"].ol-clone {
}
#section__content h1 {
font-weight: 200;
font-size: 115px;
font-size: 105px;
line-height: 0.9;
hyphens: auto;
-moz-column-break-inside: avoid;
break-inside: avoid;
display: flex;
flex-direction: column;
justify-content: space-between;
text-align: center;
hyphenate-limit-chars: 12 4 3;
}
#section__content h1 span {
display: block;
@ -424,51 +408,68 @@ ol[type="1"].ol-clone {
font-size: 22px;
font-weight: 200;
text-transform: uppercase;
text-align: center;
text-align: left;
line-height: calc(var(--baseline) * 1.4);
margin-top: 4mm;
padding-bottom: 4mm;
margin-top: 6mm;
padding-bottom: 6mm;
hyphens: auto;
margin-left: calc(var(--unit) * 1);
padding-left: calc(var(--unit) * 0.5);
position: relative;
max-width: calc(var(--unit) * 5);
text-wrap: balance;
}
#section__content h2::before {
display: block;
position: absolute;
left: 0;
}
#section__content h3 {
font-weight: 500;
font-size: 1em;
line-height: calc(var(--baseline) * 0.75);
font-size: var(--fs-medium);
line-height: 1.1;
padding-left: calc(var(--unit) * 1);
margin-left: calc(var(--unit) * 2);
padding-left: calc(var(--unit) * 0.5);
position: relative;
margin-top: 4mm;
padding-bottom: 4mm;
padding-left: 10mm;
text-align: center;
margin-top: 6mm;
padding-bottom: 6mm;
margin-right: 8mm;
}
#section__content h3::before {
display: block;
position: absolute;
left: 0;
}
#section__content h4 {
font-weight: 500;
font-weight: normal;
font-size: 1em;
line-height: calc(var(--baseline) * 0.75);
line-height: var(--baseline);
position: relative;
margin-top: calc(var(--baseline) * 1);
padding-bottom: calc(var(--baseline) * 0.5);
padding-left: 20mm;
margin-top: 6mm;
padding-bottom: 6mm;
margin-right: 20mm;
-webkit-text-decoration: 0.5px underline;
text-decoration: 0.5px underline;
text-underline-offset: 3px;
margin-left: calc(var(--unit) * 2);
padding-left: calc(var(--unit) * 0.5);
}
#section__content h4::before {
display: block;
position: absolute;
left: 10mm;
left: 0;
text-decoration: none;
}
#section__content h5 {
font-weight: normal;
font-size: 1em;
line-height: calc(var(--baseline) * 0.75);
line-height: calc(var(--baseline) * 1);
position: relative;
top: -2px;
margin-top: calc(var(--baseline) * 1);
padding-bottom: calc(var(--baseline) * 0.25);
padding-left: 10mm;
text-indent: 10mm;
margin-left: calc(var(--unit) * 3);
padding-left: calc(var(--unit) * 0.5);
}
#section__content h5::before {
display: block;
@ -478,19 +479,15 @@ ol[type="1"].ol-clone {
#section__content h6 {
font-weight: normal;
font-size: 1em;
line-height: calc(var(--baseline) * 0.75);
position: relative;
line-height: calc(var(--baseline) * 1);
margin-top: calc(var(--baseline) * 1);
padding-left: 10mm;
text-indent: 10mm;
margin-left: calc(var(--unit) * 2);
position: relative;
top: -2px;
}
#section__content h6::before {
display: block;
position: absolute;
left: 0;
}
[data-id=section__content][data-split-from] > :first-child {
[data-id=section__content] > .chapter h2:first-child,
[data-id=section__content] > .chapter h3:first-child,
[data-id=section__content] > .chapter h4:first-child {
margin-top: 0;
}
@ -499,12 +496,26 @@ ol[type="1"].ol-clone {
color: red;
}
.container-following-note {
.pagedjs_page_content {
position: relative;
}
.container-note {
padding-left: calc(var(--unit) * 2);
}
.page-with-h1 .before-h1,
.container-note-first {
position: absolute;
top: 0;
left: 0;
}
.body-note {
display: block;
font-family: var(--font-sans);
font-size: var(--fs-small);
line-height: calc(var(--baseline) * 0.75);
position: relative;
margin-top: 2px;
hyphens: auto;
hyphenate-limit-chars: 7 3 4;
hyphenate-limit-lines: 2;
@ -513,13 +524,14 @@ ol[type="1"].ol-clone {
text-align: justify;
}
.following-note_marker::after {
content: ". ";
.note_marker {
font-weight: bold;
}
.following-note_call {
.note_call {
font-family: var(--font-sans);
font-size: var(--fs-small);
font-weight: normal;
line-height: 1;
position: relative;
top: -4px;

File diff suppressed because one or more lines are too long

View file

@ -6,5 +6,7 @@
@import 'modules/num-paragraph';
@import 'modules/titles';
@import 'modules/list-of-abbr';
@import 'modules/followingNotes';
@import 'modules/notes';
// @import 'modules/followingNotes';
@import 'modules/toc';

View file

@ -1,11 +1,10 @@
{
"plugins": [
"baseline",
"grid",
"gridColumn",
"marginBox",
"imposition","spread","previewPage","reloadInPlace",
"inlineNotes",
"followingNotes",
"inlineNotes",
"tableOfContent"
],
"pluginsParameters":{},
@ -18,20 +17,15 @@
"containerNotes": "#footnotes",
"newClass": "inline-note"
},
"followingNotes": {
"selector": ".inline-note",
"reset": ".chapter"
},
"tableOfContent": {
"tocContainer": "#toc_container",
"tocTitles": ["#section__content h1", "#section__content h2", "h3", "h4", "h5", "h6"]
}
},
"hook": [
"/js/beforeAll.js",
"/js/counters.js",
"/js/these.js",
"/js/snapToBaseline.js",
"/js/numParagraph.js"
"/js/addPagesNotes.js"
]
}

View file

@ -1,8 +0,0 @@
{
"name": "FollowingNotes",
"description": "Create followingNotes with call & markers",
"author": ["Julie Blanc"],
"licence": "MIT",
"version": "1.0",
"hook": "followingNotes.js"
}

View file

@ -1,244 +0,0 @@
/**
* @name FollowingNotes
* @author Julie Blanc <contact@julie-blanc.fr>
* @see { @link https://gitlab.com/csspageweaver/plugins/followingNotes/ }
*/
import { Handler } from '/csspageweaver/lib/paged.esm.js';
export default class followingNotes extends Handler {
constructor(chunker, polisher, caller) {
super(chunker, polisher, caller);
this.parameters = cssPageWeaver.features.followingNotes.parameters;
this.notesClass = this.parameters?.selector || ".inline-note";
this.newNotesClass = this.parameters?.newNotesClass || "following-note";
this.reset = this.parameters?.reset;
this.align = this.parameters?.align;
this.followingNoteOverflow = new Set();
}
beforeParsed(content) {
let newNotesClass = this.newNotesClass;
resetCounter(content, this.reset, this.notesClass);
createCallandMarker(content, this.notesClass, newNotesClass);
const containerMap = new Map();
let notes = content.querySelectorAll(this.notesClass);
notes.forEach(function (note) {
let paragraph = note.closest("p");
if (!paragraph) return;
// Remonter au niveau direct de #section__content (ignorer blockquote et autres conteneurs)
const sectionContent = note.closest('#section__content') || content;
let topLevel = paragraph;
while (topLevel.parentElement && topLevel.parentElement !== sectionContent) {
topLevel = topLevel.parentElement;
}
// Find next boundary: heading or ol[type="1"], au niveau de #section__content
let boundary = null;
let sibling = topLevel.nextElementSibling;
while (sibling) {
if (sibling.matches('h1, h2, h3, h4, h5, h6, ol[type="1"]')) {
boundary = sibling;
break;
}
sibling = sibling.nextElementSibling;
}
const mapKey = boundary || sectionContent;
if (!containerMap.has(mapKey)) {
let container = document.createElement("div");
container.classList.add("container-following-note");
if (boundary) {
boundary.before(container);
} else {
sectionContent.appendChild(container);
}
containerMap.set(mapKey, container);
}
containerMap.get(mapKey).appendChild(note);
});
}
}
/// FUNCTIONS -----------------------------------------------------
// RESET COUNTER
function resetCounter(content, reset, notesClass){
if(reset && reset != ""){
const elements = content.querySelectorAll(reset + ", " + notesClass);
let resetEligible = false;
elements.forEach(element => {
if (element.matches(reset)) {
resetEligible = true;
} else if (resetEligible && element.matches(notesClass)) {
element.dataset.resetCounterFollowingNote = true;
resetEligible = false;
}
});
}
}
// CALL & MARKER
function createCallandMarker(content, notesClass, newNotesClass){
let notes = content.querySelectorAll(notesClass);
let resetNum = 0;
notes.forEach(function (note, index) {
if (note.dataset.resetCounterFollowingNote === "true") {
resetNum = index;
}
let num = index + 1 - resetNum;
note.classList.add(newNotesClass);
note.dataset.counterNote = num;
// call
let ref_note = document.createElement('span');
ref_note.className = newNotesClass + "_call";
ref_note.dataset.counterNote = num;
ref_note.innerHTML = num;
// wrap preceding word + call in .wrapper__note-call
let wrapper = document.createElement('span');
wrapper.className = 'wrapper__note-call';
let prevSibling = note.previousSibling;
if (prevSibling && prevSibling.nodeType === Node.TEXT_NODE) {
let text = prevSibling.textContent;
let m = text.match(/^([\s\S]*\s)(\S+\s*)$/);
if (m) {
let before = m[1];
let extracted = m[2];
// Si le dernier mot extrait est uniquement », prendre aussi le mot d'avant
if (/^»\s*$/.test(extracted)) {
let m2 = before.trimEnd().match(/^([\s\S]*\s|)(\S+)$/);
if (m2) {
let spaceBetween = before.slice(m2[1].length + m2[2].length);
before = m2[1];
extracted = m2[2] + spaceBetween + extracted;
}
}
prevSibling.textContent = before;
wrapper.appendChild(document.createTextNode(extracted));
} else {
prevSibling.textContent = '';
wrapper.appendChild(document.createTextNode(text));
}
}
wrapper.appendChild(ref_note);
note.after(wrapper);
// marker + content note wrapped in body_note
let marker_note = document.createElement('span');
marker_note.className = newNotesClass + "_marker";
//marker_note.innerHTML = num + ". ";
marker_note.innerHTML = num;
let body_note = document.createElement('div');
body_note.className = 'body_note';
while (note.firstChild) {
body_note.appendChild(note.firstChild);
}
body_note.prepend(marker_note);
note.appendChild(body_note);
});
}
// MARGINS
function marginNoteTop(elem) {
let marginTop = parseInt(window.getComputedStyle(elem).marginTop, 10)
return marginTop;
}
function marginNoteBottom(elem) {
let marginBottom = parseInt(window.getComputedStyle(elem).marginBottom, 10)
return marginBottom;
}
function biggestMargin(a, b) {
let margin;
let marginBottom = marginNoteBottom(a);
let marginTop = marginNoteTop(b);
if (marginBottom > marginTop) {
margin = marginBottom;
} else {
margin = marginTop;
}
return margin;
}
function checkOverflownote(notesClass, pageElement, maxHeight, arrayOverflow, container) {
let notes = pageElement.querySelectorAll(notesClass);
let notesHeightAll = [];
for (let n = 0; n < notes.length; ++n) {
// Add height of the notes to array notesHeightAll
let noteHeight = notes[n].offsetHeight;
notesHeightAll.push(noteHeight);
// Add margins of the notes to array notesHeightAll
if (n >= 1) {
let margins = biggestMargin(notes[n - 1], notes[n]);
notesHeightAll.push(margins);
}
}
// If notes on page
if (notesHeightAll.length > 0) {
// Calculate if all notes fit on the page;
let reducer = (accumulator, currentValue) => accumulator + currentValue;
let allHeight = notesHeightAll.reduce(reducer);
let paddingTop = getComputedStyle(container).paddingTop;
let paddingContainer = parseInt(paddingTop);
let totalHeight = allHeight + paddingContainer;
if (totalHeight > maxHeight) {
let lastNote = notes[notes.length - 1];
arrayOverflow.add(lastNote);
lastNote.remove();
checkOverflownote(notesClass, pageElement, maxHeight, arrayOverflow, container);
}
}
}

View file

@ -1 +0,0 @@
.DS_Store

View file

@ -1,14 +0,0 @@
{
"name": "Grid",
"description": "",
"version": "1.0",
"ui": {
"title": "Squared grid",
"description": "This Toogle a squared grid",
"template": "template.html",
"toggle": true
},
"stylesheet": "grid.css",
"script": "grid-ui.js",
"hook": "grid-hook.js"
}

View file

@ -1,17 +0,0 @@
/**
* @name Grid
* @author Julie Blanc <contact@julie-blanc.fr>
* @see { @link https://gitlab.com/csspageweaver/plugins/grid/ }
*/
import { Handler } from '/csspageweaver/lib/paged.esm.js';
export default class GridPage extends Handler {
constructor(chunker, polisher, caller) {
super(chunker, polisher, caller);
}
}

View file

@ -1,115 +0,0 @@
/**
* @name Grid
* @author Julie Blanc <contact@julie-blanc.fr>
* @see { @link https://gitlab.com/csspageweaver/plugins/grid/ }
*/
export default function gridEvents(){
let body = cssPageWeaver.ui.body;
let fileTitle = cssPageWeaver.docTitle;
let parameters = cssPageWeaver.features.grid.parameters || {};
let isParametersSet = Object.keys(parameters).length > 0;
let grid = {};
// valeur par défaut
grid.default = {
toggle: 'no-grid',
spacing: 56,
steps: 5,
positionX: 28,
positionY: 0
};
grid.toggle = {};
grid.toggle.input = cssPageWeaver.ui.grid.toggleInput;
grid.toggle.label = cssPageWeaver.ui.grid.toggleLabel;
grid.spacing = {};
grid.spacing.value = parameters.spacing || grid.default.spacing;
grid.spacing.input = document.querySelector('#spacing-grid');
grid.steps = {};
grid.steps.value = parameters.steps || grid.default.steps;
grid.steps.input = document.querySelector('#steps-grid');
grid.positionX = {};
grid.positionX.value = parameters.positionX || grid.default.positionX;
grid.positionX.input = document.querySelector('#position-x-grid');
grid.positionY = {};
grid.positionY.value = parameters.positionY || grid.default.positionY;
grid.positionY.input = document.querySelector('#position-y-grid');
/* Récupération de la session précédente */
grid.toggle.value = localStorage.getItem('gridToggle_' + fileTitle) || grid.default.toggle;
grid.spacing.value = localStorage.getItem('gridSpacing_' + fileTitle) || grid.spacing.value;
grid.steps.value = localStorage.getItem('gridSteps_' + fileTitle) || grid.steps.value;
grid.positionX.value = localStorage.getItem('gridPositionX_' + fileTitle) || grid.positionX.value;
grid.positionY.value = localStorage.getItem('gridPositionY_' + fileTitle) || grid.positionY.value;
/* DOM edit */
if(grid.toggle.value === "grid"){
body.classList.add('grid'); // on indique qu'il y a la grille
grid.toggle.input.checked = true;
} else {
body.classList.remove('grid'); // grille désactivée
grid.toggle.input.checked = false;
}
/* Set grid values on load */
grid.spacing.input.value = grid.spacing.value;
document.documentElement.style.setProperty('--grid-spacing', grid.spacing.value + 'px');
grid.steps.input.value = grid.steps.value;
document.documentElement.style.setProperty('--steps', grid.steps.value);
grid.positionX.input.value = grid.positionX.value;
document.documentElement.style.setProperty('--grid-position-x', grid.positionX.value + 'px');
grid.positionY.input.value = grid.positionY.value;
document.documentElement.style.setProperty('--grid-position-y', grid.positionY.value + 'px');
/* Event listeners */
/* Toggle event */
grid.toggle.input.addEventListener("input", (e) => {
if(e.target.checked){
body.classList.add('grid'); // grille activée
localStorage.setItem('gridToggle_' + fileTitle, 'grid');
} else {
body.classList.remove('grid'); // grille désactivée
localStorage.setItem('gridToggle_' + fileTitle, 'no-grid');
}
});
/* Change grid spacing on input */
document.querySelector("#spacing-grid").addEventListener("input", (e) => {
grid.spacing.value = e.target.value;
document.documentElement.style.setProperty('--grid-spacing', grid.spacing.value + 'px');
localStorage.setItem('gridSpacing_' + fileTitle, grid.spacing.value);
});
/* Change grid steps on input */
document.querySelector("#steps-grid").addEventListener("input", (e) => {
grid.steps.value = e.target.value;
document.documentElement.style.setProperty('--steps', grid.steps.value);
localStorage.setItem('gridSteps_' + fileTitle, grid.steps.value);
});
/* Change grid position X on input */
document.querySelector("#position-x-grid").addEventListener("input", (e) => {
grid.positionX.value = e.target.value;
document.documentElement.style.setProperty('--grid-position-x', grid.positionX.value + 'px');
localStorage.setItem('gridPositionX_' + fileTitle, grid.positionX.value);
});
/* Change grid position Y on input */
document.querySelector("#position-y-grid").addEventListener("input", (e) => {
grid.positionY.value = e.target.value;
document.documentElement.style.setProperty('--grid-position-y', grid.positionY.value + 'px');
localStorage.setItem('gridPositionY_' + fileTitle, grid.positionY.value);
});
}

View file

@ -1,124 +0,0 @@
:root {
--grid-bold: #bfbfbf;
--grid-light: #efefef;
--grid-spacing: 56px;
--steps: 5;
--grid-position-x: 28px;
--grid-position-y: 0px;
--grid-subdivisions: calc(var(--grid-spacing)/var(--steps));
}
@media screen{
body.grid .pagedjs_sheet {
z-index: -1;
background-image:
/* Traits bold */
repeating-linear-gradient(
90deg,
var(--grid-bold) 0 1px,
transparent 1px var(--grid-spacing)
),
repeating-linear-gradient(
0deg,
var(--grid-bold) 0 1px,
transparent 1px var(--grid-spacing)
),
/* Traits fins (3 traits → 4 carrés) */
repeating-linear-gradient(
90deg,
var(--grid-light) 0 1px,
transparent 1px var(--grid-subdivisions)
),
repeating-linear-gradient(
0deg,
var(--grid-light) 0 1px,
transparent 1px var(--grid-subdivisions)
);
background-position:
var(--grid-position-x) var(--grid-position-y),
var(--grid-position-x) var(--grid-position-y),
var(--grid-position-x) var(--grid-position-y),
var(--grid-position-x) var(--grid-position-y);
}
.grid-page{
--nbr-columns: 8;
width: var(--pagedjs-pagebox-width);
height: var(--pagedjs-pagebox-height);
position: absolute;
top: 0;
left: 0;
display: grid;
grid-template-columns: repeat(var(--nbr-columns), calc(100%/var(--nbr-columns)));
box-shadow: 1px 0px 0px 0px var(--grid-color);
--grid-color: magenta;
z-index: -1;
}
.pagedjs_right_page .grid-page{
padding-left: var(--pagedjs-margin-left);
padding-right: var(--pagedjs-margin-right);
}
.pagedjs_left_page .grid-page{
padding-left: var(--pagedjs-margin-left);
padding-right: var(--pagedjs-margin-right);
}
.grid-page .grid-column{
box-shadow: 1px 0px 0px 0px var(--grid-color);
grid-row: 1/end;
width: 100%;
justify-self: right;
}
.grid-column-0{
grid-column: 1;
box-shadow: -1px 0px 0px 0px var(--grid-color)!important;
justify-self: left;
}
.grid-column-1{ grid-column: 1; }
.grid-column-2{ grid-column: 2; }
.grid-column-3{ grid-column: 3; }
.grid-column-4{ grid-column: 4; }
.grid-column-5{ grid-column: 5; }
.grid-column-6{ grid-column: 6; }
.grid-column-7{ grid-column: 7; }
.grid-column-8{ grid-column: 8; }
.grid-column-9{ grid-column: 9; }
.grid-column-10{ grid-column: 10; }
.grid-column-11{ grid-column: 11; }
.grid-column-12{ grid-column: 12; }
}
.no-grid .grid-page{
display: none;
}

View file

@ -1,16 +0,0 @@
<div class="panel-group-values">
<label for="spacing-grid">Spacing (px)</label>
<input type="number" id="spacing-grid" name="spacing-grid" min="1" max="200" value="56">
</div>
<div class="panel-group-values">
<label for="steps-grid">Steps</label>
<input type="number" id="steps-grid" name="steps-grid" min="1" max="20" value="5">
</div>
<div class="panel-group-values">
<label for="position-x-grid">Position X (px)</label>
<input type="number" id="position-x-grid" name="position-x-grid" value="28">
</div>
<div class="panel-group-values">
<label for="position-y-grid">Position Y (px)</label>
<input type="number" id="position-y-grid" name="position-y-grid" value="0">
</div>

View file

@ -0,0 +1,13 @@
{
"name": "Column grid",
"description": "",
"version": "1.0",
"ui": {
"title": "Column grid",
"description": "This Toogle a column grid",
"template": "template.html",
"toggle": true
},
"stylesheet": "grid.css",
"script": "grid-ui.js"
}

View file

@ -0,0 +1,73 @@
/**
* @name Grid
* @author Julie Blanc <contact@julie-blanc.fr>
* @see { @link https://gitlab.com/csspageweaver/plugins/grid/ }
*/
export default function gridEvents(id){
let body = cssPageWeaver.ui.body;
let fileTitle = cssPageWeaver.docTitle;
let parameters = cssPageWeaver.features[id].parameters || {};
let isParametersSet = Object.keys(parameters).length > 0;
let grid = {};
// valeur par défaut
grid.default = {
steps: 7,
};
grid.toggle = {};
grid.toggle.value = localStorage.getItem('gridColToggle_' + fileTitle) || 'no-grid-col';
grid.toggle.input = document.querySelector(`#${id}-toggle`);
grid.steps = {};
grid.steps.value = parameters.steps || grid.default.steps;
grid.steps.input = document.querySelector('#steps-grid-col');
/* Récupération de la session précédente si elle existe */
grid.steps.value = localStorage.getItem('gridColSteps_' + fileTitle) || grid.steps.value;
grid.steps.input.value = grid.steps.value;
document.documentElement.style.setProperty('--grid-col-steps', grid.steps.value);
/* DOM edit */
if(grid.toggle.value === "grid-col"){
body.classList.add('grid-col'); // on indique qu'il y a la grille
grid.toggle.input.checked = true;
} else {
body.classList.remove('grid-col'); // grille désactivée
grid.toggle.input.checked = false;
}
/* Toggle event */
grid.toggle.input.addEventListener("input", (e) => {
if(e.target.checked){
body.classList.add('grid-col'); // grille activée
localStorage.setItem('gridColToggle_' + fileTitle, 'grid-col');
} else {
body.classList.remove('grid-col'); // grille désactivée
localStorage.setItem('gridColToggle_' + fileTitle, 'no-grid-col');
}
});
/* Change grid steps on input */
document.querySelector("#steps-grid-col").addEventListener("input", (e) => {
grid.steps.value = e.target.value;
document.documentElement.style.setProperty('--grid-col-steps', grid.steps.value);
localStorage.setItem('gridColSteps_' + fileTitle, grid.steps.value);
});
}

View file

@ -0,0 +1,36 @@
:root {
--grid-col-color: #ee33d2;
--grid-light: #efefef;
--grid-spacing: 56px;
--steps: 5;
--grid-position-x: 28px;
--grid-position-y: 0px;
--grid-subdivisions: calc(var(--grid-spacing)/var(--steps));
}
@media screen{
body.grid-col .pagedjs_area {
z-index: -1;
box-shadow: 0px 0px 1px 0px var(--grid-col-color);
background-image: repeating-linear-gradient(to right, var(--grid-col-color), var(--grid-col-color) 0.5px, transparent 0.5px, transparent);
background-size: calc(100%/var(--grid-col-steps));
}
}

View file

@ -0,0 +1,4 @@
<div class="panel-group-values">
<label for="steps-grid-col">Steps</label>
<input type="number" id="steps-grid-col" name="steps-grid" min="1" max="22" value="6">
</div>

View file

@ -91,7 +91,6 @@ function createNotes(content, input, type){
inline_note.innerHTML = unwrapBlockChildren(note).innerHTML;
call.after(inline_note);
call.parentElement.removeChild(call);
})

1150
index.html

File diff suppressed because it is too large Load diff

96
js/addPagesNotes.js Normal file
View file

@ -0,0 +1,96 @@
import { Handler } from '/csspageweaver/lib/paged.esm.js';
export default class addPagesNotes extends Handler {
constructor(chunker, polisher, caller) {
super(chunker, polisher, caller);
}
afterParsed(parsed){
let notes = parsed.querySelectorAll(".inline-note");
notes.forEach(function (note, index) {
// console.log(note);
note.style.position = "absolute";
note.style.top = "0px";
note.style.left = "0px";
note.style.height = "0px";
let counter = note.getAttribute('data-counter-note');
let call = document.createElement('span');
call.classList.add('note_call');
call.textContent = counter;
note.insertAdjacentElement('beforebegin', call);
note.classList.replace('inline-note', 'body-note');
let marker = document.createElement('span');
marker.classList.add('note_marker');
marker.textContent = counter + ". ";
note.prepend(marker);
});
}
afterPageLayout(pageElement, page, breakToken, chunker) {
// add class if page contains h1
if (pageElement.querySelector('h1')) {
pageElement.classList.add('page-with-h1');
}
// move notes into previous page
let notes = pageElement.querySelectorAll(".body-note");
if(notes){
let container = document.createElement('div');
container.classList.add('container-note');
notes.forEach(function (note, index) {
container.appendChild(note);
note.style.position = "relative";
note.style.height = "auto";
if (note.getAttribute('data-counter-note') === '1') {
container.classList.add('container-note-first');
}
});
let pageNum = parseInt(pageElement.getAttribute('data-page-number'));
let prevPage = document.querySelector('[data-page-number="' + (pageNum - 1) + '"]');
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){
contentId.appendChild(container);
}else{
prevPage.querySelector('.pagedjs_page_content').appendChild(container);
}
}
}
// create blank left page
if (
page.element.classList.contains('pagedjs_right_page') &&
page.element.classList.contains('pagedjs_chapter_page')
) {
// Check if previous page is not end chapter
let pageEnd = pageElement.querySelector(".chapter-end");
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');
}
}
}
}

263
js/beforeAll.js Normal file
View file

@ -0,0 +1,263 @@
import { Handler } from '/csspageweaver/lib/paged.esm.js';
export default class beforeAll extends Handler {
constructor(chunker, polisher, caller) {
super(chunker, polisher, caller);
}
beforeParsed(content){
listAbbr(content);
numParagraph(content);
thesis(content);
wrapChapterAndIntro(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 - 4; // 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";
}
}
}
function listAbbr(content){
const h1s = content.querySelectorAll('h1');
let abbrH1 = null;
h1s.forEach(h1 => {
if (h1.textContent.trim().includes('Abkürzungsverzeichnis')) {
abbrH1 = h1;
}
});
if (!abbrH1) return;
const sectionContent = content.querySelector('#section__content');
if (!sectionContent || !sectionContent.contains(abbrH1)) return;
// Collect h1 and all following siblings until next h1
const elements = [abbrH1];
let next = abbrH1.nextElementSibling;
while (next && next.tagName.toLowerCase() !== 'h1') {
elements.push(next);
next = next.nextElementSibling;
}
// Create section and move elements into it
const section = document.createElement('section');
section.id = 'list-of-abbr';
elements.forEach(el => section.appendChild(el));
// content is the DocumentFragment; insert #list-of-abbr before #section__content
content.insertBefore(section, sectionContent);
}
function numParagraph(content){
let numParagraphs = content.querySelectorAll('ol[type="1"]');
numParagraphs.forEach(function (num, index) {
let start = num.getAttribute('start');
num.querySelector('li').innerHTML = start;
});
}
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 .thesis
const chapters = sectionContent.querySelectorAll('.chapter');
chapters.forEach(chapter => {
if (chapter.querySelector('.thesis')) {
// 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');
const thesisElements = [];
strongs.forEach(strong => {
if (/^these\s+\d+/i.test(strong.textContent.trim())) {
const parent = strong.closest('p');
if (parent) {
// Create thesis wrapper
const thesisWrapper = document.createElement('div');
thesisWrapper.classList.add('thesis');
// Find preceding ol if it exists
let prev = parent.previousElementSibling;
let olElement = null;
if (prev && prev.tagName.toLowerCase() === 'ol') {
olElement = prev;
}
// Insert thesis wrapper before ol or before p
if (olElement) {
olElement.parentNode.insertBefore(thesisWrapper, olElement);
thesisWrapper.appendChild(olElement);
} else {
parent.parentNode.insertBefore(thesisWrapper, parent);
}
// Create thesis-title
const thesisTitleDiv = document.createElement('div');
thesisTitleDiv.classList.add('thesis-title');
const thesisP = document.createElement('p');
thesisP.textContent = strong.textContent;
var line = document.createElement('div');
line.classList.add('thesis-line');
thesisTitleDiv.appendChild(thesisP);
thesisTitleDiv.appendChild(line)
thesisWrapper.appendChild(thesisTitleDiv);
// Transform parent p into thesis-content
strong.remove();
parent.classList.add('thesis-content');
thesisWrapper.appendChild(parent);
thesisElements.push(thesisWrapper);
}
}
});
// Mark first and last thesis
if (thesisElements.length > 0) {
thesisElements[0].classList.add('thesis-first');
thesisElements[thesisElements.length - 1].classList.add('thesis-last');
}
}

View file

@ -56,6 +56,7 @@ export default class counters extends Handler {
h2Count = 0; // reset h2
const originalText = el.innerHTML;
el.innerHTML = `<span class="h1-count">${this.toUpperAlpha(h1Count)}</span><span class="h1-text">${originalText}</span>`;
el.setAttribute('data-counter', this.toUpperAlpha(h1Count));
break;
case 'h2':

View file

@ -1,110 +0,0 @@
import { Handler } from '/csspageweaver/lib/paged.esm.js';
export default class thesis extends Handler {
constructor(chunker, polisher, caller) {
super(chunker, polisher, caller);
}
// Créer un wrapper pour récupérer tous les éléments qui suivent le ol (hors titres et .container-following-note)
// --------------------------------------------------------------------------------------------------------------
beforeParsed(content){
const nums = content.querySelectorAll('ol[type="1"]');
nums.forEach((num) => {
const wrapper = document.createElement('div');
wrapper.classList.add('wrapper-ol');
wrapper.id = 'wrapper-' + (num.getAttribute('start') || '1');
// Collecter les frères/sœurs suivants jusqu'à la prochaine limite
const siblings = [];
let sibling = num.nextElementSibling;
while (sibling) {
if (sibling.matches('ol[type="1"], h1, h2, h3, h4, h5, h6, .container-following-note')) break;
siblings.push(sibling);
sibling = sibling.nextElementSibling;
}
// Insérer le wrapper à la place du ol
num.before(wrapper);
wrapper.appendChild(num);
siblings.forEach(s => wrapper.appendChild(s));
});
// Si le dernier enfant d'un wrapper est un p et que le suivant est aussi un wrapper → .wrapper-indent
const wrappers = content.querySelectorAll('.wrapper-ol');
wrappers.forEach((wrapper) => {
const last = wrapper.lastElementChild;
const next = wrapper.nextElementSibling;
if (last && last.nodeName === 'P' && next && next.classList.contains('wrapper-ol')) {
const firstP = next.querySelector('p');
if (!firstP || !firstP.classList.contains('p-these')) {
next.classList.add('wrapper-indent');
}
}
});
}
afterPageLayout(pageElement, page, breakToken){
const wrappers = pageElement.querySelectorAll('.wrapper-ol');
const minSize = 37; // taille minimal du wrapper pour quil y ait clone (2 lignes)
// Fais un clone du ol pour de la page précédente
// -----------------------------------------------
if (wrappers.length > 0) {
const first = wrappers[0];
if (first.hasAttribute('data-split-from')) {
let idWrapper = first.getAttribute('data-id');
let numPage = pageElement.getAttribute('data-page-number');
let numPrev = parseInt(numPage) - 1;
let prevPage = document.querySelector('#page-' + numPrev);
let olPara = prevPage.querySelector('#' + idWrapper + ' ol[type="1"]');
if (olPara && first.offsetHeight >= minSize) {
const start = olPara.getAttribute('start') || '1';
const olClonePage = document.createElement('ol');
olClonePage.setAttribute('start', start);
olClonePage.setAttribute('type', '1');
olClonePage.classList.add('ol-clone-page');
olClonePage.style.height = first.offsetHeight + 'px';
const li = document.createElement('li');
li.setAttribute('data-item-num', start);
olClonePage.appendChild(li);
first.prepend(olClonePage);
}
}
}
// Fais un clone du ol pour la colonne suivante (dans la même page)
// ----------------------------------------------------------------
wrappers.forEach((wrapper) => {
const ol = wrapper.querySelector('ol[type="1"]');
if (!ol) return;
const rects = wrapper.getClientRects();
if (rects.length === 1) {
ol.style.height = rects[0].height + 'px';
} else if (rects.length === 2) {
ol.style.height = rects[0].height + 'px';
if (rects[1].height >= minSize) {
const olClone = ol.cloneNode(true);
olClone.classList.add('ol-clone');
olClone.style.height = rects[1].height + 'px';
olClone.removeAttribute('id');
ol.after(olClone);
}
}
});
}
}

View file

@ -9,12 +9,12 @@ export default class snapToBaseline extends Handler {
beforeParsed(content){
this.baseline = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--baseline').trim());
content.querySelectorAll('blockquote').forEach((bq) => {
const prev = bq.previousElementSibling;
if (!prev || prev.nodeName !== 'P') {
// bq.style.color = 'red';
}
});
// content.querySelectorAll('blockquote').forEach((bq) => {
// const prev = bq.previousElementSibling;
// if (!prev || prev.nodeName !== 'P') {
// // bq.style.color = 'red';
// }
// });
}
renderNode(node, sourceNode){

View file

@ -7,26 +7,7 @@ export default class thesis extends Handler {
beforeParsed(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) {
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');
}
});
}

View file

@ -1,5 +1,4 @@
<p><strong>Höchstpersönlichkeit</strong></p>
<p>Eine Erbrechtsgeschichte von Missverständnissen</p>
<p>«Der Gedanke … des … [W]illens hat sich nicht bewährt, der Glaube der
modernen Jurisprudenz, in dem <em>animus</em> … den Schlüssel entdeckt
zu haben, der ihr das Verständniß der ganzen … [L]ehre erschlüsse, hat