...
 
Commits (44)
FROM node:12-stretch
FROM node:15-stretch
# Application parameters and variables
ENV NODE_ENV=development
......
......@@ -138,6 +138,7 @@ layoutNode(node)
renderNode(node, sourceNode, layout)
onOverflow(overflow, rendered, bounds)
onBreakToken(breakToken, overflow, rendered)
afterOverflowRemoved(removed, rendered)
```
## Setup
......
This diff is collapsed.
{
"name": "pagedjs",
"version": "0.1.42",
"version": "0.2.0",
"description": "Chunks up a document into paged media flows and applies print styles",
"author": "Fred Chasen",
"license": "MIT",
......@@ -10,33 +10,33 @@
"browser": "dist/paged.js",
"dependencies": {
"@babel/polyfill": "^7.10.1",
"@babel/runtime": "^7.10.2",
"@babel/runtime": "^7.14.0",
"clear-cut": "^2.0.2",
"css-tree": "1.0.0-alpha.39",
"css-tree": "^1.1.3",
"event-emitter": "^0.3.5"
},
"devDependencies": {
"@babel/cli": "^7.10.1",
"@babel/core": "^7.10.2",
"@babel/plugin-proposal-async-generator-functions": "^7.10.1",
"@babel/plugin-transform-runtime": "^7.10.1",
"@babel/preset-env": "^7.10.2",
"chalk": "^4.0.0",
"eslint": "^7.1.0",
"@babel/cli": "^7.14.3",
"@babel/core": "^7.14.3",
"@babel/plugin-proposal-async-generator-functions": "^7.14.2",
"@babel/plugin-transform-runtime": "^7.14.3",
"@babel/preset-env": "^7.14.2",
"@rollup/plugin-commonjs": "^19.0.0",
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^13.0.0",
"chalk": "^4.1.1",
"eslint": "^7.27.0",
"express": "^4.17.1",
"ghostscript4js": "^3.2.1",
"jest": "^25.2.3",
"jest-image-snapshot": "^3.0.1",
"puppeteer": "^3.3.0",
"jest": "^26.6.3",
"jest-image-snapshot": "^4.5.0",
"puppeteer": "^9.1.1",
"rimraf": "^3.0.2",
"rollup": "^2.13.1",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-json": "^4.0.0",
"rollup": "^2.38.3",
"rollup-plugin-license": "^2.1.0",
"rollup-plugin-livereload": "^1.3.0",
"rollup-plugin-livereload": "^2.0.0",
"rollup-plugin-node-builtins": "^2.1.2",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-serve": "^1.0.1"
"rollup-plugin-serve": "^1.1.0"
},
"scripts": {
"build": "rollup -c",
......
import resolve from "rollup-plugin-node-resolve";
import commonjs from "rollup-plugin-commonjs";
import json from "rollup-plugin-json";
import { nodeResolve } from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import json from "@rollup/plugin-json";
import license from "rollup-plugin-license";
import pkg from "./package.json";
const plugins = [
resolve(),
nodeResolve(),
commonjs({
include: "node_modules/**"
}),
......
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import json from 'rollup-plugin-json';
import { nodeResolve } from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import json from "@rollup/plugin-json";
import pkg from './package.json';
const plugins = [
resolve(),
nodeResolve(),
commonjs(),
json()
];
......
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import json from 'rollup-plugin-json';
import { nodeResolve } from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import json from "@rollup/plugin-json";
// import builtins from 'rollup-plugin-node-builtins';
// import globals from 'rollup-plugin-node-globals';
import pkg from './package.json';
// import pkg from './package.json';
import serve from 'rollup-plugin-serve'
import livereload from 'rollup-plugin-livereload'
const plugins = [
resolve(),
nodeResolve(),
commonjs(),
json(),
// globals(),
......
<!DOCTYPE html PUBLIC>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>break-inside-avoid-table-cell</title>
<script src="../../../../dist/paged.polyfill.js"></script>
<style>
@page {
size: 210mm 100mm;
border: 1px solid #cfc2c2;
}
table {
border-collapse: collapse;
}
table, th, td {
border: 1px solid black;
}
tr, td {
break-inside: avoid;
}
</style>
</head>
<body>
<table>
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
</tr>
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
<td>e</td>
</tr>
<tr>
<td>
<p>Sed sollicitudin ac neque at tincidunt. Proin gravida neque sit amet euismod imperdiet.</p>
<p>Nunc eu faucibus mi, nec tincidunt turpis. In mi lacus, sagittis et <em>iaculis</em> id, tincidunt vitae dui. Sed <strong>aliquet ornare ornare</strong>.</p>
<p>Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vivamus iaculis finibus nisl in pharetra.</p>
</td>
<td><p>Lorem ipsum dolor sit amet</p></td>
<td><p>Lorem ipsum dolor sit amet</p></td>
<td><p>Lorem ipsum dolor sit amet</p></td>
<td><p>Lorem ipsum dolor sit amet</p></td>
</tr>
</tbody>
</table>
</body>
</html>
const TIMEOUT = 10000; // Some book might take longer than this to renderer
describe("break-inside-avoid-table-cell", () => {
let page;
beforeAll(async () => {
page = await loadPage("breaks/break-inside/break-inside-avoid/break-inside-avoid-table-cell.html");
return page.rendered;
}, TIMEOUT);
afterAll(async () => {
if (!DEBUG) {
await page.close();
}
});
it("should render 2 pages", async () => {
let pages = await page.$$eval(".pagedjs_page", (r) => {
return r.length;
});
expect(pages).toEqual(2);
});
if (!DEBUG) {
it("should create a pdf", async () => {
let pdf = await page.pdf(PDF_SETTINGS);
expect(pdf).toMatchPDFSnapshot(1);
expect(pdf).toMatchPDFSnapshot(2);
});
}
});
<!DOCTYPE html>
<html lang="en">
<head>
<title>table-avoid-break-rowspan</title>
<meta charset="UTF-8">
<script src="../../../dist/paged.polyfill.js"></script>
<style>
@page {
size: A5;
margin: 1cm;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
tr {
break-inside: avoid;
}
.table td, .table th {
border: 1px solid #dbdbdb;
padding: .5em .75em;
vertical-align: top;
}
/* interface */
@media screen {
body {
background-color: whitesmoke;
}
.pagedjs_page {
margin-bottom: 20px;
flex: none;
box-shadow: 0 0 0 1px rgba(0, 0,0,0.2);
background-color: white;
}
}
</style>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<main>
<section>
<table class="table is-bordered">
<thead>
<tr>
<th>id</th>
<th>first_name</th>
<th>last_name</th>
<th colspan="2">email + score</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Magdalen</td>
<td>Holtaway</td>
<td>Flowdesk</td>
<td rowspan="3">37.67</td>
</tr>
<tr>
<td>2</td>
<td>Olenka</td>
<td>Tuckett</td>
<td>Subin</td>
</tr>
<tr>
<td>3</td>
<td>Towny</td>
<td>Calverley</td>
<td>Fintone</td>
</tr>
<tr>
<td>4</td>
<td>Maribeth</td>
<td>Caskie</td>
<td>Tresom</td>
<td rowspan="3">13.64</td>
</tr>
<tr>
<td>5</td>
<td>Roldan</td>
<td>Whitham</td>
<td>Flowdesk</td>
</tr>
<tr>
<td>6</td>
<td>Melody</td>
<td>Gentle</td>
<td>Asoka</td>
</tr>
<tr>
<td>7</td>
<td>Aida</td>
<td>Holtum</td>
<td>Bigtax</td>
<td rowspan="3">84.10</td>
</tr>
<tr>
<td>8</td>
<td>Angelia</td>
<td>O'Farrell</td>
<td>Bamity</td>
</tr>
<tr>
<td>9</td>
<td>Puff</td>
<td>Stennet</td>
<td>Aerified</td>
</tr>
<tr>
<td>10</td>
<td>Carmel</td>
<td>Ennion</td>
<td>Kanlam</td>
<td rowspan="3">59.44</td>
</tr>
<tr>
<td>11</td>
<td>Phyllida</td>
<td>Sarra</td>
<td>Toughjoyfax</td>
</tr>
<tr>
<td>12</td>
<td>Dulcy</td>
<td>Lamb-shine</td>
<td>Tresom</td>
</tr>
<tr>
<td>13</td>
<td>Piggy</td>
<td>Junifer</td>
<td>Bitchip</td>
<td rowspan="3">23.64</td>
</tr>
<tr>
<td>14</td>
<td>Adrianna</td>
<td>Millichap</td>
<td>It</td>
</tr>
<tr>
<td>15</td>
<td>Celeste</td>
<td>Milleton</td>
<td>Daltfresh</td>
</tr>
<tr>
<td>16</td>
<td>Ted</td>
<td>Slyde</td>
<td>Treeflex</td>
<td rowspan="3">74.64</td>
</tr>
<tr>
<td>17</td>
<td>Maurene</td>
<td>Sylvester</td>
<td>Tres-Zap</td>
</tr>
<tr>
<td>18</td>
<td>Monte</td>
<td>Tingley</td>
<td>Redhold</td>
</tr>
<tr>
<td>19</td>
<td>Louise</td>
<td>McMichell</td>
<td>Latlux</td>
<td rowspan="3">18.86</td>
</tr>
<tr>
<td>20</td>
<td>Turner</td>
<td>McQuirter</td>
<td>Keylex</td>
</tr>
<tr>
<td>21</td>
<td>Alvin</td>
<td>Emilien</td>
<td>Cardguard</td>
</tr>
<tr>
<td>22</td>
<td>Joanne</td>
<td>Obey</td>
<td>Regrant</td>
<td rowspan="3">25.32</td>
</tr>
<tr>
<td>23</td>
<td>Lorne</td>
<td>Lescop</td>
<td>Home Ing</td>
</tr>
<tr>
<td>24</td>
<td>Zara</td>
<td>Jillett</td>
<td>Matsoft</td>
</tr>
<tr>
<td>25</td>
<td>Delmore</td>
<td>Hellis</td>
<td>Regrant</td>
<td>42.33</td>
</tr>
</tbody>
</table>
</section>
</main>
</body>
</html>
const TIMEOUT = 10000;
describe("breaks-table-avoid-break-rowspan", () => {
let page;
beforeAll(async () => {
page = await loadPage("breaks/table/avoid-break-rowspan.html");
return page.rendered;
}, TIMEOUT);
afterAll(async () => {
if (!DEBUG) {
await page.close();
}
});
if (!DEBUG) {
it("should create a pdf", async () => {
let pdf = await page.pdf(PDF_SETTINGS);
expect(pdf).toMatchPDFSnapshot(1);
expect(pdf).toMatchPDFSnapshot(2);
});
}
});
This diff is collapsed.
const TIMEOUT = 10000;
describe("footnote-display", () => {
let page;
beforeAll(async () => {
page = await loadPage("notes/footnote-display/footnote-display.html");
return page.rendered;
}, TIMEOUT);
afterAll(async () => {
if (!DEBUG) {
await page.close();
}
});
it("should render 6 pages", async () => {
let pages = await page.$$eval(".pagedjs_page", (r) => {
return r.length;
});
expect(pages).toEqual(6);
});
if (!DEBUG) {
it("should create a pdf", async () => {
let pdf = await page.pdf(PDF_SETTINGS);
expect(pdf).toMatchPDFSnapshot(2);
expect(pdf).toMatchPDFSnapshot(3);
expect(pdf).toMatchPDFSnapshot(4);
});
}
}
);
This diff is collapsed.
const TIMEOUT = 10000;
describe("footnote-policy", () => {
let page;
beforeAll(async () => {
page = await loadPage("notes/footnote-policy/footnote-policy.html");
return page.rendered;
}, TIMEOUT);
afterAll(async () => {
if (!DEBUG) {
await page.close();
}
});
it("should render 6 pages", async () => {
let pages = await page.$$eval(".pagedjs_page", (r) => {
return r.length;
});
expect(pages).toEqual(6);
});
it("display auto footnotes should split text", async () => {
let textStart = await page.$eval("[data-page-number='1']", (r) => r.textContent);
expect(textStart).toContain("Characteres");
let textEnd = await page.$eval("[data-page-number='2']", (r) => r.textContent);
expect(textEnd).toContain("genus typos me vidisse");
});
it("display line footnotes should stay with the callout line", async () => {
let textStart = await page.$eval("[data-page-number='4']", (r) => r.textContent);
// line
expect(textStart).toContain("Strasburg");
// footnote
expect(textStart).toContain("Argentoratensi");
});
it("display block footnotes should stay with the callout paragraph block", async () => {
let textStart = await page.$eval("[data-page-number='6']", (r) => r.textContent);
// paragraph
expect(textStart).toContain("The legend");
// footnote
expect(textStart).toContain("Argentoratensi");
});
if (!DEBUG) {
it("should create a pdf", async () => {
let pdf = await page.pdf(PDF_SETTINGS);
expect(pdf).toMatchPDFSnapshot(2);
expect(pdf).toMatchPDFSnapshot(3);
expect(pdf).toMatchPDFSnapshot(4);
expect(pdf).toMatchPDFSnapshot(6);
});
}
}
);
const TIMEOUT = 10000;
describe("footnotes-counter-reset-page", () => {
let page;
beforeAll(async () => {
page = await loadPage("notes/footnotes-counter-reset-page/footnotes-counter-reset-page.html");
return page.rendered;
}, TIMEOUT);
afterAll(async () => {
if (!DEBUG) {
await page.close();
}
});
it("should render 6 pages", async () => {
let pages = await page.$$eval(".pagedjs_page", (r) => {
return r.length;
});
expect(pages).toEqual(6);
});
if (!DEBUG) {
it("should create a pdf", async () => {
let pdf = await page.pdf(PDF_SETTINGS);
expect(pdf).toMatchPDFSnapshot(1);
expect(pdf).toMatchPDFSnapshot(2);
expect(pdf).toMatchPDFSnapshot(6);
});
}
}
);
const TIMEOUT = 10000;
describe("footnotes-counter-reset", () => {
let page;
beforeAll(async () => {
page = await loadPage("notes/footnotes-counter-reset/footnotes-counter-reset.html");
return page.rendered;
}, TIMEOUT);
afterAll(async () => {
if (!DEBUG) {
await page.close();
}
});
it("should render 5 pages", async () => {
let pages = await page.$$eval(".pagedjs_page", (r) => {
return r.length;
});
expect(pages).toEqual(5);
});
if (!DEBUG) {
it("should create a pdf", async () => {
let pdf = await page.pdf(PDF_SETTINGS);
expect(pdf).toMatchPDFSnapshot(2);
expect(pdf).toMatchPDFSnapshot(4);
expect(pdf).toMatchPDFSnapshot(5);
});
}
}
);
<!DOCTYPE html PUBLIC>
<html lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<title>
Footnotes
</title>
<!-- Paged js-->
<script src="../../../dist/paged.polyfill.js"></script>
<style>
body {
widows: 1;
orphans: 1;
}
@media screen {
.pagedjs_page {
box-shadow: 0 0 0 1px #666;
}
.pagedjs_area {
box-shadow: 0 0 0 1px teal;
}
}
.footnote,
.footnote-ref::after {
font-family: Arial, Helvetica, sans-serif;
font-weight: bold;
font-size: 12px;
line-height: 14px;
margin-top: 16px;
}
@page {
size: 160mm 210mm;
margin-top: 83px;
margin-bottom: 86px;
margin-left: 35mm;
margin-right: 35mm;
@bottom-center {
content: counter(page);
}
@footnote {
background-color: #cfcfcf;
border-top: 2px dotted black;
}
}
p {
font-family: Georgia, 'Times New Roman', Times, serif;
margin-top: 0;
margin-bottom: 0;
text-align: justify;
font-size: 14px;
line-height: 16px;
}
.afnanch {
display: none;
}
hr {
border: none;
}
.pfirst {
padding-top: 50mm;
}
.footnote {
color: red;
float: footnote;
}
::footnote-marker {
color: blue !important;
font-weight: bold;
font-size: 30px;
content: "hello";
}
::footnote-call {
color: orange;
font-weight: bold;
font-size: 30px !important;
content: "hello";
}
</style>
</head>
<body>
<p>No one has done more to clear the way for a free
investigation of all questions relating to the origin
of printing than Dr. Van der Linde, in his able essay,
<em>The Haarlem Legend</em>,
<span class="footnote" data-note="01" id="note-01"><em>The Haarlem Legend of the Invention of Printing by
Lourens Janszoon Coster, critically examined.</em> From the Dutch by J.
H. Hessels, with an introduction and classified list of the Costerian
Incunabula. London, 1871. 8vo.</span> which, while disposing ruthlessly of
the fiction of Coster’s invention, lays down the important
principle, too often neglected by writers on the subject,
that the essence of Typography consists in the mobility of
the types, and that, therefore, it is not a development of
the long practised art of printing from fixed blocks, but
an entirely distinct invention.</p>
<p>The principle is so important, and Dr. Van der Linde’s words are so
emphatic, that we make no apology for quoting them:―</p>
</section>
</body>
</html>
\ No newline at end of file
const TIMEOUT = 10000;
describe("footnotes counter content", () => {
let page;
beforeAll(async () => {
page = await loadPage("notes/footnotes-counter/footnotes-counter.html");
return page.rendered;
}, TIMEOUT);
afterAll(async () => {
if (!DEBUG) {
await page.close();
}
});
it("should render 1 page", async () => {
let pages = await page.$$eval(".pagedjs_page", (r) => {
return r.length;
});
expect(pages).toEqual(1);
});
if (!DEBUG) {
it("should create a pdf", async () => {
let pdf = await page.pdf(PDF_SETTINGS);
expect(pdf).toMatchPDFSnapshot(1);
});
}
}
);