From 7ef6b9cf9ac66ab32eb9b2adf75925de744168fe Mon Sep 17 00:00:00 2001 From: ada Date: Fri, 7 Jun 2024 17:09:08 +0200 Subject: [PATCH 1/2] Upload files to 'print/plugins' --- print/plugins/marginNotes.js | 255 +++++++++++++++++++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 print/plugins/marginNotes.js diff --git a/print/plugins/marginNotes.js b/print/plugins/marginNotes.js new file mode 100644 index 0000000..01d1410 --- /dev/null +++ b/print/plugins/marginNotes.js @@ -0,0 +1,255 @@ +let classNotes = "margin-note"; // ← Change the CLASS of the notes here +let notesFloat = "outside"; // ← 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); + + + for (let i = 0; i < notes.length; ++i) { + + // Add call notes + var spanCall = document.createElement("span"); + spanCall.classList.add("note-call"); + spanCall.classList.add("note-call_" + classNotes); + spanCall.dataset.noteCall = classNotes + '-' + i + 1; + 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 + '-' + i + 1; + notes[i].prepend(spanMarker); + + + // 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 - 1px); width: var(--pagedjs-margin-left);' + + 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) { + + /* 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; + 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 { + + /* 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; + // Push down the note to bottom if it's over the previous one + if (notePrevBottom > noteTop) { + 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 + "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; + if (notePrevBottom > noteLastTop) { + notePrev.style.top = notes[i].offsetTop - marginNoteTop(notePrev) - notePrevHeight - newMargin + "px"; + } + } + + } /* end push up */ + + } + + } + }/* end afterPageLayout*/ + +} +Paged.registerHandlers(marginNotes); + + + +/* FUNCTIONS -------------------------------------------------------------------------------------- +--------------------------------------------------------------------------------------------------- */ + +// 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; +} + From b951bed3ddd12967dacccf76d2b5b676ae38ea8f Mon Sep 17 00:00:00 2001 From: ada Date: Fri, 7 Jun 2024 17:10:31 +0200 Subject: [PATCH 2/2] Update 'print/booklet.template.html' --- print/booklet.template.html | 1 + 1 file changed, 1 insertion(+) diff --git a/print/booklet.template.html b/print/booklet.template.html index a0d0c52..372d132 100644 --- a/print/booklet.template.html +++ b/print/booklet.template.html @@ -4,6 +4,7 @@ +