Initial commit

This commit is contained in:
sarahgarcin1 2026-01-05 19:33:15 +01:00
commit 388079e6bb
1108 changed files with 330121 additions and 0 deletions

View file

@ -0,0 +1,16 @@
class index extends Paged.Handler {
constructor(chunker, polisher, caller) {
super(chunker, polisher, caller);
}
beforeParsed(content) {
createIndex({
content: content,
spanClassIndex: '.book-index',
indexElement: '#book-index',
alphabet: true
});
}
}
Paged.registerHandlers(index);

View file

@ -0,0 +1,121 @@
function createIndex(config){
const content = config.content;
let indexElements = content.querySelectorAll(config.spanClassIndex);
let arrayIndex = [];
let num = 0;
for(let i = 0; i < indexElements.length; ++i){
let indexElement = indexElements[i];
// create array with all data-book-index
let indexKey = indexElement.dataset.bookIndex;
let indexKeyFirst = indexKey.slice(0, 1);
let newIndexKey;
if(indexKeyFirst == "<"){
if(indexKey.slice(0, 3) == "<i>"){
newIndexKey = indexKey.replace("<i>", "") + "-iTemp";
}else if(indexKey.slice(0, 4) == "<em>"){
newIndexKey = indexKey.replace("<em>", "") + "-emTemp";
}
}else{
newIndexKey = indexKey;
}
arrayIndex.push(newIndexKey);
// create id for span whithout
num++;
if(indexElement.id == ''){ indexElement.id = 'book-index-' + num; }
}
// filter array to remove dublicate and sort by alphabetical order
let newArrayIndex = arrayIndex.filter(onlyUnique).sort(function(a,b) {
a = a.toLowerCase();
b = b.toLowerCase();
if( a == b) return 0;
return a < b ? -1 : 1;
});
// create <ul> element for the index
let indexElementDiv = content.querySelector(config.indexElement);
if(indexElementDiv != null){
let indexUl = document.createElement("ul");
indexUl.id = "list-index-generated";
indexElementDiv.appendChild(indexUl);
// create <li> element for the index
for(var a = 0; a < newArrayIndex.length; a++){
// create alphabet
if(config.alphabet){
z = a - 1;
let firstLetter = newArrayIndex[a].toUpperCase().slice(0, 1);
if(a == 0){
let alphabetLiFirst = document.createElement("li");
alphabetLiFirst.classList.add("list-alphabet-element");
alphabetLiFirst.id = "alphabet-element-" + firstLetter;
alphabetLiFirst.innerHTML = firstLetter;
indexUl.appendChild(alphabetLiFirst);
}
if(z >= 0){
let firstLetterPrevious = newArrayIndex[z].toUpperCase().slice(0, 1);
if(firstLetter != firstLetterPrevious){
let alphabetLi = document.createElement("li");
alphabetLi.classList.add("list-alphabet-element");
alphabetLi.id = "alphabet-element-" + firstLetter;
alphabetLi.innerHTML = firstLetter;
indexUl.appendChild(alphabetLi);
}
}
}
// create <li> element for the index
let indexNewLi = document.createElement("li");
indexNewLi.classList.add("list-index-element");
let dataIndex;
if(newArrayIndex[a].substr(newArrayIndex[a].length - 6) == "-iTemp"){
dataIndex = "<i>" + newArrayIndex[a].replace("-iTemp", "");
}else if(newArrayIndex[a].substr(newArrayIndex[a].length - 7) == "-emTemp"){
dataIndex = "<em>" + newArrayIndex[a].replace("-emTemp", "");
}else{
dataIndex = newArrayIndex[a];
}
indexNewLi.dataset.listIndex = dataIndex;
indexUl.appendChild(indexNewLi);
}
let indexLi = content.getElementById('list-index-generated').getElementsByClassName('list-index-element');
for(var n = 0; n < indexLi.length; n++){
// find data and add HTML of the list
let dataIndex = indexLi[n].dataset.listIndex;
let spanIndex = content.querySelectorAll("[data-book-index='" + dataIndex + "']");
indexLi[n].innerHTML = '<span class="index-value">' + dataIndex + '</span><span class="links-pages"></span>';
// add span for link page
spanIndex.forEach(function(elem) {
spanIndexId = elem.id;
let spanPage = document.createElement("span");
spanPage.classList.add("link-page");
spanPage.innerHTML = '<a href="#' + spanIndexId + '"></a>';
indexLi[n].getElementsByClassName('links-pages')[0].appendChild(spanPage);
});
}
}
}
// function for filter array to remove dublicate
function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,29 @@
// fixed text align justify before images page
class fixJustif extends Paged.Handler {
constructor(chunker, polisher, caller) {
super(chunker, polisher, caller);
}
afterRendered(pages){
for(let i=0; i<pages.length; i++){
let currentPageClassList = pages[i].element.classList;
if(i+1 < pages.length){
let nextPageClassList = pages[i+1].element.classList;
// console.log(currentPageClassList[0], nextPageClassList);
if(currentPageClassList[0] == "pagedjs_page" && nextPageClassList[4] == "pagedjs_pagedjs-fullpage_page"){
// console.log('div with images following');
let pageId = pages[i].id;
let selectedPage = document.getElementById(pageId);
let selectedLastP = selectedPage.querySelector(".chapter .content > p:last-child");
// console.log(selectedPage, selectedLastP);
if(selectedLastP != null){
selectedLastP.style.textAlignLast = "justify";
}
}
}
}
}
}
Paged.registerHandlers(fixJustif);

View file

@ -0,0 +1,296 @@
let bleedFull = '6mm';
let cssFullSpread = `.pagedjs_page_fullLeft .pagedjs_full-spread_container{
margin: 0;
width: calc(var(--pagedjs-pagebox-width) + `+ bleedFull + `);
height: calc(var(--pagedjs-pagebox-height) + `+ bleedFull + `*2) !important;
position: absolute;
top: calc((var(--pagedjs-margin-top) + `+ bleedFull + `)*-1);
left: calc((var(--pagedjs-margin-left) + `+ bleedFull + `)*-1);
overflow: hidden;
}
.pagedjs_page_fullRight .pagedjs_full-spread_container{
margin: 0;
width: calc(var(--pagedjs-pagebox-width) + `+ bleedFull + `);
height: calc(var(--pagedjs-pagebox-height) + `+ bleedFull + `*2) !important;
position: absolute;
top: calc((var(--pagedjs-margin-top) + `+ bleedFull + `)*-1);
left: calc(var(--pagedjs-margin-left)*-1);
overflow: hidden;
}
.pagedjs_full-spread_content{
margin: 0;
width: calc(var(--pagedjs-pagebox-width)*2 + `+ bleedFull + `*2);
height: calc(var(--pagedjs-pagebox-height) + `+ bleedFull + `*2) !important;
position: absolute;
top: 0;
left: 0;
}
.pagedjs_page_fullLeft .pagedjs_full-spread_content{
left: calc(var(--pagedjs-fold)*-1);
}
.pagedjs_page_fullRight .pagedjs_full-spread_content{
left: calc((var(--pagedjs-pagebox-width) + `+ bleedFull + `)*-1 + var(--pagedjs-fold))
}`;
let cssFullPage = `
.pagedjs_full-page_content {
margin: 0;
position: absolute;
top: calc((var(--pagedjs-margin-top) + `+ bleedFull + `)*-1);
}
.pagedjs_left_page .pagedjs_full-page_content {
width: calc(var(--pagedjs-pagebox-width) + `+ bleedFull + `);
height: calc(var(--pagedjs-pagebox-height) + `+ bleedFull + `*2);
left: calc((var(--pagedjs-margin-left) + `+ bleedFull + `)*-1);
}
.pagedjs_right_page .pagedjs_full-page_content {
width: calc(var(--pagedjs-pagebox-width) + `+ bleedFull + `);
height: calc(var(--pagedjs-pagebox-height) + `+ bleedFull + `*2);
left: calc(var(--pagedjs-margin-left)*-1);
}
`;
class fullPageImage extends Paged.Handler {
constructor(chunker, polisher, caller) {
super(chunker, polisher, caller);
this.selectorFullSpread = new Set();
this.fullSpreadEls = new Set();
this.selectorFullPage = new Set();
this.fullPageEls = new Set();
this.selectorFullRight = new Set();
this.fullRightEls = new Set();
this.selectorFullLeft= new Set();
this.fullLeftEls = new Set();
this.usedPagedEls = new Set();
}
onDeclaration(declaration, dItem, dList, rule) {
// Read customs properties
if (declaration.property == "--pagedjs-full-page") {
// get selector of the declaration (NOTE: need csstree.js)
let selector = csstree.generate(rule.ruleNode.prelude);
// Push selector in correct set
if (declaration.value.value.includes("page")) {
this.selectorFullPage.add(selector);
}else if(declaration.value.value.includes("spread")) {
this.selectorFullSpread.add(selector);
}else if(declaration.value.value.includes("right")) {
this.selectorFullRight.add(selector);
}else if(declaration.value.value.includes("left")) {
this.selectorFullLeft.add(selector);
}
}
}
afterParsed(parsed){
// ADD global css
addcss(cssFullSpread);
addcss(cssFullPage);
// ADD pagedjs classes to elements
for (let item of this.selectorFullPage) {
let elems = parsed.querySelectorAll(item);
for (let elem of elems) {
elem.classList.add("pagedjs_full-page-elem");
}
}
for (let item of this.selectorFullSpread) {
let elems = parsed.querySelectorAll(item);
for (let elem of elems) {
elem.classList.add("pagedjs_full-spread-elem");
}
}
for (let item of this.selectorFullLeft) {
let elems = parsed.querySelectorAll(item);
for (let elem of elems) {
elem.classList.add("pagedjs_full-page-left-elem");
}
}
for (let item of this.selectorFullRight) {
let elems = parsed.querySelectorAll(item);
for (let elem of elems) {
elem.classList.add("pagedjs_full-page-right-elem");
}
}
}
renderNode(clone, node) {
// FULL SPREAD
// if you find a full page element, move it in the array
if (node.nodeType == 1 && node.classList.contains("pagedjs_full-spread-elem")) {
this.fullSpreadEls.add(node);
this.usedPagedEls.add(node);
// remove the element from the flow by hiding it.
clone.style.display = "none";
}
// FULL PAGE
if (node.nodeType == 1 && node.classList.contains("pagedjs_full-page-left-elem")) {
this.fullLeftEls.add(node);
this.usedPagedEls.add(node);
clone.style.display = "none";
}else if (node.nodeType == 1 && node.classList.contains("pagedjs_full-page-right-elem")) {
this.fullRightEls.add(node);
this.usedPagedEls.add(node);
clone.style.display = "none";
}else if (node.nodeType == 1 && node.classList.contains("pagedjs_full-page-elem")) {
this.fullPageEls.add(node);
this.usedPagedEls.add(node);
clone.style.display = "none";
}
}
afterPageLayout(pageElement, page, breakToken, chunker) {
// ADD --pagedjs-fold on body if doesn't exist
if(pageElement.classList.contains("pagedjs_first_page")){
let body = document.getElementsByTagName("body")[0];
let style = window.getComputedStyle(body);
let fold = style.getPropertyValue('--pagedjs-fold');
if(!fold){
body.style.setProperty('--pagedjs-fold', '0mm')
}
}
// FULL SPREAD
// if there is an element in the fullSpreadEls Set, (goodbye arrays!)
for (let img of this.fullSpreadEls) {
if (page.element.classList.contains("pagedjs_right_page")) {
let imgLeft;
let imgRight;
if (img.nodeName == "IMG") {
/* Add outside + inside container if the element is an img */
let containerLeft = document.createElement("div");
containerLeft.classList.add("pagedjs_full-spread_container");
let containerLeftInside = document.createElement("div");
containerLeftInside.classList.add("pagedjs_full-spread_content");
containerLeft.appendChild(containerLeftInside).appendChild(img);
imgLeft = containerLeft;
let containerRight = document.createElement("div");
containerRight.classList.add("pagedjs_full-spread_container");
let containerRightInside = document.createElement("div");
containerRightInside.classList.add("pagedjs_full-spread_content");
containerRight.appendChild(containerRightInside).appendChild(img.cloneNode(true));
imgRight = containerRight;
} else {
/* Add outside container if the element is an img */
let containerLeft = document.createElement("div");
containerLeft.classList.add("pagedjs_full-spread_container");
img.classList.add("pagedjs_full-spread_content");
containerLeft.appendChild(img);
imgLeft = containerLeft;
let containerRight = document.createElement("div");
containerRight.classList.add("pagedjs_full-spread_container");
img.classList.add("pagedjs_full-spread_content");
containerRight.appendChild(img.cloneNode(true));
imgRight = containerRight;
}
// put the first element on the page
let fullPage = chunker.addPage();
fullPage.element
.querySelector(".pagedjs_page_content")
.insertAdjacentElement("afterbegin", imgLeft);
fullPage.element.classList.add("pagedjs_page_fullLeft");
// page right
let fullPageRight = chunker.addPage();
fullPageRight.element
.querySelector(".pagedjs_page_content")
.insertAdjacentElement("afterbegin", imgRight);
fullPageRight.element.classList.add("pagedjs_page_fullRight");
img.style.removeProperty("display");
this.fullSpreadEls.delete(img);
}
}
// FULL PAGE
// if there is an element in the fullPageEls Set
for (let img of this.fullPageEls) {
let container = document.createElement("div");
container.classList.add("pagedjs_full-page_content");
container.appendChild(img);
let fullPage = chunker.addPage();
fullPage.element
.querySelector(".pagedjs_page_content")
.insertAdjacentElement("afterbegin", container);
fullPage.element.classList.add("pagedjs_page_fullPage");
img.style.removeProperty("display");
this.fullPageEls.delete(img);
}
// FULL Left PAGE
// if there is an element in the fullLeftEls Set
for (let img of this.fullLeftEls) {
if (page.element.classList.contains("pagedjs_right_page")) {
let container = document.createElement("div");
container.classList.add("pagedjs_full-page_content");
container.appendChild(img);
let fullPage = chunker.addPage();
fullPage.element
.querySelector(".pagedjs_page_content")
.insertAdjacentElement("afterbegin", container);
fullPage.element.classList.add("pagedjs_page_fullPage");
img.style.removeProperty("display");
this.fullLeftEls.delete(img);
}
}
// FULL RIGHT PAGE
// if there is an element in the fullRightEls Set
for (let img of this.fullRightEls) {
if (page.element.classList.contains("pagedjs_left_page")) {
let container = document.createElement("div");
container.classList.add("pagedjs_full-page_content");
container.appendChild(img);
let fullPage = chunker.addPage();
fullPage.element
.querySelector(".pagedjs_page_content")
.insertAdjacentElement("afterbegin", container);
fullPage.element.classList.add("pagedjs_page_fullPage");
img.style.removeProperty("display");
this.fullRightEls.delete(img);
}
}
}
}
Paged.registerHandlers(fullPageImage);
function addcss(css){
var head = document.getElementsByTagName('head')[0];
var s = document.createElement('style');
s.setAttribute('type', 'text/css');
if (s.styleSheet) { // IE
s.styleSheet.cssText = css;
} else {// the world
s.appendChild(document.createTextNode(css));
}
head.appendChild(s);
}

View file

@ -0,0 +1,56 @@
// ---- C O R R E C T P O S I T I O N O F I M A G E S ----
var classElemFullPage = "full-page"; // ← class of full page images
class fullPageStuff extends Paged.Handler {
constructor(chunker, polisher, caller) {
super(chunker, polisher, caller);
this.fullPageEls = new Set();
this.usedPagedEls = new Set();
}
//find from the css the element you wanna have full page
onDeclaration(declaration, dItem, dList, rule) {
if (declaration.property == "position") {
if (declaration.value.children.head.data.name.includes("fullpage")) {
let sel = csstree.generate(rule.ruleNode.prelude);
sel = sel.replace('[data-id="', "#");
sel = sel.replace('"]', "");
this.floatFullPage.push(sel.split(","));
}
}
}
renderNode(clone, node) {
// if you find a full page element, move it in the array
if (node.nodeType == 1 && node.classList.contains(classElemFullPage)) {
// console.log(node);
this.fullPageEls.add(node);
this.usedPagedEls.add(node);
// remove the element from the flow by hiding it.
clone.style.display = "none";
}
}
afterPageLayout(pageElement, page, breakToken, chunker) {
// if there is an element in the fullPageEls Set, (goodbye arrays!)
for (let img of this.fullPageEls) {
let fullPage = chunker.addPage();
fullPage.element
.querySelector(".pagedjs_page_content")
.insertAdjacentElement("afterbegin", img);
fullPage.element.classList.add("addedpage");
fullPage.element.classList.add("pagedjs_named_page");
fullPage.element.classList.add("pagedjs_pagedjs-fullpage_page");
if(img.classList.contains('background-black')){
fullPage.element.classList.add("pagedjs_pagedjs-fullpageblack_page");
}
this.fullPageEls.delete(img);
}
}
}
Paged.registerHandlers(fullPageStuff);

View file

@ -0,0 +1,367 @@
// Imposition for booklet(s)
//
// This script re-arrange the pages of your document in order to make an imposed sheet layouts for printing.
// Two pages per sheet, double-sided
class Booklet extends Paged.Handler {
constructor(chunker, polisher, caller) {
super(chunker, polisher, caller);
this.pagedbooklet;
this.sourceSize;
this.pageStart;
this.pageEnd;
}
onAtPage(node, item, list) {}
onDeclaration(declaration, dItem, dList, rule) {
if (declaration.property == "--paged-layout") {
if (declaration.value.value.includes("booklet")) {
this.pagedbooklet = true;
let valuesBooklet = declaration.value.value.split(' ');
let index = valuesBooklet.indexOf("booklet");
/* Set first page of the imposition */
if(valuesBooklet[index + 1]){
this.pageStart = parseInt(valuesBooklet[index + 1]);
}else{
this.pageStart = 1;
}
/* Set last page of the imposition */
if(valuesBooklet[index + 2]){
this.pageEnd = parseInt(valuesBooklet[index + 2]);
}
}
}
}
afterRendered(pages) {
/* Verify this.pageEnd */
if(!this.pageEnd){
let allPagesBefore = document.querySelectorAll(".pagedjs_page").length;
this.pageEnd = allPagesBefore;
}
/* Verify this.pageStart */
if(this.pageStart == 0){
this.pageStart = 1;
}else if(this.pageStart % 2 == 0){
this.pageStart = this.pageStart - 1;
}
// Bouton pour activer/désactiver l'imposition
const imposeButton = document.querySelector("#imposition-toggle");
let styleElement; // Variable pour stocker l'élément <style>
imposeButton.addEventListener("click", () => {
if (imposeButton.checked) {
imposeBooklet();
} else {
resetOrder();
}
});
function imposeBooklet() {
const allPages = Array.from(document.querySelectorAll(".pagedjs_page"));
const totalPages = allPages.length;
// Ajouter des pages vierges pour arriver à un multiple de 4
const pagesToAdd = (4 - (totalPages % 4)) % 4;
for (let i = 0; i < pagesToAdd; i++) {
const blankPage = document.createElement("div");
blankPage.classList.add("pagedjs_page", "blank");
blankPage.innerText = "Blank Page";
document.querySelector(".pagedjs_pages").appendChild(blankPage);
}
// Répartition des pages pour booklet
const pages = Array.from(document.querySelectorAll(".pagedjs_page"));
const totalBookletPages = pages.length;
const bookletOrder = [];
const half = totalBookletPages / 2;
for (let i = 0; i < half; i++) {
bookletOrder.push(totalBookletPages - i); // Dernière page
bookletOrder.push(i + 1); // Première page
}
// Réordonner les pages dans le DOM
bookletOrder.forEach((pageNumber, index) => {
const pageElement = document.querySelector(`#page-${pageNumber}`);
if (pageElement) {
pageElement.style.order = index; // Affecter un ordre CSS
}
});
// Injecter le CSS pour les styles booklet
injectCSS();
console.log("Booklet imposition completed.");
}
function resetOrder() {
// Réinitialiser l'ordre des pages
const allPages = document.querySelectorAll(".pagedjs_page");
allPages.forEach((page, index) => {
page.style.order = index; // Remettre à l'ordre initial
});
// Supprimer les styles injectés
removeCSS();
console.log("Order reset to default.");
}
function injectCSS() {
let format = document.querySelector(".pagedjs_page");
/* Width of page without bleed, extract the first number of calc() function */
let width = getCSSCustomProp("--pagedjs-width", format);
let numbers = width
.match(/[0-9]+/g)
.map(function (n) {
return + (n);
});
width = parseInt(numbers[0]);
/* Height of page with bleed, addition of all the numbers of calc() function*/
let height = getCSSCustomProp("--pagedjs-height", format);
numbers = height
.match(/[0-9]+/g)
.map(function (n) {
return + (n);
});
const reducer = (previousValue, currentValue) => previousValue + currentValue;
height = numbers.reduce(reducer);
/* Bleed of the page */
let bleed = getCSSCustomProp("--pagedjs-bleed-top", format);
let bleedNum = parseInt(bleed);
/* Spread and half-spread*/
let spread = width * 2 + bleedNum * 2;
let spreadHalf = width + bleedNum;
let numberOfPages = getCSSCustomProp("--pagedjs-page-count", format);
let halfNumberOfPages = numberOfPages / 2;
// Créer un élément <style> avec les styles CSS pour l'imposition
styleElement = document.createElement("style");
styleElement.textContent = `
@media print{
@page{
size: ${spread}mm ${height}mm;
}
pagedjs_pages {
width: auto;
}
}
@media screen{
.pagedjs_pages{
max-width: calc(var(--pagedjs-width) * 2);
}
}
.pagedjs_pages {
display: flex !important;
flex-wrap: wrap;
transform: none !important;
height: 100% !important;
min-height: 100%;
max-height: 100%;
overflow: visible;
}
.pagedjs_page {
margin: 0;
padding: 0;
max-height: 100%;
min-height: 100%;
height: 100% !important;
}
.pagedjs_sheet {
margin: 0;
padding: 0;
max-height: 100%;
min-height: 100%;
height: 100% !important;
}
body{
--pagedjs-bleed-right-left: 0mm;
}
.pagedjs_left_page{
z-index: 20;
width: calc(var(--pagedjs-bleed-left) + var(--pagedjs-pagebox-width))!important;
}
.pagedjs_right_page {
left: 0;
}
.pagedjs_left_page .pagedjs_bleed-right .pagedjs_marks-crop {
border-color: transparent;
}
.pagedjs_right_page,
.pagedjs_right_page .pagedjs_sheet{
width: calc(var(--pagedjs-bleed-right-right) + var(--pagedjs-pagebox-width))!important;
}
.pagedjs_right_page .pagedjs_sheet{
grid-template-columns: [bleed-left] var(--pagedjs-bleed-right-left) [sheet-center] 1fr [bleed-right] var(--pagedjs-bleed-right-right);
}
/*.pagedjs_right_page .pagedjs_bleed-left{
display: none;
}*/
.pagedjs_right_page .pagedjs_bleed-top .pagedjs_marks-crop:nth-child(1),
.pagedjs_right_page .pagedjs_bleed-bottom .pagedjs_marks-crop:nth-child(1){
width: 0!important;
}
/* 10 dernières pages de droite (qui sont en réalité à gauche) */
.pagedjs_right_page:nth-child(n+${halfNumberOfPages}){
left:0;
z-index: 10;
width: calc(var(--pagedjs-bleed-left) + var(--pagedjs-pagebox-width))!important;
}
/*.pagedjs_right_page:nth-child(n+${halfNumberOfPages}) .pagedjs_bleed-right .pagedjs_marks-crop {
border-color: transparent;
}*/
.pagedjs_right_page:nth-child(n+${halfNumberOfPages}),
.pagedjs_right_page:nth-child(n+${halfNumberOfPages}) .pagedjs_sheet{
width: calc(var(--pagedjs-bleed-right-right) + var(--pagedjs-pagebox-width))!important;
}
.pagedjs_right_page:nth-child(n+${halfNumberOfPages}) {
z-index: 10;
position: relative;
left: 0;
}
.pagedjs_right_page:nth-child(n+${halfNumberOfPages}) .pagedjs_sheet{
grid-template-columns: [bleed-left] var(--pagedjs-bleed-left) [sheet-center] calc(var(--pagedjs-width) - var(--pagedjs-bleed-left) - var(--pagedjs-bleed-right)) [bleed-right] var(--pagedjs-bleed-right);
}
/*.pagedjs_right_page:nth-child(n+${halfNumberOfPages}) .pagedjs_bleed-left{
display: none;
}*/
.pagedjs_right_page:nth-child(n+${halfNumberOfPages}) .pagedjs_bleed-top .pagedjs_marks-crop:nth-child(1),
.pagedjs_right_page:nth-child(n+${halfNumberOfPages}) .pagedjs_bleed-bottom .pagedjs_marks-crop:nth-child(1){
width: calc(var(--pagedjs-bleed-left-left) - var(--pagedjs-crop-stroke)) !important;
}
.pagedjs_right_page:nth-child(n+${halfNumberOfPages}) .pagedjs_bleed-left .pagedjs_marks-crop:nth-child(1),.pagedjs_right_page:nth-child(n+${halfNumberOfPages}) .pagedjs_bleed-left .pagedjs_marks-crop:nth-child(3){
width: calc(var(--pagedjs-bleed-left-left) - var(--pagedjs-crop-stroke) - 5px) !important;
}
/* 10 premières pages de gauche (qui sont en réalité à droite) */
.pagedjs_left_page:nth-child(-n+${halfNumberOfPages}),
.pagedjs_left_page:nth-child(-n+${halfNumberOfPages}) .pagedjs_sheet{
width: calc(var(--pagedjs-bleed-right-right) + var(--pagedjs-pagebox-width))!important;
}
.pagedjs_left_page:nth-child(-n+${halfNumberOfPages}) {
z-index: 10;
position: relative;
left: 0;
}
.pagedjs_left_page:nth-child(-n+${halfNumberOfPages}) .pagedjs_sheet{
grid-template-columns: [bleed-left] var(--pagedjs-bleed-right-left) [sheet-center] 1fr [bleed-right] var(--pagedjs-bleed-right-right);
}
.pagedjs_left_page:nth-child(-n+${halfNumberOfPages}) .pagedjs_bleed-left{
display: none;
}
.pagedjs_left_page:nth-child(-n+${halfNumberOfPages}) .pagedjs_bleed-top .pagedjs_marks-crop:nth-child(1),
.pagedjs_left_page:nth-child(-n+${halfNumberOfPages}) .pagedjs_bleed-bottom .pagedjs_marks-crop:nth-child(1){
width: 0!important;
}
.pagedjs_left_page:nth-child(-n+${halfNumberOfPages}) .pagedjs_bleed-left{
display: block;
}
.pagedjs_left_page:nth-child(-n+${halfNumberOfPages}) .pagedjs_bleed-right .pagedjs_marks-crop{
border-color: var(--pagedjs-crop-color);
}
.pagedjs_first_page {
margin-left: 0;
}
body{
margin: 0
}
.pagedjs_page:nth-of-type(even){
break-after: always;
}
.pagedjs_page,
.pagedjs_sheet{
width: ${spreadHalf - 0.1}mm!important;
}
`;
// Ajouter l'élément <style> au <head> du document
document.head.appendChild(styleElement);
}
function removeCSS() {
if (styleElement && styleElement.parentNode) {
styleElement.parentNode.removeChild(styleElement);
styleElement = null;
}
}
}
}
Paged.registerHandlers(Booklet);
/**
* Pass in an element and its CSS Custom Property that you want the value of.
* Optionally, you can determine what datatype you get back.
*
* @param {String} propKey
* @param {HTMLELement} element=document.documentElement
* @param {String} castAs='string'
* @returns {*}
*/
const getCSSCustomProp = (
propKey,
element = document.documentElement,
castAs = "string"
) => {
let response = getComputedStyle(element).getPropertyValue(propKey);
// Tidy up the string if there's something to work with
if (response.length) {
response = response
.replace(/\'|"/g, "")
.trim();
}
// Convert the response into a whatever type we wanted
switch (castAs) {
case "number":
case "int":
return parseInt(response, 10);
case "float":
return parseFloat(response, 10);
case "boolean":
case "bool":
return response === "true" || response === "1";
}
// Return the string response by default
return response;
};

View file

@ -0,0 +1,275 @@
// -------------- M A R G I N N O T E S S C R I P T -----------------
let classNotes = "margin-note"; // ← Change the CLASS of the notes here
let notesFloat = "left"; // ← Change the POSITION of the notes here
class marginNotes extends Paged.Handler {
constructor(chunker, polisher, caller) {
super(chunker, polisher, caller);
}
beforeParsed(content) {
let notes = content.querySelectorAll("." + classNotes);
let chapter = content.querySelector('.chapter');
if(chapter != null){
let chapterName = chapter.dataset.page;
let noteNumber = 1;
for (let i = 0; i < notes.length; ++i) {
// get parent chapter name
// this code is used to separate notes by chapters
let noteChapter = notes[i].closest('.chapter');
let noteChapterName = noteChapter.dataset.page;
if(chapterName != noteChapter){
noteNumber = 1;
chapterName = noteChapter;
}
// Add call notes
var spanCall = document.createElement("sup");
spanCall.classList.add("note-call");
spanCall.classList.add("note-call_" + classNotes);
spanCall.dataset.noteCall = classNotes + '-' + noteNumber;
spanCall.innerHTML = noteNumber;
notes[i].parentNode.insertBefore(spanCall, notes[i]);
// Add marker notes
var spanMarker = document.createElement("span");
spanMarker.classList.add("note-marker");
spanMarker.classList.add("note-marker_" + classNotes);
spanMarker.dataset.noteMarker = classNotes + '-' + noteNumber;
spanMarker.innerHTML = noteNumber;
notes[i].prepend(spanMarker);
// increase the number of the note
noteNumber ++;
// Hide notes to avoid rendering problems
notes[i].style.display = "none";
}
}
/* NOTE FLOAT ---------------------------------------------------------------------------------- */
let positionRight = 'left: calc(var(--pagedjs-pagebox-width) - var(--pagedjs-margin-left) - var(--pagedjs-margin-right) - 1px); width: var(--pagedjs-margin-right);';
let positionLeft = 'left: calc(var(--pagedjs-margin-left)*-1 + 4px); width: calc(var(--pagedjs-margin-left) - 4px);'
let notePosition;
switch (notesFloat) {
case 'inside':
notePosition = '.pagedjs_left_page .' + classNotes + '{' + positionRight + '} \
.pagedjs_right_page .' + classNotes + '{' + positionLeft + '}';
break;
case 'left':
notePosition = '.pagedjs_left_page .' + classNotes + '{' + positionLeft + '} \
.pagedjs_right_page .' + classNotes + '{' + positionLeft + '}';
break;
case 'right':
notePosition = '.pagedjs_left_page .' + classNotes + '{' + positionRight + '} \
.pagedjs_right_page .' + classNotes + '{' + positionRight + '}';
break;
default:
notePosition = '.pagedjs_left_page .' + classNotes + '{' + positionLeft + '} \
.pagedjs_right_page .' + classNotes + '{' + positionRight + '}';
}
/* SPECIFIC CSS ---------------------------------------------------------------------------------- */
addcss('\
body {\
counter-reset: callNote_' + toCamelClassNote(classNotes) + ' markerNote_' + toCamelClassNote(classNotes) + ';\
}\
\
.' + classNotes + '{\
position: absolute;\
text-align-last: initial;\
box-sizing: border-box;\
}\
\
.note-call_' + classNotes + ' {\
counter-increment: callNote_' + toCamelClassNote(classNotes) + ';\
}\
\
.note-call_' + classNotes + '::after {\
content: counter(callNote_' + toCamelClassNote(classNotes) + ');\
}\
\
.note-marker_' + classNotes + ' {\
counter-increment: markerNote_' + toCamelClassNote(classNotes) + ';\
}\
.note-marker_' + classNotes + '::before {\
content: counter(markerNote_' + toCamelClassNote(classNotes) + ') "";\
}\
' + notePosition
);
} /* end beforeParsed*/
afterPageLayout(pageElement, page, breakToken) {
let notes = pageElement.querySelectorAll("." + classNotes);
let noteOverflow = false;
let notesHeightAll = [];
if (typeof (notes) != 'undefined' && notes != null && notes.length != 0) {
for (let n = 0; n < notes.length; ++n) {
// Display notes of the page
notes[n].style.display = "inline-block";
// 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);
}
}
/* FIT PAGE ------------------------------------------------------------------------------------- */
// Calculate if all notes fit on the page;
let reducer = (accumulator, currentValue) => accumulator + currentValue;
let allHeight = notesHeightAll.reduce(reducer);
let maxHeight = pageElement.querySelectorAll(".pagedjs_page_content")[0].offsetHeight;
if (allHeight > maxHeight) {
// console.log("doesn't fit");
/* IF DOESN'T FIT ----------------------------------------------------------------------------- */
// positions all the notes one after the other starting from the top
notes[0].style.top = parseInt(window.getComputedStyle(notes[0]).marginBottom, 10) * -1 + "px";
for (let a = 1; a < notes.length; ++a) {
let notePrev = notes[a - 1];
let newMargin = biggestMargin(notePrev, notes[a]);
let newTop = notePrev.offsetTop + notePrev.offsetHeight - marginNoteTop(notes[a]) + newMargin + 5 ;
notes[a].style.top = newTop + "px";
}
// alert
let pageNumber = pageElement.dataset.pageNumber;
// alert("Rendering issue \n ☞ A marginal note overflow on page " + pageNumber + " (this is because there is too many on this page and paged.js can't breaks notes between pages for now.)");
noteOverflow = true;
} else {
// console.log("fit");
/* PUSH DOWN ---------------------------------------------------- */
for (let i = 0; i < notes.length; ++i) {
if (i >= 1) {
let noteTop = notes[i].offsetTop;
let notePrev = notes[i - 1];
let newMargin = biggestMargin(notes[i], notePrev);
let notePrevBottom = notePrev.offsetTop - marginNoteTop(notePrev) + notePrev.offsetHeight + newMargin + 5;
// Push down the note to bottom if it's over the previous one
if (notePrevBottom > noteTop) {
// console.log("overflow");
notes[i].style.top = notePrevBottom + "px";
}
}
}
/* PUSH UP ---------------------------------------------- */
// Height of the page content
let contentHeight = pageElement.querySelectorAll(".pagedjs_page_content")[0].querySelectorAll("div")[0].offsetHeight;
// Check if last note overflow
let nbrLength = notes.length - 1;
let lastNote = notes[nbrLength];
let lastNoteHeight = lastNote.offsetHeight + marginNoteTop(lastNote);
let noteBottom = lastNote.offsetTop + lastNoteHeight;
if (noteBottom > contentHeight) {
// Push up the last note
lastNote.style.top = contentHeight - lastNoteHeight - 13 + "px";
// Push up previous note(s) if if it's over the note
for (let i = nbrLength; i >= 1; --i) {
let noteLastTop = notes[i].offsetTop;
let notePrev = notes[i - 1];
let notePrevHeight = notePrev.offsetHeight;
let newMargin = biggestMargin(notePrev, notes[i]);
let notePrevBottom = notePrev.offsetTop + notePrev.offsetHeight + newMargin + 13;
if (notePrevBottom > noteLastTop) {
notePrev.style.top = notes[i].offsetTop - marginNoteTop(notePrev) - notePrevHeight - newMargin - 17 + "px";
}
}
} /* end push up */
}
}
}/* end afterPageLayout*/
}
Paged.registerHandlers(marginNotes);
// 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;
}
// ADD CSS
function addcss(css) {
var head = document.getElementsByTagName('head')[0];
var s = document.createElement('style');
s.setAttribute('type', 'text/css');
if (s.styleSheet) { // IE
s.styleSheet.cssText = css;
} else {// the world
s.appendChild(document.createTextNode(css));
}
head.appendChild(s);
}
// CAMEL CLASS NOTE
function toCamelClassNote(elem) {
let splitClass = elem.split("-");
if (splitClass.length > 1) {
for (let s = 1; s < splitClass.length; ++s) {
let strCapilize = splitClass[s].charAt(0).toUpperCase() + splitClass[s].slice(1)
splitClass[s] = strCapilize;
}
}
let reducer = (accumulator, currentValue) => accumulator + currentValue;
let classCamel = splitClass.reduce(reducer);
return classCamel;
}

View file

@ -0,0 +1,14 @@
class ragadjustHandler extends Paged.Handler {
constructor(chunker, polisher, caller) {
super(chunker, polisher, caller);
}
beforeParsed(content) {
// Adjusts the headers by adding a non-breaking space after
// all the prepositions listed, and without any whitelisted
// word.
ragadjust('p,h1,h2,h3,h4,h5,h6,li', ['determiners', 'pronouns', 'dashes'], [], content);
}
}
Paged.registerHandlers(ragadjustHandler);

126
assets/js/plugins/ragadjust.js Executable file
View file

@ -0,0 +1,126 @@
// based on Nathan Ford's Ragadjust
// https://github.com/nathanford/ragadjust
// "Use it however you like. I'll add a GPL I think as soon as I can." licence
// Forked by Yann Trividic and Nicolas Taffin
// https://github.com/yanntrividic/ragadjustfr
// TODO:
// Make the tool language independant by supporting the lang attribute
// cleanup the code a bit (maybe get rid of the dictionary thing?)
// Elements in those lists have to be unique in order for the exceptions to work
// French prepositions
arts = ["un", "une", "le", "la", "les", "du", "de", "des", "au", "aux"];
dets = ["ce", "ces", "cet", "cette", "mes", "tes", "ses", "mon", "ton", "ma", "ta", "son", "sa", "notre", "votre", "leur", "nos", "vos", "leurs", "p."];
prons = ["je", "tu", "il", "elle", "on", "nous", "vous", "ils", "elles"];
conjs = ["mais", "où", "et", "donc", "or", "ni", "car", "ou", "que"];
short = ["à", "y", "en", "de", "sur", "par"];
preps = ["après", "avant", "avec", "chez", "concernant", "contre", "dans", "depuis", "derrière", "dès", "durant", "entre", "hormis", "jusquà", "jusque", "loin", "malgré", "moyennant", "outre", "parmi", "pour", "près", "sans", "selon", "sous", "suivant", "touchant", "très", "vers"];
// English prepositions
// preps = /(\s|^|>)((aboard|about|above|across|after|against|along|amid|among|anti|around|before|behind|below|beneath|beside|besides|between|beyond|concerning|considering|despite|down|during|except|excepting|excluding|following|from|inside|into|like|minus|near|onto|opposite|outside|over|past|plus|regarding|round|save|since|than|that|this|through|toward|towards|under|underneath|unlike|until|upon|versus|with|within|without)\s)+/gi,
case_sensitivity = true;
make_case_sensitive = function(l) {
title_case = [];
l.forEach(function (item, i) {
var word = l[i];
word = word[0].toUpperCase() + word.slice(1);
title_case.push(word);
});
return l.concat(title_case);
}
get_regex_from_array_of_words = function(l, exceptions) {
exceptions.forEach(function (item, i) {
if (l.indexOf(item) != -1) {
l.splice(l.indexOf(item), 1);
}
});
reg = case_sensitivity ? make_case_sensitive(l).join("|") : l.join("|")
//console.log(reg)
return reg
}
build_regex_from_words = function(l, exceptions) {
return new RegExp("(\\s|^|>|&#160;|&nbsp;)(((" + get_regex_from_array_of_words(l, exceptions) + ")(\\s))+)" , 'gi');
}
ragadjust = function(s, method, exceptions = [], content = null) {
console.log("ragadjust elements", s, "following those methods:", method)
if(content) {
doc = content;
} else {
doc = document;
}
if (doc.querySelectorAll) {
var eles = doc.querySelectorAll(s),
elescount = eles.length,
dictionary = { // Is used to perform the same operations over each of those words
"articles": build_regex_from_words(arts, exceptions),
"determiners": build_regex_from_words(dets, exceptions),
"pronouns": build_regex_from_words(prons, exceptions),
"conjunctions": build_regex_from_words(conjs, exceptions),
"short_prepositions": build_regex_from_words(short, exceptions),
"prepositions": build_regex_from_words(preps, exceptions),
}
smallwords = /(\s|^)(([a-zA-ZÀ-ž-_(]{1,2}('|)*[a-zA-ZÀ-ž-_,;]{0,1}?\s)+)/gi, // words with 3 or less characters
dashes = /([-–—])\s/gi,
emphasis = /(<(strong|em|b|i)>)(([^\s]+\s*){2,3})?(<\/(strong|em|b|i)>)/gi;
while (elescount-- > 0) {
var ele = eles[elescount],
elehtml = ele.innerHTML;
for (const [key, value] of Object.entries(dictionary)) {
if (method.indexOf(key) != -1 || method.indexOf('all') != -1)
elehtml = elehtml.replace(value, function(contents, p1, p2) {
return p1 + p2.replace(/\s/gi, '&#160;');
});
}
if (method.indexOf('small-words') != -1 || method.indexOf('all') != -1)
// replace small words
elehtml = elehtml.replace(smallwords, function(contents, p1, p2) {
return contents.replace(/\s/gi, '&#160;');
});
if (method.indexOf('dashes') != -1 || method.indexOf('all') != -1)
// replace small words
elehtml = elehtml.replace(dashes, function(contents) {
return contents.replace(/\s/gi, '&#160;');
});
if (method.indexOf('emphasis') != -1 || method.indexOf('all') != -1)
// emphasized text
elehtml = elehtml.replace(emphasis, function(contents, p1, p2, p3, p4, p5) {
return p1 + p3.replace(/\s/gi, '&#160;') + p5;
});
// doesn't work :(
// if (method.indexOf('orphans') || method.indexOf('all'))
// // no single words on there own last line
// elehtml = elehtml.replace(orphans, function(contents) {
// return contents.replace(/(\s|^&#160;)/, '&#160;')
// });
ele.innerHTML = elehtml;
}
}
};

View file

@ -0,0 +1,13 @@
class correctTypo extends Paged.Handler {
constructor(chunker, polisher, caller) {
super(chunker, polisher, caller);
}
beforeParsed(content) {
orthotypo(content);
exposants(content);
noHyphens(content);
}
}
Paged.registerHandlers(correctTypo);

View file

@ -0,0 +1,279 @@
// window.onload = function(){
// orthotypo(document.body);
// spaces(document.body);
// exposants();
// }
function orthotypo( content ){
// var nodes = document.createTreeWalker(element, NodeFilter.SHOW_TEXT, null, null);
let all = content.querySelectorAll('p, span');
all.forEach(element => {
// console.log(element);
element.innerHTML = orthotypoRegex(element.innerHTML)
})
// all french caracteres: [A-Za-zÀ-ÖØ-öø-ÿœŒ
// var node;
// while (node = nodes.nextNode()) {
// for (var i = 0; i < array.length; i++) {
// node.textContent = node.textContent.replace(array[i].reg, array[i].repl);
// }
// }
}
function orthotypoRegex(elem){
let array = [
// {
// // oe
// reg: /oe/g,
// repl: 'œ'
// },
{
// XIème = XIe
reg: /(X|I|V)ème/g,
repl: '$1e'
},
]
for (var i = 0; i < array.length; i++) {
elem = elem.replace(array[i].reg, array[i].repl);
}
return elem;
}
function spaces( content ){
// var nodes = document.createTreeWalker(element, NodeFilter.SHOW_TEXT, null, null);
let all = content.querySelectorAll('p, span');
// all french caracteres: [A-Za-zÀ-ÖØ-öø-ÿœŒ]
all.forEach(element => {
// console.log(element);
element.innerHTML = spacesRegex(element.innerHTML)
})
}
function spacesRegex(elem){
let array = [
{
// french open quotes
reg: /\"([A-Za-zÀ-ÖØ-öø-ÿœŒ])/g,
repl: '«$1'
},
{
// french close quotes
reg: /([A-Za-zÀ-ÖØ-öø-ÿœŒ])\"/g,
repl: '$1»'
},
{
// real apostrophe
reg: /\'/g,
repl: ''
},
{
// real suspension points
reg: /\.+\.+\./g,
repl: '\u2026'
},
{
// delete all spaces before punctuation !?;:»›”)].,
reg: /\s+([!?;:»›”)\]\.\,])/g,
repl: '$1'
},
{
// add narrow no break space before !?;:»›
reg: /([!?;:»›])/g,
repl: '\u202F$1'
},
{
// delete all spaces after «‹“[(
reg: /([«‹“\[(])\s+/g,
repl: '$1'
},
{
// add narrow no break space after «‹
reg: /([«‹])/g,
repl: '$1\u202F'
},
{
// OPTION 1 : no break space after two letter words (if not follow by an other two letter word)
// reg: /\s+([a-zØ-öø-ÿœ]{2})\s+([A-Za-zÀ-ÖØ-öø-ÿœŒ]{3,})/gi,
// repl: ' $1\u00A0$2'
// OPTION 2: no break space after some two letter words
reg: /\s(le|la|un|une|ce|ces|il|on|les|des|du|ils)\s+/g,
repl: ' $1\u00A0'
},
{
// if prev OPTION 2: no break space after successive two letter words
reg: /\s+([a-zØ-öø-ÿœ]{2})\s+([A-Za-zÀ-ÖØ-öø-ÿœŒ]{2})\s+/g,
repl: ' $1 $2\u00A0'
},
{
// no break space after one letter words
reg: /\s+([a-zà])\s+/gi,
repl: ' $1\u00A0'
},
{
// no break space after first word (2-5 letter) of the sentence
reg: /\.\s([A-ZÀ-Ö])([A-Za-zÀ-ÖØ-öø-ÿœŒ]{1,5})\s+/g,
repl: '. $1$2\u00A0'
},
{
// no break space into names
reg: /([A-ZÀ-ÖØŒ])([A-Za-zÀ-ÖØ-öø-ÿœŒ]+)\s+([A-ZÀ-ÖØŒ])([A-Za-zÀ-ÖØ-öø-ÿœŒ]+)/g,
repl: '$1$2\u00A0$3$4'
},
{
// no break space before Caps + .
reg: /\s([A-ZÀ-ÖØŒ])\./g,
repl: '\u00A0$1. '
},
{
// no break space before 'siècles'
reg: /(X|I|V)(er|e)\s+siècle/g,
repl: '$1$2\u00A0siècles'
},
// {
// // no break space after figures table page chapitre ect. + number
// reg: /(figures?|tables?|planches?|chapitres?|pages?|parties?|sections?|volumes?|vol\.)\s+(\d|I|X|V)/g,
// repl: '$1\u00A0$2'
// },
// {
// // p. and pp. in blibliography
// reg: /(\spp?\.)\s?(\d)/g,
// repl: '$1\u00A0$2'
// }
]
for (var i = 0; i < array.length; i++) {
elem = elem.replace(array[i].reg, array[i].repl);
}
return elem;
}
function noHyphens( content ){
// var nodes = document.createTreeWalker(element, NodeFilter.SHOW_TEXT, null, null);
let all = content.querySelectorAll('p');
// all french caracteres: [A-Za-zÀ-ÖØ-öø-ÿœŒ]
all.forEach(element => {
// console.log(element);
element.innerHTML = noHyphensRegex(element.innerHTML)
})
}
function noHyphensRegex(elem){
let array = [
{
// no break space into names
reg: /([A-ZÀ-ÖØŒ])([A-Za-zÀ-ÖØ-öø-ÿœŒ]+)\s+([A-ZÀ-ÖØŒ])([A-Za-zÀ-ÖØ-öø-ÿœŒ]+)/g,
repl: '$1$2\u00A0$3$4'
},
{
// no break space before Caps + .
reg: /\s([A-ZÀ-ÖØŒ])\./g,
repl: '\u00A0$1. '
},
{
// no break space before 'siècles'
reg: /(X|I|V)(er|e)\s+siècle/g,
repl: '$1$2\u00A0siècles'
},
{
// règles le problème de 1ep qui met le e en exposant
reg: '1<sup>e</sup>p',
repl: '1ep'
}
]
for (var i = 0; i < array.length; i++) {
elem = elem.replace(array[i].reg, array[i].repl);
}
return elem;
}
function exposants(content){
// let paragraphs = document.querySelectorAll('p, ul, h1, h2, h3, h4, h5, h6');
let all = content.querySelectorAll('p, span');
// console.log(all);
all.forEach(element => {
element.innerHTML = exposantsRegex(element.innerHTML)
})
// for (var p = 0; p < paragraphs.length; p++) {
// paragraphs[p].innerHTML = exposantsRegex(paragraphs[p].innerHTML);
// }
}
function exposantsRegex(elem){
let array = [
{
// numéros
reg: /\sno\.?\s?(\d+)/g,
repl: ' n<sup>o</sup>&nbsp;$1'
},
{
// siècles + small caps
reg: /(XXI|XX|XIX|XVIII|XVII|XVI|XV|xxi|xx|xix|xviii|xvii|xvi|xv)(e|er)/g,
repl: '<span style="text-transform: lowercase; font-variant: small-caps;">$1</span><sup>$2</sup>'
},
{
// exposant e après chiffres
reg: /(\d+)(er|e)[\s\\u00A0]/g,
repl: '$1<sup>$2</sup>'
},
{
// exposant e après chiffres
reg: '22e',
repl: '22<sup>e</sup>'
},
{
// exposant e après chiffres
reg: '4e éd.',
repl: '4<sup>e</sup> éd.'
},
{
// exposant e après chiffres
reg: 'IVe',
repl: 'IV<sup>e</sup>'
},
]
for (var i = 0; i < array.length; i++) {
elem = elem.replace(array[i].reg, array[i].repl);
}
return elem;
}
// function noHyphens(){
// let paragraphs = document.querySelectorAll('p');
// // Problems here because replace also content in `href`, `data`atttribute, etc.
// // for (var i = 0; i < paragraphs.length; i++) {
// // let p = paragraphs[i];
// // p.innerHTML = p.innerHTML.replace(/([A-ZÀ-Ö][a-zØ-öø-ÿœ]{3,})/g, '<span style="hyphens: none">$1</span>');
// // }
// }

View file

@ -0,0 +1 @@
(function(a,b){'object'==typeof exports&&'object'==typeof module?module.exports=b():'function'==typeof define&&define.amd?define([],b):'object'==typeof exports?exports.smartquotes=b():a.smartquotes=b()})(this,function(){return function(a){function b(d){if(c[d])return c[d].exports;var e=c[d]={i:d,l:!1,exports:{}};return a[d].call(e.exports,e,e.exports,b),e.l=!0,e.exports}var c={};return b.m=a,b.c=c,b.d=function(a,c,d){b.o(a,c)||Object.defineProperty(a,c,{configurable:!1,enumerable:!0,get:d})},b.n=function(a){var c=a&&a.__esModule?function(){return a['default']}:function(){return a};return b.d(c,'a',c),c},b.o=function(a,b){return Object.prototype.hasOwnProperty.call(a,b)},b.p='',b(b.s=3)}([function(a,b,c){'use strict';var d=c(1);a.exports=function(a,b){return b=b||{},d.forEach(function(c){var d='function'==typeof c[1]?c[1](b.retainLength):c[1];a=a.replace(c[0],d)}),a}},function(a){'use strict';a.exports=[[/'''/g,function(a){return'\u2034'+(a?'\u2063\u2063':'')}],[/(\W|^)"(\w)/g,'$1\u201C$2'],[/(\u201c[^"]*)"([^"]*$|[^\u201c"]*\u201c)/g,'$1\u201D$2'],[/([^0-9])"/g,'$1\u201D'],[/''/g,function(a){return'\u2033'+(a?'\u2063':'')}],[/(\W|^)'(\S)/g,'$1\u2018$2'],[/([a-z])'([a-z])/ig,'$1\u2019$2'],[/(\u2018)([0-9]{2}[^\u2019]*)(\u2018([^0-9]|$)|$|\u2019[a-z])/ig,'\u2019$2$3'],[/((\u2018[^']*)|[a-z])'([^0-9]|$)/ig,'$1\u2019$3'],[/(\B|^)\u2018(?=([^\u2018\u2019]*\u2019\b)*([^\u2018\u2019]*\B\W[\u2018\u2019]\b|[^\u2018\u2019]*$))/ig,'$1\u2019'],[/"/g,'\u2033'],[/'/g,'\u2032']]},function(a,b,c){'use strict';function d(a){if(-1===['CODE','PRE','SCRIPT','STYLE'].indexOf(a.nodeName.toUpperCase())){var b,c,h,i='',j=a.childNodes,k=[];for(b=0;b<j.length;b++)c=j[b],c.nodeType===g||'#text'===c.nodeName?(k.push([c,i.length]),i+=c.nodeValue||c.value):c.childNodes&&c.childNodes.length&&(i+=d(c));for(b in i=f(i,{retainLength:!0}),k)h=k[b],h[0].nodeValue?h[0].nodeValue=e(i,h[0].nodeValue,h[1]):h[0].value&&(h[0].value=e(i,h[0].value,h[1]));return i}}function e(a,b,c){return a.substr(c,b.length).replace('\u2063','')}var f=c(0),g='undefined'!=typeof Element&&Element.TEXT_NODE||3;a.exports=function(a){return d(a),a}},function(a,b,c){'use strict';function d(a){return'undefined'!=typeof document&&'undefined'==typeof a?(g.runOnReady(function(){return f(document.body)}),d):'string'==typeof a?h(a):f(a)}var e=c(1),f=c(2),g=c(4),h=c(0);a.exports=d,a.exports.string=h,a.exports.element=f,a.exports.replacements=e,a.exports.listen=g},function(a,b,c){'use strict';function d(a){var b=new MutationObserver(function(a){a.forEach(function(a){var b,c=!0,d=!1;try{for(var f,g,h=a.addedNodes[Symbol.iterator]();!(c=(f=h.next()).done);c=!0)g=f.value,e(g)}catch(a){d=!0,b=a}finally{try{!c&&h.return&&h.return()}finally{if(d)throw b}}})});return d.runOnReady(function(){b.observe(a||document.body,{childList:!0,subtree:!0})}),b}var e=c(2),f=c(0);d.runOnReady=function(a){if('loading'!==document.readyState)a();else if(document.addEventListener)document.addEventListener('DOMContentLoaded',a,!1);else var b=setInterval(function(){'loading'!==document.readyState&&(clearInterval(b),a())},10)},a.exports=d}])});

105
assets/js/plugins/toc.js Normal file
View file

@ -0,0 +1,105 @@
// ------------------ TABLE OF CONTENTS --------------
class toc extends Paged.Handler {
constructor(chunker, polisher, caller) {
super(chunker, polisher, caller);
}
beforeParsed(content){
const toc = content.querySelector('#table-of-contents');
let elements = ['.chapter h2'];
createToc({
content: content,
container: '#table-of-contents',
titleElements: elements,
});
}
}
Paged.registerHandlers(toc);
function createToc(config) {
const content = config.content;
const tocElement = config.container;
const titleElements = config.titleElements;
let tocElementDiv = content.querySelector(tocElement)
if(!tocElementDiv) return console.warn('couldnt start the toc')
tocElementDiv.innerHTML = ''
let tocUl = document.createElement('ul')
tocUl.id = 'list-toc-generated'
if(config.before){
tocUl.style.setProperty('--before-page', '"' + config.before + '"');
}
tocElementDiv.appendChild(tocUl)
// add class to all title elements
let tocElementNbr = 0
for (var i = 0; i < titleElements.length; i++) {
let titleHierarchy = i + 1
let titleElement = content.querySelectorAll(titleElements[i])
titleElement.forEach(function (element) {
// check if shouldbe shown
if (
!element.classList.contains('toc-ignore') ||
!element.classList.contains('toc-ignore')
) {
// add classes to the element
element.classList.add('title-element')
element.setAttribute('data-title-level', titleHierarchy)
// add an id if doesn't exist
tocElementNbr++
if (element.id == '') {
element.id = 'title-element-' + tocElementNbr
}
let newIdElement = element.id
}
})
}
// create toc list
let tocElements = content.querySelectorAll('.title-element')
for (var i = 0; i < tocElements.length; i++) {
let tocElement = tocElements[i]
let tocNewLi = document.createElement('li')
// Add class for the hierarcy of toc
tocNewLi.classList.add('toc-element')
tocNewLi.classList.add('toc-element-level-' + tocElement.dataset.titleLevel)
let classes = [
...(tocElement.className ? tocElement.className.split(' ') : []),
...(tocElement.closest('section')?.className ? tocElement.closest('section')?.className.split(' ') : []),
];
classes.forEach((meta) => {
if (!meta || meta === 'title-element') return;
tocNewLi.classList.add(`toc-${meta}`);
});
//get the exisiting class
// Keep class of title elements
let classTocElement = tocElement.classList
for (var n = 0; n < classTocElement.length; n++) {
if (classTocElement[n] != 'title-element') {
tocNewLi.classList.add(classTocElement[n])
}
}
tocNewLi.innerHTML =
'<a class="toc-link" href="#' + tocElement.id + '">' + tocElement.innerHTML + '</a>';
tocUl.appendChild(tocNewLi)
}
}