Percollate is a command-line tool to turn web pages into beautifully formatted PDFs. See How it works.
Example spread from the generated PDF of a chapter in Dimensions of Colour; rendered here in black & white for a smaller image file size.
๐ก
percollate
needs Node.js version 8.6.0 or later, as it uses new(ish) JavaScript syntax. If you get SyntaxError: Unexpected token errors, check your Node version withnode --version
.
You can install percollate
globally:
# using npm
npm install -g percollate
# using yarn
yarn global add percollate
To keep the package up-to-date, you can run:
# using npm, upgrading is the same command as installing
npm install -g percollate
# yarn has a separate command
yarn global upgrade --latest percollate
๐ก Run
percollate --help
for a list of available commands. For a particular command,percollate <command> --help
lists all available options.
Command | What it does |
---|---|
percollate pdf |
Bundles one or more web pages into a PDF |
percollate epub |
Not implemented yet |
percollate html |
Not implemented yet |
The pdf
, epub
, and html
commands have these options:
Option | What it does |
---|---|
-o, --output |
The path of the resulting bundle; when ommited, we derive the output file name from the title of the web page. |
--individual |
Export each web page as an individual file. |
--template |
Path to a custom HTML template |
--style |
Path to a custom CSS |
--css |
Additional CSS styles you can pass from the command-line to override the default/custom stylesheet styles |
To transform a single web page to PDF:
percollate pdf --output some.pdf https://example.com
To bundle several web pages into a single PDF, specify them as separate arguments to the command:
percollate pdf --output some.pdf https://example.com/page1 https://example.com/page2
You can use common Unix commands and keep the list of URLs in a newline-delimited text file:
cat urls.txt | xargs percollate pdf --output some.pdf
To transform several web pages into individual PDF files at once, use the --individual
flag:
percollate pdf --individual https://example.com/page1 https://example.com/page2
The --css
option lets you pass a small snippet of CSS to percollate. Here are some common use-cases:
The default page size is A5 (portrait). You can use the --css
option to override it using any supported CSS size
:
percollate pdf --css "@page { size: A3 landscape }" http://example.com
Similarly, you can define:
- custom margins, e.g.
@page { margin: 0 }
- the base font size:
html { font-size: 10pt }
The idea with percollate is to make PDFs that can be printed without losing where the hyperlinks point to. However, for some link-heavy pages, the appended href
s can become bothersome. You can remove them using:
percollate pdf --css "a:after { display: none }" http://example.com
The --style
option lets you use your own CSS stylesheet instead of the default one. Here are some common use-cases for this option:
โ ๏ธ TODO add examples here
The --template
option lets you use a custom HTML template for the PDF. Here are some common use-cases:
Puppeteer can print some basic information about the page in the PDF. The following CSS class names are available for the header / footer, into which the appropriate content will be injected:
date
โ The formatted print datetitle
โ The document titleurl
โ document location (Note: this will print the path of the temporary html, not the original web page URL)pageNumber
โ the current page numbertotalPages
โ total pages in the document
๐ See the Chromium source code for details.
You place your header / footer template in a template
element in your HTML:
<template class='header-template'>
My header
</template>
<template class='footer-template'>
<div class='text center'>
<span class='pageNumber'></span>
</div>
</template>
See the default HTML for example usage.
You can add CSS styles to the header / footer with either the --css
option or a separate CSS stylesheet (the --style
option).
๐ก The header / footer template do not inherit their styles from the rest of the page (i.e. they are not part of the cascade), so you'll have to write the full CSS you want to apply to them.
An example from the default stylesheet:
.footer-template {
font-size: 10pt;
font-weight: bold;
}
- Fetch the page(s) using
got
- Enhance the DOM using
jsdom
- Pass the DOM through
mozilla/readability
to strip unnecessary elements - Apply the HTML template and the print stylesheet to the resulting HTML
- Use
puppeteer
to generate a PDF from the page
Percollate inherits the limitations of two of its main components, Readability and Puppeteer (headless Chrome).
The imperative approach Readability takes will not be perfect in each case, especially on HTML pages with atypical markup; you may occasionally notice that it either leaves in superfluous content, or that it strips out parts of the content. You can confirm the problem against Firefox's Reader View. In this case, consider filing an issue on mozilla/readability
.
Using a browser to generate the PDF is a double-edged sword. On the one hand, you get excellent support for web platform features. On the other hand, print CSS as defined by W3C specifications is only partially implemented, and it seems unlikely that support will be improved any time soon. However, even with modest print support, I think Chrome is the best (free) tool for the job.
On some Linux machines you'll need to install a few more Chrome dependencies before percollate
works correctly. (Thanks to @ptica for sorting it out)
The percollate pdf
command supports the --no-sandbox
Puppeteer flag, but make sure you're aware of the implications before disabling the sandbox.
Contributions of all kinds are welcome! See CONTRIBUTING.md for details.
Here are some other projects to check out if you're interested in building books using the browser: