├── .eslintrc.json ├── .git-hooks ├── post-commit └── pre-commit ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── config.yml │ └── feature_request.md ├── dimensions-of-colour.png ├── percollate.svg └── workflows │ └── nodejs.yml ├── .gitignore ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── cli.js ├── index.js ├── package-lock.json ├── package.json ├── src ├── cli-opts.js ├── constants │ └── markdown.js ├── enhancements.js ├── exif.js ├── get-style-attribute-value.js ├── headings.js ├── hyphenate.js ├── inline-images.js ├── remote-resources.js ├── replace-element-type.js └── util │ ├── epub-date.js │ ├── fetch-base64.js │ ├── file-mimetype.js │ ├── get-css-page-format.js │ ├── human-date.js │ ├── language.js │ ├── output-path.js │ ├── page-size.js │ ├── promises.js │ ├── slurp.js │ └── url-origin.js ├── templates ├── cover.html ├── default.css ├── default.html └── epub │ ├── META-INF │ ├── com.apple.ibooks.display-options.xml │ └── container.xml │ └── OEBPS │ ├── content.opf │ ├── content.xhtml │ ├── nav.xhtml │ └── toc.ncx └── test ├── cli-opts.test.js ├── encoding.test.js ├── enhancements.test.js ├── epub-date.test.js ├── exif.test.js ├── fixtures └── server.js ├── headings.test.js ├── hyphenate.test.js ├── index.test.js ├── integration.test.js ├── language.test.js ├── output-path.test.js ├── page-size.test.js ├── promises.test.js ├── readability.test.js ├── slurp.test.js └── url-origin.test.js /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2021": true, 5 | "node": true 6 | }, 7 | "extends": ["eslint:recommended", "plugin:import/recommended"], 8 | "parserOptions": { 9 | "ecmaVersion": 12, 10 | "sourceType": "module" 11 | }, 12 | "rules": { 13 | "array-callback-return": 2, 14 | "consistent-return": 2, 15 | "constructor-super": 1, 16 | "no-cond-assign": 2, 17 | "no-console": [1, { "allow": ["log", "error"] }], 18 | "no-const-assign": 1, 19 | "no-constant-condition": 2, 20 | "no-dupe-keys": 2, 21 | "no-else-return": 2, 22 | "no-extra-bind": 2, 23 | "no-magic-numbers": 0, 24 | "no-param-reassign": 2, 25 | "no-redeclare": 2, 26 | "no-return-assign": 2, 27 | "no-sequences": 2, 28 | "no-this-before-super": 1, 29 | "no-undef": 2, 30 | "no-unreachable": 2, 31 | "no-unused-expressions": 1, 32 | "no-unused-vars": [ 33 | 1, 34 | { "args": "after-used", "ignoreRestSiblings": true } 35 | ], 36 | "no-use-before-define": [2, { "functions": false }], 37 | "no-useless-call": 2, 38 | "use-isnan": 2, 39 | "valid-typeof": 2, 40 | "eqeqeq": 2, 41 | "yoda": 1, 42 | "no-mixed-spaces-and-tabs": 0 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /.git-hooks/post-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | npm run lint -------------------------------------------------------------------------------- /.git-hooks/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | npx pretty-quick --staged -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Help make percollate better 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### Environment 11 | 12 | * Operating System: 13 | * `node --version`: 14 | * `npm --version`: 15 | * `yarn --version`, if using Yarn: 16 | * `percollate --version`: 17 | 18 | ### Description 19 | 20 | _Please describe the issue._ 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | contact_links: 3 | - name: Start a discussion 4 | url: https://github.com/danburzo/percollate/discussions/ 5 | about: For questions and answers, please use the Discussions area. 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### Feature description 11 | 12 | _Describe the feature you're proposing._ 13 | 14 | ### Existing workarounds 15 | 16 | _Is there any way to obtain the desired effect with the current functionality?_ 17 | -------------------------------------------------------------------------------- /.github/dimensions-of-colour.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danburzo/percollate/b65f6748d2c5e1f2e2380584e8ad85e354e7763f/.github/dimensions-of-colour.png -------------------------------------------------------------------------------- /.github/percollate.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 36 | 37 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | name: Node.js CI 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | strategy: 10 | matrix: 11 | node-version: [14.x, 16.x, 18.x] 12 | 13 | steps: 14 | - uses: actions/checkout@v2 15 | - name: Use Node.js ${{ matrix.node-version }} 16 | uses: actions/setup-node@v1 17 | with: 18 | node-version: ${{ matrix.node-version }} 19 | - run: npm install 20 | - run: npm run lint 21 | - run: npm run test 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | 63 | .DS_Store 64 | .idea/ 65 | .project 66 | .settings 67 | 68 | # Test files 69 | /*.pdf 70 | /*.epub 71 | /*.html 72 | /test/percollate-output* 73 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Percollate Changelog 2 | 3 | Please see [the Releases tab on GitHub](https://github.com/danburzo/percollate/releases) for the changelog. 4 | 5 | --- 6 | 7 | _Here are the release notes for older versions, kept here for historical purposes._ 8 | 9 | ### 0.6.4 10 | 11 | - Use the value of the `--output` option as a prefix for file names when converting multiple files with the `--individual` flag. 12 | - Switched `fetch` implementation from `got` to the smaller `node-fetch` package. 13 | 14 | ### 0.6.2 15 | 16 | Fix `-V / --version` argument parsing. 17 | 18 | ### 0.6.1 19 | 20 | Fix template resolution issue introduced in 0.6.0. 21 | 22 | ### 0.6.0 23 | 24 | - Upgraded to latest version, ~~and devendorized,~~ [@mozilla/readability](https://github.com/mozilla/readability); 25 | - Enhancement: remove `loading=lazy` attributes; 26 | - Bugfix: identify AMP version when the `rel` attribute has multiple, space-separated values. 27 | - Bugfix: add underlines to links in Apple Books 28 | 29 | ### 0.5.0 30 | 31 | You can now generate (basic) EPUB and HTML with the `epub` and `html` commands, respectively. 32 | 33 | Added the ability to read HTML content from `stdin` with the `-` operand; you can pass the original URL with the `-u` / `--url` option. 34 | 35 | ### 0.4.0 36 | 37 | Enhancement: expand `
` elements. 38 | 39 | Chore: upgrade dependencies to their latest version. 40 | 41 | ### 0.3.0 42 | 43 | Prefer the AMP version of an article, if available. [Details here](https://github.com/danburzo/percollate/pull/70). 44 | 45 | Support for lazy-loaded images. ([#71](https://github.com/danburzo/percollate/issues/71)) 46 | 47 | Increased Puppeteer navigation timeout to 2 minutes. ([#80](https://github.com/danburzo/percollate/issues/80), thanks [@butu5](https://github.com/butu5)!). Also added a `--debug` flag to print more information about the process. 48 | 49 | Fixed URL encoding before fetching it. ([#83](https://github.com/danburzo/percollate/pull/83), thanks [@ncsing](https://github.com/ncsing)!) 50 | 51 | Generate a Table of Contents page ([#81](https://github.com/danburzo/percollate/pull/81), thanks [@guybedo](https://github.com/guybedo)!) when using the `--toc` option. 52 | 53 | ### 0.2.14 54 | 55 | Fixes bug with the URL class not being globally available in Node < 10. ([#64](https://github.com/danburzo/percollate/pull/64), thanks [@tanmayrajani](https://github.com/tanmayrajani)!). 56 | 57 | Adds usage examples to the CLI help output. ([#55](https://github.com/danburzo/percollate/pull/55), thanks [@opw0011](https://github.com/opw0011)!) 58 | 59 | ### 0.2.13 60 | 61 | Adds `percollate/${version}` user-agent to prevent some HTTP 405 errors ([#59](https://github.com/danburzo/percollate/issues/59)). 62 | 63 | We now perform relative to absolute URI conversion inside Percollate itself rather than rely on Readability ([#33](https://github.com/danburzo/percollate/issues/33), thank you [@ramadis](https://github.com/ramadis), [@tanmayrajani](https://github.com/tanmayrajani) for the help!). This includes the `srcset` attribute, which caused images to be broken on some sites ([#58](https://github.com/danburzo/percollate/issues/58)). 64 | 65 | Made `imagesAtFullSize` ignore Wikipedia image file links ([#42](https://github.com/danburzo/percollate/issues/42)). 66 | 67 | Percollate now emulates a high-resolution display, which in some cases helps get the best quality image available. 68 | 69 | Adds new enhancement, `singleImgToFigure`, that transforms single images into `
` elements, using the image's `alt` attribute as `
`. 70 | 71 | Preserve `anchor` class on hyperlinks, hide them when they're part of a heading. (A common pattern for Markdown to HTML tools). 72 | 73 | Align `ol` and `ul` elements to match paragraph indentation. 74 | 75 | ### 0.2.12 76 | 77 | - Fixes indentation of images wrapped in `

` tags ([#48](https://github.com/danburzo/percollate/issues/48)) 78 | - Adds basic styles for tables ([#50](https://github.com/danburzo/percollate/issues/50)), figures, definition terms, et cetera. 79 | - Adds a better font stack, using CSS variables 80 | - Better CLI feedback with [ora](https://github.com/sindresorhus/ora) (thanks [@emersonlaurentino](https://github.com/emersonlaurentino)!) 81 | 82 | ### 0.2.11 83 | 84 | - Bump required Node version to 8.6.0 ([#45](https://github.com/danburzo/percollate/issues/45)) 85 | - Show help when no arguments provided or command chosen ([#36](https://github.com/danburzo/percollate/issues/36), thanks [@tanmayrajani](https://github.com/tanmayrajani)!) 86 | - Don't append the HREF for in-page anchors or anchors which have the full URL as their text content ([#31](https://github.com/danburzo/percollate/issues/31)) 87 | 88 | ### 0.2.10 89 | 90 | - Started separating the CLI from the Node library, working towards a programmatic API (Thank you, [@phenax](https://github.com/phenax)!) 91 | - Adds `--individual` flag to export many pages as individual PDFs ([#38](https://github.com/danburzo/percollate/issues/38)) 92 | 93 | ### 0.2.9 94 | 95 | - Adds a default output file path when the `--output` option is omitted ([#37](https://github.com/danburzo/percollate/issues/37)) 96 | 97 | ### 0.2.8 98 | 99 | - Added support for inline CSS styles via the `--css` option ([#27](https://github.com/danburzo/percollate/issues/27)) 100 | 101 | ### 0.2.7 102 | 103 | - Added the ability to run `percollate` with the `--no-sandbox` Puppeteer flag 104 | 105 | ### 0.2.5 106 | 107 | - More print styles to handle blockquotes and `aria-hidden` elements; re: [#19](https://github.com/danburzo/percollate/issues/19) 108 | 109 | ### 0.2.2 110 | 111 | - Adds article header, including byline, where it exists, and the source URL ([#18](https://github.com/danburzo/percollate/issues/18)) 112 | 113 | ### 0.2.1 114 | 115 | - Some Wikipedia-specific enhancements: remove `edit` links next to headings. 116 | - Added more print styles to the default stylesheet. 117 | - Fixes relative links ([#12](https://github.com/danburzo/percollate/issues/12)) 118 | 119 | ### 0.2.0 120 | 121 | - Deprecates short names for some options ([#16](https://github.com/danburzo/percollate/issues/16)) 122 | 123 | ### 0.1.9 124 | 125 | - Fixes template path resolution ([#17](https://github.com/danburzo/percollate/issues/17)) when percollate is installed globally 126 | 127 | ### 0.1.8 128 | 129 | - Adds support for a custom page header/footer via the HTML template and CSS stylesheet 130 | 131 | ### 0.1.6 132 | 133 | - Uses Puppeteer's `preferCSSPageSize` to make the page size and margins configurable from the CSS 134 | 135 | ### 0.1.5 136 | 137 | - Only replace single image SRCs with their parent's HREF if the latter matches an image file 138 | 139 | ### 0.1.3 140 | 141 | - Introduces separate commands. For now, the `pdf` command is implemented. 142 | - Adds the ability to specify a custom HTML template / custom stylesheet. 143 | 144 | ### 0.1.2 145 | 146 | - Run `percollate` as a CLI tool that takes one or more URLs and bundles them into a single PDF file. 147 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | - Using welcoming and inclusive language 12 | - Being respectful of differing viewpoints and experiences 13 | - Gracefully accepting constructive criticism 14 | - Focusing on what is best for the community 15 | - Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | - The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | - Trolling, insulting/derogatory comments, and personal or political attacks 21 | - Public or private harassment 22 | - Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | - Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at dan@danburzo.ro. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Contributions to this repository are welcome. 4 | 5 | I appreciate feedback of any kind via [GitHub issues](https://github.com/danburzo/percollate/issues): 6 | 7 | - bug reports 8 | - feature suggestions 9 | - examples of web pages where `percollate` could do a better job 10 | 11 | You can contribute to the code via [pull requests](https://github.com/danburzo/percollate/pulls). For small, straightforward fixes, you can create a PR directly. For more sophisticated changes, please open an issue beforehand to make sure we're on the same page. 12 | 13 | ## Common tasks 14 | 15 | ## Set up the project locally 16 | 17 | Clone the repository to your local computer: 18 | 19 | ```bash 20 | git clone git@github.com:danburzo/percollate.git 21 | cd percollate 22 | ``` 23 | 24 | Then install the necessary dependencies: 25 | 26 | ```bash 27 | npm install 28 | ``` 29 | 30 | You can then run the CLI by using `./cli.js` instead of `percollate`: 31 | 32 | ```bash 33 | ./cli.js pdf --output some.pdf http://example.com 34 | ``` 35 | 36 | > 💡 You may need to add _execution permissions_ to the file using `chmod +x ./cli.js` 37 | 38 | ## Check that an EPUB is valid 39 | 40 | We use the excellent [epubcheck](https://github.com/w3c/epubcheck) Java tool to validate EPUBs generated by percollate. 41 | 42 | ```bash 43 | npx epubcheck ./book.epub 44 | ``` 45 | 46 | ## Debug the temporary HTML 47 | 48 | If the generated PDF doesn't look like you'd expect, use the `--debug` flag to save to the disk the temporary HTML file that `percollate` generates. Open the HTML in your browser to inspect the markup and styles. 49 | 50 | ## Run the code checks 51 | 52 | Code is formatted automatically by [Prettier](https://prettier.io) on each commit. Additionally: 53 | 54 | * `npm run lint` runs eslint on the codebase to enforce more aspects of coding style; 55 | * `npm run test` runs the automated tests to ensure things work as expected. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Dan Burzo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | percollate 2 | 3 | npm version 4 | 5 | Percollate is a command-line tool that turns web pages into beautifully formatted PDF, EPUB, HTML or Markdown files. 6 | 7 |

8 | Sample Output 9 |
Sample spread from the generated PDF of a chapter in Dimensions of Colour; rendered here in black & white for a smaller image file size.
10 |
11 | 12 | - [Installation](#installation) 13 | - [Usage](#usage) 14 | - [Available commands](#available-commands) 15 | - [Available options](#available-options) 16 | - [Recipes](#recipes) 17 | - [Basic bundling](#basic-bundling) 18 | - [The `--css` option](#the---css-option) 19 | - [The `--style` option](#the---style-option) 20 | - [The `--template` option](#the---template-option) 21 | - [How it works](#how-it-works) 22 | - [Updating](#updating) 23 | - [Limitations](#limitations) 24 | - [Troubleshooting](#troubleshooting) 25 | - [Contributing](#contributing) 26 | - [See also](#see-also) 27 | 28 | ## Installation 29 | 30 | `percollate` is a Node.js command-line tool which you can install globally from npm: 31 | 32 | ```bash 33 | npm install -g percollate 34 | ``` 35 | 36 | Percollate and its dependencies **require Node.js 14.17.0** or later. 37 | 38 | #### Community-maintained packages 39 | 40 | There's [a packaged version](https://aur.archlinux.org/packages/nodejs-percollate/) available on [Arch User Repository](https://wiki.archlinux.org/index.php/Arch_User_Repository), which you can install using your local [AUR helper](https://wiki.archlinux.org/index.php/AUR_helpers) (`yay`, `pacaur`, or similar): 41 | 42 | ``` 43 | yay -S nodejs-percollate 44 | ``` 45 | 46 | Some Docker images are available in this [tracking issue](https://github.com/danburzo/percollate/issues/95). 47 | 48 | ## Usage 49 | 50 | > Run `percollate --help` for a list of available commands and options. 51 | 52 | Percollate is invoked on one or more operands (usually URLs): 53 | 54 | ```bash 55 | percollate [options] url [url]... 56 | ``` 57 | 58 | The following commands are available: 59 | 60 | - `percollate pdf` produces a PDF file; 61 | - `percollate epub` produces an EPUB file; 62 | - `percollate html` produces a HTML file. 63 | - `percollate md` produces a Markdown file. 64 | 65 | The operands can be URLs, paths to local files, or the `-` character which stands for `stdin` (the standard inputs). 66 | 67 | ### Available options 68 | 69 | Unless otherwise stated, these options apply to all three commands. 70 | 71 | #### `-o, --output` 72 | 73 | Specify the path of the resulting bundle relative to the current folder. 74 | 75 | ```bash 76 | percollate pdf https://example.com -o my-example.pdf 77 | ``` 78 | 79 | #### `-u, --url` 80 | 81 | Using the `-` operand you can read the HTML content from `stdin`, as fetched by a separate command, such as `curl`. In this sort of setup, `percollate` does not know the URL from which the content has been fetched, and relative paths on images, anchors, et cetera won't resolve correctly. 82 | 83 | Use the `--url` option to supply the source's original URL. 84 | 85 | ```bash 86 | curl https://example.com | percollate pdf - --url=https://example.com 87 | ``` 88 | 89 | #### `-w, --wait` 90 | 91 | By default, percollate processes URLs in parallel. Use the `--wait` option to process them sequentially instead, with a pause between items. The delay is specified in seconds, and can be zero. 92 | 93 | ```bash 94 | percollate epub --wait=1 url1 url2 url3 95 | ``` 96 | 97 | #### `--individual` 98 | 99 | By default, percollate bundles all web pages in a single file. Use the `--individual` flag to export each source to a separate file. 100 | 101 | ```bash 102 | percollate pdf --individual http://example.com/page1 http://example.com/page2 103 | ``` 104 | 105 | #### `--template` 106 | 107 | Path to a custom HTML template. Applies to `pdf`, `html`, and `md`. 108 | 109 | #### `--style` 110 | 111 | Path to a custom CSS stylesheet, relative to the current folder. 112 | 113 | #### `--css` 114 | 115 | Additional CSS styles you can pass from the command-line to override styles specified by the default/custom stylesheet. 116 | 117 | #### `--no-amp` 118 | 119 | Don't prefer the AMP version of the web page. 120 | 121 | #### `--debug` 122 | 123 | Print more detailed information. 124 | 125 | #### `-t, --title` 126 | 127 | Provide a title for the bundle. 128 | 129 | ```bash 130 | percollate epub http://example.com/page-1 http://example.com/page-2 --title="Best Of Example" 131 | ``` 132 | 133 | #### `-a, --author` 134 | 135 | Provide an author for the bundle. 136 | 137 | ```bash 138 | percollate pdf --author="Ella Example" http://example.com 139 | ``` 140 | 141 | #### `--cover` 142 | 143 | Generate a cover. The option is implicitly enabled when the `--title` option is provided, or when bundling more than one web page to a single file. Disable this implicit behavior by passing the `--no-cover` flag. 144 | 145 | #### `--toc` 146 | 147 | Generate a hyperlinked table of contents. The option is implicitly enabled when bundling more than one web page to a single file. Disable this implicit behavior by passing the `--no-toc` flag. 148 | 149 | Applies to `pdf`, `html`, and `md`. 150 | 151 | #### `--toc-level=` 152 | 153 | By default, the table of contents is a flat list of article titles. With the `--toc-level` option the table of contents will include headings under each article title (`

`, `

`, etc.), up to the specified heading depth. A number between `1` and `6` is expected. 154 | 155 | Using `--toc-level` with a value greater than `1` implies `--toc`. 156 | 157 | #### `--hyphenate` 158 | 159 | Hyphenation is enabled by default for `pdf`, and disabled for `epub`, `html`, and `md`. You can opt into hyphenation with the `--hyphenate` flag, or disable it with the `--no-hyphenate` flag. 160 | 161 | See also the [Hyphenation and justification](#hyphenation-and-justification) recipe. 162 | 163 | #### `--inline` 164 | 165 | Embed images inline with the document. Images are fetched and converted to Base64-encoded `data` URLs. 166 | 167 | This option is particularly useful for `html` to produce self-contained HTML files. 168 | 169 | #### `--md.