Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

CLI reference

Every option of the sghtmltopdf command.

sghtmltopdf [OPTIONS] <INPUT.HTML>
sghtmltopdf server [OPTIONS]

The first converts a file; the second runs the HTTP server.

For how these map to wkhtmltopdf’s options, including the full list of the ones that are not supported, see the wkhtmltopdf option mapping.

Basics

# The simplest form; the system fonts are used
sghtmltopdf invoice.html -o invoice.pdf

# Without an output path, the input name with the extension changed to .pdf
sghtmltopdf invoice.html

# Read from standard input and write to standard output
cat invoice.html | sghtmltopdf - -o - > invoice.pdf

Input and output

OptionDefaultDescription
<INPUT.HTML>(required)The input HTML; - means standard input
-o, --output <PATH>The input name with .pdfWhere to write. - means standard output. It cannot be omitted when reading from standard input
--base-url <URL|DIR>The directory of the input HTMLThe base for resolving relative references. An http(s) URL becomes the default <base href>; a <base href> in the HTML wins
--encoding <NAME>DetectedThe character encoding of the input. The order is BOM, then --encoding, then <meta charset>, then UTF-8
--streamingOffProcess in streaming mode

The output is written to a temporary file and then renamed, so a failure never leaves a broken PDF behind.

Page setup

OptionDefaultDescription
-s, --page-size <SIZE>A4A3, A4, A5, Letter, or Legal, case insensitive
--page-width <LENGTH>The paper width; takes precedence over --page-size
--page-height <LENGTH>The paper height; takes precedence over --page-size
-O, --orientation <O>PortraitLandscape swaps width and height at the end
-T, --margin-top <LENGTH>1in (96px)Top margin
-B, --margin-bottom <LENGTH>1inBottom margin
-L, --margin-left <LENGTH>1inLeft margin
-R, --margin-right <LENGTH>1inRight margin

Lengths take the units mm, cm, in, pt, and px. A bare number means mm, as in wkhtmltopdf.

How this relates to @page in CSS

These options are initial values. If the CSS in the HTML says @page { size: … } or @page { margin: … }, the CSS wins, property by property. Note that this is the opposite of wkhtmltopdf.

Fonts

OptionDescription
--font <PATH>The font to use; may be given more than once. Without it, system fonts are used
--font-index <N>The face index inside a TrueType Collection (.ttc), for the preceding --font
--gothic-font <PATH> (with --gothic-font-index)The font behind font-family: sans-serif
--serif-font <PATH> (with --serif-font-index)The font behind font-family: serif
--mono-font <PATH> (with --mono-font-index)The font behind font-family: monospace

Fonts are resolved in the order --font, then @font-face, then a system search by font-family name. Only if none of those finds anything does a system sans-serif candidate become the default font.

Without --font, the output depends on the fonts of the machine it runs on. To keep output stable on a server or in CI, name the fonts with --font or @font-face. See Fonts for details.

PDF output and metadata

OptionDefaultDescription
--title <TEXT>The <title> of the HTMLThe /Title of the PDF
--author, --subject, --keywords <TEXT>The matching entries of the Info dictionary; specific to sghtmltopdf
-d, --dpi <DPI>96How many dpi a CSS px stands for. At 72, 1px equals 1pt
--zoom <FACTOR>1.0A scale factor, multiplied into the --dpi factor
-g, --grayscaleOffConvert fills and strokes to greyscale, by sRGB relative luminance
--no-pdf-compressionOffTurn off Flate compression of PDF objects; image data is unaffected

/Producer and /CreationDate are always written.

The limits of greyscale

JPEG images, which pass through as /DCTDecode, and CMYK images have no decoder here, so they stay in colour.

What gets drawn

OptionDescription
--no-imagesDo not load <img> or the CSS background-image
--no-backgroundDo not paint element backgrounds, neither colour nor image
--user-style-sheet <PATH>CSS in the user origin; may be given more than once. Stronger than the UA stylesheet, weaker than the author’s CSS
--minimum-font-size <PX>A lower bound on the computed font-size
--disable-external-linksDo not create PDF annotations for external http(s) links
--disable-internal-linksDo not create PDF annotations for internal #id links
--keep-relative-linksWrite relative external links as they are, without making them absolute
--load-media-error-handling <ignore|abort>What to do when an image, stylesheet, or font cannot be fetched; ignore by default

Headers and footers

There are two ways to do this. If both are given for the same side, --header-html wins.

1. As text

These map onto the margin boxes of @page.

sghtmltopdf report.html \
  --header-center "Quarterly report" \
  --footer-right "[page] / [topage]" \
  --header-line
OptionDescription
--header-left, --header-center, --header-right <TEXT>The three positions across the header
--footer-left, --footer-center, --footer-right <TEXT>The three positions across the footer
--header-font-name, --header-font-sizeThe header font; the footer has the same pair
--header-line, --footer-lineDraw a rule
--header-spacing, --footer-spacing <MM>The gap from the body text; the margin grows by that much
--default-headerA default header with the title and the page number
--replace <NAME=VALUE>Replace any [NAME] with a value; may be given more than once

The placeholders are [page] for the current page, [topage] for the total page count, [frompage], [title] and [doctitle], [date], [time], and any name you define with --replace.

[section], [subsection], [webpage], [sitepage], and [sitepages] are not supported.

2. As HTML

sghtmltopdf report.html --header-html header.html --footer-html footer.html

A separate HTML file is rendered into the margin area of every page. Placeholders are substituted in the HTML as text; JavaScript is not executed.

  • Anything that does not fit in the margin is clipped; the margin does not grow to accommodate it
  • No external resources are fetched. Inline <style>, text, borders, and background colours work; <img> and external CSS do not
  • @font-face inside the header or footer HTML is not loaded. Name any font used only there with --font

Cover page and table of contents

sghtmltopdf report.html --cover cover.html --toc --footer-center "[page]"

They are written in the order cover, table of contents, body.

OptionDefaultDescription
--cover <PATH>The HTML to use as the cover. It is not counted in the page numbers and gets no header or footer
--tocOffInsert a table of contents before the body; not available in streaming mode
--toc-header-text <TEXT>Table of ContentsThe <h1> of the table of contents
--toc-level-indentation <WIDTH>1emThe indent added per level
--toc-text-size-shrink <REAL>0.8The text size ratio applied per level
--disable-dotted-lines(drawn)Do not draw the dotted leader under each entry
--disable-toc-links(linked)Do not link the entries to their headings
--enable-toc-back-links(not linked)Link each heading back to the table of contents
--page-offset <N>0Shift where the page numbering starts

The HTML structure and default styling of the table of contents follow what wkhtmltopdf’s default TOC XSL produces: nested <ul> for the levels, and <div><a>heading</a><span>page number</span></div> for each entry. To change how it looks, apply CSS with --user-style-sheet; XSLT is not supported.

Headings are collected from h1 through h6. A heading without an id is given a generated destination name.

Access control

OptionCLI defaultServer default
--enable-local-file-access, --disable-local-file-accessAllowedDenied
--allow <PATH>No restrictionNo restriction
--allow-remote-assetsDeniedDenied

Given one or more --allow paths, local references are confined to those directories. This applies to <img src>, external CSS, and @font-face alike.

Ranges

References outside the base directory

Local references stay inside the base directory (--base-url, defaulting to the directory the input HTML lives in) by default. A ../ that would escape it is an error. This keeps untrusted HTML from reading arbitrary files through a reference such as <img src="../../../../etc/passwd">.

A ../ that resolves within the base directory, such as assets/../images/logo.png, keeps working as before.

Ranges

$ sghtmltopdf pages/index.html -o out.pdf
エラー: ../images/logo.png: 基準ディレクトリ(pages)の外を参照しています。
  外部のファイルを読む場合は --allow でディレクトリを明示してください

$ sghtmltopdf pages/index.html --allow . -o out.pdf

The check is lexical, so symlinks under the base directory are followed. Use --allow when you want the boundary to hold across symlinks as well (that check resolves real paths).

Limits on input size

HTML with more than roughly 500,000 nodes is rejected. Computed styles, the box tree and the layout result all grow in proportion to the node count; measured at 472 B to 1210 B per node.

Even a document of several thousand pages stays in the hundreds of thousands of nodes, so real documents practically never hit this. If you do hit it, split the document or use streaming mode. Streaming releases each processed part as it goes, so it can convert documents whose total exceeds the limit.

Memory that scales with the amount of text is not covered by this limit (three elements holding 10 MiB of text still use about 1.7 GiB). In HTTP server mode --max-body-size plays that role.

Logging and exit codes

--log-level <none|error|warn|info>, info by default, and -q or --quiet, which is the same as --log-level none.

CodeMeaning
0Success
1Usage error: an unknown option, a malformed value, or an option that is not supported
2Input or resource error: a missing file, a font that cannot be read, or a failed fetch under abort
3Rendering error, such as breaking one of the streaming mode restrictions
4Time limit exceeded (HTTP server mode’s --timeout only; the CLI has no time limit, so this never appears)