Repository files navigation

Paged.js logo - pagination in the browser

Paged.js - Paged Media Tools

Paged.js is an open-source library to display paginated content in the browser and to generate print books using web technology.

It contains a set of handlers for CSS transformations and fragmented layout which polyfill the Paged Media and Generated Content CSS modules, along with hooks to create new handlers for custom properties.

The currently supported properties can be found on the pagedjs website.

A quick overview to getting started with Paged Media CSS and Paged.js is available on pagedjs.org/documentation.

NPM Module

$ npm install pagedjs
import{Previewer}from'pagedjs';letpaged=newPreviewer();letflow=paged.preview(DOMContent,["path/to/css/file.css"],document.body).then((flow)=>{console.log("Rendered",flow.total,"pages.");})

Polyfill

Add the the paged.polyfill.js script to replace all @page css and render the html page with the Paged Media styles applied:

<scriptsrc="https://unpkg.com/pagedjs/dist/paged.polyfill.js"></script>

Try the polyfill with Aurorae.

By default the polyfill will run automatically as soon as the DOM is ready. However, you can add an async before function or return a Promise to delay the polyfill starting.

<script>window.PagedConfig={before: ()=>{returnnewPromise((resolve,reject)=>{setTimeout(()=>{resolve()},1000);})},after: (flow)=>{console.log("after",flow)},};</script>

Otherwise you can disable auto running the previewer and call window.PagedPolyfill.preview(); whenever you want to start.

<script>window.PagedConfig={auto: false,after: (flow)=>{console.log("after",flow)},};setTimeout(()=>{window.PagedPolyfill.preview();},1000);</script>

Chunker

Chunks up a document into paged media flows and applies print classes.

Examples:

Polisher

Converts @page css to classes, and applies counters and content.

Examples:

CLI

Command line interface to render out PDFs of HTML files using Puppeteer: https://github.com/pagedjs/pagedjs-cli.

Module

Modules are groups of handlers for that apply the layout and styles of a CSS module, such as Generated Content.

New handlers can be registered from import { registerHandlers } from 'pagedjs' or by calling Paged.registerHandlers on an html page.

<scriptsrc="https://unpkg.com/pagedjs/dist/paged.polyfill.js"></script><script>classMyHandlerextendsPaged.Handler{constructor(chunker,polisher,caller){super(chunker,polisher,caller);}afterPageLayout(pageFragment,page){console.log(pageFragment);}}Paged.registerHandlers(MyHandler);</script>

Handlers have methods that correspond to the hooks for the parsing, layout and rendering of the Chunker and Polisher. Returning a promise or async function from a method in a handler will complete that task before continuing with the other registered methods for that hook.

// PreviewerbeforePreview(content,renderTo)afterPreview(pages)// ChunkerbeforeParsed(content)filter(content)afterParsed(parsed)beforePageLayout(page)onPageLayout(pageWrapper,breakToken,layout);afterPageLayout(pageElement,page,breakToken)finalizePage(pageElement,page,breakToken)afterRendered(pages)// PolisherbeforeTreeParse(text,sheet)beforeTreeWalk(ast)afterTreeWalk(ast,sheet)onUrl(urlNode)onAtPage(atPageNode)onRule(ruleNode)onDeclaration(declarationNode,ruleNode)onContent(contentNode,declarationNode,ruleNode)// LayoutlayoutNode(node)renderNode(node,sourceNode,layout)onOverflow(overflow,rendered,bounds)onBreakToken(breakToken,overflow,rendered)afterOverflowRemoved(removed,rendered)beforeRenderResult(breakToken,pageWrapper)

How Pagedjs processes content

Chunker.flow()
└── Chunker.render() -> Looping through all pages
└──── Chunker.layout*() -> Handles overflowing pages, adding new ones
└────── Page.layout() -> Creates new Layout and waits for new Breaktoken
└──────── Layout.renderTo() -> Iterates through nodes
└────────── Layout.findBreakToken() -> Tries to find overflow/breaktoken

Setup

Install dependencies

$ npm install

Development

Run the local dev-server with livereload and autocompile on http://localhost:9090/

$ npm start

Deployment

Build the dist output

$ npm run build

Compile the lib output

$ npm run compile

Generate legacy builds with polyfills included

$ npm run legacy

Testing

Testing for Paged.js uses Jest but is split into Tests and Specs.

Tests

Unit tests for Chunker and Polisher methods are run in node using JSDOM.

npm test

Specs

Specs run a html file in Chrome (using puppeteer) to test against CSS specifications.

They can also output a pdf and compare pages (one at a time) in that PDF with samples PDFs (saved as images).

The PDF comparison tests depend on the ghostscript and the ghostscript4js package.

It is recomend to run these in the Docker container below via:

npm run docker-specs

However if you'd like to run the specs outside of Docker, you'll need to install a local version of Ghostscript for your system according to https://www.npmjs.com/package/ghostscript4js#prerequisites

For Mac you can install it with

brew install ghostscript

For Debian you can install it with

sudo apt-get install ghostscript
sudo apt-get install libgs-dev

Now you can install the ghostscript4js library. For Linux you can optionally pass the location ghostscript was installed to in GS4JS_HOME.

GS4JS_HOME="/usr/lib/$(gcc -dumpmachine)" npm install ghostscript4js

To test the pdf output of specs, you'll need to build the library locally.

npm run build

Then run the jest tests in puppeteer.

npm run specs

To debug the results of a test in a browser you can add NODE_ENV=debug

NODE_ENV=debug npm run specs

To update the stored pdf images you can run

npm run specs -- --updateSnapshot

Docker

A pagedmedia/pagedjs docker image contains all the dependencies needed to run the pagedjs development server, as well as the pdf comparison tests.

To build the image run

docker build -t pagedmedia/pagedjs .

By default the container will run the development server with npm start

docker run -it -p 9090:9090 pagedmedia/pagedjs

The tests and specs can be run within the container by passing a seccomp file for Chrome and running npm test

docker run -it --security-opt 'seccomp=seccomp.json' pagedmedia/pagedjs npm test&& npm run specs

Licence

MIT License (MIT), which you can read here

About

Display paginated content in the browser and generate print books using web technology

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Paged.js logo - pagination in the browser

Paged.js - Paged Media Tools

Paged.js is an open-source library to display paginated content in the browser and to generate print books using web technology.

It contains a set of handlers for CSS transformations and fragmented layout which polyfill the Paged Media and Generated Content CSS modules, along with hooks to create new handlers for custom properties.

The currently supported properties can be found on the pagedjs website.

A quick overview to getting started with Paged Media CSS and Paged.js is available on pagedjs.org/documentation.

NPM Module

$ npm install pagedjs
import{Previewer}from'pagedjs';letpaged=newPreviewer();letflow=paged.preview(DOMContent,["path/to/css/file.css"],document.body).then((flow)=>{console.log("Rendered",flow.total,"pages.");})

Polyfill

Add the the paged.polyfill.js script to replace all @page css and render the html page with the Paged Media styles applied:

<scriptsrc="https://unpkg.com/pagedjs/dist/paged.polyfill.js"></script>

Try the polyfill with Aurorae.

By default the polyfill will run automatically as soon as the DOM is ready. However, you can add an async before function or return a Promise to delay the polyfill starting.

<script>window.PagedConfig={before: ()=>{returnnewPromise((resolve,reject)=>{setTimeout(()=>{resolve()},1000);})},after: (flow)=>{console.log("after",flow)},};</script>

Otherwise you can disable auto running the previewer and call window.PagedPolyfill.preview(); whenever you want to start.

<script>window.PagedConfig={auto: false,after: (flow)=>{console.log("after",flow)},};setTimeout(()=>{window.PagedPolyfill.preview();},1000);</script>

Chunker

Chunks up a document into paged media flows and applies print classes.

Examples:

Polisher

Converts @page css to classes, and applies counters and content.

Examples:

CLI

Command line interface to render out PDFs of HTML files using Puppeteer: https://github.com/pagedjs/pagedjs-cli.

Module

Modules are groups of handlers for that apply the layout and styles of a CSS module, such as Generated Content.

New handlers can be registered from import { registerHandlers } from 'pagedjs' or by calling Paged.registerHandlers on an html page.

<scriptsrc="https://unpkg.com/pagedjs/dist/paged.polyfill.js"></script><script>classMyHandlerextendsPaged.Handler{constructor(chunker,polisher,caller){super(chunker,polisher,caller);}afterPageLayout(pageFragment,page){console.log(pageFragment);}}Paged.registerHandlers(MyHandler);</script>

Handlers have methods that correspond to the hooks for the parsing, layout and rendering of the Chunker and Polisher. Returning a promise or async function from a method in a handler will complete that task before continuing with the other registered methods for that hook.

// PreviewerbeforePreview(content,renderTo)afterPreview(pages)// ChunkerbeforeParsed(content)filter(content)afterParsed(parsed)beforePageLayout(page)onPageLayout(pageWrapper,breakToken,layout);afterPageLayout(pageElement,page,breakToken)finalizePage(pageElement,page,breakToken)afterRendered(pages)// PolisherbeforeTreeParse(text,sheet)beforeTreeWalk(ast)afterTreeWalk(ast,sheet)onUrl(urlNode)onAtPage(atPageNode)onRule(ruleNode)onDeclaration(declarationNode,ruleNode)onContent(contentNode,declarationNode,ruleNode)// LayoutlayoutNode(node)renderNode(node,sourceNode,layout)onOverflow(overflow,rendered,bounds)onBreakToken(breakToken,overflow,rendered)afterOverflowRemoved(removed,rendered)beforeRenderResult(breakToken,pageWrapper)

How Pagedjs processes content

Chunker.flow()
└── Chunker.render() -> Looping through all pages
└──── Chunker.layout*() -> Handles overflowing pages, adding new ones
└────── Page.layout() -> Creates new Layout and waits for new Breaktoken
└──────── Layout.renderTo() -> Iterates through nodes
└────────── Layout.findBreakToken() -> Tries to find overflow/breaktoken

Setup

Install dependencies

$ npm install

Development

Run the local dev-server with livereload and autocompile on http://localhost:9090/

$ npm start

Deployment

Build the dist output

$ npm run build

Compile the lib output

$ npm run compile

Generate legacy builds with polyfills included

$ npm run legacy

Testing

Testing for Paged.js uses Jest but is split into Tests and Specs.

Tests

Unit tests for Chunker and Polisher methods are run in node using JSDOM.

npm test

Specs

Specs run a html file in Chrome (using puppeteer) to test against CSS specifications.

They can also output a pdf and compare pages (one at a time) in that PDF with samples PDFs (saved as images).

The PDF comparison tests depend on the ghostscript and the ghostscript4js package.

It is recomend to run these in the Docker container below via:

npm run docker-specs

However if you'd like to run the specs outside of Docker, you'll need to install a local version of Ghostscript for your system according to https://www.npmjs.com/package/ghostscript4js#prerequisites

For Mac you can install it with

brew install ghostscript

For Debian you can install it with

sudo apt-get install ghostscript
sudo apt-get install libgs-dev

Now you can install the ghostscript4js library. For Linux you can optionally pass the location ghostscript was installed to in GS4JS_HOME.

GS4JS_HOME="/usr/lib/$(gcc -dumpmachine)" npm install ghostscript4js

To test the pdf output of specs, you'll need to build the library locally.

npm run build

Then run the jest tests in puppeteer.

npm run specs

To debug the results of a test in a browser you can add NODE_ENV=debug

NODE_ENV=debug npm run specs

To update the stored pdf images you can run

npm run specs -- --updateSnapshot

Docker

A pagedmedia/pagedjs docker image contains all the dependencies needed to run the pagedjs development server, as well as the pdf comparison tests.

To build the image run

docker build -t pagedmedia/pagedjs .

By default the container will run the development server with npm start

docker run -it -p 9090:9090 pagedmedia/pagedjs

The tests and specs can be run within the container by passing a seccomp file for Chrome and running npm test

docker run -it --security-opt 'seccomp=seccomp.json' pagedmedia/pagedjs npm test&& npm run specs

Licence

MIT License (MIT), which you can read here

About

Display paginated content in the browser and generate print books using web technology

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Paged.js logo - pagination in the browser

Paged.js - Paged Media Tools

Paged.js is an open-source library to display paginated content in the browser and to generate print books using web technology.

It contains a set of handlers for CSS transformations and fragmented layout which polyfill the Paged Media and Generated Content CSS modules, along with hooks to create new handlers for custom properties.

The currently supported properties can be found on the pagedjs website.

A quick overview to getting started with Paged Media CSS and Paged.js is available on pagedjs.org/documentation.

NPM Module

$ npm install pagedjs
import{Previewer}from'pagedjs';letpaged=newPreviewer();letflow=paged.preview(DOMContent,["path/to/css/file.css"],document.body).then((flow)=>{console.log("Rendered",flow.total,"pages.");})

Polyfill

Add the the paged.polyfill.js script to replace all @page css and render the html page with the Paged Media styles applied:

<scriptsrc="https://unpkg.com/pagedjs/dist/paged.polyfill.js"></script>

Try the polyfill with Aurorae.

By default the polyfill will run automatically as soon as the DOM is ready. However, you can add an async before function or return a Promise to delay the polyfill starting.

<script>window.PagedConfig={before: ()=>{returnnewPromise((resolve,reject)=>{setTimeout(()=>{resolve()},1000);})},after: (flow)=>{console.log("after",flow)},};</script>

Otherwise you can disable auto running the previewer and call window.PagedPolyfill.preview(); whenever you want to start.

<script>window.PagedConfig={auto: false,after: (flow)=>{console.log("after",flow)},};setTimeout(()=>{window.PagedPolyfill.preview();},1000);</script>

Chunker

Chunks up a document into paged media flows and applies print classes.

Examples:

Polisher

Converts @page css to classes, and applies counters and content.

Examples:

CLI

Command line interface to render out PDFs of HTML files using Puppeteer: https://github.com/pagedjs/pagedjs-cli.

Module

Modules are groups of handlers for that apply the layout and styles of a CSS module, such as Generated Content.

New handlers can be registered from import { registerHandlers } from 'pagedjs' or by calling Paged.registerHandlers on an html page.

<scriptsrc="https://unpkg.com/pagedjs/dist/paged.polyfill.js"></script><script>classMyHandlerextendsPaged.Handler{constructor(chunker,polisher,caller){super(chunker,polisher,caller);}afterPageLayout(pageFragment,page){console.log(pageFragment);}}Paged.registerHandlers(MyHandler);</script>

Handlers have methods that correspond to the hooks for the parsing, layout and rendering of the Chunker and Polisher. Returning a promise or async function from a method in a handler will complete that task before continuing with the other registered methods for that hook.

// PreviewerbeforePreview(content,renderTo)afterPreview(pages)// ChunkerbeforeParsed(content)filter(content)afterParsed(parsed)beforePageLayout(page)onPageLayout(pageWrapper,breakToken,layout);afterPageLayout(pageElement,page,breakToken)finalizePage(pageElement,page,breakToken)afterRendered(pages)// PolisherbeforeTreeParse(text,sheet)beforeTreeWalk(ast)afterTreeWalk(ast,sheet)onUrl(urlNode)onAtPage(atPageNode)onRule(ruleNode)onDeclaration(declarationNode,ruleNode)onContent(contentNode,declarationNode,ruleNode)// LayoutlayoutNode(node)renderNode(node,sourceNode,layout)onOverflow(overflow,rendered,bounds)onBreakToken(breakToken,overflow,rendered)afterOverflowRemoved(removed,rendered)beforeRenderResult(breakToken,pageWrapper)

How Pagedjs processes content

Chunker.flow()
└── Chunker.render() -> Looping through all pages
└──── Chunker.layout*() -> Handles overflowing pages, adding new ones
└────── Page.layout() -> Creates new Layout and waits for new Breaktoken
└──────── Layout.renderTo() -> Iterates through nodes
└────────── Layout.findBreakToken() -> Tries to find overflow/breaktoken

Setup

Install dependencies

$ npm install

Development

Run the local dev-server with livereload and autocompile on http://localhost:9090/

$ npm start

Deployment

Build the dist output

$ npm run build

Compile the lib output

$ npm run compile

Generate legacy builds with polyfills included

$ npm run legacy

Testing

Testing for Paged.js uses Jest but is split into Tests and Specs.

Tests

Unit tests for Chunker and Polisher methods are run in node using JSDOM.

npm test

Specs

Specs run a html file in Chrome (using puppeteer) to test against CSS specifications.

They can also output a pdf and compare pages (one at a time) in that PDF with samples PDFs (saved as images).

The PDF comparison tests depend on the ghostscript and the ghostscript4js package.

It is recomend to run these in the Docker container below via:

npm run docker-specs

However if you'd like to run the specs outside of Docker, you'll need to install a local version of Ghostscript for your system according to https://www.npmjs.com/package/ghostscript4js#prerequisites

For Mac you can install it with

brew install ghostscript

For Debian you can install it with

sudo apt-get install ghostscript
sudo apt-get install libgs-dev

Now you can install the ghostscript4js library. For Linux you can optionally pass the location ghostscript was installed to in GS4JS_HOME.

GS4JS_HOME="/usr/lib/$(gcc -dumpmachine)" npm install ghostscript4js

To test the pdf output of specs, you'll need to build the library locally.

npm run build

Then run the jest tests in puppeteer.

npm run specs

To debug the results of a test in a browser you can add NODE_ENV=debug

NODE_ENV=debug npm run specs

To update the stored pdf images you can run

npm run specs -- --updateSnapshot

Docker

A pagedmedia/pagedjs docker image contains all the dependencies needed to run the pagedjs development server, as well as the pdf comparison tests.

To build the image run

docker build -t pagedmedia/pagedjs .

By default the container will run the development server with npm start

docker run -it -p 9090:9090 pagedmedia/pagedjs

The tests and specs can be run within the container by passing a seccomp file for Chrome and running npm test

docker run -it --security-opt 'seccomp=seccomp.json' pagedmedia/pagedjs npm test&& npm run specs

Licence

MIT License (MIT), which you can read here

About

Display paginated content in the browser and generate print books using web technology

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Paged.js logo - pagination in the browser

Paged.js - Paged Media Tools

Paged.js is an open-source library to display paginated content in the browser and to generate print books using web technology.

It contains a set of handlers for CSS transformations and fragmented layout which polyfill the Paged Media and Generated Content CSS modules, along with hooks to create new handlers for custom properties.

The currently supported properties can be found on the pagedjs website.

A quick overview to getting started with Paged Media CSS and Paged.js is available on pagedjs.org/documentation.

NPM Module

$ npm install pagedjs
import{Previewer}from'pagedjs';letpaged=newPreviewer();letflow=paged.preview(DOMContent,["path/to/css/file.css"],document.body).then((flow)=>{console.log("Rendered",flow.total,"pages.");})

Polyfill

Add the the paged.polyfill.js script to replace all @page css and render the html page with the Paged Media styles applied:

<scriptsrc="https://unpkg.com/pagedjs/dist/paged.polyfill.js"></script>

Try the polyfill with Aurorae.

By default the polyfill will run automatically as soon as the DOM is ready. However, you can add an async before function or return a Promise to delay the polyfill starting.

<script>window.PagedConfig={before: ()=>{returnnewPromise((resolve,reject)=>{setTimeout(()=>{resolve()},1000);})},after: (flow)=>{console.log("after",flow)},};</script>

Otherwise you can disable auto running the previewer and call window.PagedPolyfill.preview(); whenever you want to start.

<script>window.PagedConfig={auto: false,after: (flow)=>{console.log("after",flow)},};setTimeout(()=>{window.PagedPolyfill.preview();},1000);</script>

Chunker

Chunks up a document into paged media flows and applies print classes.

Examples:

Polisher

Converts @page css to classes, and applies counters and content.

Examples:

CLI

Command line interface to render out PDFs of HTML files using Puppeteer: https://github.com/pagedjs/pagedjs-cli.

Module

Modules are groups of handlers for that apply the layout and styles of a CSS module, such as Generated Content.

New handlers can be registered from import { registerHandlers } from 'pagedjs' or by calling Paged.registerHandlers on an html page.

<scriptsrc="https://unpkg.com/pagedjs/dist/paged.polyfill.js"></script><script>classMyHandlerextendsPaged.Handler{constructor(chunker,polisher,caller){super(chunker,polisher,caller);}afterPageLayout(pageFragment,page){console.log(pageFragment);}}Paged.registerHandlers(MyHandler);</script>

Handlers have methods that correspond to the hooks for the parsing, layout and rendering of the Chunker and Polisher. Returning a promise or async function from a method in a handler will complete that task before continuing with the other registered methods for that hook.

// PreviewerbeforePreview(content,renderTo)afterPreview(pages)// ChunkerbeforeParsed(content)filter(content)afterParsed(parsed)beforePageLayout(page)onPageLayout(pageWrapper,breakToken,layout);afterPageLayout(pageElement,page,breakToken)finalizePage(pageElement,page,breakToken)afterRendered(pages)// PolisherbeforeTreeParse(text,sheet)beforeTreeWalk(ast)afterTreeWalk(ast,sheet)onUrl(urlNode)onAtPage(atPageNode)onRule(ruleNode)onDeclaration(declarationNode,ruleNode)onContent(contentNode,declarationNode,ruleNode)// LayoutlayoutNode(node)renderNode(node,sourceNode,layout)onOverflow(overflow,rendered,bounds)onBreakToken(breakToken,overflow,rendered)afterOverflowRemoved(removed,rendered)beforeRenderResult(breakToken,pageWrapper)

How Pagedjs processes content

Chunker.flow()
└── Chunker.render() -> Looping through all pages
└──── Chunker.layout*() -> Handles overflowing pages, adding new ones
└────── Page.layout() -> Creates new Layout and waits for new Breaktoken
└──────── Layout.renderTo() -> Iterates through nodes
└────────── Layout.findBreakToken() -> Tries to find overflow/breaktoken

Setup

Install dependencies

$ npm install

Development

Run the local dev-server with livereload and autocompile on http://localhost:9090/

$ npm start

Deployment

Build the dist output

$ npm run build

Compile the lib output

$ npm run compile

Generate legacy builds with polyfills included

$ npm run legacy

Testing

Testing for Paged.js uses Jest but is split into Tests and Specs.

Tests

Unit tests for Chunker and Polisher methods are run in node using JSDOM.

npm test

Specs

Specs run a html file in Chrome (using puppeteer) to test against CSS specifications.

They can also output a pdf and compare pages (one at a time) in that PDF with samples PDFs (saved as images).

The PDF comparison tests depend on the ghostscript and the ghostscript4js package.

It is recomend to run these in the Docker container below via:

npm run docker-specs

However if you'd like to run the specs outside of Docker, you'll need to install a local version of Ghostscript for your system according to https://www.npmjs.com/package/ghostscript4js#prerequisites

For Mac you can install it with

brew install ghostscript

For Debian you can install it with

sudo apt-get install ghostscript
sudo apt-get install libgs-dev

Now you can install the ghostscript4js library. For Linux you can optionally pass the location ghostscript was installed to in GS4JS_HOME.

GS4JS_HOME="/usr/lib/$(gcc -dumpmachine)" npm install ghostscript4js

To test the pdf output of specs, you'll need to build the library locally.

npm run build

Then run the jest tests in puppeteer.

npm run specs

To debug the results of a test in a browser you can add NODE_ENV=debug

NODE_ENV=debug npm run specs

To update the stored pdf images you can run

npm run specs -- --updateSnapshot

Docker

A pagedmedia/pagedjs docker image contains all the dependencies needed to run the pagedjs development server, as well as the pdf comparison tests.

To build the image run

docker build -t pagedmedia/pagedjs .

By default the container will run the development server with npm start

docker run -it -p 9090:9090 pagedmedia/pagedjs

The tests and specs can be run within the container by passing a seccomp file for Chrome and running npm test

docker run -it --security-opt 'seccomp=seccomp.json' pagedmedia/pagedjs npm test&& npm run specs

Licence

MIT License (MIT), which you can read here

About

Display paginated content in the browser and generate print books using web technology

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Paged.js logo - pagination in the browser

Paged.js - Paged Media Tools

Paged.js is an open-source library to display paginated content in the browser and to generate print books using web technology.

It contains a set of handlers for CSS transformations and fragmented layout which polyfill the Paged Media and Generated Content CSS modules, along with hooks to create new handlers for custom properties.

The currently supported properties can be found on the pagedjs website.

A quick overview to getting started with Paged Media CSS and Paged.js is available on pagedjs.org/documentation.

NPM Module

$ npm install pagedjs
import{Previewer}from'pagedjs';letpaged=newPreviewer();letflow=paged.preview(DOMContent,["path/to/css/file.css"],document.body).then((flow)=>{console.log("Rendered",flow.total,"pages.");})

Polyfill

Add the the paged.polyfill.js script to replace all @page css and render the html page with the Paged Media styles applied:

<scriptsrc="https://unpkg.com/pagedjs/dist/paged.polyfill.js"></script>

Try the polyfill with Aurorae.

By default the polyfill will run automatically as soon as the DOM is ready. However, you can add an async before function or return a Promise to delay the polyfill starting.

<script>window.PagedConfig={before: ()=>{returnnewPromise((resolve,reject)=>{setTimeout(()=>{resolve()},1000);})},after: (flow)=>{console.log("after",flow)},};</script>

Otherwise you can disable auto running the previewer and call window.PagedPolyfill.preview(); whenever you want to start.

<script>window.PagedConfig={auto: false,after: (flow)=>{console.log("after",flow)},};setTimeout(()=>{window.PagedPolyfill.preview();},1000);</script>

Chunker

Chunks up a document into paged media flows and applies print classes.

Examples:

Polisher

Converts @page css to classes, and applies counters and content.

Examples:

CLI

Command line interface to render out PDFs of HTML files using Puppeteer: https://github.com/pagedjs/pagedjs-cli.

Module

Modules are groups of handlers for that apply the layout and styles of a CSS module, such as Generated Content.

New handlers can be registered from import { registerHandlers } from 'pagedjs' or by calling Paged.registerHandlers on an html page.

<scriptsrc="https://unpkg.com/pagedjs/dist/paged.polyfill.js"></script><script>classMyHandlerextendsPaged.Handler{constructor(chunker,polisher,caller){super(chunker,polisher,caller);}afterPageLayout(pageFragment,page){console.log(pageFragment);}}Paged.registerHandlers(MyHandler);</script>

Handlers have methods that correspond to the hooks for the parsing, layout and rendering of the Chunker and Polisher. Returning a promise or async function from a method in a handler will complete that task before continuing with the other registered methods for that hook.

// PreviewerbeforePreview(content,renderTo)afterPreview(pages)// ChunkerbeforeParsed(content)filter(content)afterParsed(parsed)beforePageLayout(page)onPageLayout(pageWrapper,breakToken,layout);afterPageLayout(pageElement,page,breakToken)finalizePage(pageElement,page,breakToken)afterRendered(pages)// PolisherbeforeTreeParse(text,sheet)beforeTreeWalk(ast)afterTreeWalk(ast,sheet)onUrl(urlNode)onAtPage(atPageNode)onRule(ruleNode)onDeclaration(declarationNode,ruleNode)onContent(contentNode,declarationNode,ruleNode)// LayoutlayoutNode(node)renderNode(node,sourceNode,layout)onOverflow(overflow,rendered,bounds)onBreakToken(breakToken,overflow,rendered)afterOverflowRemoved(removed,rendered)beforeRenderResult(breakToken,pageWrapper)

How Pagedjs processes content

Chunker.flow()
└── Chunker.render() -> Looping through all pages
└──── Chunker.layout*() -> Handles overflowing pages, adding new ones
└────── Page.layout() -> Creates new Layout and waits for new Breaktoken
└──────── Layout.renderTo() -> Iterates through nodes
└────────── Layout.findBreakToken() -> Tries to find overflow/breaktoken

Setup

Install dependencies

$ npm install

Development

Run the local dev-server with livereload and autocompile on http://localhost:9090/

$ npm start

Deployment

Build the dist output

$ npm run build

Compile the lib output

$ npm run compile

Generate legacy builds with polyfills included

$ npm run legacy

Testing

Testing for Paged.js uses Jest but is split into Tests and Specs.

Tests

Unit tests for Chunker and Polisher methods are run in node using JSDOM.

npm test

Specs

Specs run a html file in Chrome (using puppeteer) to test against CSS specifications.

They can also output a pdf and compare pages (one at a time) in that PDF with samples PDFs (saved as images).

The PDF comparison tests depend on the ghostscript and the ghostscript4js package.

It is recomend to run these in the Docker container below via:

npm run docker-specs

However if you'd like to run the specs outside of Docker, you'll need to install a local version of Ghostscript for your system according to https://www.npmjs.com/package/ghostscript4js#prerequisites

For Mac you can install it with

brew install ghostscript

For Debian you can install it with

sudo apt-get install ghostscript
sudo apt-get install libgs-dev

Now you can install the ghostscript4js library. For Linux you can optionally pass the location ghostscript was installed to in GS4JS_HOME.

GS4JS_HOME="/usr/lib/$(gcc -dumpmachine)" npm install ghostscript4js

To test the pdf output of specs, you'll need to build the library locally.

npm run build

Then run the jest tests in puppeteer.

npm run specs

To debug the results of a test in a browser you can add NODE_ENV=debug

NODE_ENV=debug npm run specs

To update the stored pdf images you can run

npm run specs -- --updateSnapshot

Docker

A pagedmedia/pagedjs docker image contains all the dependencies needed to run the pagedjs development server, as well as the pdf comparison tests.

To build the image run

docker build -t pagedmedia/pagedjs .

By default the container will run the development server with npm start

docker run -it -p 9090:9090 pagedmedia/pagedjs

The tests and specs can be run within the container by passing a seccomp file for Chrome and running npm test

docker run -it --security-opt 'seccomp=seccomp.json' pagedmedia/pagedjs npm test&& npm run specs

Licence

MIT License (MIT), which you can read here

About

Display paginated content in the browser and generate print books using web technology

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Paged.js logo - pagination in the browser

Paged.js - Paged Media Tools

Paged.js is an open-source library to display paginated content in the browser and to generate print books using web technology.

It contains a set of handlers for CSS transformations and fragmented layout which polyfill the Paged Media and Generated Content CSS modules, along with hooks to create new handlers for custom properties.

The currently supported properties can be found on the pagedjs website.

A quick overview to getting started with Paged Media CSS and Paged.js is available on pagedjs.org/documentation.

NPM Module

$ npm install pagedjs
import{Previewer}from'pagedjs';letpaged=newPreviewer();letflow=paged.preview(DOMContent,["path/to/css/file.css"],document.body).then((flow)=>{console.log("Rendered",flow.total,"pages.");})

Polyfill

Add the the paged.polyfill.js script to replace all @page css and render the html page with the Paged Media styles applied:

<scriptsrc="https://unpkg.com/pagedjs/dist/paged.polyfill.js"></script>

Try the polyfill with Aurorae.

By default the polyfill will run automatically as soon as the DOM is ready. However, you can add an async before function or return a Promise to delay the polyfill starting.

<script>window.PagedConfig={before: ()=>{returnnewPromise((resolve,reject)=>{setTimeout(()=>{resolve()},1000);})},after: (flow)=>{console.log("after",flow)},};</script>

Otherwise you can disable auto running the previewer and call window.PagedPolyfill.preview(); whenever you want to start.

<script>window.PagedConfig={auto: false,after: (flow)=>{console.log("after",flow)},};setTimeout(()=>{window.PagedPolyfill.preview();},1000);</script>

Chunker

Chunks up a document into paged media flows and applies print classes.

Examples:

Polisher

Converts @page css to classes, and applies counters and content.

Examples:

CLI

Command line interface to render out PDFs of HTML files using Puppeteer: https://github.com/pagedjs/pagedjs-cli.

Module

Modules are groups of handlers for that apply the layout and styles of a CSS module, such as Generated Content.

New handlers can be registered from import { registerHandlers } from 'pagedjs' or by calling Paged.registerHandlers on an html page.

<scriptsrc="https://unpkg.com/pagedjs/dist/paged.polyfill.js"></script><script>classMyHandlerextendsPaged.Handler{constructor(chunker,polisher,caller){super(chunker,polisher,caller);}afterPageLayout(pageFragment,page){console.log(pageFragment);}}Paged.registerHandlers(MyHandler);</script>

Handlers have methods that correspond to the hooks for the parsing, layout and rendering of the Chunker and Polisher. Returning a promise or async function from a method in a handler will complete that task before continuing with the other registered methods for that hook.

// PreviewerbeforePreview(content,renderTo)afterPreview(pages)// ChunkerbeforeParsed(content)filter(content)afterParsed(parsed)beforePageLayout(page)onPageLayout(pageWrapper,breakToken,layout);afterPageLayout(pageElement,page,breakToken)finalizePage(pageElement,page,breakToken)afterRendered(pages)// PolisherbeforeTreeParse(text,sheet)beforeTreeWalk(ast)afterTreeWalk(ast,sheet)onUrl(urlNode)onAtPage(atPageNode)onRule(ruleNode)onDeclaration(declarationNode,ruleNode)onContent(contentNode,declarationNode,ruleNode)// LayoutlayoutNode(node)renderNode(node,sourceNode,layout)onOverflow(overflow,rendered,bounds)onBreakToken(breakToken,overflow,rendered)afterOverflowRemoved(removed,rendered)beforeRenderResult(breakToken,pageWrapper)

How Pagedjs processes content

Chunker.flow()
└── Chunker.render() -> Looping through all pages
└──── Chunker.layout*() -> Handles overflowing pages, adding new ones
└────── Page.layout() -> Creates new Layout and waits for new Breaktoken
└──────── Layout.renderTo() -> Iterates through nodes
└────────── Layout.findBreakToken() -> Tries to find overflow/breaktoken

Setup

Install dependencies

$ npm install

Development

Run the local dev-server with livereload and autocompile on http://localhost:9090/

$ npm start

Deployment

Build the dist output

$ npm run build

Compile the lib output

$ npm run compile

Generate legacy builds with polyfills included

$ npm run legacy

Testing

Testing for Paged.js uses Jest but is split into Tests and Specs.

Tests

Unit tests for Chunker and Polisher methods are run in node using JSDOM.

npm test

Specs

Specs run a html file in Chrome (using puppeteer) to test against CSS specifications.

They can also output a pdf and compare pages (one at a time) in that PDF with samples PDFs (saved as images).

The PDF comparison tests depend on the ghostscript and the ghostscript4js package.

It is recomend to run these in the Docker container below via:

npm run docker-specs

However if you'd like to run the specs outside of Docker, you'll need to install a local version of Ghostscript for your system according to https://www.npmjs.com/package/ghostscript4js#prerequisites

For Mac you can install it with

brew install ghostscript

For Debian you can install it with

sudo apt-get install ghostscript
sudo apt-get install libgs-dev

Now you can install the ghostscript4js library. For Linux you can optionally pass the location ghostscript was installed to in GS4JS_HOME.

GS4JS_HOME="/usr/lib/$(gcc -dumpmachine)" npm install ghostscript4js

To test the pdf output of specs, you'll need to build the library locally.

npm run build

Then run the jest tests in puppeteer.

npm run specs

To debug the results of a test in a browser you can add NODE_ENV=debug

NODE_ENV=debug npm run specs

To update the stored pdf images you can run

npm run specs -- --updateSnapshot

Docker

A pagedmedia/pagedjs docker image contains all the dependencies needed to run the pagedjs development server, as well as the pdf comparison tests.

To build the image run

docker build -t pagedmedia/pagedjs .

By default the container will run the development server with npm start

docker run -it -p 9090:9090 pagedmedia/pagedjs

The tests and specs can be run within the container by passing a seccomp file for Chrome and running npm test

docker run -it --security-opt 'seccomp=seccomp.json' pagedmedia/pagedjs npm test&& npm run specs

Licence

MIT License (MIT), which you can read here

About

Display paginated content in the browser and generate print books using web technology

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Paged.js logo - pagination in the browser

Paged.js - Paged Media Tools

Paged.js is an open-source library to display paginated content in the browser and to generate print books using web technology.

It contains a set of handlers for CSS transformations and fragmented layout which polyfill the Paged Media and Generated Content CSS modules, along with hooks to create new handlers for custom properties.

The currently supported properties can be found on the pagedjs website.

A quick overview to getting started with Paged Media CSS and Paged.js is available on pagedjs.org/documentation.

NPM Module

$ npm install pagedjs
import{Previewer}from'pagedjs';letpaged=newPreviewer();letflow=paged.preview(DOMContent,["path/to/css/file.css"],document.body).then((flow)=>{console.log("Rendered",flow.total,"pages.");})

Polyfill

Add the the paged.polyfill.js script to replace all @page css and render the html page with the Paged Media styles applied:

<scriptsrc="https://unpkg.com/pagedjs/dist/paged.polyfill.js"></script>

Try the polyfill with Aurorae.

By default the polyfill will run automatically as soon as the DOM is ready. However, you can add an async before function or return a Promise to delay the polyfill starting.

<script>window.PagedConfig={before: ()=>{returnnewPromise((resolve,reject)=>{setTimeout(()=>{resolve()},1000);})},after: (flow)=>{console.log("after",flow)},};</script>

Otherwise you can disable auto running the previewer and call window.PagedPolyfill.preview(); whenever you want to start.

<script>window.PagedConfig={auto: false,after: (flow)=>{console.log("after",flow)},};setTimeout(()=>{window.PagedPolyfill.preview();},1000);</script>

Chunker

Chunks up a document into paged media flows and applies print classes.

Examples:

Polisher

Converts @page css to classes, and applies counters and content.

Examples:

CLI

Command line interface to render out PDFs of HTML files using Puppeteer: https://github.com/pagedjs/pagedjs-cli.

Module

Modules are groups of handlers for that apply the layout and styles of a CSS module, such as Generated Content.

New handlers can be registered from import { registerHandlers } from 'pagedjs' or by calling Paged.registerHandlers on an html page.

<scriptsrc="https://unpkg.com/pagedjs/dist/paged.polyfill.js"></script><script>classMyHandlerextendsPaged.Handler{constructor(chunker,polisher,caller){super(chunker,polisher,caller);}afterPageLayout(pageFragment,page){console.log(pageFragment);}}Paged.registerHandlers(MyHandler);</script>

Handlers have methods that correspond to the hooks for the parsing, layout and rendering of the Chunker and Polisher. Returning a promise or async function from a method in a handler will complete that task before continuing with the other registered methods for that hook.

// PreviewerbeforePreview(content,renderTo)afterPreview(pages)// ChunkerbeforeParsed(content)filter(content)afterParsed(parsed)beforePageLayout(page)onPageLayout(pageWrapper,breakToken,layout);afterPageLayout(pageElement,page,breakToken)finalizePage(pageElement,page,breakToken)afterRendered(pages)// PolisherbeforeTreeParse(text,sheet)beforeTreeWalk(ast)afterTreeWalk(ast,sheet)onUrl(urlNode)onAtPage(atPageNode)onRule(ruleNode)onDeclaration(declarationNode,ruleNode)onContent(contentNode,declarationNode,ruleNode)// LayoutlayoutNode(node)renderNode(node,sourceNode,layout)onOverflow(overflow,rendered,bounds)onBreakToken(breakToken,overflow,rendered)afterOverflowRemoved(removed,rendered)beforeRenderResult(breakToken,pageWrapper)

How Pagedjs processes content

Chunker.flow()
└── Chunker.render() -> Looping through all pages
└──── Chunker.layout*() -> Handles overflowing pages, adding new ones
└────── Page.layout() -> Creates new Layout and waits for new Breaktoken
└──────── Layout.renderTo() -> Iterates through nodes
└────────── Layout.findBreakToken() -> Tries to find overflow/breaktoken

Setup

Install dependencies

$ npm install

Development

Run the local dev-server with livereload and autocompile on http://localhost:9090/

$ npm start

Deployment

Build the dist output

$ npm run build

Compile the lib output

$ npm run compile

Generate legacy builds with polyfills included

$ npm run legacy

Testing

Testing for Paged.js uses Jest but is split into Tests and Specs.

Tests

Unit tests for Chunker and Polisher methods are run in node using JSDOM.

npm test

Specs

Specs run a html file in Chrome (using puppeteer) to test against CSS specifications.

They can also output a pdf and compare pages (one at a time) in that PDF with samples PDFs (saved as images).

The PDF comparison tests depend on the ghostscript and the ghostscript4js package.

It is recomend to run these in the Docker container below via:

npm run docker-specs

However if you'd like to run the specs outside of Docker, you'll need to install a local version of Ghostscript for your system according to https://www.npmjs.com/package/ghostscript4js#prerequisites

For Mac you can install it with

brew install ghostscript

For Debian you can install it with

sudo apt-get install ghostscript
sudo apt-get install libgs-dev

Now you can install the ghostscript4js library. For Linux you can optionally pass the location ghostscript was installed to in GS4JS_HOME.

GS4JS_HOME="/usr/lib/$(gcc -dumpmachine)" npm install ghostscript4js

To test the pdf output of specs, you'll need to build the library locally.

npm run build

Then run the jest tests in puppeteer.

npm run specs

To debug the results of a test in a browser you can add NODE_ENV=debug

NODE_ENV=debug npm run specs

To update the stored pdf images you can run

npm run specs -- --updateSnapshot

Docker

A pagedmedia/pagedjs docker image contains all the dependencies needed to run the pagedjs development server, as well as the pdf comparison tests.

To build the image run

docker build -t pagedmedia/pagedjs .

By default the container will run the development server with npm start

docker run -it -p 9090:9090 pagedmedia/pagedjs

The tests and specs can be run within the container by passing a seccomp file for Chrome and running npm test

docker run -it --security-opt 'seccomp=seccomp.json' pagedmedia/pagedjs npm test&& npm run specs

Licence

MIT License (MIT), which you can read here

About

Display paginated content in the browser and generate print books using web technology

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Paged.js logo - pagination in the browser

Paged.js - Paged Media Tools

Paged.js is an open-source library to display paginated content in the browser and to generate print books using web technology.

It contains a set of handlers for CSS transformations and fragmented layout which polyfill the Paged Media and Generated Content CSS modules, along with hooks to create new handlers for custom properties.

The currently supported properties can be found on the pagedjs website.

A quick overview to getting started with Paged Media CSS and Paged.js is available on pagedjs.org/documentation.

NPM Module

$ npm install pagedjs
import{Previewer}from'pagedjs';letpaged=newPreviewer();letflow=paged.preview(DOMContent,["path/to/css/file.css"],document.body).then((flow)=>{console.log("Rendered",flow.total,"pages.");})

Polyfill

Add the the paged.polyfill.js script to replace all @page css and render the html page with the Paged Media styles applied:

<scriptsrc="https://unpkg.com/pagedjs/dist/paged.polyfill.js"></script>

Try the polyfill with Aurorae.

By default the polyfill will run automatically as soon as the DOM is ready. However, you can add an async before function or return a Promise to delay the polyfill starting.

<script>window.PagedConfig={before: ()=>{returnnewPromise((resolve,reject)=>{setTimeout(()=>{resolve()},1000);})},after: (flow)=>{console.log("after",flow)},};</script>

Otherwise you can disable auto running the previewer and call window.PagedPolyfill.preview(); whenever you want to start.

<script>window.PagedConfig={auto: false,after: (flow)=>{console.log("after",flow)},};setTimeout(()=>{window.PagedPolyfill.preview();},1000);</script>

Chunker

Chunks up a document into paged media flows and applies print classes.

Examples:

Polisher

Converts @page css to classes, and applies counters and content.

Examples:

CLI

Command line interface to render out PDFs of HTML files using Puppeteer: https://github.com/pagedjs/pagedjs-cli.

Module

Modules are groups of handlers for that apply the layout and styles of a CSS module, such as Generated Content.

New handlers can be registered from import { registerHandlers } from 'pagedjs' or by calling Paged.registerHandlers on an html page.

<scriptsrc="https://unpkg.com/pagedjs/dist/paged.polyfill.js"></script><script>classMyHandlerextendsPaged.Handler{constructor(chunker,polisher,caller){super(chunker,polisher,caller);}afterPageLayout(pageFragment,page){console.log(pageFragment);}}Paged.registerHandlers(MyHandler);</script>

Handlers have methods that correspond to the hooks for the parsing, layout and rendering of the Chunker and Polisher. Returning a promise or async function from a method in a handler will complete that task before continuing with the other registered methods for that hook.

// PreviewerbeforePreview(content,renderTo)afterPreview(pages)// ChunkerbeforeParsed(content)filter(content)afterParsed(parsed)beforePageLayout(page)onPageLayout(pageWrapper,breakToken,layout);afterPageLayout(pageElement,page,breakToken)finalizePage(pageElement,page,breakToken)afterRendered(pages)// PolisherbeforeTreeParse(text,sheet)beforeTreeWalk(ast)afterTreeWalk(ast,sheet)onUrl(urlNode)onAtPage(atPageNode)onRule(ruleNode)onDeclaration(declarationNode,ruleNode)onContent(contentNode,declarationNode,ruleNode)// LayoutlayoutNode(node)renderNode(node,sourceNode,layout)onOverflow(overflow,rendered,bounds)onBreakToken(breakToken,overflow,rendered)afterOverflowRemoved(removed,rendered)beforeRenderResult(breakToken,pageWrapper)

How Pagedjs processes content

Chunker.flow()
└── Chunker.render() -> Looping through all pages
└──── Chunker.layout*() -> Handles overflowing pages, adding new ones
└────── Page.layout() -> Creates new Layout and waits for new Breaktoken
└──────── Layout.renderTo() -> Iterates through nodes
└────────── Layout.findBreakToken() -> Tries to find overflow/breaktoken

Setup

Install dependencies

$ npm install

Development

Run the local dev-server with livereload and autocompile on http://localhost:9090/

$ npm start

Deployment

Build the dist output

$ npm run build

Compile the lib output

$ npm run compile

Generate legacy builds with polyfills included

$ npm run legacy

Testing

Testing for Paged.js uses Jest but is split into Tests and Specs.

Tests

Unit tests for Chunker and Polisher methods are run in node using JSDOM.

npm test

Specs

Specs run a html file in Chrome (using puppeteer) to test against CSS specifications.

They can also output a pdf and compare pages (one at a time) in that PDF with samples PDFs (saved as images).

The PDF comparison tests depend on the ghostscript and the ghostscript4js package.

It is recomend to run these in the Docker container below via:

npm run docker-specs

However if you'd like to run the specs outside of Docker, you'll need to install a local version of Ghostscript for your system according to https://www.npmjs.com/package/ghostscript4js#prerequisites

For Mac you can install it with

brew install ghostscript

For Debian you can install it with

sudo apt-get install ghostscript
sudo apt-get install libgs-dev

Now you can install the ghostscript4js library. For Linux you can optionally pass the location ghostscript was installed to in GS4JS_HOME.

GS4JS_HOME="/usr/lib/$(gcc -dumpmachine)" npm install ghostscript4js

To test the pdf output of specs, you'll need to build the library locally.

npm run build

Then run the jest tests in puppeteer.

npm run specs

To debug the results of a test in a browser you can add NODE_ENV=debug

NODE_ENV=debug npm run specs

To update the stored pdf images you can run

npm run specs -- --updateSnapshot

Docker

A pagedmedia/pagedjs docker image contains all the dependencies needed to run the pagedjs development server, as well as the pdf comparison tests.

To build the image run

docker build -t pagedmedia/pagedjs .

By default the container will run the development server with npm start

docker run -it -p 9090:9090 pagedmedia/pagedjs

The tests and specs can be run within the container by passing a seccomp file for Chrome and running npm test

docker run -it --security-opt 'seccomp=seccomp.json' pagedmedia/pagedjs npm test&& npm run specs

Licence

MIT License (MIT), which you can read here

About

Display paginated content in the browser and generate print books using web technology

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages