Commit 9f26f8bd authored by julien's avatar julien

Merge branch 'master' of gitlab.pagedmedia.org:tools/experiments

parents 582384cd 955f4d8f
......@@ -7,7 +7,7 @@
}
.pagedjs_pages {
display: flex;
width: calc(var(--width) * 2);
width: calc(var(--pagedjs-width) * 2);
flex: 0;
flex-wrap: wrap;
margin: 0 auto;
......
# Book index
A script to generate a book index.
## Preparing your HTML
In the simplest terms, a book index is simply a key to locating information contained in a book. The main idea of the book index is to help the reader find information quickly and easily. It is not a way to locate in the book all the paragraph where the word "music" appears but to locate the places in the book where the word music is "revealing" in relation to the content. In this way, create an index is a semantic work that cannot be done automatically.
When you think your content is revelant and need to be in the index, simply add a span around the content:
```HTML
<p>General definitions of <span class="book-index" data-book-index="music">music</span> include common elements such as pitch, rhythm, dynamics, and the sonic qualities of timbre and texture.</p>
```
Your span must contain at least two elements:
- **a class**: this class is common to all index span elements of your document, you can name it as you wish
- **a data attribut**: this data attribut must be named `data-book-index`, it indicates the word(s) that will appear in the index
- you can also add an id if you want but it's not required
About the data attribute:
- all data attributes containing the same word will be combined in a single line in the index, so you can use the same data attribute several times in your document
- it is possible to use spaces, capital letters and dashes in the data attribute, like this for example: `data-book-index="Wolfgang Amadeus Mozart"`
- it is also possible to format the text with the `<em>` en `<i>` elements (only): `data-book-index="<em>String Quartet in C major</em>"`
Finally, you must add somewhere in your HTML an element in which the book index will be generated. It can be a section or a div but it must be indicated by an id (that you name as you wish):
```HTML
<div id="book-index"></div>
```
## Use the script with paged.js
1. Add the `async` property to the paged.js script:
* if you use paged.js with npm: `<script async src="http://localhost:9090/dist/paged.polyfill.js"></script>`
* if you use the online script of paged.js: `<script async src="http://unpkg.com/pagedjs/dist/paged.polyfill.js"></script>`
2. Add the book index script:
```html
<script src="js/createIndex.js" type="text/javascript"></script>
```
3. Call the book index script:
The book index need to be generated before that paged.js fragmented the content into pages. You need to the hook `before` to call the script.
Add this code in the `head` of you html document:
```html
<script>
window.PagedConfig = {
before: function () {
createIndex({
spanClassIndex: 'book-index',
indexElement: '#book-index',
alphabet: true
});
}
};
</script>
```
4. Use the print CSS properties in your stylesheet file to target the pages where the index elements appears:
```CSS
.link-page a::after{ content: target-counter(attr(href), page); }
.link-page::after{ content: ", "; }
.link-page:last-of-type::after{ content: none; }
.index-value::after{ content: " – "; }
```
## Configuring the script
* `spanClassIndex`: define the id element where the toc list will be create
* `indexElement`: define the id element where the toc list will be create
* `alphabet`: choose if you want the alphabetical elements (`true`) or not (`false`)
## Styling the book index
The script generates a list whith items you can style. Here is an example of a book index generated:
![Exemple of a generated book index](example-index.png)
```HTML
<ul id="list-index-generated">
<li class="list-alphabet-element" id="alphabet-element-A">A</li>
<li class="list-index-element" data-list-index="Apple">
<span class="index-value">Apple</span>
<span class="links-pages">
<span class="link-page"><a href="#book-index-10"></a></span>
<span class="link-page"><a href="#book-index-23"></a></span>
</span>
</li>
<li class="list-index-element" data-list-index="Apricot">
<span class="index-value">Apricot</span>
<span class="links-pages">
<span class="link-page"><a href="#book-index-15"></a></span>
<span class="link-page"><a href="#book-index-35"></a></span>
</span>
</li>
<li class="list-index-element" data-list-index="Avocado">
<span class="index-value">Avocado</span>
<span class="links-pages">
<span class="link-page"><a href="#book-index-19"></a></span>
</span>
</li>
<li class="list-alphabet-element" id="alphabet-element-B">B</li>
<li class="list-index-element" data-list-index="Banana">
<span class="index-value">Banana</span>
<span class="links-pages">
<span class="link-page"><a href="#book-index-2"></a></span>
<span class="link-page"><a href="#book-index-38"></a></span>
<span class="link-page"><a href="#book-index-12"></a></span>
</span>
</li>
<li class="list-index-element" data-list-index="Blackberry">
<span class="index-value">Blackberry</span>
<span class="links-pages">
<span class="link-page"><a href="#book-index-17"></a></span>
<span class="link-page"><a href="#book-index-24"></a></span>
</span>
</li>
<li class="list-alphabet-element" id="alphabet-element-C">C</li>
<li class="list-index-element" data-list-index="Cherry">
<span class="index-value">Cherry</span>
<span class="links-pages">
<span class="link-page"><a href="#book-index-32"></a></span>
<span class="link-page"><a href="#book-index-27"></a></span>
</span>
</li>
<li class="list-index-element" data-list-index="Coconut">
<span class="index-value">Coconut</span>
<span class="links-pages">
<span class="link-page"><a href="#book-index-41"></a></span>
<span class="link-page"><a href="#book-index-8"></a></span>
</span>
</li>
</ul>
```
An example of CSS to styling the book index:
![Exemple of a generated and styled book index](example-index-styled.png)
```CSS
#list-index-generated{
list-style-type: none;
}
.list-alphabet-element{
font-weight: bold;
padding-top: 18px;
padding-bottom: 9px;
font-family: Arial, Helvetica, sans-serif;
}
.index-value{
display: inline-block;
min-width: 120px;
}
.index-value:first-letter{ text-transform: uppercase; }
.index-value::after{ content: "none"; }
.link-page a{
text-decoration: none;
color: currentColor;
font-family: Arial, Helvetica, sans-serif;
font-size: 12px;
}
```
/* To define how the book look on the screen: */
:root {
/* color for the interface */
--color-background: rgba(0, 0, 0, 0.2);
--color-marginBox: transparent;
--color-pageBox: transparent;
--color-paper: white;
/* color used for the baseline */
--color-baseline: transparent;
/* fonts for the book */
/* colors */
/* typographic related variables */
--font-size: 12px;
--font-lineHeight: 16px;
}
@media screen {
body {
background-color: var(--color-background);
}
.pagedjs_pages {
display: flex;
width: calc(var(--pagedjs-width) * 2);
flex: 0;
flex-wrap: wrap;
margin: 0 auto;
margin-bottom: 3em;
}
.pagedjs_page {
background-color: var(--color-paper);
box-shadow: 0 0 0 2px var(--color-pageBox);
margin: 0;
flex-shrink: 0;
flex-grow: 0;
margin-top: 10mm;
}
.pagedjs_first_page {
margin-left: var(--pagedjs-width);
}
/* uncomment for recto/verso book.
--------------------------------------------------- */
/* .pagedjs_pages {
flex-direction: column;
width: 100%;
}
.pagedjs_first_page {
margin-left: 0;
}
.pagedjs_page {
margin: 0 auto;
margin-top: 10mm;
} */
}
\ No newline at end of file
/* Book index style */
.link-page a::after{ content: target-counter(attr(href), page); }
.link-page::after{ content: ", "; }
.link-page:last-of-type::after{ content: none; }
.index-value::after{ content: " – "; }
#list-index-generated{
list-style-type: none;
padding-left: 0;
columns: 2;
column-fill: auto!important;
padding-top: 20px;
}
.list-alphabet-element{
font-weight: bold;
padding-top: 18px;
padding-bottom: 9px;
font-family: Arial, Helvetica, sans-serif;
break-after: avoid;
}
.index-value{ display: inline-block; }
.index-value:first-letter{ text-transform: uppercase; }
.link-page a{
text-decoration: none;
color: currentColor;
font-family: Arial, Helvetica, sans-serif;
font-size: 12px;
}
.book-index{ color: red!important; }
/* General style */
@page {
size: 160mm 210mm;
margin: 15mm 15mm;
}
@page:left{
margin-top:15mm;
margin-bottom: 25mm;
margin-left: 40mm;
margin-right: 25mm;
@bottom-left{
content: counter(page);
font-family: Arial, Helvetica, sans-serif;
font-size: 12px;
}
}
@page:right{
margin-top:15mm;
margin-bottom: 25mm;
margin-right: 40mm;
margin-left: 25mm;
@bottom-right{
content: counter(page);
font-family: Arial, Helvetica, sans-serif;
font-size: 12px;
}
}
@page:first{
margin: 10mm 30mm;
@bottom-right{ content: none };
}
@page:blank{
@bottom-left{ content: none };
@bottom-right{ content: none };
}
#book-index-section{ page: index;}
@page index{
margin-left: 15mm;
margin-right: 15mm;
}
#cover-page{
/*break-after: right;*/
break-after: left;
}
#cover-page h1{
font-family: Georgia, 'Times New Roman', Times, serif;
font-size: 40px;
text-align: center;
font-weight: normal;
margin-top: 20mm;
}
#cover-page h1 small{
display: block;
font-size: 20px;
margin-top: 32px;
}
#author{
margin-top: 250px;
font-family: Georgia, 'Times New Roman', Times, serif;
font-size: 25px;
text-align: center;
}
#editor{
width: 100%;
position: absolute;
bottom: 0;
}
#editor p{
font-family: Arial, Helvetica, sans-serif;
font-weight: bold;
text-align: center;
}
#editor::before{
content: "";
display: block;
border-top: 1px solid black;
width: 100%;
margin: 0 auto;
padding-bottom: 16px;
}
p{
font-family: Georgia, 'Times New Roman', Times, serif;
margin-top: 0;
margin-bottom: 0;
text-align: justify;
font-size: 14px;
line-height: 16px;
text-indent: 16px;
}
#book-index-section, .chapter{
break-before: right;
}
.chapter h1{
margin-top: 50px;
margin-bottom: 120px;
font-family: Georgia, 'Times New Roman', Times, serif;
font-size: 25px;
font-weight: normal;
text-align: center;
}
.chapter h1 small, #book-index-section h1{
display: block;
margin-bottom: 16px;
font-family: Arial, Helvetica, sans-serif;
font-weight: bold;
font-size: 16px;
}
.chapter h1 small{ text-align: center; }
.chapter h2{
font-family: Georgia, 'Times New Roman', Times, serif;
font-weight: normal;
font-size: 18px;
text-align: center;
break-before: right;
}
.chapter h2::after{
content: "—";
display: block;
}
.chapter h3{
font-family: Georgia, 'Times New Roman', Times, serif;
font-size: 14px;
break-after: avoid;
}
h1 + p, h2 + p, h3 + p{ text-indent: 0; }
.afnanch{ display: none; }
This diff is collapsed.
function createIndex(config){
let indexElements = document.getElementsByClassName(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 = document.querySelector(config.indexElement);
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 alaphabet
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 = document.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 = document.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;
}
......@@ -523,7 +523,7 @@ pre{
}
.pagedjs_pages{
display:flex;
width:calc(var(--width) * 2);
width:calc(var(--pagedjs-width) * 2);
flex:0;
flex-wrap:wrap;
margin:0 auto;
......@@ -537,7 +537,7 @@ pre{
margin-top:10mm;
}
.pagedjs_first_page{
margin-left:var(--width);
margin-left:var(--pagedjs-widthh);
}
.pagedjs_margin-content{
......
......@@ -10,21 +10,13 @@
--color-paper: white;
/* color used for the baseline */
--color-baseline: transparent;
--pagedjs-baseline-color: cyan;
/* height of the baseline*/
--pagedjs-baseline: 8px;
/* fonts for the book */
/* colors */
/* typographic related variables */
--font-size: 12px;
--font-lineHeight: 16px;
}
......@@ -34,7 +26,7 @@
}
.pagedjs_pages {
display: flex;
width: calc(var(--width) * 2);
width: calc(var(--pagedjs-width) * 2);
flex: 0;
flex-wrap: wrap;
margin: 0 auto;
......@@ -49,7 +41,8 @@
margin-top: 10mm;
}
.pagedjs_first_page {
margin-left: var(--width);
margin-left: var(--pagedjs-width);
}
......@@ -69,4 +62,15 @@
margin: 0 auto;
margin-top: 10mm;
} */
/* uncomment for baseline
--------------------------------------------------- */
/* .pagedjs_page {
background: linear-gradient( white 0%, white calc(var(--pagedjs-baseline) - 1px), var(--pagedjs-baseline-color) calc(var(--pagedjs-baseline) - 1px), var(--pagedjs-baseline-color) var(--pagedjs-baseline)), transparent;
background-size: 100% var(--pagedjs-baseline);
background-repeat: repeat-y;
background-position-y: 0;
} */
}
\ No newline at end of file
......@@ -34,7 +34,7 @@ body {
vertical-align:super;
}
.pagedjs_callnote::before{ content: counter(pagedjsCallNote); }
.pagedjs_callnote::after{ content: counter(pagedjsCallNote); }
.pagedjs_note::before{ content: counter(pagedjsMarkerNote) ". ";}
......
.pagedjs_left_page .pagedjs_area-notes {
position: relative;
left: -35mm;
margin-right: -35mm;
/* box-shadow: 0 0 0 1px #e6e6e6; */
padding-right: 6mm;
padding-left: 6mm;
/* border: 1px solid black; */
box-sizing: content-box!important;
}
.pagedjs_right_page .pagedjs_area-notes {
width: 150px;
position: relative;
right: -35mm;
margin-left: -35mm;
padding-left: 12mm;
/* border: 1px solid black; */
box-sizing: content-box!important;
}
......@@ -9,28 +31,29 @@
}
/* *{ box-sizing: border-box; } */
@page {
size: 160mm 210mm;
margin: 15mm 15mm;
}
@page:left{
margin-top:15mm;
margin-bottom:15mm;
margin-left:50mm;
margin-right: 15mm;
margin-top: 83px;
margin-bottom: 86px;
margin-left: 50mm;
margin-right: 20mm;