summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSarah White <graphitefriction@gmail.com>2022-04-19 14:31:27 -0600
committerGitHub <noreply@github.com>2022-04-19 14:31:27 -0600
commitc0cba0a55a20284ad9c5b4e7e5673b6d4057ef83 (patch)
treecf3e69cdd8cb56ae26dc35e7b567fdc175b7ed10
parentcbdc768c46d8c650f0ad719a47a011e1386315e8 (diff)
resolves #1887 set up PDF docs component version (PR #2035)
* set up PDF docs component version * move optional prerequisite installation content * update list keys; move dlists to own key page * add line-height key to table keys * update key filenames, titles, and navtitles * add inner-text-indent key * change key name to new kbd name * change literal to codespan; update filenames * add callout-list category * add anchor-top key to block category * change inner-text-indent to text-indent-inner * change blockquote key to quote key
-rw-r--r--docs/antora.yml22
l---------docs/modules/ROOT/attachments/basic-example.adoc1
l---------docs/modules/ROOT/images/example-pdf-screenshot.png1
-rw-r--r--docs/modules/ROOT/nav.adoc22
-rw-r--r--docs/modules/ROOT/pages/autofit-text.adoc45
-rw-r--r--docs/modules/ROOT/pages/autowidth-tables.adoc23
-rw-r--r--docs/modules/ROOT/pages/background-images.adoc75
-rw-r--r--docs/modules/ROOT/pages/convert-to-pdf.adoc42
-rw-r--r--docs/modules/ROOT/pages/features.adoc56
-rw-r--r--docs/modules/ROOT/pages/font-based-icons.adoc69
-rw-r--r--docs/modules/ROOT/pages/fonts.adoc40
-rw-r--r--docs/modules/ROOT/pages/image-paths-and-formats.adoc103
-rw-r--r--docs/modules/ROOT/pages/image-scaling.adoc81
-rw-r--r--docs/modules/ROOT/pages/import-pdf-pages.adoc47
-rw-r--r--docs/modules/ROOT/pages/index-catalog.adoc67
-rw-r--r--docs/modules/ROOT/pages/index.adoc27
-rw-r--r--docs/modules/ROOT/pages/inline-images.adoc17
-rw-r--r--docs/modules/ROOT/pages/install.adoc93
-rw-r--r--docs/modules/ROOT/pages/interdocument-xrefs.adoc124
-rw-r--r--docs/modules/ROOT/pages/optimize-pdf.adoc183
-rw-r--r--docs/modules/ROOT/pages/page-range.adoc10
-rw-r--r--docs/modules/ROOT/pages/passthrough-content.adoc29
-rw-r--r--docs/modules/ROOT/pages/stem.adoc56
-rw-r--r--docs/modules/ROOT/pages/syntax-highlighting.adoc29
-rw-r--r--docs/modules/ROOT/pages/title-page.adoc15
-rw-r--r--docs/modules/ROOT/pages/toc.adoc21
-rw-r--r--docs/modules/ROOT/pages/verbatim-blocks.adoc10
-rw-r--r--docs/modules/extend/nav.adoc4
-rw-r--r--docs/modules/extend/pages/converter-class-and-methods.adoc17
-rw-r--r--docs/modules/extend/pages/define-converter.adoc91
-rw-r--r--docs/modules/extend/pages/index.adoc26
-rw-r--r--docs/modules/extend/pages/require-converter.adoc10
-rw-r--r--docs/modules/theme/nav.adoc70
-rw-r--r--docs/modules/theme/pages/abstract.adoc128
-rw-r--r--docs/modules/theme/pages/admonition.adoc251
-rw-r--r--docs/modules/theme/pages/apply-theme.adoc75
-rw-r--r--docs/modules/theme/pages/asciidoc-attributes.adoc172
-rw-r--r--docs/modules/theme/pages/base.adoc119
-rw-r--r--docs/modules/theme/pages/block-image.adoc122
-rw-r--r--docs/modules/theme/pages/block.adoc43
-rw-r--r--docs/modules/theme/pages/button.adoc75
-rw-r--r--docs/modules/theme/pages/callout.adoc144
-rw-r--r--docs/modules/theme/pages/caption.adoc86
-rw-r--r--docs/modules/theme/pages/cjk.adoc50
-rw-r--r--docs/modules/theme/pages/code.adoc116
-rw-r--r--docs/modules/theme/pages/codespan.adoc92
-rw-r--r--docs/modules/theme/pages/color.adoc97
-rw-r--r--docs/modules/theme/pages/cover.adoc28
-rw-r--r--docs/modules/theme/pages/custom-font.adoc152
-rw-r--r--docs/modules/theme/pages/description-list.adoc101
-rw-r--r--docs/modules/theme/pages/example.adoc75
-rw-r--r--docs/modules/theme/pages/extend-theme.adoc100
-rw-r--r--docs/modules/theme/pages/extends.adoc30
-rw-r--r--docs/modules/theme/pages/fallback-font.adoc94
-rw-r--r--docs/modules/theme/pages/font-support.adoc101
-rw-r--r--docs/modules/theme/pages/font.adoc83
-rw-r--r--docs/modules/theme/pages/footnotes.adoc47
-rw-r--r--docs/modules/theme/pages/heading.adoc191
-rw-r--r--docs/modules/theme/pages/image.adoc65
-rw-r--r--docs/modules/theme/pages/index-section.adoc17
-rw-r--r--docs/modules/theme/pages/index.adoc31
-rw-r--r--docs/modules/theme/pages/keyboard.adoc75
-rw-r--r--docs/modules/theme/pages/keys.adoc21
-rw-r--r--docs/modules/theme/pages/language.adoc130
-rw-r--r--docs/modules/theme/pages/link.adoc64
-rw-r--r--docs/modules/theme/pages/list.adoc144
-rw-r--r--docs/modules/theme/pages/mark.adoc33
-rw-r--r--docs/modules/theme/pages/math-operations.adoc70
-rw-r--r--docs/modules/theme/pages/measurement-units.adoc58
-rw-r--r--docs/modules/theme/pages/menu.adoc41
-rw-r--r--docs/modules/theme/pages/page-numbers.adoc47
-rw-r--r--docs/modules/theme/pages/page.adoc111
-rw-r--r--docs/modules/theme/pages/prepare-custom-font.adoc113
-rw-r--r--docs/modules/theme/pages/print-and-prepress.adoc83
-rw-r--r--docs/modules/theme/pages/prose.adoc39
-rw-r--r--docs/modules/theme/pages/quote.adoc150
-rw-r--r--docs/modules/theme/pages/quoted-string.adoc24
-rw-r--r--docs/modules/theme/pages/quotes.adoc20
-rw-r--r--docs/modules/theme/pages/role.adoc145
-rw-r--r--docs/modules/theme/pages/running-content.adoc851
-rw-r--r--docs/modules/theme/pages/section.adoc21
-rw-r--r--docs/modules/theme/pages/sidebar.adoc137
-rw-r--r--docs/modules/theme/pages/source-highlighting-theme.adoc89
-rw-r--r--docs/modules/theme/pages/svg.adoc20
-rw-r--r--docs/modules/theme/pages/table.adoc401
-rw-r--r--docs/modules/theme/pages/text.adoc51
-rw-r--r--docs/modules/theme/pages/thematic-break.adoc39
-rw-r--r--docs/modules/theme/pages/title-page.adoc523
-rw-r--r--docs/modules/theme/pages/toc.adoc212
-rw-r--r--docs/modules/theme/pages/variables.adoc83
-rw-r--r--docs/modules/theme/pages/verse.adoc134
91 files changed, 8140 insertions, 0 deletions
diff --git a/docs/antora.yml b/docs/antora.yml
new file mode 100644
index 00000000..cf4d5cec
--- /dev/null
+++ b/docs/antora.yml
@@ -0,0 +1,22 @@
+name: pdf-converter
+title: Asciidoctor PDF
+version: '2.0'
+prerelease: '.0-alpha.1'
+asciidoc:
+ attributes:
+ xrefstyle: short@
+ table-caption: false
+ release-line: '2.0.x'
+ url-gem: https://rubygems.org/gems/asciidoctor-pdf
+ url-project-repo: https://github.com/asciidoctor/asciidoctor-pdf
+ url-repo-root: https://github.com/asciidoctor/asciidoctor-pdf/tree/main
+ url-project-issues: https://github.com/asciidoctor/asciidoctor-pdf/issues
+ url-api-docs: https://www.rubydoc.info/github/asciidoctor/asciidoctor-pdf/Asciidoctor/PDF/Converter
+ url-prawn: https://prawnpdf.org
+ url-prawn-gmagick: https://github.com/packetmonkey/prawn-gmagick
+ url-prawn-svg: https://github.com/mogest/prawn-svg
+ url-graphicsmagick: https://www.graphicsmagick.org
+nav:
+ - modules/ROOT/nav.adoc
+ - modules/theme/nav.adoc
+ - modules/extend/nav.adoc
diff --git a/docs/modules/ROOT/attachments/basic-example.adoc b/docs/modules/ROOT/attachments/basic-example.adoc
new file mode 120000
index 00000000..658227f0
--- /dev/null
+++ b/docs/modules/ROOT/attachments/basic-example.adoc
@@ -0,0 +1 @@
+../../../../examples/basic-example.adoc \ No newline at end of file
diff --git a/docs/modules/ROOT/images/example-pdf-screenshot.png b/docs/modules/ROOT/images/example-pdf-screenshot.png
new file mode 120000
index 00000000..91b828c6
--- /dev/null
+++ b/docs/modules/ROOT/images/example-pdf-screenshot.png
@@ -0,0 +1 @@
+../../../../examples/example-pdf-screenshot.png \ No newline at end of file
diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc
new file mode 100644
index 00000000..eb1f2dcb
--- /dev/null
+++ b/docs/modules/ROOT/nav.adoc
@@ -0,0 +1,22 @@
+* xref:features.adoc[]
+* xref:install.adoc[]
+* xref:convert-to-pdf.adoc[]
+* xref:fonts.adoc[]
+* xref:font-based-icons.adoc[]
+* xref:image-paths-and-formats.adoc[]
+* xref:image-scaling.adoc[]
+* xref:background-images.adoc[]
+* xref:inline-images.adoc[]
+* xref:import-pdf-pages.adoc[]
+* xref:interdocument-xrefs.adoc[]
+* xref:verbatim-blocks.adoc[]
+** xref:syntax-highlighting.adoc[]
+** xref:autofit-text.adoc[]
+* xref:stem.adoc[]
+* xref:passthrough-content.adoc[]
+* xref:autowidth-tables.adoc[]
+* xref:title-page.adoc[]
+* xref:toc.adoc[]
+* xref:index-catalog.adoc[]
+* xref:page-range.adoc[]
+* xref:optimize-pdf.adoc[]
diff --git a/docs/modules/ROOT/pages/autofit-text.adoc b/docs/modules/ROOT/pages/autofit-text.adoc
new file mode 100644
index 00000000..31229d2b
--- /dev/null
+++ b/docs/modules/ROOT/pages/autofit-text.adoc
@@ -0,0 +1,45 @@
+= Autofit Text
+
+Verbatim blocks often have long lines that don't fit within the fixed width of the PDF canvas.
+And unlike on the web, the PDF reader cannot scroll horizontally to reveal the overflow text.
+Therefore, the long lines are forced to wrap.
+Wrapped lines can make the verbatim blocks hard to read or even cause confusion.
+
+To help address this problem, Asciidoctor PDF provides the `autofit` option on all verbatim--literal, listing and source--blocks to attempt to fit the text within the available width.
+
+[#autofit]
+== autofit option
+
+When the `autofit` option is enabled, Asciidoctor PDF will decrease the font size as much as it can until the longest line fits without wrapping.
+
+CAUTION: The converter won't shrink the font size beyond the value of the `base_font_size_min` key specified in the PDF theme.
+If that threshold is reached, lines may still wrap.
+To allow `autofit` to handle all cases, set `base_font_size_min` to `0` in your theme.
+
+Here's an example of the `autofit` option enabled on a source block:
+
+[source,asciidoc]
+....
+[source%autofit,java]
+----
+@SessionScoped
+public class WidgetRepository {
+ @GET
+ @Produces("application/json")
+ public List<String> listAll(@QueryParam("start") Integer start, @QueryParam("max") Integer max) {
+ ...
+ }
+}
+----
+....
+
+[#autofit-attribute]
+== autofit-option attribute
+
+To enable the `autofit` option globally, set the `autofit-option` document attribute in the document header or before the relevant blocks in your content.
+
+[source,asciidoc]
+----
+= Document Title
+:autofit-option:
+----
diff --git a/docs/modules/ROOT/pages/autowidth-tables.adoc b/docs/modules/ROOT/pages/autowidth-tables.adoc
new file mode 100644
index 00000000..2740ed8f
--- /dev/null
+++ b/docs/modules/ROOT/pages/autowidth-tables.adoc
@@ -0,0 +1,23 @@
+= Autowidth Tables
+
+Asciidoctor PDF supports autowidth tables.
+However, the behavior differs from HTML when the content forces the table to the page boundary.
+The behavior, which is handled by the prawn-table library, is explained in this section.
+
+If the natural width of all columns (based on the width of the cell content) is less than the width of the page, it behaves as you'd expect.
+Each column is assigned the width it needs to prevent the content from wrapping.
+
+However, when the natural width of all columns exceeds the width of the page, the behavior may not be what you expect.
+What prawn-table does is compute how to arrange the table on an infinite canvas, where each column can have a width no greater than the width of the page.
+Then, it reduces the width of the table by reducing the width of each column proportionally.
+As a result, columns which reported the width necessary to render without wrapping now no longer do.
+
+The reason this compression is not performed like in HTML is because prawn-table has no awareness of words.
+Thus, it doesn't know how to redistribute with width intelligently.
+
+To protected against truncation or insufficient width errors, prawn-table wraps text by character.
+That's why the last character in the cell can end up getting wrapped.
+(There's a small amount of tolerance built in to prawn-table to address some edge cases, but it's not sufficient to handle all of them).
+
+For the reason just explained, you should be extremely careful with relying on autowidth tables in Asciidoctor PDF, especially when the natural content of the cells forces the table to page boundary.
+Let experience be your guide.
diff --git a/docs/modules/ROOT/pages/background-images.adoc b/docs/modules/ROOT/pages/background-images.adoc
new file mode 100644
index 00000000..fec1a368
--- /dev/null
+++ b/docs/modules/ROOT/pages/background-images.adoc
@@ -0,0 +1,75 @@
+= Background Images
+
+[#fit]
+== fit attribute
+
+Cover and background images can be sized relative to the page using the `fit` attribute on the image macro.
+The `fit` attribute works similarly to the `object-fit` property in CSS.
+Its value must be specified as a single keyword, chosen from the table below.
+The starting size of the image is determined by the explicit width, if specified, or the implicit width.
+The height is always derived from the width while respecting the implicit aspect ratio of the image.
+The available space for a background image (i.e., the canvas) is the page.
+If the `fit` attribute is not specified, it defaults to `contain` (i.e., the image is automatically scaled to fit the bounds of the page).
+
+.Values accepted by the fit attribute
+[cols="1s,3"]
+|===
+| Value | Purpose
+
+| contain
+| The image is scaled up or down while retaining its aspect ratio to fit within the available space. (default)
+
+| cover
+| The image is scaled up or down while retaining its aspect ratio so the image completely covers the available space, even if it means the image must be clipped in one direction.
+
+| scale-down
+| The image is scaled down while retaining its aspect ratio to fit within the available space.
+If the image already fits, it is not scaled.
+
+| fill
+| The image is scaled to fit the available space even if it means modifying the aspect ratio of the image.
+Does not apply to SVG images.
+
+| none
+| The image is not scaled.
+|===
+
+The `fit` attribute is often combined with the `position` attribute, covered next, to control the placement of the image on the canvas.
+
+[#position]
+== position attribute
+
+In addition to scaling, background images for cover pages, content pages, and the title page support positioning using the `position` attribute.
+The `position` attribute accepts a syntax similar to the `background-position` property in CSS, except only the keyword positions are supported.
+The position consists of two values, the vertical position and the horizontal position (e.g., `top center`).
+If only one value is specified (e.g., `top`), the other value is assumed to be `center`.
+If the `position` attribute is not specified, the value is assumed to be `center center` (i.e., the image is centered on the page).
+
+The following table provides a list of the vertical and horizontal positioning keywords that are supported.
+You can use any combination of these keywords to position the image.
+
+|===
+| Vertical Positions | Horizontal Positions
+
+| top +
+center +
+bottom
+
+| left +
+center +
+right
+|===
+
+Here's an example of how to place a background image at the top center of every page:
+
+----
+:page-background-image: image:bg.png[fit=none,pdfwidth=50%,position=top]
+----
+
+Here's how to move it to the bottom right:
+
+----
+:page-background-image: image:bg.png[fit=none,pdfwidth=50%,position=bottom right]
+----
+
+If an image dimension matches the height or width of the page, the positioning keyword for that axis has no effect.
diff --git a/docs/modules/ROOT/pages/convert-to-pdf.adoc b/docs/modules/ROOT/pages/convert-to-pdf.adoc
new file mode 100644
index 00000000..52b00053
--- /dev/null
+++ b/docs/modules/ROOT/pages/convert-to-pdf.adoc
@@ -0,0 +1,42 @@
+= Convert AsciiDoc to PDF
+
+== Run Asciidoctor PDF
+
+Assuming all the required gems install properly, verify you can run the `asciidoctor-pdf` script:
+
+ $ asciidoctor-pdf -v
+
+If you see the version of Asciidoctor PDF printed, you're ready to use Asciidoctor PDF!
+
+Let's grab an AsciiDoc document to distill and start putting Asciidoctor PDF to use.
+If you don't already have an AsciiDoc document, you can download and use the xref:attachment$basic-example.adoc[Basic Example AsciiDoc file].
+
+.basic-example.adoc
+[source,asciidoc]
+....
+include::attachment$basic-example.adoc[]
+....
+//TODO update link to https in example doc
+
+It's time to convert the AsciiDoc document directly to PDF.
+
+== Convert an AsciiDoc document to a PDF
+
+IMPORTANT: You'll need the `rouge` gem installed to run this example since it uses the `source-highlighter` attribute with the value of `rouge`.
+
+Converting to PDF is as simple as running the `asciidoctor-pdf` script using Ruby and passing our AsciiDoc document as the first argument.
+
+ $ asciidoctor-pdf basic-example.adoc
+
+This command is just a shorthand way of running:
+
+ $ asciidoctor -r asciidoctor-pdf -b pdf basic-example.adoc
+
+The `asciidoctor-pdf` command just saves you from having to remember all those flags.
+That's why we created it.
+
+When the script completes, you should see the file [.path]_basic-example.pdf_ in the same directory.
+Open the [.path]_basic-example.pdf_ file with a PDF viewer to see the result.
+
+.Example PDF document rendered in a PDF viewer
+image::example-pdf-screenshot.png[Screenshot of PDF document,width=850,467,scaledwidth=100%]
diff --git a/docs/modules/ROOT/pages/features.adoc b/docs/modules/ROOT/pages/features.adoc
new file mode 100644
index 00000000..91a3c175
--- /dev/null
+++ b/docs/modules/ROOT/pages/features.adoc
@@ -0,0 +1,56 @@
+= Asciidoctor PDF Features
+:navtitle: Features
+
+== Highlights
+
+* Direct AsciiDoc to PDF conversion
+* xref:theme:index.adoc[Configuration-driven theme]
+* Custom fonts (TTF or OTF)
+* Full SVG support (thanks to {url-prawn-svg}[prawn-svg^])
+* PDF document outline (i.e., bookmarks)
+* Title page
+* Table of contents page(s)
+* Document metadata (title, authors, subject, keywords, etc.)
+* Configurable page size (e.g., A4, Letter, Legal, etc.)
+* Internal cross reference links
+* Syntax highlighting with Rouge (preferred), Pygments, or CodeRay
+* Cover pages
+* Page background color or page background image with named scaling
+* Page numbering
+* Double-sided (aka prepress) printing mode (i.e., margins alternate on recto and verso pages)
+* Customizable running content (header and footer)
+* “Keep together” blocks (i.e., page breaks avoided in certain block content):
+** Explicitly delimited blocks other than open blocks
+** Open blocks with the "unbreakable" option `[%unbreakable]`
+* Orphaned section titles avoided
+* Autofit verbatim blocks (as permitted by `base_font_size_min` setting)
+* Table border settings honored
+* Font-based icons
+* Auto-generated index
+* Automatic hyphenation (when enabled)
+* Permissive line breaking for CJK languages
+* Compression / optimization of output file
+
+[#limitations]
+== Known limitations
+
+* Footnotes are always displayed as endnotes (at the end of chapter for books; at the end of document for all other doctypes).
+*Footnotes cannot be displayed at the bottom of the page because the PDF generator does not support content reflows* (see {url-project-issues}/85#issuecomment-577412975[#85^] for reasoning).
+* Table cells that exceed the height of a single page are truncated (see https://github.com/prawnpdf/prawn-table/issues/41[prawn-table#41^]).
+* A column can't be assigned a `width` of `0%` or a `width` less than the width of a single character.
+The converter will throw the error `Prawn::Errors::CannotFit` if such a case occurs.
+* A column can't be set to `autowidth` if the width of all the other columns in the table meet or exceed 100%.
+The converter will throw the error `Prawn::Errors::CannotFit` if such a case occurs.
+* An inline image in a table cell will not force the column wider if the width of the image exceeds the width of the column; either reduce the image width using `pdfwidth`, increase the width of the column using `cols`, or convert the cell to an AsciiDoc table cell and, preferably, use a block image (see {url-project-issues}/830[#830^]).
+* Must use development version of prawn for error to include font name when requested font style is missing.
+* AsciiDoc table cell leaves padding below last block (due to lack of margin collapsing).
+* Prawn does not support double-wide box drawing glyphs correctly, so box drawings aren't aligned properly in verbatim blocks (see https://github.com/prawnpdf/prawn/issues/1002[prawn#1002^]).
+* Orphan / widow support is limited; a page break can occur between a section title and its section content, a table caption and the caption, etc.; use a manual page break to avoid.
+* If a no-break hyphen is surrounded by formatted text on both sides (or is formatted individually), it will not prevent a line break.
+* Images cannot float.
+* You cannot use inline HTML (like a link or emphasized text) in a source block that also uses syntax highlighting.
+These two technologies just don't combine in the PDF generation process due to how the syntax highlighters work.
+* Verse blocks do not use a fixed-width font by default, but you can control this setting using the theme.
+* An inline image with a percentage `width` value in an `autowidth` table cell is resized relative to its intrinsic width.
+The space reserved for the image matches its intrinsic width.
+This matches the behavior of HTML.
diff --git a/docs/modules/ROOT/pages/font-based-icons.adoc b/docs/modules/ROOT/pages/font-based-icons.adoc
new file mode 100644
index 00000000..20177b14
--- /dev/null
+++ b/docs/modules/ROOT/pages/font-based-icons.adoc
@@ -0,0 +1,69 @@
+= Font-Based Icons
+
+You can use icons from any of the following icon sets in your PDF document:
+
+* *fa* - https://fontawesome.com/v4.7.0/icons (default)
+* *fas* - https://fontawesome.com/icons?d=gallery&s=solid[Font Awesome - Solid^]
+* *fab* - https://fontawesome.com/icons?d=gallery&s=brands[Font Awesome - Brands^]
+* *far* - https://fontawesome.com/icons?d=gallery&s=regular[Font Awesome - Regular^]
+* *fi* - http://zurb.com/playground/foundation-icon-fonts-3[Foundation Icons^]
+* *pf* - https://paymentfont.com/[Payment font^]
+
+The fa icon set is deprecated.
+Please use one of the other three FontAwesome icon sets.
+
+== Activate font-based icons
+
+You can enable font-based icons by setting the following attribute in the header of your document:
+
+[source,asciidoc]
+----
+:icons: font
+----
+
+If you want to override the font set globally, also set the `icon-set` attribute:
+
+[source,asciidoc]
+----
+:icons: font
+:icon-set: pf
+----
+
+You can enable use of fonts during PDF generation (instead of in the document header) by passing the `icons` attribute to the `asciidoctor-pdf` command.
+
+ $ asciidoctor-pdf -a icons=font -a icon-set=pf sample.adoc
+
+Icon-based fonts are handled by the `prawn-icon` gem.
+To find a complete list of available icons, consult the https://github.com/jessedoyle/prawn-icon/tree/master/data/fonts[prawn-icon^] repository.
+
+== Insert an icon
+
+Here's an example that shows how to use the Amazon icon from the payment font (pf) icon set in a sentence (assuming the `icon-set` is set to `pf):
+
+[source,asciidoc]
+----
+Available now at icon:amazon[].
+----
+
+You can use the `set` attribute on the icon macro to override the icon set for a given icon.
+
+[source,asciidoc]
+----
+Available now at icon:amazon[set=pf].
+----
+
+You can also specify the font set using the following shorthand.
+
+[source,asciidoc]
+----
+Available now at icon:amazon@pf[].
+----
+
+In addition to the sizes supported in the HTML backend (lg, 1x, 2x, etc.), you can enter any relative value in the size attribute (e.g., 1.5em, 150%, etc.).
+
+[source,asciidoc]
+----
+icon:android[size=40em]
+----
+
+
diff --git a/docs/modules/ROOT/pages/fonts.adoc b/docs/modules/ROOT/pages/fonts.adoc
new file mode 100644
index 00000000..d5915fe0
--- /dev/null
+++ b/docs/modules/ROOT/pages/fonts.adoc
@@ -0,0 +1,40 @@
+= Fonts
+:url-cjk-gothic: https://github.com/chloerei/asciidoctor-pdf-cjk-kai_gen_gothic
+
+== Support for non-Latin languages
+
+Asciidoctor can process the full range of characters in the UTF-8 character set.
+That means you can write your document in any language, save the file with UTF-8 encoding (_that's important!_), and expect Asciidoctor to convert the text properly.
+But you still need a font that provides the glyphs for those characters.
+
+When converting a document with Asciidoctor PDF, you may notice that some glyphs for certain languages, such as Chinese, are missing from the PDF.
+PDF is a "`bring your own font`" kind of system.
+In other words, the font you provide must provide glyphs for all the characters used.
+There's no one font that supports all the world's languages (though some, like Noto Serif, certainly come close).
+Even if there were such a font, bundling that font with the main gem would make it enormous.
+It would also severely limit the style choices in the default theme, which targets Latin-based languages.
+Therefore, we're taking the strategy of creating separate dedicated theme gems that target each language family, such as CJK.
+Read on to find out how to use these themes.
+
+Asciidoctor PDF provides a built-in theme that provides a broad range of characters in the CJK charsets, so you can start with that theme:
+
+ $ asciidoctor-pdf -a scripts=cjk -a pdf-theme=default-with-fallback-font document.adoc
+
+Notice the `-a scripts=cjk` option.
+That's important.
+It tells the converter to insert break opportunities between CJK characters so that the line wraps properly when mixing English and a CJK language like Japanese.
+
+If the built-in theme with the fallback font doesn't go far enough, you'll need to use a theme that is optimized for CJK text.
+You can get such a theme by installing the `asciidoctor-pdf-cjk-kai_gen_gothic` gem.
+The {url-cjk-gothic}[asciidoctor-pdf-cjk-kai_gen_gothic^] project provides themes optimized for CJK languages based on the kai_gen_gothic font.
+See the {url-cjk-gothic}/blob/master/README.md[asciidoctor-pdf-cjk-kai_gen_gothic project README^] for detailed setup instructions.
+
+WARNING: The theme provided by the `asciidoctor-pdf-cjk-kai_gen_gothic` gem isn't compatible with Asciidoctor PDF {page-component-display-version}.
+However, you can still use it to create a xref:theme:cjk.adoc[custom CJK theme].
+
+Once you have that gem installed (and the fonts), you need to tell Asciidoctor PDF to use one of the themes.
+If you're converting a document that is primarily written in Japanese, you'd run Asciidoctor PDF as follows:
+
+ asciidoctor-pdf -r asciidoctor-pdf-cjk-kai_gen_gothic -a pdf-theme=KaiGenGothicJP document.adoc
+
+If that command fails, you may have better luck creating your own CJK theme.
diff --git a/docs/modules/ROOT/pages/image-paths-and-formats.adoc b/docs/modules/ROOT/pages/image-paths-and-formats.adoc
new file mode 100644
index 00000000..8ec6ab61
--- /dev/null
+++ b/docs/modules/ROOT/pages/image-paths-and-formats.adoc
@@ -0,0 +1,103 @@
+= Image Paths and Formats
+
+Images are resolved at the time the converter runs.
+That means they need to be located where the converter can find them and be in a format it can read.
+
+== imagesdir attribute
+
+Relative image paths in a document are resolved relative to the value of the `imagesdir` attribute.
+This is effectively the same as how the built-in HTML converter works when the `data-uri` attribute is set.
+The `imagesdir` is blank by default, which means relative images paths are resolved relative to the input document.
+Relative images paths in the theme are resolved relative to the value of the `pdf-themesdir` attribute (which defaults to the directory of the theme file).
+The `imagesdir` attribute is not used when resolving an image path in the theme file.
+Absolute image paths are used as is.
+
+If the image is an SVG, and the SVG includes a nested raster image (PNG or JPG) with a relative path, that path is resolved relative to the directory that contains the SVG.
+
+The converter will refuse to embed an image if the target is a URI (including image references in an SVG) unless the `allow-uri-read` attribute is enabled via the CLI or API.
+
+If you use a linked image in an SVG, the width and height of that image must be specified.
+Otherwise, the SVG library will fail to process it.
+
+== Asciidoctor Diagram integration
+
+Asciidoctor PDF provides seamless integration with Asciidoctor Diagram by setting the `data-uri` attribute by default.
+When the `data-uri` attribute is set, Asciidoctor Diagram returns the absolute path to the generated image, which Asciidoctor PDF can then locate.
+(This makes sense since technically, Asciidoctor Diagram must embed the image in the document, similar in spirit to the `data-uri` feature for HTML).
+This means the input directory and the output directory (and thus the `imagesoutdir`) can differ and Asciidoctor PDF will still be able to locate the generated image.
+
+== Image formats
+
+The following image types (and corresponding file extensions) are supported:
+
+* PNG (.png)
+* JPEG (.jpg)
+* SVG (.svg)
+
+CAUTION: The GIF (.gif), TIFF (.tiff), BMP (.bmp), and interlaced PNG formats are not supported unless you install prawn-gmagick.
+See <<other-image-formats>> for details.
+//TODO confirm all these formats are unsupported both in the theme and content as we use the same admonition in both locations
+
+In order to embed an image into a PDF, Asciidoctor PDF must understand how to read it.
+To perform this work, Asciidoctor delegates to the underlying libraries.
+{url-prawn}[Prawn^] provides support for reading JPG and PNG images.
+{url-prawn-svg}[prawn-svg^] brings support for SVG images.
+Without any additional libraries, those are the only supported image file formats.
+
+[#other-image-formats]
+=== Supporting additional image file formats
+
+If you need support for additional image formats, such as GIF, TIFF, BMP, or interlaced PNG--and you don't want to convert those images to a supported format--you must install the {url-prawn-gmagick}[prawn-gmagick^] (>= 0.0.9) Ruby gem.
+//TODO the gmagick version should not be mentioned here, instead it should be specified in the optional prerequisites (or whatever we decide to call it) table
+prawn-gmagick is an extension for Prawn based on {url-graphicsmagick}[GraphicsMagick^] that adds support for all the image formats recognized by that library.
+prawn-gmagick has the added benefit of significantly reducing the time it takes to generate a PDF containing a lot of images.
+
+The prawn-gmagick gem uses native extensions to compile against GraphicsMagick.
+This system prerequisite limits installation to Linux and OSX.
+Please refer to the {url-prawn-gmagick}[README for prawn-gmagick^] to learn how to install it.
+
+Once this gem is installed, Asciidoctor automatically loads it, then delegates to it to handle all image embedding.
+In addition to support for additional image file formats, this gem also speeds up image processing considerably.
+We highly recommend using this gem if you're able to install it.
+
+[#svg]
+== Fonts in SVG images
+
+Asciidoctor PDF uses {url-prawn-svg}[prawn-svg^] to embed SVGs in the PDF document, including SVGs generated by Asciidoctor Diagram.
+
+Actually, it's not accurate to say that prawn-svg embeds the SVG.
+Rather, prawn-svg is an SVG _renderer_.
+prawn-svg translates an SVG into native PDF text and graphic objects.
+You can think of the SVG as a sequence of drawing commands.
+The result becomes indistinguishable from other PDF objects.
+
+What that means for text is that any font family used for text in the SVG _must_ be registered in the Asciidoctor PDF theme file (and thus with Prawn).
+Otherwise, Prawn will fall back to using the closest matching built-in (afm) font from PDF (e.g., sans-serif becomes Helvetica).
+Recall that afm fonts only support basic Latin.
+As we like to say, PDF is xref:theme:font-support.adoc#built-in[bring your own font].
+
+If you're using Asciidoctor Diagram to generate SVGs to embed in the PDF, you likely need to specify the default font the diagramming tool uses.
+Let's assume you are making a plantuml diagram.
+
+To set the font used in the diagram, first create a file named [.path]_plantuml.cfg_ and populate it with the following content:
+
+----
+skinparam defaultFontName Noto Serif
+----
+
+TIP: You can choose any font name that is registered in your Asciidoctor PDF theme file.
+When using the default theme, your options are "Noto Serif", "M+ 1mn", and "M+ 1p Fallback".
+
+Next, pass that path to the `plantumlconfig` attribute in your AsciiDoc document (or set the attribute via the CLI or API):
+
+----
+:plantumlconfig: plantuml.cfg
+----
+
+Clear the cache of your diagrams and run Asciidoctor PDF with Asciidoctor Diagram enabled.
+The diagrams will be generated using Noto Serif as the default font, and Asciidoctor PDF will know what to do.
+
+The bottom line is this:
+If you're using fonts in your SVG, and you want those fonts to be preserved, those fonts must be defined in the Asciidoctor PDF theme file.
+
+
diff --git a/docs/modules/ROOT/pages/image-scaling.adoc b/docs/modules/ROOT/pages/image-scaling.adoc
new file mode 100644
index 00000000..6049fc0b
--- /dev/null
+++ b/docs/modules/ROOT/pages/image-scaling.adoc
@@ -0,0 +1,81 @@
+= Image Scaling
+
+PDF is a fixed-width canvas, therefore you almost always need to specify a width to get the image to fit properly on the page.
+
+== Image width attributes
+
+There are five ways to specify the width of an image, listed in the following table in order of precedence.
+
+[cols="1s,3"]
+|===
+|Attribute{nbsp}Name | Description
+
+|<<pdfwidth,pdfwidth>>
+|The display width of the image as an absolute size (e.g., 2in), percentage of the content area width (e.g., 75%), or percentage of the page width (e.g., 100vw).
+If a unit of measurement is not specified (or not recognized), pt (points) is assumed.
+_Intended to be used for the PDF converter only._
+
+|scaledwidth
+|The display width of the image as an absolute size (e.g., 2in) or percentage of the content area width (e.g., 75%).
+If a unit of measurement is not specified, % (percentage) is assumed.
+If a unit of measurement is recognized, pt (points) is assumed.
+_Intended to be used for print output such as PDF._
+
+|image_width key from theme
+|Accepts the same values as pdfwidth.
+_Only applies to block images._
+
+|width
+|The unitless display width of the image (assumed to be pixels), typically matching the intrinsic width of the image.
+If the value ends in % (not recommended), it's assumed to be the percentage of the available content area width.
+If the width exceeds the content area width, the image is scaled down to the content area width.
+
+|_unspecified_
+|If you don't specify one of the aforementioned width settings, the intrinsic width of the image is used (the px value is multiplied by 75% to convert to pt, assuming canvas is 96 dpi) unless the width exceeds the content area width, in which case the image is scaled down to the content area width.
+|===
+
+The image is always sized according to the explicit or intrinsic width, then its height is scaled proportionally.
+The height of the image is ignored by the PDF converter unless the height of the image exceeds the content height of the page.
+In this case, the image is scaled down to fit on a single page.
+
+If you want a block image to align to the boundaries of the page (not the content margin), specify the `align-to-page` option (e.g., `opts="align-to-page"`).
+This is most useful when using vw units because you can make the image cover the entire width of the page.
+
+Images in running content and page background images also support the `fit` attribute (when specified using the image macro).
+See xref:background-images.adoc[] for details.
+
+[#default-width]
+== Default image width
+
+To scale all block images that don't define either a `pdfwidth` or `scaledwidth` attribute on the image macro, assign a value to the image-width key in your theme file.
+
+[source,yaml]
+----
+image:
+ width: 100%
+----
+
+The image-width key accepts the same values as the `pdfwidth` attribute.
+Thus, you can think of it as the fallback value for the `pdfwidth` attribute.
+If specified, this value takes precedence over the `width` attribute on the image macro.
+
+[#pdfwidth]
+== pdfwidth attribute
+
+The `pdfwidth` attribute is the recommended way to set the image size for the PDF output.
+This attribute is provided for two reasons.
+First, the fixed-width canvas often calls for a width that is distinct from other output formats, such as HTML.
+Second, this attribute allows the width to be expressed using a variety of units.
+
+The `pdfwidth` attribute supports the following units:
+
+* pt (default)
+* in
+* cm
+* mm
+* px
+* pc
+* vw (percentage of page width)
+* % (percentage of content area width)
+
+In all cases, the width is converted to pt.
diff --git a/docs/modules/ROOT/pages/import-pdf-pages.adoc b/docs/modules/ROOT/pages/import-pdf-pages.adoc
new file mode 100644
index 00000000..57c0d237
--- /dev/null
+++ b/docs/modules/ROOT/pages/import-pdf-pages.adoc
@@ -0,0 +1,47 @@
+= Import PDF Pages
+:url-import-blog-post: https://fromplantoprototype.com/blog/2019/08/07/importing-pdf-pages-in-asciidoctor-pdf/
+
+In addition to using a PDF page for the front or back cover, you can also insert a PDF page at an arbitrary location.
+This technique is useful for adding pages that have complex layouts and graphics prepared in a specialized design program, which would otherwise not be achievable using this converter.
+One such example is an insert such as an advertisement or visual interlude.
+
+== Import a page from a PDF file
+
+To import the first page from a PDF file, use the block image macro with the PDF filename as the image target.
+
+[source,asciidoc]
+----
+image::custom-page.pdf[]
+----
+
+The converter will insert the page from the PDF as a dedicated page that matches the size and layout of the page being imported (no matter where the block image occurs).
+Therefore, there's no need to put a manual page break (i.e., `<<<`) around the image macro.
+
+By default, this macro will import the first page of the PDF.
+To import a different page, specify it as a 1-based index using the `page` attribute.
+
+[source,asciidoc]
+----
+image::custom-pages.pdf[page=2]
+----
+
+== Import multiple pages from a PDF file
+
+You can import multiple pages either using multiple image macros or using the `pages` attribute.
+The `pages` attribute accepts individual page numbers or page number ranges (two page numbers separated by `..`).
+The values can be separated either by commas or semicolons.
+(The syntax is similar to the syntax uses for the `lines` attribute of the AsciiDoc include directive).
+
+[source,asciidoc]
+----
+image::custom-pages.pdf[pages=3;1..2]
+----
+
+Pages are imported in the order listed.
+
+To see a practical example of how to use this feature, refer to the blog post {url-import-blog-post}[Importing PDF Pages in asciidoctor-pdf^].
+
+CAUTION: An image macro used to import PDF pages should never be nested inside a delimited block or table cell.
+It should be a direct descendant of the document or a section.
+That's because what it imports are entire pages.
+If it's used inside a delimited block or table cell, the behavior is unspecified.
diff --git a/docs/modules/ROOT/pages/index-catalog.adoc b/docs/modules/ROOT/pages/index-catalog.adoc
new file mode 100644
index 00000000..8f738179
--- /dev/null
+++ b/docs/modules/ROOT/pages/index-catalog.adoc
@@ -0,0 +1,67 @@
+= Index Catalog
+
+Asciidoctor PDF supports generating an index catalog that itemizes all index terms defined in the document, allowing the reader to navigate the document by keyword.
+
+== Add index section
+
+To generate an index, add a level-1 section annotated with the `index` style near the end of your document.
+The converter will automatically populate the catalog with the list of index terms in the document, organized by first letter.
+
+[source,asciidoc]
+----
+[index]
+= Index
+----
+
+You can use any text you want for the title of this section.
+The only restriction is that no index terms may be defined below this section.
+
+NOTE: Although the catalog is generated automatically, you have to mark the index terms manually.
+However, you could use an extension, such as a TreeProcessor, to automatically mark index terms.
+
+== How index terms are grouped and sorted
+
+By default, the converter groups index terms by the first letter of the primary term (e.g., A), which we call the category.
+These categories are displayed in alphabetically order in the index.
+Within the category, the converter sorts the terms alphabetically.
+
+The exception to this rule is if the primary term does not start with a letter.
+In this case, the converter group the term (along with its secondary and tertiary terms) in a special category named @.
+The @ category is displayed before all other categories in the index.
+
+== Customize the grouping and sorting rules
+
+If you want to modify the default index grouping and sorting behavior, you must extend the index catalog and apply your own rules.
+
+For example, let's say that all your functions begin with the prefix `fn`, but you want to group and sort them by the function name that follows.
+Here's rudimentary code you can use to do that:
+
+.index-customizer.rb
+[source,ruby]
+----
+require 'asciidoctor-pdf'
+
+module Asciidoctor::PDF
+ IndexCatalog.prepend (::Module.new do
+ def store_primary_term name, dest = nil
+ store_dest dest if dest
+ category = (name.delete_prefix 'fn').upcase.chr
+ (init_category category).store_term name, dest
+ end
+ end)
+
+ IndexTermGroup.prepend (::Module.new do
+ def <=> other
+ this = @name.delete_prefix 'fn'
+ that = other.name.delete_prefix 'fn'
+ (val = this.casecmp that) == 0 ? this <=> that : val
+ end
+ end)
+end
+----
+
+You load this code when calling Asciidoctor PDF as follows:
+
+ $ asciidoctor-pdf -r ./index-customizer.rb doc.adoc
+
+Now the index terms will be grouped and sorted according to your custom rules.
diff --git a/docs/modules/ROOT/pages/index.adoc b/docs/modules/ROOT/pages/index.adoc
new file mode 100644
index 00000000..61222de9
--- /dev/null
+++ b/docs/modules/ROOT/pages/index.adoc
@@ -0,0 +1,27 @@
+= Asciidoctor PDF Documentation
+
+Asciidoctor PDF is a native PDF converter for AsciiDoc.
+It bypasses the requirement to generate an intermediary format such as DocBook, Apache FO, or LaTeX.
+Instead, you can use Asciidoctor PDF to convert your documents directly from AsciiDoc to PDF.
+Its aim is to take the pain out of creating PDF documents from AsciiDoc.
+
+[NOTE]
+====
+You're viewing the documentation for Asciidoctor PDF {page-component-display-version}.
+If you're looking for the documentation for a previous release line, refer to one of the following repository branches:
+
+* {url-project-repo}/tree/v1.6.x#readme[Asciidoctor PDF 1.6.x^]
+* {url-project-repo}/tree/v1.5.x#readme[Asciidoctor PDF 1.5.x^]
+====
+
+== Overview
+
+Asciidoctor PDF converts an AsciiDoc document directly to a PDF document.
+The style and layout of the PDF is controlled by a dedicated theme file.
+To the degree possible, Asciidoctor PDF supports all the features of AsciiDoc that are supported by Asciidoctor.
+It also provides xref:features.adoc[additional PDF-specific features].
+However, there are xref:features.adoc#limitations[certain limits] imposed by the PDF format and the underlying PDF library this extension uses.
+
+Asciidoctor PDF uses the Prawn gem and Prawn's extensions, such as prawn-svg and prawn-table, to generate a PDF document.
+{url-prawn}[Prawn^] is a general purpose PDF generator for Ruby that features high-level APIs for common needs like setting up the page and inserting images and low-level APIs for positioning and rendering text and graphics.
+
diff --git a/docs/modules/ROOT/pages/inline-images.adoc b/docs/modules/ROOT/pages/inline-images.adoc
new file mode 100644
index 00000000..77de2c27
--- /dev/null
+++ b/docs/modules/ROOT/pages/inline-images.adoc
@@ -0,0 +1,17 @@
+= Inline Images
+
+== Inline image sizing
+
+Inline images can be sized in much the same way as block images, using the `pdfwidth`, `scaledwidth`, or `width` attributes, with the following exceptions:
+
+* The viewport width unit (i.e., vw) is not recognized in this context.
+* The image will be scaled down, if necessary, to fit the width and height of the content area.
+* Inline images do not currently support a default width controlled from the theme.
+
+To confine the inline image to the height of the line while preserving the aspect ratio, use the attribute `fit=line`.
+
+If the resolved height of the image is less than or equal to 1.5 times the line height, the image won't disrupt the line height and is centered vertically in the line.
+This is done to maximize the use of available space.
+Once the resolved height exceeds this amount, the height of the line is increased (by increasing the font size of the invisible placeholder text) to accommodate the image.
+In this case, the surrounding text will be aligned to the bottom of the image.
+If the image height exceeds the height of the page, the image will be scaled down to fit on a single page (this may cause the image to advance to the subsequent page).
diff --git a/docs/modules/ROOT/pages/install.adoc b/docs/modules/ROOT/pages/install.adoc
new file mode 100644
index 00000000..a60b8166
--- /dev/null
+++ b/docs/modules/ROOT/pages/install.adoc
@@ -0,0 +1,93 @@
+= Install Asciidoctor PDF
+//:navtitle: Get Started
+:url-rvm: https://rvm.io
+
+[#prerequisites]
+== Required prerequisites
+
+=== Ruby
+
+All that's needed is Ruby 2.5 or greater (or JRuby 9.2 or greater) and a few Ruby gems (including at least Asciidoctor 2.0.0), which we explain how to install in the next section.
+
+To check if you have Ruby available, use the `ruby` command to query the version installed:
+
+ $ ruby -e 'puts RUBY_VERSION'
+
+//TODO This Ruby version command (line above) is different than the Ruby version command in Core. Which one do we prefer?
+Make sure this command reports a Ruby version that's at least 2.5.
+If so, you may proceed.
+
+//TODO What about installing Asciidoctor Core? What about the Prawn extensions (table? svg? etc.)?
+
+=== Windows system encoding
+
+Asciidoctor assumes you're using UTF-8 encoding.
+To minimize encoding problems, make sure the default encoding of your system is set to UTF-8.
+
+If you're using a non-English Windows environment, the default encoding of your system may not be UTF-8.
+As a result, you may get an `Encoding::UndefinedConversionError` or other encoding issues when invoking Asciidoctor.
+To solve these problems, we recommend at least changing the active code page in your console to UTF-8.
+
+ chcp 65001
+
+Once you make this change, all your Unicode headaches will be behind you.
+
+== Optional prerequisites
+
+PDF optimization::
+If you want to optimize your PDF, you'll need rghost or hexapdf.
+See xref:optimize-pdf.adoc[] for installation and usage instructions.
+
+Source highlighting::
+You'll need to xref:syntax-highlighting.adoc[install a syntax highlighter] to use source highlighting.
+
+Similarly, if you want to use the hyphen option you will need to install the `text-hyphen` gem:
+
+ $ gem install text-hyphen
+
+//TODO what is text hyphen and where should its content be located?
+//NOTE I'd prefer not to have the optional prerequisite install instructions here as the install process and possible troubleshooting of the required prereqs and Asciidoctor PDF is already a lot.
+
+== Install Asciidoctor PDF
+
+You can get Asciidoctor PDF by installing the published gem.
+To install Asciidoctor PDF, first make sure you have satisfied the <<prerequisites>>.
+Then, install the gem from RubyGems.org using the following command:
+
+ $ gem install asciidoctor-pdf
+
+=== Install a development version
+
+You can also {url-project-repo}/blob/main/CONTRIBUTING-CODE.adoc[run the code from source^] if you want to use a development version or participate in development.
+
+== Installation troubleshooting
+
+If you get a permission error while installing the gem, such as the one below, it's likely you're attempting to install the gem directly into your system.
+Installing gems for tech writing directly into your system is not recommended.
+
+.Permission error when attempting to install as a system gem
+....
+ERROR: While executing gem ... (Gem::FilePermissionError)
+ You don't have write permissions for the /Library/Ruby/Gems/2.x.x directory.
+....
+
+A better practice (and one that will ensure your sanity) is to ignore any version of Ruby installed on your system and use {url-rvm}[RVM^] to manage the Ruby installation instead.
+The benefit of this approach is that a) Ruby is guaranteed to be set up correctly, b) installing gems will in no way interfere with the operation of your system, and c) any bin scripts provided by the installed gems will be available on your PATH.
+All files are managed in user space (aka your home or user directory).
+If something gets messed up, you can simply remove the [.path]_$HOME/.rvm_ folder and start over.
+
+To learn how to install RVM, follow the https://asciidoctor.org/docs/install-asciidoctor-macos/#rvm-procedure-recommended[RVM installation procedure^] covered in the Asciidoctor documentation.
+//TODO determine best RVM instructions, if we still recommend, and put them in their proper home for xrefing to.
+Once you have installed RVM and used it to install Ruby, make sure to activate the Ruby managed by RVM using `rvm use default` or a specific Ruby version like `rvm use 2.7`.
+(You'll need to do this each time you open a new terminal).
+
+After installing the gem, you can see where it was installed using the following command:
+
+ $ gem which asciidoctor-pdf
+
+To see where the bin script is located, use this command:
+
+ $ command -v asciidoctor-pdf
+
+Both paths should be underneath the [.path]_$HOME/.rvm_ directory.
+If not, check your RVM setup.
diff --git a/docs/modules/ROOT/pages/interdocument-xrefs.adoc b/docs/modules/ROOT/pages/interdocument-xrefs.adoc
new file mode 100644
index 00000000..e89ac217
--- /dev/null
+++ b/docs/modules/ROOT/pages/interdocument-xrefs.adoc
@@ -0,0 +1,124 @@
+= Interdocument Xrefs
+
+An xref to another AsciiDoc document (i.e., an interdocument xref) will either become a link to the PDF file generated from that source document or an internal link to an anchor within the current document.
+Which one it becomes depends on whether the target has been included into the current document.
+This page describes these two scenarios.
+
+== Referencing another document
+
+If the target PDF is generated from an AsciiDoc file, you can make a reference to that PDF using the xref macro.
+
+Let's assume the current document is [.path]_a.adoc_ and the PDF you want to reference is generated from [.path]_b.adoc_.
+Here's how you can make a reference from the PDF generated from [.path]_a.adoc_ to the PDF generated from [.path]_b.adoc_.
+
+[source,asciidoc]
+----
+A link to xref:b.adoc[b].
+----
+
+This xref macro is translated to a link that refers to [.path]_b.pdf_.
+
+If there's an anchor you want to target in [.path]_b.pdf_, for example _chapter-b_, you can describe it using a URL fragment just like you would with any URL.
+
+[source,asciidoc]
+----
+A link to xref:b.adoc#chapter-b[b].
+----
+
+WARNING: Linking to a named anchor isn't supported by all PDF viewers.
+Some viewers (like Firefox) only support relative links when the PDF is accessed through a web server.
+To verify it's working, test the PDF in Firefox and served through a local web server.
+
+PDF supports a variety of PDF link open parameters you can control using the URL fragment.
+For example, you can configure the PDF to open on a specific page using the special fragment `page=<N>`, where `<N>` is the 1-based page number.
+
+[source,asciidoc]
+----
+A link to page 2 of xref:b.adoc#page=2[b].
+----
+
+You can find a list of all the special fragment parameters in the https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/pdf_open_parameters.pdf#G4.1500549[PDF Open Parameters^] reference.
+
+== Converting interdocument xrefs to internal xrefs
+
+If you're using this converter to generate a single PDF file from multiple source documents (combined using the include directive), references between those included documents must become internal references.
+Interdocument cross references (i.e., xrefs) will only successfully make that transition if you structure your document in accordance with the rules.
+
+Those rules are as follows:
+
+. The path segment of the interdocument xref must match the project-relative path of the included document
+. The reference must include the ID of the target element
+
+For instance, if your primary document contains the following include:
+
+[source,asciidoc]
+----
+\include::chapters/chapter-1.adoc[]
+----
+
+Then an interdocument xref to an anchor in that chapter must be expressed as:
+
+[source,asciidoc]
+----
+<<chapters/chapter-1.adoc#_anchor_name,Destination in Chapter 1>>
+----
+
+This rule holds regardless of which document the xref is located in.
+
+To resolve the interdocument xref, the converter first checks if the target matches the `docname` attribute.
+It then looks to see if the target matches one of the included files.
+(In both cases, it ignores the file extension).
+If Asciidoctor cannot resolve the target of an interdocument xref, it simply makes a link (like the HTML converter).
+
+Let's consider a complete example.
+Assume you are converting the following book document at the root of the project:
+
+[source,asciidoc]
+----
+= Book Title
+:doctype: book
+
+\include::chapters/chapter-1.adoc[]
+
+\include::chapters/chapter-2.adoc[]
+----
+
+Where the contents of chapter 1 is as follows:
+
+[source,asciidoc]
+----
+== Chapter 1
+
+We cover a little bit here.
+The rest you can find in <<chapters/chapter-2.adoc#_chapter_2,Chapter 2>>.
+----
+
+And the contents of chapter 2 is as follows:
+
+[source,asciidoc]
+----
+== Chapter 2
+
+Prepare to be educated.
+This chapter has it all!
+
+To begin, jump to <<chapters/chapter-2/first-steps.adoc#_first_steps,first steps>>.
+
+<<<
+
+\include::chapter-2/first-steps.adoc[]
+----
+
+And, finally, the contents of the nested include is as follows:
+
+[source,asciidoc]
+----
+=== First Steps
+
+Let's start small.
+----
+
+You'll find when you run this example that all the interdocument xrefs become internal references in the PDF.
+
+The reason both the path and anchor are required (even when linking to the top of a chapter) is so the interdocument xref works independent of the converter.
+In other words, it encodes the complete information about the reference so the converter can sort out where the target is in all circumstances.
diff --git a/docs/modules/ROOT/pages/optimize-pdf.adoc b/docs/modules/ROOT/pages/optimize-pdf.adoc
new file mode 100644
index 00000000..3dbab6f0
--- /dev/null
+++ b/docs/modules/ROOT/pages/optimize-pdf.adoc
@@ -0,0 +1,183 @@
+= Optimize a PDF
+:url-hexapdf: https://hexapdf.gettalong.org/
+
+By default, Asciidoctor PDF does not optimize the PDF it generates or compress its streams.
+This page covers several approaches you can take to optimize your PDF.
+
+IMPORTANT: If you're creating a PDF for Amazon's Kindle Direct Publishing (KDP), GitLab repository preview, or other online publishers, you'll likely need to optimize the file before uploading.
+In their words, you must tidy up the reference tree and https://kdp.amazon.com/en_US/help/topic/G201953020#check[flatten all transparencies^] (mostly likely referring to images).
+If you don't do this step, the platform may reject your upload or fail to display it properly.
+(For KDP, `-a optimize` works best.
+For GitLab repository preview, either `-a optimize` or `hexapdf optimize` will do the trick.)
+
+== Shaded blocks and performance
+
+Certain blocks are rendered with a shaded background, such as verbatim (listing, literal, and source), sidebar, and example blocks.
+In order to calculate the dimensions of the shaded region, Asciidoctor PDF has to "`dry run`" the block to determine how many pages it consumes.
+While this strategy has a low impact when processing shorter blocks, it can drastically deteriorate performance when processing a block that spans dozens of pages.
+As a general rule of thumb, you should avoid using shaded blocks which span more than a handful of pages.
+
+== Enable stream compression
+
+A simple way to reduce the size of the PDF file is to enable stream compression (using the FlateDecode method).
+You can enable this feature by setting the `compress` attribute on the document:
+
+ $ asciidoctor-pdf -a compress filename.adoc
+
+For a more thorough optimization, you can use the <<rghost,integrated optimizer>> or <<hexapdf>>.
+
+[#rghost]
+== rghost
+
+Asciidoctor PDF also provides a flag (and bin script) that uses GhostScript (via rghost) to optimize and compress the generated PDF with minimal impact on its quality.
+You must have Ghostscript (command: `gs`) and the `rghost` gem installed to use it.
+
+=== Install rghost
+
+To install the rghost gem, open a terminal and type the following command.
+
+ $ gem install rghost
+
+=== Convert and optimize
+
+Here's an example usage that converts your document and optimizes it:
+
+ $ asciidoctor-pdf -a optimize filename.adoc
+
+The command will generate an optimized PDF 1.4 file.
+In addition to optimizing the PDF file, it also converts it from plain PDF to a PDF/X-1a.
+
+If this command fails because the `gs` command cannot be found, you'll need to set it using the `GS` environment variable.
+On Windows, this step is almost always required since the Ghostscript installer does not install the `gs` command into a standard location.
+Here's an example that shows how you can override the `gs` command path:
+
+ $ GS=/path/to/gs asciidoctor-pdf -a optimize filename.adoc
+
+You'll need to use the technique for assigning an environment variable that's relevant for your system.
+
+The one limitation of generating a PDF/X-1a file is that it does not allow non-ASCII characters in the document metadata fields (i.e., title, author, subject, etc.).
+To work around this limitation, you can force Ghostscript to generate a PDF 1.3 file using the `pdf-version` attribute:
+
+ $ asciidoctor-pdf -a optimize -a pdf-version=1.3 filename.adoc
+
+CAUTION: Downgrading the PDF version may break the PDF if it contains an image that uses color blending or transparency.
+Specifically, the text on the page can become rasterized, which causes links to stop working and prevents text from being selected.
+If you're in this situation, it might be best to try <<hexapdf>> instead.
+
+If you're looking for a smaller file size, you can try reducing the quality of the output file by passing a quality keyword to the `optimize` attribute (e.g., `--optimize=screen`).
+The `optimize` attribute accepts the following keywords: `default` (default, same if value is empty), `screen`, `ebook`, `printer`, and `prepress`.
+Refer to the https://www.ghostscript.com/doc/current/VectorDevices.htm#PSPDF_IN[Ghostscript documentation^] to learn what settings these presets affect.
+
+If you've already generated the PDF, and want to optimize it directly, you can use the bin script:
+
+ $ asciidoctor-pdf-optimize filename.pdf
+
+The command will overwrite the PDF file with an optimized version.
+You can also try reducing the quality of the output file using the `--quality` flag (e.g., `--quality screen`).
+The `--quality` flag accepts the following keywords: `default` (default), `screen`, `ebook`, `printer`, and `prepress`.
+
+In both cases, if a file is found with the extension `.pdfmark` and the same rootname as the input file, it will be used to add metadata to the generated PDF document.
+This file is necessary when using versions of Ghostscript < 8.54, which did not automatically preserve this metadata.
+You can instruct the converter to automatically generate a pdfmark file by setting the `pdfmark` attribute (i.e., `-a pdfmark`)
+When using a more recent version of Ghostscript, you do not need to generate a `.pdfmark` file for this purpose.
+
+IMPORTANT: The `asciidoctor-pdf-optimize` is not guaranteed to reduce the size of the PDF file.
+It may actually make the PDF larger.
+You should probably only consider using it if the file size of the original PDF is several megabytes.
+
+If you have difficulty getting the `rghost` gem installed, or you aren't getting the results you expect, you can try the optimizer provided by hexapdf instead.
+
+[#hexapdf]
+== hexapdf
+
+Another option to optimize the PDF is {url-hexapdf}[hexapdf^] (gem: hexapdf, command: hexapdf).
+Before introducing it, though, it's important to point out that its license is AGPL.
+If that's okay with you, read on to learn how to use it.
+
+=== Install hexapdf
+
+First, install the hexapdf gem using the following command:
+
+ $ gem install hexapdf
+
+=== Compress a PDF
+
+You can then use it to optimize your PDF as follows:
+
+ $ hexapdf optimize --compress-pages --force filename.pdf filename.pdf
+
+This command does not manipulate the images in any way.
+It merely compresses the objects in the PDF and prunes any unreachable references.
+But given how much waste Prawn leaves behind, this turns out to reduce the file size substantially.
+
+You can hook this command directly into the converter by providing your own implementation of the `Optimizer` class.
+Start by creating a Ruby file named [.path]_optimizer-hexapdf.rb_, then populate it with the following code:
+
+.optimizer-hexapdf.rb
+[source,ruby]
+----
+require 'hexapdf/cli'
+
+class Asciidoctor::PDF::Optimizer
+ def initialize(*)
+ app = HexaPDF::CLI::Application.new
+ app.instance_variable_set :@force, true
+ @optimize = app.main_command.commands['optimize']
+ end
+
+ def optimize_file path
+ options = @optimize.instance_variable_get :@out_options
+ options.compress_pages = true
+ #options.object_streams = :preserve
+ #options.xref_streams = :preserve
+ #options.streams = :preserve # or :uncompress
+ @optimize.execute path, path
+ nil
+ rescue
+ # retry without page compression, which can sometimes fail
+ options.compress_pages = false
+ @optimize.execute path, path
+ nil
+ end
+end
+----
+
+To activate your custom optimizer, load this file when invoking the `asciidoctor-pdf` using the `-r` flag and set the `optimize` attribute as well using the `-a` flag.
+
+ $ asciidoctor-pdf -r ./optimizer-hexapdf.rb -a optimize filename.adoc
+
+Now you can convert and optimize all in one go.
+
+To see more options that `hexapdf optimize` offers, run:
+
+ $ hexapdf help optimize
+
+For example, to make the source of the PDF a bit more readable (though less optimized), set the stream-related options to `preserve` (e.g.,, `--streams preserve` from the CLI or `options.streams = :preserve` from the API).
+You can also disable page compression (e.g., `--no-compress-pages` from the CLI or `options.compress_pages = false` from the API).
+
+hexapdf also allows you to add password protection to your PDF, if that's something you're interested in doing.
+
+== Rasterizing the PDF
+
+Instead of optimizing the objects in the vector PDF, you may want to rasterize the PDF instead.
+Rasterizing the PDF prevents any of the text or other objects from being selected, similar to a scanned document.
+
+Asciidoctor PDF doesn't provide built-in support for rasterizing the generated PDF.
+However, you can use Ghostscript to flatten all the text in the PDF, thus preventing it from being selected.
+
+ $ gs -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -dNoOutputFonts -r300 -o output.pdf input.pdf
+
+You can adjust the value of the `-r` option (the density) to get a higher or lower quality result.
+
+Alternately, you can use the `convert` command from ImageMagick to convert each page in the PDF to an image.
+
+ $ convert -density 300 -quality 100 input.pdf output.pdf
+
+Yet another option is to combine Ghostscript and ImageMagick to produce a PDF with pages converted to images.
+
+ $ gs -dBATCH -dNOPAUSE -sDEVICE=png16m -o /tmp/tmp-%02d.png -r300 input.pdf
+ convert /tmp/tmp-*.png output.pdf
+ rm -f /tmp/tmp-*.png
+
+Using Ghostscript to handle the rasterization produces a much smaller output file.
+The drawback of using Ghostscript in this way is that it has to use intermediate files.
diff --git a/docs/modules/ROOT/pages/page-range.adoc b/docs/modules/ROOT/pages/page-range.adoc
new file mode 100644
index 00000000..2e5db6c9
--- /dev/null
+++ b/docs/modules/ROOT/pages/page-range.adoc
@@ -0,0 +1,10 @@
+= Page Ranges
+
+== Printing page ranges
+
+The print dialog doesn't understand the page numbers labels (which appear in the running content).
+Instead, it only considers physical pages.
+Therefore, to print a range of pages as they are labeled in the document, you need to add the number of front matter pages (i.e., the non-numbered pages) to the page number range in the print dialog.
+
+For example, if you only want to print the first 5 pages labeled with a page number (e.g., 1-5), and there are 2 pages before the page labeled as page 1, you need to add 2 to both numbers in the range, giving you a physical page range of 3-7.
+That's the range you need to enter into the print dialog.
diff --git a/docs/modules/ROOT/pages/passthrough-content.adoc b/docs/modules/ROOT/pages/passthrough-content.adoc
new file mode 100644
index 00000000..6f112d4b
--- /dev/null
+++ b/docs/modules/ROOT/pages/passthrough-content.adoc
@@ -0,0 +1,29 @@
+= Passthrough Content
+
+== Skipping passthrough content
+
+Asciidoctor PDF does not support arbitrary passthrough content.
+While the basebackend for the PDF converter is html, it only recognizes a limited subset of inline HTML elements that can be mapped to PDF (e.g., a, strong, em, code, etc.).
+Therefore, if your content contains passthrough blocks or inlines, you most likely have to use a conditional preprocessor to skip them (and make other arrangements).
+
+Here's an example of how to skip a passthrough block when converting to PDF:
+
+[source,asciidoc]
+----
+\ifndef::backend-pdf[]
+<script>
+//...
+</script>
+\endif::[]
+----
+
+Here's an example of how to only enable a passthrough block when converting to HTML5:
+
+[source,asciidoc]
+----
+\ifdef::backend-html5[]
+<script>
+//...
+</script>
+\endif::[]
+----
diff --git a/docs/modules/ROOT/pages/stem.adoc b/docs/modules/ROOT/pages/stem.adoc
new file mode 100644
index 00000000..46409333
--- /dev/null
+++ b/docs/modules/ROOT/pages/stem.adoc
@@ -0,0 +1,56 @@
+= STEM
+:url-asciidoctor-mathematical: https://github.com/asciidoctor/asciidoctor-mathematical
+
+When converting to HTML, Asciidoctor relies on the JavaScript-based MathJax library to parse and render the STEM expressions in the browser when the page is loaded.
+The HTML converter wraps the expressions in special markup so MathJax can find and process them.
+However, unlike Asciidoctor's built-in HTML converter, Asciidoctor PDF does not provide native support for STEM blocks and inline macros (i.e., asciimath and latexmath).
+
+In order to insert a rendered expression into the PDF, the toolchain must parse the expressions and convert them to a format the PDF writer (Prawn) can understand.
+That typically means converting to an image.
+
+One solution that provides this capability is an extension named <<mathematical>>, which is covered in the next section.
+
+////
+Another solution, which is still under development, uses Mathoid to convert STEM equations to images.
+Mathoid is a library that invokes MathJax using a headless browser, so it supports both asciimath and latexmath equations.
+That prototype can be found in the https://github.com/asciidoctor/asciidoctor-extensions-lab#extension-catalog[Asciidoctor extensions lab].
+////
+
+[#mathematical]
+== Asciidoctor Mathematical
+
+{url-asciidoctor-mathematical}[Asciidoctor Mathematical] is an extension that processes STEM blocks and inline macros and converts them to a PDF-compatible format.
+After the document has been parsed, the extension locates each asciimath, latexmath, and stem block and inline macro, converts the expression to an image, and replaces the expression with an image.
+It uses Mathematical to render the LaTeX notation as an image.
+If the expression is AsciiMath, it first uses AsciiMath gem to convert to LaTeX.
+Conversion then proceeds as normal.
+
+Asciidoctor Mathematical is a Ruby gem that uses native extensions.
+It has a few system prerequisites which limit installation to Linux and macOS.
+Refer to the {url-asciidoctor-mathematical}#installation[installation section^] in the Asciidoctor Mathematical README to learn how to install it.
+
+=== Activate Asciidoctor Mathematical
+
+Once Asciidoctor Mathematical is installed, you can enable it when invoking Asciidoctor PDF using the `-r` flag:
+
+ $ asciidoctor-pdf -r asciidoctor-mathematical sample.adoc
+
+If you're invoking Asciidoctor PDF via the API, you need to require the Asciidoctor Mathematical gem before invoking Asciidoctor PDF.
+
+[source,ruby]
+----
+require 'asciidoctor-mathematical'
+require 'asciidoctor-pdf'
+
+Asciidoctor.convert_file 'sample.adoc', backend: 'pdf', safe: :safe
+----
+
+[#mathematical-format]
+=== mathematical-format attribute
+
+To get the best quality output and maximize the speed of conversion, we recommend configuring Asciidoctor Mathematical to convert equations to SVG.
+You control this setting using the `mathematical-format` AsciiDoc attribute:
+
+ $ asciidoctor-pdf -r asciidoctor-mathematical -a mathematical-format=svg sample.adoc
+
+Refer to the {url-asciidoctor-mathematical}#readme[README^] for Asciidoctor Mathematical to learn about additional settings and options.
diff --git a/docs/modules/ROOT/pages/syntax-highlighting.adoc b/docs/modules/ROOT/pages/syntax-highlighting.adoc
new file mode 100644
index 00000000..816f2d7a
--- /dev/null
+++ b/docs/modules/ROOT/pages/syntax-highlighting.adoc
@@ -0,0 +1,29 @@
+= Syntax Highlighting
+
+[#install]
+== Install a syntax highlighter
+
+To syntax highlight source listings, you need to install Rouge, Pygments, or CodeRay.
+Choose one (or more) of the following:
+
+.Rouge (preferred, minimum version: 2.0.0)
+ $ gem install rouge
+
+//TODO Remove the version of Rouge from the content above. The minimum version should be listed in the supported platforms table instead.
+
+.Pygments
+ $ gem install pygments.rb
+
+.CodeRay
+ $ gem install coderay
+
+[#activate]
+== Activate syntax highlighting
+
+Once you've installed a syntax highlighter, you need to activate it for a given document by setting the `source-highlighter` attribute in the document header and assigning it the keyword value of the applicable library.
+
+[source,asciidoc]
+----
+= Document Title
+:source-highlighter: rouge
+----
diff --git a/docs/modules/ROOT/pages/title-page.adoc b/docs/modules/ROOT/pages/title-page.adoc
new file mode 100644
index 00000000..9f6e4744
--- /dev/null
+++ b/docs/modules/ROOT/pages/title-page.adoc
@@ -0,0 +1,15 @@
+= Title Page
+
+The Asciidoctor PDF converter introduces a dedicated title page at the start of the document.
+The title page contains the doctitle, author, date, and revision info.
+If a front cover image is specified, the title page comes after the front cover.
+The title page can be styled using the theme and reserved page attributes.
+
+== Enable the title page
+
+The title page is enabled if one of these conditions is met:
+
+* The document has the `book` doctype.
+* The `title-page` attribute is set (with an empty value) in the document header.
+
+When the title page is enabled, the table of contents also gets its own page (or pages, if necessary).
diff --git a/docs/modules/ROOT/pages/toc.adoc b/docs/modules/ROOT/pages/toc.adoc
new file mode 100644
index 00000000..21ee2e5e
--- /dev/null
+++ b/docs/modules/ROOT/pages/toc.adoc
@@ -0,0 +1,21 @@
+= Table of Contents
+:navtitle: TOC
+
+== Add a table of contents
+
+The table of contents (TOC) is not included by default.
+The TOC is only included if the `toc` attribute is set on the document.
+The value of this attribute determines the placement.
+If a value is not specified, the placement defaults to `auto`, which is directly after the document title.
+
+For documents that have the book doctype, the TOC is inserted using discrete pages between the title page and the first page of content.
+For all other doctypes (unless the `title-page` attribute is set), the TOC is inserted in the flow of text.
+If a placement is not specified, that location is between the document title and the first block of content.
+
+While the table of contents is not included by default, the PDF outline is always included.
+The `toclevels` attribute controls the depth of both the TOC and the PDF outline (regardless of whether the TOC is enabled).
+The depth of the outline can be controlled independently using the `outlinelevels` attribute.
+Both attributes can also be set on individual sections to override the depth for a given section and its children.
+
+NOTE: If a document that has the book doctype includes a preface, an entry for the preface is only included in the TOC if the `preface-title` is assigned a value (e.g., `preface-title=Preface`).
+This value is used as the heading of the preface and as the text of the entry in the TOC.
diff --git a/docs/modules/ROOT/pages/verbatim-blocks.adoc b/docs/modules/ROOT/pages/verbatim-blocks.adoc
new file mode 100644
index 00000000..cbb910f0
--- /dev/null
+++ b/docs/modules/ROOT/pages/verbatim-blocks.adoc
@@ -0,0 +1,10 @@
+= Verbatim Blocks
+
+Verbatim blocks are listing, literal, and source blocks.
+
+== Verbatim blocks and performance
+
+Verbatim blocks are rendered with a shaded background.
+In order to calculate the dimensions of the shaded region, Asciidoctor PDF has to "`dry run`" the block to determine how many pages it consumes.
+While this strategy has a low impact when processing shorter blocks, it can drastically deteriorate performance when processing a block that spans dozens of pages.
+As a general rule of thumb, you should avoid creating verbatim blocks which span more than a handful of pages.
diff --git a/docs/modules/extend/nav.adoc b/docs/modules/extend/nav.adoc
new file mode 100644
index 00000000..b3e6772b
--- /dev/null
+++ b/docs/modules/extend/nav.adoc
@@ -0,0 +1,4 @@
+* xref:index.adoc[]
+** xref:converter-class-and-methods.adoc[]
+** xref:define-converter.adoc[]
+** xref:require-converter.adoc[]
diff --git a/docs/modules/extend/pages/converter-class-and-methods.adoc b/docs/modules/extend/pages/converter-class-and-methods.adoc
new file mode 100644
index 00000000..44f2dcf8
--- /dev/null
+++ b/docs/modules/extend/pages/converter-class-and-methods.adoc
@@ -0,0 +1,17 @@
+= Converter Class and Methods
+
+== Tailoring conversion
+
+The methods on a converter class that handle conversion follow the pattern `convert_<name>` for block elements (e.g., `convert_example`) and `convert_inline_<name>` for inline elements (e.g., `convert_inline_anchor`), where `<name>` is the name of the element.
+
+When you override a block element, you write PDF objects directly to the Prawn Document (the current context).
+When you override an inline element, you return pseudo-HTML, which is then parsed and converted into PDF objects.
+
+The pseudo-HTML in Asciidoctor PDF evolved from the inline formatting in Prawn, now supporting the following elements: a, br, button, code, color, del, em, font, img, key, mark, span, strong, sub, sup.
+All decimal and hexadecimal character references are supported, as well as the named entities amp, apos, gt, lt, nbsp, and quot (e.g., `\&apos;`).
+You can change the font color using the `rgb` attribute on the `color` element (e.g., `<color rgb="#ff0000">`) and the font family and size using the `name` and `size` attributes on the `font` element, respectively (e.g., `<font name="sans" size="12">`).
+You can also use the `style` attribute on `span` to control the font color, weight, and style using the relevant CSS property names.
+The pseudo-HTML in Asciidoctor PDF also supports the `class` attribute on any element for applying roles from the theme.
+(Though not recommended, you can pass this pseudo-HTML straight through to Prawn using an inline passthrough in AsciiDoc).
+
+To find all the available methods to override, see the {url-api-docs}[API docs^].
diff --git a/docs/modules/extend/pages/define-converter.adoc b/docs/modules/extend/pages/define-converter.adoc
new file mode 100644
index 00000000..d3228e43
--- /dev/null
+++ b/docs/modules/extend/pages/define-converter.adoc
@@ -0,0 +1,91 @@
+= Create an Extended Converter
+:url-infoq-template: https://github.com/mraible/infoq-mini-book/blob/main/src/main/ruby/asciidoctor-pdf-extensions.rb
+
+== Define an extended converter
+
+Starting with Asciidoctor 2, defining an extending converter and registering it in place of the original is straightforward.
+
+.custom-pdf-converter.rb
+[source,ruby]
+----
+class CustomPDFConverter < (Asciidoctor::Converter.for 'pdf')
+ register_for 'pdf'
+
+ # overrides go here
+end
+----
+
+As it stands, the converter doesn't do anything differently than the primary converter because we haven't yet overridden any of its methods.
+
+== Override a method
+
+Let's start by overriding the thematic break--the horizontal rule--to make it render like a ribbon.
+
+[source,ruby]
+----
+ def convert_thematic_break node
+ theme_margin :thematic_break, :top
+ stroke_horizontal_rule 'FF0000', line_width: 0.5, line_style: :solid
+ move_down 1
+ stroke_horizontal_rule 'FF0000', line_width: 1, line_style: :solid
+ move_down 1
+ stroke_horizontal_rule 'FF0000', line_width: 0.5, line_style: :solid
+ theme_margin :thematic_break, :bottom
+ end
+----
+
+This converter will replace the thematic break with a red ribbon.
+
+Another way to override the converter is to modify the node, then delegate back to the primary converter.
+
+== Modify a node
+
+Let's put a page break before all paragraphs unless the cursor is at the top of the page.
+We'll call `super` to let the primary converter handle the work of rendering the paragraph.
+
+[source,ruby]
+----
+ def convert_paragraph node
+ bounds.move_past_bottom unless at_page_top?
+ super
+ end
+----
+
+Now let's look at how to modify an inline element.
+Let's say we want to override the kbd element.
+
+[source,ruby]
+----
+ def convert_inline_kbd node
+ %(<strong><color rgb="AA0000">#{(node.attr 'keys').join ' + '}</color></strong>)
+ end
+----
+
+Refer to the primary converter to discover the pseudo-HTML you can use for inline elements.
+
+== Customize a page using an extended converter
+
+So far we've just been biting around the edges.
+A more realistic use case is to customize the part title page in a multi-part book.
+Since this is a specialized section element, there's a dedicated method named `layout_part_title` that you'll need to override.
+
+Let's customize the part title page by making the background orange, making the font white, centering the title on the page, and disabling the running content.
+(You don't need to start a new page before and after the part title since that's already done for you).
+
+[source,ruby]
+----
+ def layout_part_title node, title, opts = {}
+ fill_absolute_bounds 'E64C3D'
+ move_down 20
+ typeset_text title, (calc_line_metrics 1.5), color: 'FFFFFF', inline_format: true, align: :center, size: 42
+ page.instance_variable_set :@imported_page, true
+ end
+----
+
+The method `typeset_text` and `calc_line_metrics` are provided by Asciidoctor PDF to make writing text easier.
+If you wanted, you could just use the low-level `text` method provided by Prawn.
+
+To find all the available methods to override, consult the {url-api-docs}[API docs^].
+For deeper examples of how to override the behavior of the converter, refer to the extended converter in the {url-infoq-template}[InfoQ Mini-Book template^].
+
+Now that you've seen some examples of how to extend the converter, let's look at how to use it.
diff --git a/docs/modules/extend/pages/index.adoc b/docs/modules/extend/pages/index.adoc
new file mode 100644
index 00000000..7fb7d1d7
--- /dev/null
+++ b/docs/modules/extend/pages/index.adoc
@@ -0,0 +1,26 @@
+= Extend the PDF Converter
+:url-typeset-with-prawn: https://www.sitepoint.com/hackable-pdf-typesetting-in-ruby-with-prawn/
+
+Asciidoctor PDF uses {url-prawn}[Prawn^] under the covers to generate the PDF.
+Prawn is a low-level PDF writer that can load fonts, ink text, embed images, add graphics, and draw lines.
+With those operations alone, this converter manages to produce a PDF from an AsciiDoc document.
+This page explains the role of theming in this process and how to extend the converter to take it further.
+
+== Prawn
+
+Before you dive into extending this converter, you'll need to understand how to use Prawn.
+The article {url-typeset-with-prawn}[Hackable PDF Typesetting in Ruby with Prawn^] gives a crash course in how to create your first PDF document containing text, graphics, and images with Prawn.
+That article is essential reading for extending Asciidoctor PDF, because Asciidoctor PDF uses many of the same operations (as well as many helpful add-ons).
+Once you feel comfortable with Prawn, you're ready to extend the converter.
+
+== Going beyond theming
+
+While creating the PDF document, there are thousands of small decisions the converter must make about how to instruct Prawn to layout the content elements on the page (so-called "`hackable typesetting`").
+But once these elements are written, they can't be moved or styled (as is the case with HTML and CSS).
+To help influence those decisions--and thus prevent the converter from becoming too opinionated, a theming system was introduced.
+
+The theme support is there to provide basic customizations (fonts, colors, borders, spacing, etc.).
+But it can only go so far.
+At some point, it becomes necessary to extend the converter to meet advanced design requirements.
+
+
diff --git a/docs/modules/extend/pages/require-converter.adoc b/docs/modules/extend/pages/require-converter.adoc
new file mode 100644
index 00000000..008ab8e9
--- /dev/null
+++ b/docs/modules/extend/pages/require-converter.adoc
@@ -0,0 +1,10 @@
+= Use an Extended Converter
+
+== Require the extended converter
+
+To use this converter, require it by passing the path to the `-r` flag when calling the `asciidoctor-pdf` command:
+
+ $ asciidoctor-pdf -r ./custom-pdf-converter.rb document.adoc
+
+That's all there is too it.
+Now you're hacking the typesetting!
diff --git a/docs/modules/theme/nav.adoc b/docs/modules/theme/nav.adoc
new file mode 100644
index 00000000..a376d179
--- /dev/null
+++ b/docs/modules/theme/nav.adoc
@@ -0,0 +1,70 @@
+* xref:index.adoc[]
+** xref:language.adoc[]
+*** xref:measurement-units.adoc[]
+*** xref:text.adoc[]
+*** xref:image.adoc[]
+*** xref:color.adoc[]
+*** xref:variables.adoc[]
+*** xref:math-operations.adoc[]
+*** xref:quoted-string.adoc[]
+** xref:font-support.adoc[]
+*** xref:custom-font.adoc[]
+*** xref:prepare-custom-font.adoc[]
+*** xref:fallback-font.adoc[]
+*** xref:cjk.adoc[]
+** xref:extend-theme.adoc[]
+** xref:apply-theme.adoc[]
+** xref:asciidoc-attributes.adoc[]
+** xref:page-numbers.adoc[]
+** xref:print-and-prepress.adoc[]
+** xref:source-highlighting-theme.adoc[]
+* xref:keys.adoc[]
+** xref:extends.adoc[]
+** xref:font.adoc[]
+** xref:page.adoc[]
+** xref:base.adoc[]
+** xref:role.adoc[]
+** xref:abstract.adoc[]
+** xref:admonition.adoc[]
+** xref:block.adoc[]
+** xref:block-image.adoc[]
+** xref:button.adoc[]
+** xref:callout.adoc[]
+** xref:caption.adoc[]
+** xref:code.adoc[]
+** xref:codespan.adoc[]
+** xref:cover.adoc[]
+** xref:description-list.adoc[]
+** xref:example.adoc[]
+** xref:footnotes.adoc[]
+** xref:heading.adoc[]
+** xref:index-section.adoc[]
+** xref:keyboard.adoc[]
+** xref:link.adoc[]
+** xref:list.adoc[]
+** xref:mark.adoc[]
+** xref:menu.adoc[]
+** xref:prose.adoc[]
+** xref:quote.adoc[]
+** xref:quotes.adoc[]
+** xref:running-content.adoc[]
+** xref:section.adoc[]
+** xref:sidebar.adoc[]
+** xref:svg.adoc[]
+** xref:table.adoc[]
+** xref:thematic-break.adoc[]
+** xref:title-page.adoc[]
+** xref:toc.adoc[]
+** xref:verse.adoc[]
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/modules/theme/pages/abstract.adoc b/docs/modules/theme/pages/abstract.adoc
new file mode 100644
index 00000000..0e66edcb
--- /dev/null
+++ b/docs/modules/theme/pages/abstract.adoc
@@ -0,0 +1,128 @@
+= Abstract Category Keys
+:navtitle: Abstract
+
+== abstract
+
+The keys in the `abstract` category control the arrangement and style of the abstract.
+
+.abstract keys
+[#key-prefix-abstract,cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+
+|font-color
+|xref:color.adoc[Color] +
+(default: $base-font-color)
+|abstract:
+font-color: #5c6266
+
+|font-size
+|xref:language.adoc#values[Number] +
+(default: 13.5)
+|abstract:
+font-size: 13
+
+|font-style
+|xref:text.adoc#font-style[Font style] +
+(default: $base-font-style)
+|abstract:
+font-style: italic
+
+|text-transform
+|xref:text.adoc#transform[Text transform] +
+(default: $base-text-transform)
+|abstract:
+text-transform: uppercase
+
+|line-height
+|xref:language.adoc#values[Number] +
+(default: 1.4)
+|abstract:
+line-height: 1.4
+
+|padding
+|xref:measurement-units.adoc[Measurement] {vbar} xref:measurement-units.adoc[Measurement[top,right,bottom,left\]] +
+(default: 0)
+|abstract:
+padding: [0, 12, 0, 12]
+|===
+
+== abstract-first-line
+
+The keys in the `abstract-first-line` category control the style of the first line of the abstract.
+
+.abstract-first-line keys
+[#key-prefix-abstract-first-line,cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+|font-color
+|xref:color.adoc[Color] +
+(default: _not set_)
+|abstract:
+first-line:
+font-color: #AA0000
+
+|font-style
+|xref:text.adoc#font-style[Font style] +
+(default: _not set_)
+|abstract:
+first-line:
+font-style: bold
+|===
+
+== abstract-title
+
+The keys in the `abstract-title` category control the style and alignment of the abstract's title.
+
+.abstract-title keys
+[#key-prefix-abstract-title,cols="3,4,5l"]
+|===
+|align
+|xref:text.adoc#align[Text alignment] +
+(default: center)
+|abstract:
+title:
+align: center
+
+|font-color
+|xref:color.adoc[Color] +
+(default: $base-font-color)
+|abstract:
+title:
+font-color: #333333
+
+|font-family
+|xref:font-support.adoc[Font family name] +
+(default: $base-font-family)
+|abstract:
+title:
+font-family: Noto Serif
+
+|font-kerning
+|normal {vbar} none +
+(default: _inherit_)
+|abstract:
+title:
+font-kerning: none
+
+|font-size
+|xref:language.adoc#values[Number] +
+(default: $base-font-size)
+|abstract:
+title:
+font-size: 13
+
+|font-style
+|xref:text.adoc#font-style[Font style] +
+(default: bold)
+|abstract:
+title:
+font-style: bold
+
+|text-transform
+|xref:text.adoc#transform[Text transform] +
+(default: $base-text-transform)
+|abstract:
+title:
+text-transform: uppercase
+|===
diff --git a/docs/modules/theme/pages/admonition.adoc b/docs/modules/theme/pages/admonition.adoc
new file mode 100644
index 00000000..3dba4423
--- /dev/null
+++ b/docs/modules/theme/pages/admonition.adoc
@@ -0,0 +1,251 @@
+= Admonition Category Keys
+:navtitle: Admonition
+
+== admonition
+
+The keys in the `admonition` category control the arrangement and style of admonition blocks and the icon used for each admonition type.
+
+[#key-prefix-admonition,cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+
+|column-rule-color
+|xref:color.adoc[Color] +
+(default: #eeeeee)
+|admonition:
+column-rule-color: #aa0000
+
+|column-rule-style
+|solid {vbar} double {vbar} dashed {vbar} dotted +
+(default: solid)
+|admonition:
+column-rule-style: double
+
+|column-rule-width
+|xref:language.adoc#values[Number] +
+(default: 0.5)
+|admonition:
+column-rule-width: 0.5
+
+|font-color
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|admonition:
+font-color: #999999
+
+|font-family
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|admonition:
+font-family: Noto Sans
+
+|font-kerning
+|normal {vbar} none +
+(default: _inherit_)
+|admonition:
+font-kerning: none
+
+|font-size
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|admonition:
+font-size: $base-font-size-large
+
+|font-style
+|xref:text.adoc#font-style[Font style] +
+(default: _inherit_)
+|admonition:
+font-style: italic
+
+|text-transform
+|xref:text.adoc#transform[Text transform] +
+(default: _inherit_)
+|admonition:
+text-transform: none
+
+|padding
+|xref:measurement-units.adoc[Measurement] {vbar} xref:measurement-units.adoc[Measurement[top,right,bottom,left\]] +
+(default: [0, 12, 0, 12])
+|admonition:
+padding: [0, 12, 0, 12]
+|===
+
+== admonition-label
+
+The keys in the `admonition-label` category control the arrangement and style of the text-based labels on admonition blocks.
+Top and bottom padding values are ignored on the `admonition-label-padding` key.
+
+[#key-prefix-admonition-label,cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+
+|align
+|xref:text.adoc#align[Text alignment] +
+(default: center)
+|admonition:
+label:
+align: center
+
+|font-color
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|admonition:
+label:
+font-color: #262626
+
+|font-family
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|admonition:
+label:
+font-family: M+ 1p
+
+|font-kerning
+|normal {vbar} none +
+(default: _inherit_)
+|admonition:
+label:
+font-kerning: none
+
+|font-size
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|admonition:
+label:
+font-size: 12
+
+|font-style
+|xref:text.adoc#font-style[Font style] +
+(default: bold)
+|admonition:
+label:
+font-style: bold_italic
+
+|min-width
+|xref:measurement-units.adoc[Measurement] +
+(default: _not set_)
+|admonition:
+label:
+min-width: 48
+
+|padding
+|xref:measurement-units.adoc[Measurement] {vbar} xref:measurement-units.adoc[Measurement[top,right,bottom,left\]] +
+(default: $admonition-padding)
+|admonition:
+label:
+padding: [0, 12, 0, 12]
+
+|text-transform
+|xref:text.adoc#transform[Text transform] +
+(default: uppercase)
+|admonition:
+label:
+text-transform: lowercase
+
+|vertical-align
+|top {vbar} middle {vbar} bottom +
+(default: middle)
+|admonition:
+label:
+vertical-align: top
+|===
+
+=== admonition-label-<name>
+
+The keys in the `admonition-label-<name>` category control the arrangement and style of the text-based label that matches a built-in admonition name.
+`<name>` can be `note`, `tip`, `warning`, `important`, or `caution`.
+
+[#key-prefix-admonition-label-name,cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+
+|font-color
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|admonition:
+label:
+caution:
+font-color: #262626
+
+|font-family
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|admonition:
+label:
+important:
+font-family: M+ 1p
+
+|font-kerning
+|normal {vbar} none +
+(default: _inherit_)
+|admonition:
+label:
+warning:
+font-kerning: none
+
+|font-size
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|admonition:
+label:
+tip:
+font-size: 12
+
+|font-style
+|xref:text.adoc#font-style[Font style] +
+(default: bold)
+|admonition:
+label:
+tip:
+font-style: bold_italic
+
+|text-transform
+|xref:text.adoc#transform[Text transform] +
+(default: uppercase)
+|admonition:
+label:
+note:
+text-transform: lowercase
+|===
+
+== admonition-icon-<name>
+
+The keys in the `admonition-icon-<name>` category control the arrangement and style of the specified icon associated with a built-in admonition name.
+`<name>` can be `note`, `tip`, `warning`, `important`, or `caution`.
+All icon types must be grouped under a single `icons` category.
+In other words, _do not_ declare the `icons` category multiple times.
+The keys in the `admonition-icon` category can't be flattened (e.g., `tip-name: far-lightbulb` is not valid syntax).
+
+The `<icon set>-<icon name>` value is required when assigning an icon to a built-in admonition.
+See the `.yml` files in the https://github.com/jessedoyle/prawn-icon/tree/master/data/fonts[prawn-icon repository^] for a list of valid icon names.
+The prefix (e.g., `fas-`) of the value determines which font set to use.
+If the prefix is not specified, `fa-` is assumed.
+
+[#key-prefix-admonition-icon,cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+
+|name
+|<icon set>-<icon name> +
+(default: _not set_)
+|admonition:
+icon:
+tip:
+name: fas-fire
+
+|stroke-color
+|xref:color.adoc[Color] +
+(default: caution=#bf3400; important=#bf0000; note=#19407c; tip=#111111; warning=#bf6900)
+|admonition:
+icon:
+important:
+stroke-color: ff0000
+
+|size
+|xref:language.adoc#values[Number] +
+(default: 24)
+|admonition:
+icon:
+note:
+size: 24
+|===
diff --git a/docs/modules/theme/pages/apply-theme.adoc b/docs/modules/theme/pages/apply-theme.adoc
new file mode 100644
index 00000000..ea7c223b
--- /dev/null
+++ b/docs/modules/theme/pages/apply-theme.adoc
@@ -0,0 +1,75 @@
+= Apply a Theme
+
+After creating a theme, you'll need to tell Asciidoctor PDF where to find it.
+This is done using AsciiDoc attributes.
+
+== Theme and font directories
+
+There are three AsciiDoc attributes that tell Asciidoctor PDF how to locate and apply your theme.
+
+pdf-theme:: The name of the YAML theme file to load.
+If the name ends with `.yml`, it's assumed to be the complete name of a file and is resolved relative to `pdf-themesdir`, if specified, otherwise the current directory.
+Otherwise, `-theme.yml` is appended to the name to make the file name (i.e., `<name>-theme.yml`) and is resolved relative to `pdf-themesdir`, if specified, otherwise the built-in themes dir.
+
+pdf-themesdir:: The directory where the theme file is located.
+_Specifying an absolute path is recommended._
++
+If you use images in your theme, image paths are resolved relative to this directory.
+If `pdf-theme` ends with `.yml`, and `pdf-themesdir` is not specified, then `pdf-themesdir` defaults to the directory of the path specified by `pdf-theme`.
+
+pdf-fontsdir:: The directory or directories where the fonts used by your theme, if any, are located.
+Multiple entries must be separated by either a comma or a semi-colon.
+To reference a file inside a JAR file on the classpath, prefix with the path with `uri:classloader:` (AsciidoctorJ only).
+_Specifying an absolute path is recommended._
+
+== Load a theme
+
+Let's assume that you've put your theme files inside a directory named `resources` with the following layout:
+
+....
+document.adoc
+resources/
+ themes/
+ basic-theme.yml
+ fonts/
+ roboto-normal.ttf
+ roboto-italic.ttf
+ roboto-bold.ttf
+ roboto-bold_italic.ttf
+....
+
+Here's how you'd load your theme when calling Asciidoctor PDF:
+
+ $ asciidoctor-pdf -a pdf-themesdir=resources/themes -a pdf-theme=basic -a pdf-fontsdir=resources/fonts
+
+If all goes well, Asciidoctor PDF should run without an error or warning.
+
+NOTE: You only need to specify the `pdf-fontsdir` if you're using custom fonts in your theme.
+
+You can skip setting the `pdf-themesdir` attribute and just pass the absolute path of your theme file to the `pdf-theme` attribute.
+
+ $ asciidoctor-pdf -a pdf-theme=resources/themes/basic-theme.yml -a pdf-fontsdir=resources/fonts
+
+However, in this case, image paths in your theme won't be resolved properly.
+
+Paths are resolved relative to the current directory.
+However, in the future, this may change so that paths are resolved relative to the base directory (typically the document's directory).
+Therefore, it's recommend that you specify absolute paths for now to future-proof your configuration.
+
+ $ asciidoctor-pdf -a pdf-themesdir=/path/to/resources/themes -a pdf-theme=basic -a pdf-fontsdir=/path/to/resources/fonts
+
+== Using Maven and Gradle
+
+As usual, you can also use build tools like Maven and Gradle to build a themed PDF.
+The only thing you need to add to an existing build is the attributes mentioned above.
+
+* https://github.com/asciidoctor/asciidoctor-maven-examples/tree/master/asciidoctor-pdf-with-theme-example[Maven Example^]
+* https://github.com/asciidoctor/asciidoctor-gradle-examples/tree/master/asciidoc-to-pdf-with-theme-example[Gradle Example^]
+
+Speaking of Java, you can bundle and distribute your theme and fonts in a jar file.
+To reference the theme file and/or directory of fonts from inside the jar, refer to their location on the classpath using the `uri:classloader:` prefix.
+Here's how you'd load both the theme and fonts from the classpath:
+
+ $ asciidoctorj -b pdf -a pdf-theme="uri:classloader:/path/to/themes/my-theme.yml" -a pdf-fontsdir="uri:classloader:/path/to/fonts" document.adoc
+
+This only works when running Asciidoctor PDF on the JVM.
diff --git a/docs/modules/theme/pages/asciidoc-attributes.adoc b/docs/modules/theme/pages/asciidoc-attributes.adoc
new file mode 100644
index 00000000..9c4c6b61
--- /dev/null
+++ b/docs/modules/theme/pages/asciidoc-attributes.adoc
@@ -0,0 +1,172 @@
+= Theme-Related AsciiDoc Attributes
+
+There are various settings in the theme you control using document attributes.
+
+== AsciiDoc document attributes
+
+If an attribute is marked as "Header Only", it only takes effect if defined in the AsciiDoc document header or via the API.
+If an attribute matches a key in the theme file, the attribute takes precedence.
+
+[cols="2,3,^1,6l"]
+|===
+|Attribute |Value Type | Header Only |Example
+
+|autofit-option
+|flag (default: _not set_)
+|No
+|:autofit-option:
+
+|<face>-cover-image^[1]^
+|path^[2]^ {vbar} image macro^[3]^ +
+(format can be image or PDF)
+|Yes
+|:front-cover-image: image:front-cover.pdf[]
+
+|hyphens^[7]^
+|language code {vbar} _blank_ to default to en_us (default: _not set_)
+|Yes
+|:hyphens: de
+
+|icons^[13]^
+|font {vbar} image (default: _not set_)
+|No
+|:icons: font
+
+|media
+|screen {vbar} print {vbar} prepress
+|Yes
+|:media: prepress
+
+|compress
+|flag (default: _not set_)
+|Yes
+|:compress:
+
+|optimize
+|screen {vbar} ebook {vbar} printer {vbar} prepress {vbar} default (default: default)
+|Yes
+|:optimize: prepress
+
+|outlinelevels^[12]^
+|Integer {vbar} Integer:Integer (default: same as _toclevels_)
+|Yes
+|:outlinelevels: 2
+
+|page-background-image^[4]^
+|path^[2]^ {vbar} image macro^[3]^
+|Yes
+|:page-background-image: image:bg.jpg[]
+
+|page-background-image-(recto{vbar}verso)^[4]^
+|path^[2]^ {vbar} image macro^[3]^
+|Yes
+|:page-background-image-recto: image:bg-recto.jpg[]
+
+|page-foreground-image
+|path^[2]^ {vbar} image macro^[3]^
+|Yes
+|:page-foreground-image: image:watermark.svg[]
+
+|pagenums^[5]^
+|flag (default: _set_)
+|Yes
+|:pagenums:
+
+|pdf-page-layout
+|portrait {vbar} landscape
+|Yes
+|:pdf-page-layout: landscape
+
+|pdf-page-margin
+|xref:measurement-units.adoc[Measurement] {vbar} xref:measurement-units.adoc[Measurement[top,right,bottom,left\]]
+|Yes
+|:pdf-page-margin: [1in, 0.5in]
+
+|pdf-page-mode
+|outline {vbar} none {vbar} thumbs {vbar} fullscreen {vbar} fullscreen outline {vbar} fullscreen none {vbar} fullscreen thumbs (default: outline)
+|Yes
+|:pdf-page-mode: fullscreen none
+
+|pdf-page-size
+|https://github.com/prawnpdf/pdf-core/blob/0.6.0/lib/pdf/core/page_geometry.rb#L16-L68[Named size^] {vbar} xref:measurement-units.adoc[Measurement[width, height\]]
+|Yes
+|:pdf-page-size: [6in, 9in]
+
+|pdf-folio-placement
+|virtual {vbar} virtual-inverted {vbar} physical {vbar} physical-inverted
+|Yes
+|:pdf-folio-placement: physical
+
+|pdf-version
+|1.3 {vbar} 1.4 {vbar} 1.5 {vbar} 1.6 {vbar} 1.7 (default: 1.4)
+|Yes
+|:pdf-version: 1.7
+
+|pdfmark^[6]^
+|flag (default: _not set_)
+|Yes
+|:pdfmark:
+
+|scripts^[8]^
+|cjk (default: _not set_)
+|Yes
+|:scripts: cjk
+
+|text-align^[9]^
+|xref:text.adoc#align[Text alignment]
+|Yes
+|:text-align: left
+
+|title-logo-image
+|path^[2]^ {vbar} image macro^[3]^
+|Yes
+|:title-logo-image: image:logo.png[top=25%, align=center, pdfwidth=0.5in]
+
+|title-page^[10]^
+|flag (default: _not set_)
+|Yes
+|:title-page:
+
+|title-page-background-image
+|path^[2]^ {vbar} image macro^[3]^
+|Yes
+|:title-page-background-image: image:title-bg.jpg[]
+
+|toc-max-pagenum-digits^[11]^
+|Integer (default: 3)
+|Yes
+|:toc-max-pagenum-digits: 4
+|===
+
+1. `<face>` can be `front` or `back`.
+2. A bare path is resolved relative to base_dir, which defaults to the document directory.
+3. The target of the image macro is resolved relative to `imagesdir` since it's defined in the AsciiDoc document (unlike in the theme, where it is resolved relative to the value of `pdf-themesdir`).
+4. By default, page background images are automatically scaled to fit the bounds of the page (i.e., `fit=contain`) and centered (i.e., `position=center`).
+The size of the background image can be controlled using any of the sizing attributes on the image macro (i.e., fit, pdfwidth, scaledwidth, or width) when `fit=none`.
+The position of the background image can be controlled using the `position` attribute.
+If the recto (right-hand, odd-numbered pages) or verso (left-hand, even-numbered pages) background is specified, it will be used only for that side.
+If a background image isn't specified for a side, the converter will use the default page background image (`page-background-image`), if specified.
+To disable the background image for a side, use the value `none`.
+5. Controls whether the implicit `page-number` attribute is to the running header and footer content specified in the theme file.
+Instead of disabling page numbers, you can use the `noheader` and `nofooter` attributes to disable the running header and footer, respectively.
+6. Enables generation of the https://milan.kupcevic.net/ghostscript-ps-pdf/#marks[pdfmark^] file, which contains metadata that can be fed to Ghostscript when optimizing the PDF file.
+If you're using Ghostscript >= 8.54, this feature is not needed.
+7. Activates hyphenation for the language code specified (defaults to en_us).
+8. Activates line break rules for CJK languages (specifically Chinese and Japanese).
+Chinese and Japanese are written without spaces (and may not use spaces when mixing with English words either).
+This setting allows a line break to be placed between any two CJK characters to accommodate wrapping.
+These languages also use different punctuation for pause, full stop, and dash, which are taken into account when breaking lines.
+9. _(Experimental)_ The `text-align` document attribute is intended as a simple way to toggle text justification.
+The value of this attribute overrides the `base-align` key set by the theme.
+For more fine-grained control, you should customize using the theme.
+10. The title page is only enabled by default for the book doctype.
+To force the title page to be used for other doctypes, set the `title-page` attribute in the document header.
+11. If the TOC overlaps the first page of content, increase this number.
+12. The second number in the value of `outlinelevels` is the number of levels of the outline to expand (e.g., `3:1`).
+If the second number is not present, all levels are expanded.
+13. By default, admonitions have a text-based label that matches the admonition type.
+To use icons instead, set the `icons` attribute to `font`.
+This setting allows the theme to control the icon used for each type (see the xref:admonition.adoc#key-prefix-admonition-icon[admonition-icon key]).
+It also enables the `icon` macro (covered in the README).
+To use local image files, set the `icons` attribute to `image`.
+Note that if the value of the `icons` attribute is `image`, the `icon` macro will produce text-based output.
diff --git a/docs/modules/theme/pages/base.adoc b/docs/modules/theme/pages/base.adoc
new file mode 100644
index 00000000..3b6fe7d6
--- /dev/null
+++ b/docs/modules/theme/pages/base.adoc
@@ -0,0 +1,119 @@
+= Base Category Keys
+:navtitle: Base
+
+The keys in the `base` category provide generic theme settings and are often referenced throughout the theme file as variables.
+We recommended that you define this category after the xref:page.adoc[page category] and before all other categories.
+
+NOTE: While it's common to define additional keys in this category (e.g., `base-border-radius`) to keep your theme DRY, we recommend using xref:variables.adoc#custom[custom variables] instead.
+
+.base keys
+[#key-prefix-base,cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+
+|align
+|xref:text.adoc#align[Text alignment] +
+(default: left)
+|base:
+align: justify
+
+|border-color
+|xref:color.adoc[Color] +
+(default: #eeeeee)
+|base:
+border-color: #eeeeee
+
+// border-radius is variable, not an official key
+//|border-radius
+//|xref:language.adoc#values[Number]
+//|base:
+// border-radius: 4
+
+|border-width
+|xref:language.adoc#values[Number] +
+(default: 0.5)
+|base:
+border-width: 0.5
+
+|font-color
+|xref:color.adoc[Color] +
+(default: #000000)
+|base:
+font-color: #333333
+
+|font-family
+|xref:font-support.adoc[Font family name] +
+(default: Helvetica)
+|base:
+font-family: Noto Serif
+
+|font-kerning
+|normal {vbar} none +
+(default: normal)
+|base:
+font-kerning: none
+
+|font-size
+|xref:language.adoc#values[Number] +
+(default: 12)
+|base:
+font-size: 10.5
+
+// font-size-large is a variable, not an official key
+//|font-size-large
+//|xref:language.adoc#values[Number]
+//|base:
+// font-size-large: 13
+
+|font-size-min
+|xref:language.adoc#values[Number] +
+(default: 6)
+|base:
+font-size-min: $base-font-size * 0.75
+
+// font-size-small is a variable, not an official key
+//|font-size-small
+//|xref:language.adoc#values[Number]
+//|base:
+// font-size-small: 9
+
+|font-style
+|xref:text.adoc#font-style[Font style] +
+(default: normal)
+|base:
+font-style: normal
+
+|text-transform^[1]^
+|none +
+(default: none)
+|base:
+text-transform: none
+
+|line-height-length^[2]^
+|xref:language.adoc#values[Number] +
+(default: _not set_)
+|base:
+line-height-length: 12
+
+|line-height^[2]^
+|xref:language.adoc#values[Number] +
+(default: 1.15)
+|base:
+line-height: >
+$base-line-height-length /
+$base-font-size
+
+|text-decoration-width
+|xref:language.adoc#values[Number] +
+(default: 1)
+|base:
+text-decoration-width: 0.5
+|===
+
+1. The `text-transform` key cannot be set globally.
+Therefore, this key should not be used.
+The value of `none` is implicit and is documented here for completeness.
+2. `line-height-length` is a utility property that's internal to the theme.
+It's used as an intermediate property for computing the `base-line-height` from the base font size and the desired line height size.
+For instance, if you set `base-line-height-length`, you can use `$base-line-height-length / $base-font-size` to set the value of `base-line-height`.
+You don't have to go about it this way in your own theme.
diff --git a/docs/modules/theme/pages/block-image.adoc b/docs/modules/theme/pages/block-image.adoc
new file mode 100644
index 00000000..49fbc568
--- /dev/null
+++ b/docs/modules/theme/pages/block-image.adoc
@@ -0,0 +1,122 @@
+= Block Image Category Keys
+:navtitle: Block Image
+
+The keys in this category control the arrangement of block images.
+
+.image keys
+[#key-prefix-image,cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+
+|align
+|xref:image.adoc#align[Image alignment] +
+(default: left)
+|image:
+align: left
+
+|width^[1]^
+|xref:measurement-units.adoc[Measurement] +
+(default: _not set_)
+|image:
+width: 100%
+
+|border-color^[2]^
+|xref:color.adoc[Color] +
+(default: _not set_)
+|image:
+border-color: #cccccc
+
+|border-radius
+|xref:language.adoc#values[Number] +
+(default: _not set_)
+|image:
+border-radius: 2
+
+|border-width^[2]^
+|xref:language.adoc#values[Number] +
+(default: _not set_)
+|image:
+border-width: 0.5
+
+|border-fit^[3]^
+|content {vbar} auto
+(default: content)
+|image:
+border-fit: auto
+
+3+|[#key-prefix-image-alt]*Key Prefix:* <<key-prefix-image-alt,image-alt>>
+
+|content^[4]^
+|xref:quoted-string.adoc[Quoted string] +
+(default: "%\{link}[%\{alt}]%{/link} {vbar} %\{target}")
+|image:
+alt:
+content: "%{alt} (%{target})"
+
+|font-color
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|image:
+alt:
+font-color: #ff000
+
+|font-family
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|image
+alt:
+font-family: Courier
+
+|font-kerning
+|normal {vbar} none +
+(default: _inherit_)
+|image:
+alt:
+font-kerning: none
+
+|font-size
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|image:
+alt:
+font-size: 9
+
+|font-style
+|xref:text.adoc#font-style[Font style] +
+(default: normal)
+|image:
+alt:
+font-style: italic
+
+3+|[#key-prefix-image-caption]*Key Prefix:* <<key-prefix-image-caption,image-caption>>
+
+|caption-align
+|xref:text.adoc#align[Text alignment] {vbar} inherit +
+(default: $caption-align)
+|image:
+caption:
+align: inherit
+
+|caption-text-align
+|xref:text.adoc#align[Text alignment] {vbar} inherit +
+(default: $image-caption-align)
+|image:
+caption:
+text-align: left
+
+|caption-max-width^[5]^
+|fit-content {vbar} fit-content(percentage) {vbar} none {vbar} xref:measurement-units.adoc[Measurement] +
+(default: none)
+|image:
+caption:
+max-width: fit-content
+|===
+
+1. Only applies to block images that don't have either a `pdfwidth` or `scaledwidth` attribute on the image macro.
+If specified, this value takes precedence over the value of the `width` attribute on the image macro, but not over the value of the `pdfwidth` or `scaledwidth` attributes.
+This key accepts the same values as the `pdfwidth` attribute.
+2. The border is only used if a border color is specified, the border width is specified, the border width is greater than 0, and the `noborder` role is not present.
+The border is drawn above the image on the inside of the box reserved for the image.
+3. The value `auto` means the border should expand to fit the width of the container (i.e., full width) instead of the image.
+4. Use the placeholders `%\{alt}`, `%\{target}`, `%\{link}`, and `%{/link}` to insert the alt text, image target, and link open/close tags into the content template.
+5. In order for the image to be sized correctly when max-width is fit-content, a width should always be specified on the image.
diff --git a/docs/modules/theme/pages/block.adoc b/docs/modules/theme/pages/block.adoc
new file mode 100644
index 00000000..5ccb94d6
--- /dev/null
+++ b/docs/modules/theme/pages/block.adoc
@@ -0,0 +1,43 @@
+= Block Category Keys
+:navtitle: Block
+:source-language: yaml
+
+The keys in the `block` category control the anchor position and spacing below block elements when a more specific setting isn't designated.
+The bottom margin is only added if the block is followed by an adjacent block within the same enclosure (e.g., a sidebar, a table cell, or the area outside any blocks).
+
+[#key-prefix-block,cols="3,4,6a"]
+|===
+|Key |Value Type |Example
+
+|`anchor-top`
+|xref:measurement-units.adoc[Measurement] +
+(default: `0`)
+|[source]
+block:
+ anchor-top: -12
+
+|`margin-bottom`
+|xref:measurement-units.adoc[Measurement] +
+(default: `12`)
+|[source]
+block:
+ margin-bottom: 6
+|===
+
+Block styles are applied to the following block types:
+
+[cols="3*a",grid=none,frame=none]
+|===
+|
+* admonition
+* example
+* quote
+|
+* verse
+* sidebar
+* image
+|
+* listing
+* literal
+* table
+|===
diff --git a/docs/modules/theme/pages/button.adoc b/docs/modules/theme/pages/button.adoc
new file mode 100644
index 00000000..2e58b23e
--- /dev/null
+++ b/docs/modules/theme/pages/button.adoc
@@ -0,0 +1,75 @@
+= Button Macro Category Keys
+:navtitle: Button
+
+The keys in the `button` category apply to a button reference generated from the inline button macro.
+
+.button keys
+[#key-prefix-button,cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+
+|background-color
+|xref:color.adoc[Color] +
+(default: _not set_)
+|button:
+background-color: #0000ff
+
+|border-color^[1]^
+|xref:color.adoc[Color] +
+(default: _not set_)
+|button:
+border-color: #cccccc
+
+|border-offset^[2]^
+|xref:language.adoc#values[Number] +
+(default: 0)
+|button:
+border-offset: 1.5
+
+|border-radius
+|xref:language.adoc#values[Number] +
+(default: 0)
+|button:
+border-radius: 2
+
+|border-width
+|xref:language.adoc#values[Number] +
+(default: $base-border-width)
+|button:
+border-width: 0.5
+
+|content^[3]^
+|xref:quoted-string.adoc[Quoted string] +
+(default: "%s")
+|button:
+content: "[\u2009%s\u2009]"
+
+|font-color
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|button:
+font-color: #ffffff
+
+|font-family
+|xref:font-support.adoc[Font family name] +
+(default: Courier)
+|button:
+font-family: M+ 1mn
+
+|font-size
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|button:
+font-size: 12
+
+|font-style
+|xref:text.adoc#font-style[Font style] +
+(default: bold)
+|button:
+font-style: normal
+|===
+
+1. The border is only used if a border color is specified and the border width is not explicitly set to 0.
+2. The border offset is the amount that the background and border swells around the text.
+It does not affect the distance between the formatted phrase and the phrases that surround it.
+3. The character sequence `%s` in the content key gets replaced with the button label.
diff --git a/docs/modules/theme/pages/callout.adoc b/docs/modules/theme/pages/callout.adoc
new file mode 100644
index 00000000..382a6bed
--- /dev/null
+++ b/docs/modules/theme/pages/callout.adoc
@@ -0,0 +1,144 @@
+= Callout List and Number Category Keys
+:navtitle: Callout List and Number
+:source-language: yaml
+
+[#callout-list]
+== callout-list
+
+The keys in the `callout-list` category control the arrangement and style of callout lists.
+
+NOTE: The <<conum,conum category>> controls the appearance of the list markers (i.e., the callout numbers) in a callout list.
+If you change the `font-size` setting on the callout list, then you likely need to change the `font-size` setting on the `conum` category as well.
+
+[#key-prefix-callout-list,cols="3,4,5a"]
+|===
+|Key |Value Type |Example
+
+|`font-color`
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|[source]
+callout-list:
+ font-color: '#555555'
+
+|`font-family`
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|[source]
+callout-list:
+ font-family: M+ 1p
+
+|`font-kerning`
+|`normal` {vbar} `none` +
+(default: _inherit_)
+|[source]
+callout-list:
+ font-kerning: none
+
+|`font-size`
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|[source]
+callout-list:
+ font-size: 9
+
+|`font-style`
+|xref:text.adoc#font-style[Font style] +
+(default: _inherit_)
+|[source]
+callout-list:
+ font-style: italic
+
+|`item-spacing`
+|xref:measurement-units.adoc[Measurement] +
+(default: `$list-item-spacing`)
+|[source]
+callout-list:
+ item-spacing: 3
+
+|`line-height`
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|[source]
+callout-list:
+ line-height: 1
+
+|`margin-top-after-code`
+|xref:measurement-units.adoc[Measurement] +
+(default: `-$block-margin-bottom`)
+|[source]
+callout-list:
+ margin-top-after-code: 0
+
+|`text-align`
+|xref:text.adoc#align[Text alignment] +
+(default: `$list-text-align`)
+|[source]
+callout-list:
+ text-align: left
+
+|`text-transform`
+|xref:text.adoc#transform[Text transform] +
+(default: _inherit_)
+|[source]
+callout-list:
+ text-transform: lowercase
+|===
+
+[#conum]
+== conum
+
+The keys in the `conum` category control the style of callout numbers inside verbatim blocks and in callout lists.
+
+[#key-prefix-conum,cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+
+|font-color
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|conum:
+font-color: #b12146
+
+|font-family^[1,2]^
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|conum:
+font-family: M+ 1mn
+
+|font-kerning^[2]^
+|normal {vbar} none +
+(default: _inherit_)
+|conum:
+font-kerning: none
+
+|font-size^[2]^
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|conum:
+font-size: $base-font-size
+
+|font-style^[2]^
+|xref:text.adoc#font-style[Font style] +
+(default: _inherit_)
+|conum:
+font-style: normal
+
+|line-height^[2]^
+|xref:language.adoc#values[Number] +
+(default: 1.15)
+|conum:
+line-height: 4 / 3
+
+|glyphs^[3]^
+|circled {vbar} filled {vbar} Unicode String ranges +
+(default: circled)
+|conum:
+glyphs: \u0031-\u0039
+|===
+1. Currently, the font must contain the circle numbers starting at glyph U+2460.
+2. font-family, font-kerning, font-size, font-style, and line-height are only used for markers in a colist.
+These properties are inherited for conums inside a verbatim block.
+3. The font must provide the required glyphs.
+The glyphs can be specified as a comma-separated list of ranges, where the range values are Unicode numbers (e.g., \u2460).
+Unicode escape sequences are recognized even if the value is not enclosed in double quotes.
diff --git a/docs/modules/theme/pages/caption.adoc b/docs/modules/theme/pages/caption.adoc
new file mode 100644
index 00000000..e3f3eaaf
--- /dev/null
+++ b/docs/modules/theme/pages/caption.adoc
@@ -0,0 +1,86 @@
+= Caption Category Keys
+:navtitle: Caption
+
+The keys in the `caption` category control the arrangement and style of block captions.
+In addition to the generic caption category, each of these keys (except for text decoration) can be set on the caption key nested inside the following block categories: `blockquote`, `code` (applies to literal, listing, and source blocks), `example`, `footnotes`, `image`, `table`, and `verse`.
+
+When nested inside the `image` key (i.e., `image-caption-align`), the value `inherit` is also accepted.
+The value `inherit` resolves to the alignment of the block image.
+
+.caption keys
+[#key-prefix-caption,cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+
+|align
+|xref:text.adoc#align[Text alignment] +
+(default: left)
+|caption:
+align: left
+
+|font-color
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|caption:
+font-color: #333333
+
+|font-family
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|caption:
+font-family: M+ 1mn
+
+|font-kerning
+|normal {vbar} none +
+(default: _inherit_)
+|caption:
+font-kerning: none
+
+|font-size
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|caption:
+font-size: 11
+
+|font-style
+|xref:text.adoc#font-style[Font style] +
+(default: italic)
+|caption:
+font-style: italic
+
+|text-decoration
+|xref:text.adoc#decoration[Text decoration] +
+(default: none)
+|caption:
+text-decoration: line-through
+
+|text-decoration-color
+|xref:color.adoc[Color] +
+(default: $caption-font-color)
+|caption:
+text-decoration-color: #ff0000
+
+|text-decoration-width
+|xref:language.adoc#values[Number] +
+(default: $base-text-decoration-width)
+|caption:
+text-decoration-width: 0.5
+
+|text-transform
+|xref:text.adoc#transform[Text transform] +
+(default: _inherit_)
+|caption:
+text-transform: uppercase
+
+|margin-inside
+|xref:measurement-units.adoc[Measurement] +
+(default: 4)
+|caption:
+margin-inside: 3
+
+|margin-outside
+|xref:measurement-units.adoc[Measurement] +
+(default: 0)
+|caption:
+margin-outside: 0
+|===
diff --git a/docs/modules/theme/pages/cjk.adoc b/docs/modules/theme/pages/cjk.adoc
new file mode 100644
index 00000000..2f497b9a
--- /dev/null
+++ b/docs/modules/theme/pages/cjk.adoc
@@ -0,0 +1,50 @@
+= Create a CJK Theme
+
+You also have to option of creating your own theme gem that uses fonts of your choice.
+For example, if you want to use the `asciidoctor-pdf-cjk-kai_gen_gothic` gem to fetch fonts, but then use them in your own theme, here's how you'd do it.
+
+. Install the `asciidoctor-pdf-cjk-kai_gen_gothic` gem:
+
+ $ gem install asciidoctor-pdf-cjk-kai_gen_gothic
+
+. Download / install the fonts:
+
+ $ asciidoctor-pdf-cjk-kai_gen_gothic-install
+
+. Create a theme file named [.path]_cjk-theme.yml_ that extends the default theme to override the fonts:
++
+[source,yml]
+----
+extends: default
+font:
+ catalog:
+ merge: true
+ KaiGen Gothic CN:
+ normal: KaiGenGothicCN-Regular.ttf
+ bold: KaiGenGothicCN-Bold.ttf
+ italic: KaiGenGothicCN-Regular-Italic.ttf
+ bold_italic: KaiGenGothicCN-Bold-Italic.ttf
+ fallbacks:
+ - KaiGen Gothic CN
+base:
+ font-family: KaiGen Gothic CN
+heading:
+ font-family: $base-font-family
+abstract:
+ title:
+ font-family: $heading-font-family
+sidebar:
+ title:
+ font-family: $heading-font-family
+----
+
+. Load your theme when running Asciidoctor PDF:
+
+ $ asciidoctor-pdf -a scripts=cjk -a pdf-theme=./cjk-theme.yml -a pdf-fontsdir=GEM_FONTS_DIR,`ruby -r asciidoctor-pdf-cjk-kai_gen_gothic -e "print File.expand_path '../fonts', (Gem.datadir 'asciidoctor-pdf-cjk-kai_gen_gothic')"` document.adoc
+
+The `-a pdf-fontsdir` option is important to tell Asciidoctor PDF where to find your custom fonts.
+//TODO This sentence and related example above need to be evaluated to remove PDF 1.5 references.
+(Note that the inclusion of GEM_FONTS_DIR in the value is only required when using Asciidoctor PDF 1.5).
+
+Rather than using the installer from the `asciidoctor-pdf-cjk-kai_gen_gothic` gem, you can download fonts whatever way you choose.
+When using your own fonts, be sure to consult the xref:prepare-custom-font.adoc[] to find recommended modifications.
diff --git a/docs/modules/theme/pages/code.adoc b/docs/modules/theme/pages/code.adoc
new file mode 100644
index 00000000..fd59c9cf
--- /dev/null
+++ b/docs/modules/theme/pages/code.adoc
@@ -0,0 +1,116 @@
+= Code Block Category Keys
+:navtitle: Code Block
+:source-language: yaml
+
+[#code]
+== code
+
+The keys in the `code` category control the arrangement and style of literal, listing, and source blocks as well as literal table cells.
+
+[#key-prefix-code,cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+
+|background-color
+|xref:color.adoc[Color] +
+(default: _not set_)
+|code:
+background-color: #f5f5f5
+
+|border-color
+|xref:color.adoc[Color] +
+(default: #eeeeee)
+|code:
+border-color: #cccccc
+
+|border-radius
+|xref:language.adoc#values[Number] +
+(default: _not set_)
+|code:
+border-radius: 4
+
+|border-width
+|xref:language.adoc#values[Number] +
+(default: 0.5)
+|code:
+border-width: 0.75
+
+|font-color
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|code:
+font-color: #333333
+
+|font-family
+|xref:font-support.adoc[Font family name] +
+(default: Courier)
+|code:
+font-family: M+ 1mn
+
+|font-size
+|xref:language.adoc#values[Number] +
+(default: 10.8)
+|code:
+font-size: 11
+
+|font-style
+|xref:text.adoc#font-style[Font style] +
+(default: _inherit_)
+|code:
+font-style: italic
+
+|line-height
+|xref:language.adoc#values[Number] +
+(default: 1.2)
+|code:
+line-height: 1.25
+
+|line-gap^[1]^
+|xref:language.adoc#values[Number] +
+(default: 0)
+|code:
+line-gap: 3.8
+
+|padding
+|xref:measurement-units.adoc[Measurement] {vbar} xref:measurement-units.adoc[Measurement[top,right,bottom,left\]] +
+(default: 9)
+|code:
+padding: 11
+|===
+1. The line-gap property is used to tune the height of the background color applied to a span of block text highlighted using Rouge.
+
+== code-highlight
+
+The key in the `code-highlight` category only applies when you use Rouge as the source highlighter.
+Otherwise, the background color is controlled by the source highlighter theme.
+
+[#key-prefix-code-highlight,cols="2,4,6a"]
+|===
+|Key |Value Type |Example
+
+|`background-color`
+|xref:color.adoc[Color] +
+(default: `'#FFFFCC'`)
+|[source]
+code:
+ highlight-background-color: '#ffff00'
+|===
+
+[#code-linenum]
+== code-linenum
+
+The key in the `code-linenum` category only applies when you use Pygments as the source highlighter.
+Otherwise, the font color of line numbers are controlled by the source highlighter theme.
+
+[#key-prefix-code-linenum,cols="2,4,6a"]
+|===
+|Key |Value Type |Example
+
+|`font-color`
+|xref:color.adoc[Color] +
+(default: `'#999999'`)
+|[source]
+code:
+ linenum-font-color: '#ccc'
+|===
+
diff --git a/docs/modules/theme/pages/codespan.adoc b/docs/modules/theme/pages/codespan.adoc
new file mode 100644
index 00000000..c29db877
--- /dev/null
+++ b/docs/modules/theme/pages/codespan.adoc
@@ -0,0 +1,92 @@
+= Codespan Category Keys
+:navtitle: Codespan
+:source-language: yaml
+
+== codespan
+
+The keys in the `codespan` category are used for inline monospace text in prose and table cells.
+
+[#key-prefix-codespan,cols="3,4,6a"]
+|===
+|Key |Value Type |Example
+
+|`background-color`
+|xref:color.adoc[Color] +
+(default: _not set_)
+|[source]
+codespan:
+ background-color: '#f5f5f5'
+
+|`border-color`
+|xref:color.adoc[Color] +
+(default: _not set_)
+|[source]
+codespan:
+ border-color: '#cccccc'
+
+|`border-offset`
+|xref:language.adoc#values[Number] +
+(default: `0`)
+|[source]
+codespan:
+ border-offset: 2
+
+|`border-radius`
+|xref:language.adoc#values[Number] +
+(default: _not set_)
+|[source]
+codespan:
+ border-radius: 3
+
+|`border-width`
+|xref:language.adoc#values[Number] +
+(default: `$base-border-width`)
+|[source]
+codespan:
+ border-width: 0.5
+
+|`font-color`
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|[source]
+codespan:
+ font-color: '#b12146'
+
+|`font-family`
+|xref:font-support.adoc[Font family name] +
+(default: `Courier`)
+|[source]
+codespan:
+ font-family: M+ 1mn
+
+|`font-size`
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|[source]
+codespan:
+ font-size: 0.8em
+
+|`font-style`
+|xref:text.adoc#font-style[Font style] +
+(default: _inherit_)
+|[source]
+codespan:
+ font-style: bold
+|===
+
+== Using border-color
+
+A border is only drawn around a code phrase if a border color is specified and the border width is not explicitly set to `0`.
+The border only works properly if the code phrase does not have nested formatting.
+Otherwise, the border will be inherited, producing a less than desirable result.
+
+== Using border-offset
+
+The border offset is the amount that the background and border swells around the text.
+It does not affect the distance between the formatted phrase and the phrases that surround it.
+
+== Using font-size
+
+You're strongly encouraged to set the value of the `font-size` key to a relative font size using the `em` units (e.g., `0.9em`).
+A code phrase with a fixed font size will not be scaled when the font size of the parent element (e.g., table, caption, etc.) is specified.
+However, by using a relative value, the font size will be computed relative to the size of the text that surrounds it, giving you effectively the same result.
diff --git a/docs/modules/theme/pages/color.adoc b/docs/modules/theme/pages/color.adoc
new file mode 100644
index 00000000..af907a73
--- /dev/null
+++ b/docs/modules/theme/pages/color.adoc
@@ -0,0 +1,97 @@
+= Colors
+
+The theme language supports color values in three formats:
+
+Hex:: A string of 3 or 6 characters with an optional leading `#`, optional surrounding quotes, or both.
+RGB:: An array of numeric values ranging from 0 to 255.
+CMYK:: An array of numeric values ranging from 0 to 1 or from 0% to 100%.
+Transparent:: The special value `transparent` indicates that a color should not be used.
+
+== Hex
+
+The hex color value is likely most familiar to web developers.
+The value must be either 3 or 6 characters (case insensitive) with an optional leading hash (`#`), optional surrounding quotes, or both.
+
+To align with CSS, you may add a `+#+` in front of the hex color value.
+A YAML preprocessor is used to ensure the value is not treated as a comment as would normally be the case in YAML.
+That same preprocessor will also coerce a primitive value to a string if `color` is the name of the last segment in the key (e.g., `font-color`).
+This avoids the problem of 000 becoming 0 (and similar implicit conversions) when the theme file is parsed.
+
+You also may put quotes around the CSS-style hex value to make it friendly to a YAML editor or validation tool.
+In this case, the leading `+#+` on a hex value is entirely optional.
+
+Regardless, we recommend that you always use either a leading `+#+` or surrounding quotes (or both) to prevent YAML from mangling the value.
+
+The following are all equivalent values for the color red:
+
+[cols="8*m"]
+|===
+|#ff0000
+|#FF0000
+|'ff0000'
+|'FF0000'
+|#f00
+|#F00
+|'f00'
+|'F00'
+|===
+
+Here's how a hex color value appears in the theme file:
+
+[source,yaml]
+----
+base:
+ font-color: '#ff0000'
+----
+
+== RGB
+
+An RGB array value must be three numbers ranging from 0 to 255.
+The values must be separated by commas and be surrounded by square brackets.
+
+NOTE: An RGB array is automatically converted to a hex string internally, so there's no difference between ff0000 and [255, 0, 0].
+
+Here's how to specify the color red in RGB:
+
+* [255, 0, 0]
+
+Here's how a RGB color value appears in the theme file:
+
+[source,yaml]
+----
+base:
+ font-color: [255, 0, 0]
+----
+
+== CMYK
+
+A CMYK array value must be four numbers ranging from 0 and 1 or from 0% to 100%.
+The values must be separated by commas and be surrounded by square brackets.
+
+Unlike the RGB array, the CMYK array _is not_ converted to a hex string internally.
+PDF has native support for CMYK colors, so you can preserve the original color values in the final PDF.
+
+Here's how to specify the color red in CMYK:
+
+* [0, 0.99, 1, 0]
+* [0, 99%, 100%, 0]
+
+Here's how a CMYK color value appears in the theme file:
+
+[source,yaml]
+----
+base:
+ font-color: [0, 0.99, 1, 0]
+----
+
+== Transparent
+
+It's possible to specify no color by assigning the special value `transparent`, as shown here:
+
+[source,yaml]
+----
+table:
+ background-color: transparent
+----
+
+The `transparent` keyword can be used for the background or border color, but not the font color.
diff --git a/docs/modules/theme/pages/cover.adoc b/docs/modules/theme/pages/cover.adoc
new file mode 100644
index 00000000..d2e1ffed
--- /dev/null
+++ b/docs/modules/theme/pages/cover.adoc
@@ -0,0 +1,28 @@
+= Cover Category Keys
+:navtitle: Cover
+
+The keys in the `cover` category control the front and back cover images.
+Currently, the only supported feature is setting an image for each cover face.
+`<face>` is either `front` or `back`.
+
+[#key-prefix-cover,cols="3,4,6a"]
+|===
+|Key |Value Type |Example
+
+|`<face>-image`
+|path, image macro +
+(default: _not set_)
+|
+[,yaml]
+----
+cover:
+ front:
+ image: image:cover.pdf[page=2]
+----
+|===
+
+When assigning a value to `image` using the image macro, the target of the macro can be an image file or a PDF file.
+A relative path of the target file is resolved relative to the value of the `pdf-themesdir` attribute.
+An image file is handled just like a background image.
+If a PDF file is specified, the first page is used unless another page is specified by the `page` attribute.
+The page from the PDF file will be imported as is.
diff --git a/docs/modules/theme/pages/custom-font.adoc b/docs/modules/theme/pages/custom-font.adoc
new file mode 100644
index 00000000..bd270edc
--- /dev/null
+++ b/docs/modules/theme/pages/custom-font.adoc
@@ -0,0 +1,152 @@
+= Custom Fonts
+:url-fontforge: https://fontforge.github.io/en-US/
+:url-roboto: https://github.com/googlefonts/roboto/releases
+:conum-guard-yaml: #
+
+The limited character set of WINANSI, or the plain look of the built-in or bundled fonts, may motivate you to incorporate your own fonts.
+Custom fonts can enhance the look of your PDF theme substantially.
+
+IMPORTANT: In order for a third-party font to work properly with Prawn (and hence Asciidoctor PDF), several modifications are required.
+See xref:prepare-custom-font.adoc[] to learn how to prepare your font for use with Asciidoctor PDF.
+
+[#select]
+== Selecting your font
+
+To start, find the TTF file collection for the font you want to use.
+A collection typically consists of four font styles:
+
+* normal
+* italic
+* bold
+* bold_italic
+
+You'll need all four variants to support AsciiDoc content properly (unless the font only has a single variant).
+If you do not register the font correctly, the converter may crash or revert to the fallback font, depending on how the theme is configured.
+If one of the variants is missing from your collection, you can simply reuse the normal / single variant in its place.
+
+WARNING: Asciidoctor PDF cannot italicize a font dynamically like a browser can, so the italic styles are required to italicize text.
+
+Once you've obtained the TTF (or OTF) files, put them in the directory inside your project where you want to store the fonts.
+It's recommended that you name them consistently so it's easier to type the names in the theme file.
+
+Let's assume the name of the font is {url-roboto}[Roboto^].
+Rename the files as follows:
+
+* roboto-normal.ttf (_originally Roboto-Regular.ttf_)
+* roboto-italic.ttf (_originally Roboto-Italic.ttf_)
+* roboto-bold.ttf (_originally Roboto-Bold.ttf_)
+* roboto-bold_italic.ttf (_originally Roboto-BoldItalic.ttf_)
+
+[#declare]
+== Declaring your font
+
+Next, declare the font under the `font-catalog` key at the top of your theme file.
+Assign each font a unique key (e.g., `Roboto`) and specify the path to each of the four font styles under that key.
+
+[source,yaml,subs=attributes+]
+----
+font:
+ catalog:
+ merge: false {conum-guard-yaml} <1>
+ Roboto:
+ normal: roboto-normal.ttf
+ italic: roboto-italic.ttf
+ bold: roboto-bold.ttf
+ bold_italic: roboto-bold_italic.ttf
+----
+<1> Set value to true to merge catalog with theme you're extending.
+
+If you use this form, you must declare all four variants.
+If you're missing the font file for one of the variants, configure it to use the same font file as the normal variant.
+
+If your font only has a single variant, assign the font path to the font key directly.
+
+[source,yaml,subs=attributes+]
+----
+font:
+ catalog:
+ merge: false {conum-guard-yaml} <1>
+ VLGothic: vlgothic.ttf
+----
+<1> Set value to true to merge catalog with theme you're extending.
+
+Font paths can be absolute or relative.
+Absolute paths are used as is.
+Relative font paths are resolved from the <<configure-search-path,font search path>>.
+You can also use the `GEM_FONTS_DIR` keyword to refer to the location of the bundled fonts.
+
+You can add any number of fonts to the catalog.
+Each font must be assigned a unique key, as shown here:
+
+[source,yaml,subs=attributes+]
+----
+font:
+ catalog:
+ merge: false {conum-guard-yaml} <1>
+ Roboto:
+ normal: roboto-normal.ttf
+ italic: roboto-italic.ttf
+ bold: roboto-bold.ttf
+ bold_italic: roboto-bold_italic.ttf
+ Roboto Light:
+ normal: roboto-light-normal.ttf
+ italic: roboto-light-italic.ttf
+ bold: roboto-light-bold.ttf
+ bold_italic: roboto-light-bold_italic.ttf
+----
+<1> Set value to true to merge catalog with theme you're extending.
+
+You can use the key that you assign to the font in the font catalog anywhere the `font-family` property is accepted in the theme file.
+For example, to use the Roboto font for all headings (section titles and discrete headings), use:
+
+[source,yaml]
+----
+heading:
+ font-family: Roboto
+ font-style: bold
+----
+
+The font name and font style are used to locate an entry in the font catalog.
+
+.About Fonts in SVGs
+****
+Fonts defined for text in SVGs will be mapped to the font catalog from your theme.
+So if you have an SVG that requires a specific font, you'll need to declare that font in the font catalog in your theme.
+
+We recommend that you match the font key in your theme file to the name of the font seen by the operating system.
+This will allow you to use the same font names (aka families) in both your graphics program and Asciidoctor PDF, thus making them portable.
+****
+
+[#configure-search-path]
+== Configuring the font search path
+
+When you execute Asciidoctor PDF, specify the directory where the fonts reside using the `pdf-fontsdir` attribute:
+
+ $ asciidoctor-pdf -a pdf-theme=basic-theme.yml -a pdf-fontsdir=path/to/fonts document.adoc
+
+You can specify multiple directories by separating the paths with either a comma (`,`):
+
+ $ asciidoctor-pdf -a pdf-theme=basic-theme.yml -a pdf-fontsdir=path/to/fonts,path/to/more-fonts document.adoc
+
+or a semicolon (`;`) (which requires enclosing the combined value in double quotes to escape the delimiter from the shell):
+
+ $ asciidoctor-pdf -a pdf-theme=basic-theme.yml -a pdf-fontsdir="path/to/fonts;path/to/more-fonts" document.adoc
+
+To include the location of the bundled fonts in the search, include the `GEM_FONTS_DIR` token in the list:
+
+ $ asciidoctor-pdf -a pdf-theme=basic-theme.yml -a pdf-fontsdir="path/to/fonts;GEM_FONTS_DIR" document.adoc
+
+When running Asciidoctor PDF on the JVM (perhaps using AsciidoctorJ PDF), you can refer to a directory inside any JAR file on the classpath by prefixing the path with `uri:classloader:`:
+
+ $ asciidoctorj -b pdf -a pdf-theme=basic-theme.yml -a pdf-fontsdir="uri:classloader:/path/to/fonts;GEM_FONTS_DIR" document.adoc
+
+[#subset]
+== Subsetting your font
+
+When Asciidoctor PDF creates the PDF, it only embeds the glyphs from the font that are needed to render the characters present in the document.
+Effectively, it subsets the font.
+While that saves space taken up by the generated PDF, you may still be storing the full font in your source repository.
+
+To minimize the size of the source font, you can use {url-fontforge}[FontForge^] to subset the font ahead of time.
+Subsetting a font means remove glyphs you don't plan to use.
+Doing so is not a requirement, simply a personal preference.
diff --git a/docs/modules/theme/pages/description-list.adoc b/docs/modules/theme/pages/description-list.adoc
new file mode 100644
index 00000000..72c3eb44
--- /dev/null
+++ b/docs/modules/theme/pages/description-list.adoc
@@ -0,0 +1,101 @@
+= Description List Category Keys
+:navtitle: Description List
+
+[#description-list]
+== description-list
+
+The keys in this category control the arrangement and style of definition list items (terms and descriptions).
+
+[#key-prefix-description-list,cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+
+|term-font-color
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|description-list:
+term-font-color: #AA0000
+
+|term-font-family
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|description-list:
+term-font-family: Noto Serif
+
+|term-font-kerning
+|normal {vbar} none +
+(default: _inherit_)
+|description-list:
+term-font-kerning: none
+
+|term-font-size
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|description-list:
+term-font-size: 12
+
+|term-font-style
+|xref:text.adoc#font-style[Font style] +
+(default: bold)
+|description-list:
+term-font-style: italic
+
+|term-text-transform
+|xref:text.adoc#transform[Text transform] +
+(default: none)
+|description-list:
+term-text-transform: none
+
+|term-line-height
+|xref:language.adoc#values[Number] +
+(default: $base-line-height)
+|description-list:
+term-line-height: 1.2
+
+|term-spacing
+|xref:measurement-units.adoc[Measurement] +
+(default: 4)
+|description-list:
+term-spacing: 5
+
+|description-indent
+|xref:language.adoc#values[Number] +
+(default: 30)
+|description-list:
+description-indent: 15
+|===
+
+== Ordered and unordered description lists
+
+Asciidoctor PDF supports unordered and ordered description lists.
+These are defined as a description list, but displayed as an unordered or ordered description list with the term as a subject.
+Only one term is supported.
+The subject is shown using the term font style (bold by default).
+
+By default, the subject is arranged as a run-in followed by a subject stop (`:` by default).
+
+[source,asciidoc]
+----
+[unordered]
+alpha:: partially complete and unstable
+beta:: feature complete and undergoing testing
+----
+
+The subject stop can be customized using the `subject-stop` attribute.
+
+[source,asciidoc]
+----
+[unordered,subject-stop=)]
+alpha:: partially complete and unstable
+beta:: feature complete and undergoing testing
+----
+
+If the `stack` role is present, the subject is stacked above the description.
+In this case, the subject stop is only used if specified explicitly.
+
+[source,asciidoc]
+----
+[unordered.stack]
+alpha:: partially complete and unstable
+beta:: feature complete and undergoing testing
+----
diff --git a/docs/modules/theme/pages/example.adoc b/docs/modules/theme/pages/example.adoc
new file mode 100644
index 00000000..cf9737ec
--- /dev/null
+++ b/docs/modules/theme/pages/example.adoc
@@ -0,0 +1,75 @@
+= Example Category Keys
+:navtitle: Example
+
+The keys in the `example` category control the arrangement and style of example blocks.
+
+[#key-prefix-example,cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+
+|background-color
+|xref:color.adoc[Color] +
+(default: #ffffff)
+|example:
+background-color: #fffef7
+
+|border-color
+|xref:color.adoc[Color] +
+(default: #eeeeee)
+|example:
+border-color: #eeeeee
+
+|border-radius
+|xref:language.adoc#values[Number] +
+(default: _not set_)
+|example:
+border-radius: 4
+
+|border-width
+|xref:language.adoc#values[Number] +
+(default: 0.5)
+|example:
+border-width: 0.75
+
+|font-color
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|example:
+font-color: #262626
+
+|font-family
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|example:
+font-family: M+ 1p
+
+|font-kerning
+|normal {vbar} none +
+(default: _inherit_)
+|example:
+font-kerning: none
+
+|font-size
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|example:
+font-size: 13
+
+|font-style
+|xref:text.adoc#font-style[Font style] +
+(default: _inherit_)
+|example:
+font-style: italic
+
+|text-transform
+|xref:text.adoc#transform[Text transform] +
+(default: _inherit_)
+|example:
+text-transform: uppercase
+
+|padding
+|xref:measurement-units.adoc[Measurement] {vbar} xref:measurement-units.adoc[Measurement[top,right,bottom,left\]] +
+(default: [12, 12, 0, 12])
+|example:
+padding: [15, 15, 0, 15]
+|===
diff --git a/docs/modules/theme/pages/extend-theme.adoc b/docs/modules/theme/pages/extend-theme.adoc
new file mode 100644
index 00000000..69d4a471
--- /dev/null
+++ b/docs/modules/theme/pages/extend-theme.adoc
@@ -0,0 +1,100 @@
+= Customize the Theme
+
+[#extend-default]
+== Extend the default theme
+
+A theme can extend another theme using the `extends` key.
+For example:
+
+[source,yaml]
+----
+extends: default
+base:
+ font-color: '#ff0000'
+----
+
+The `extends` key accepts either a single value or an array of values.
+Each value is interpreted as a filename.
+If the filename equals `default`, it resolves to the location of the default (built-in) theme.
+If the filename is absolute, it's used as is.
+If the filename begins with `./`, it's resolved as a theme file relative to the current theme file.
+Otherwise, the filename is resolved as a theme file in the normal way (relative to the value of the `pdf-themesdir` attribute).
+
+Currently, the theme starts out empty.
+Then, the files referenced by the extends key are loaded in order.
+Finally, the keys in the current file are loaded.
+Each time a theme is loaded, the keys are overlaid onto the keys from the previous theme.
+
+== Basic theme
+
+Here's an example of a basic theme file that extends the base theme:
+
+.basic-theme.yml
+[source,yaml]
+----
+extends: base
+page:
+ layout: portrait
+ margin: [0.75in, 1in, 0.75in, 1in]
+ size: Letter
+base:
+ font-color: '#333333'
+ font-family: Times-Roman
+ font-size: 12
+ line-height-length: 17
+ line-height: $base-line-height-length / $base-font-size
+vertical-spacing: $base-line-height-length
+heading:
+ font-color: '#262626'
+ font-size: 17
+ font-style: bold
+ line-height: 1.2
+ margin-bottom: $vertical-spacing
+link:
+ font-color: '#002FA7'
+outline-list:
+ indent: $base-font-size * 1.5
+footer:
+ height: $base-line-height-length * 2.5
+ line-height: 1
+ recto:
+ right:
+ content: '{page-number}'
+ verso:
+ left:
+ content: $footer-recto-right-content
+----
+
+When creating a new theme, you only have to define the keys you want to override from the extended theme, which is loaded prior to loading your custom theme.
+The converter uses the information from the theme map to help construct the PDF.
+
+== Basic extended theme
+
+Instead of designing a theme from scratch, you can extend the default theme using the `extends` key as follows:
+
+[source,yaml]
+----
+extends: default
+base:
+ font-color: '#ff0000'
+----
+
+You can also point the extends key at another custom theme to extend from it.
+If you don't want to extend any theme, including the base theme, omit the `extends` key or assign the value `~` to the `extends` key (i.e., `extends: ~`).
+
+If the same theme appears multiple times in the theme hierarchy, it will only be loaded once by default.
+You can force the theme to be loaded, even if it has already been loaded, by adding the `!important` keyword at the end of the value offset by a space.
+
+WARNING: If you start a new theme from scratch, we strongly recommend defining TrueType fonts and specifying them in the `base` and `codespan` categories.
+Otherwise, Asciidoctor PDF will use built-in AFM fonts, which can result in missing functionality and warnings.
+
+[TIP]
+====
+Instead of creating a theme from scratch, another option is to download the {url-repo-root}/data/themes/default-theme.yml[default-theme.yml^] file from the source repository.
+Save the file using a unique name (e.g., _custom-theme.yml_) and start hacking on it.
+
+Alternatively, you can snag the file from your local installation using the following command:
+
+ $ ASCIIDOCTOR_PDF_DIR=`gem contents asciidoctor-pdf --show-install-dir`;\
+ cp "$ASCIIDOCTOR_PDF_DIR/data/themes/default-theme.yml" custom-theme.yml
+====
diff --git a/docs/modules/theme/pages/extends.adoc b/docs/modules/theme/pages/extends.adoc
new file mode 100644
index 00000000..b39bfdd4
--- /dev/null
+++ b/docs/modules/theme/pages/extends.adoc
@@ -0,0 +1,30 @@
+= Extends Category Key
+:navtitle: Extends
+:source-language: yaml
+
+A theme can extend another theme using the `extends` key.
+
+The `extends` key accepts either a single value or an array of values.
+Each value is interpreted as a filename.
+If the filename equals `default`, it resolves to the location of the default (built-in) theme.
+If the filename is absolute, it's used as is.
+If the filename begins with `./`, it's resolved as a theme file relative to the current theme file.
+Otherwise, the filename is resolved as a theme file in the normal way (relative to the value of the `pdf-themesdir` attribute).
+
+Currently, the theme starts out empty.
+Then, the files referenced by the extends key are loaded in order.
+Finally, the keys in the current file are loaded.
+Each time a theme is loaded, the keys are overlaid onto the keys from the previous theme.
+
+[cols="3,4,6a"]
+|===
+|Key |Value Type |Example
+
+|`extends`
+|String or Array +
+(default: [])
+|[source]
+extends:
+- default
+- ./brand-theme.yml
+|===
diff --git a/docs/modules/theme/pages/fallback-font.adoc b/docs/modules/theme/pages/fallback-font.adoc
new file mode 100644
index 00000000..58486ca9
--- /dev/null
+++ b/docs/modules/theme/pages/fallback-font.adoc
@@ -0,0 +1,94 @@
+= Fallback Fonts
+
+If a TrueType font is missing a character needed to render the document, such as a special symbol or emoji, you can have Asciidoctor PDF look for the character in a fallback font.
+
+You only need to specify a single fallback font, typically one that provides a full set of symbols.
+If the character isn't found in the fallback font, it will mostly likely be replaced by a box (i.e., the notdef glyph), which is guaranteed if you're using the bundled fallback font.
+
+IMPORTANT: When defining the fallback font, you *must specify all four variants* (normal, bold, italic, bold_italic), even if you use the same font file for each.
+
+IMPORTANT: The fallback font only gets used when the primary font is a TrueType or OpenType font (i.e., TTF, DFont, TTC, OTF).
+Any glyph missing from an AFM font is simply replaced with the "`not`" glyph (`&#172;`).
+
+CAUTION: The `default` theme does not use a fallback font.
+However, the built-in `default-with-fallback-font` theme does.
+In fact, it provides two.
+One for general writing in non-Latin languages (M+ 1p) and another for emoji (Noto Emoji).
+Using the fallback font slows down PDF generation slightly because it has to analyze every single character.
+It's use is not recommended for large documents.
+Instead, it's best to select primary fonts that have all the characters you need.
+
+Like with other custom fonts, you first need to declare the fallback font.
+Let's choose https://github.com/android/platform_frameworks_base/blob/master/data/fonts/DroidSansFallback.ttf[Droid Sans Fallback].
+You can map all the styles to a single font file (since bold and italic don't usually make sense for symbols).
+
+[source,yaml]
+----
+font:
+ catalog:
+ Roboto:
+ normal: roboto-normal.ttf
+ italic: roboto-italic.ttf
+ bold: roboto-bold.ttf
+ bold_italic: roboto-bold_italic.ttf
+ DroidSansFallback: droid-sans-fallback.ttf
+----
+
+Notice that we only declare the fallback font file once using a literal value.
+This ensures the font is defined for all four variants so it will be used regardless of which font style is active when it's called on.
+This assignment is equivalent to the following:
+
+[source,yaml]
+----
+DroidSansFallback:
+ '*': droid-sans-fallback.ttf
+----
+
+The benefit of this syntax is that it allows you to use a separate font file for just one of the variants (e.g., bold).
+
+Next, add the key name to the `fallbacks` key under the `font-catalog` key.
+The `fallbacks` key accepts an array of values, meaning you can specify more than one fallback font.
+However, we recommend using a single fallback font, if possible, as shown here:
+
+[source,yaml]
+----
+font:
+ catalog:
+ Roboto:
+ normal: roboto-normal.ttf
+ italic: roboto-italic.ttf
+ bold: roboto-bold.ttf
+ bold_italic: roboto-bold_italic.ttf
+ DroidSansFallback: droid-sans-fallback.ttf
+ fallbacks:
+ - DroidSansFallback
+----
+
+TIP: If you are using more than one fallback font, add additional lines to the `fallbacks` key.
+
+Of course, make sure you've configured your theme to use your custom font:
+
+[source,yaml]
+----
+base:
+ font-family: Roboto
+----
+
+That's it!
+Now you're covered.
+If your custom font is missing a glyph, Asciidoctor PDF will look in your fallback font.
+You don't need to reference the fallback font anywhere else in your theme file.
+
+Here's another example that shows how to use an alternative emoji font (Symbola):
+
+[source,yaml]
+----
+extends: default-with-fallback-font
+font:
+ catalog:
+ merge: true
+ Symbola: /path/to/symbola.ttf
+ fallbacks: [ M+ 1p, Symbola ]
+----
+
+Now Asciidoctor PDF will look for the emoji in the Symbola font instead of the Noto Emoji font.
diff --git a/docs/modules/theme/pages/font-support.adoc b/docs/modules/theme/pages/font-support.adoc
new file mode 100644
index 00000000..f0919a74
--- /dev/null
+++ b/docs/modules/theme/pages/font-support.adoc
@@ -0,0 +1,101 @@
+= Fonts
+:url-noto-serif: https://www.google.com/get/noto/#/family/noto-serif
+:url-mplus-onemn: https://mplus-fonts.osdn.jp/mplus-outline-fonts/design/index-en.html#mplus_1mn
+:url-mplus-onep: https://mplus-fonts.osdn.jp/mplus-outline-fonts/design/index-en.html#mplus_1p
+:url-w1252: https://en.wikipedia.org/wiki/Windows-1252
+:url-prawn-afm: https://github.com/prawnpdf/prawn/blob/master/CHANGELOG.md#vastly-improved-handling-of-encodings-for-pdf-built-in-afm-fonts
+
+You can select from <<built-in,built-in fonts>>, <<bundled,fonts bundled with Asciidoctor PDF>> or xref:custom-font.adoc[custom fonts] loaded from TrueType (TTF) or OpenType (OTF) font files.
+If you want to use custom fonts, you must first declare them in your theme file.
+
+IMPORTANT: Asciidoctor has no challenge working with Unicode.
+In fact, it prefers Unicode and considers the entire range.
+However, once you convert to PDF, you have to meet the font requirements of PDF in order to preserve Unicode characters.
+That means you need to provide a font (at least a fallback font) that contains glyphs for all the characters you want to use.
+If you don't, you may notice that characters are missing (usually replaced with a box).
+There's nothing Asciidoctor can do to convince PDF to work with extended characters without the right fonts in play.
+To see which characters are missing from the font, enable verbose mode (`-v`) when running Asciidoctor PDF.
+
+[#built-in]
+== Built-In (AFM) fonts
+
+The names of the built-in fonts (for general-purpose text) are as follows:
+
+[width=33.33%]
+|===
+|Font Name |Font Family
+
+|Helvetica
+|sans-serif
+
+|Times-Roman
+|serif
+
+|Courier
+|monospace
+|===
+
+Using a built-in font requires no additional files.
+You can use the key anywhere a `font-family` property is accepted in the theme file.
+For example:
+
+[source,yaml]
+----
+base:
+ font-family: Times-Roman
+----
+
+However, when you use a built-in font, the characters you can use in your document are limited to the characters in the WINANSI ({url-w1252}[Windows-1252^]) code set.
+WINANSI includes most of the characters needed for writing in Western languages (English, French, Spanish, etc).
+For anything outside of that, PDF is BYOF (Bring Your Own Font).
+
+Even though the built-in fonts require the content to be encoded in WINANSI, _you still type your AsciiDoc document in UTF-8_.
+Asciidoctor PDF encodes the content into WINANSI when building the PDF.
+
+WARNING: Built-in (AFM) fonts do not use the xref:fallback-font.adoc[fallback fonts].
+In order for the fallback font to kick in, you must use a TrueType font anywhere you want the fallback font to be used (e.g., the base font family, the code font family, etc).
+
+.WINANSI Encoding Behavior
+****
+When using the built-in PDF (AFM) fonts on a block of content in your AsciiDoc document, any character that cannot be encoded to WINANSI is replaced with a logic "`not`" glyph (`&#172;`) and you'll see the following warning in your console:
+
+ The following text could not be fully converted to the Windows-1252 character set:
+ | <string with unknown glyph>
+
+This behavior differs from the default behavior in Prawn, which is to simply crash.
+
+You'll often see this warning if you're using callouts in your document and you haven't specified a TrueType font in your theme.
+To prevent this warning, you need to specify a TrueType font.
+
+When using a TrueType font, you will get no warning for a missing glyph.
+That's a consequence of how Prawn works and is outside of Asciidoctor PDF's control.
+However, you'll likely see it substituted with a box (guaranteed if you're using one of the bundled fonts).
+
+For more information about how Prawn handles character encodings for built-in fonts, see {url-prawn-afm}[this note in the Prawn CHANGELOG^].
+****
+
+[#bundled]
+== Bundled fonts
+
+Asciidoctor PDF bundles several fonts that are used by the default theme.
+You can also use these fonts in your custom theme by simply declaring them.
+These fonts provide more characters than the built-in PDF fonts, but still only a subset of UTF-8 (to reduce the size of the gem).
+
+The family name of the fonts bundled with Asciidoctor PDF are as follows:
+
+{url-noto-serif}[Noto Serif^]::
+A serif font that can be styled as normal, italic, bold or bold_italic.
+
+{url-mplus-onemn}[M+ 1mn^]::
+A monospaced font that maps different thicknesses to the styles normal, italic, bold, and bold_italic.
+Also provides the circled numbers used in callouts.
+
+{url-mplus-onep}[M+ 1p Fallback^]::
+A sans-serif font that provides a very complete set of Unicode glyphs.
+Cannot be styled as italic, bold or bold_italic.
+Used as the fallback font in the `default-with-fallback-font` theme.
+
+TIP: The default themes refer to the bundled fonts using the `GEM_FONTS_DIR` prefix.
+That means you can extend a default theme and not have to worry about how the bundled fonts get resolved.
+If you redeclare the bundled fonts in your custom theme, be sure to prefix the path with the `GEM_FONTS_DIR` token.
+An alternative approach is to include `GEM_FONT_DIR` in the value of the `pdf-fontsdir` attribute separated by the location of your custom fonts using a comma (e.g., `path/to/your/fonts,GEM_FONTS_DIR`) or a semicolon (e.g., `path/to/your/fonts;GEM_FONTS_DIR`).
diff --git a/docs/modules/theme/pages/font.adoc b/docs/modules/theme/pages/font.adoc
new file mode 100644
index 00000000..28b0c4e9
--- /dev/null
+++ b/docs/modules/theme/pages/font.adoc
@@ -0,0 +1,83 @@
+= Font Category Keys
+:navtitle: Font
+
+== font
+
+The font key is where you declare custom fonts (`catalog` key) and configure the fallback fonts (`fallbacks` key).
+
+The data format of the `catalog` key is a map.
+Each key is the name of the font that you can use to refer to the font elsewhere in the theme.
+The value is either a font path (which is used for all font styles) or another map that specifies a font path to each of the four font styles.
+You can also configure the `catalog` to merge entries from an inherited font catalog.
+See <<extend-catalog>>.
+
+The data format of the `fallbacks` key is an array.
+The values of the array are the font names declared in the `catalog` (or a name inherited from another theme).
+These fallbacks are used, in the order listed, when a glyph cannot be found in the primary font for a given element.
+
+[cols="1,2,5l"]
+|===
+|Key |Value Type |Example
+
+|catalog
+|Map
+|font:
+catalog:
+Noto Serif:
+normal: GEM_FONTS_DIR/notoserif-regular-subset.ttf
+bold: GEM_FONTS_DIR/notoserif-bold-subset.ttf
+italic: GEM_FONTS_DIR/notoserif-italic-subset.ttf
+bold_italic: GEM_FONTS_DIR/notoserif-bold_italic-subset.ttf
+
+|fallbacks
+|Array
+|font:
+fallbacks:
+- M+ 1p Fallback
+- Noto Emoji
+|===
+
+[#extend-catalog]
+== Extending the font catalog
+
+If you define a xref:custom-font.adoc[custom font] in the font catalog in a theme that extends from `default`, and you want to continue to use the bundled fonts in your theme, you either have to redeclare the bundled fonts:
+
+.Redeclaring the bundle fonts in a custom theme
+[source,yaml]
+----
+extends: default
+font:
+ catalog:
+ Noto Serif:
+ normal: GEM_FONTS_DIR/notoserif-regular-subset.ttf
+ bold: GEM_FONTS_DIR/notoserif-bold-subset.ttf
+ italic: GEM_FONTS_DIR/notoserif-italic-subset.ttf
+ bold_italic: GEM_FONTS_DIR/notoserif-bold_italic-subset.ttf
+ M+ 1mn:
+ normal: GEM_FONTS_DIR/mplus1mn-regular-subset.ttf
+ bold: GEM_FONTS_DIR/mplus1mn-bold-subset.ttf
+ italic: GEM_FONTS_DIR/mplus1mn-italic-subset.ttf
+ bold_italic: GEM_FONTS_DIR/mplus1mn-bold_italic-subset.ttf
+ Your Font:
+ normal: /path/to/your/font.ttf
+heading:
+ font-family: Your Font
+----
+
+or you need to set `merge: true` above your font definitions:
+
+.Merging with the inherited font catalog
+[source,yaml]
+----
+extends: default
+font:
+ catalog:
+ merge: true
+ Your Font:
+ normal: /path/to/your/font.ttf
+heading:
+ font-family: Your Font
+----
+
+If you're referring to a bundled font, you'll need to prefix the path with `GEM_FONTS_DIR` (or add it to the value of the `pdf-fontsdir` attribute) so the converter can find and register it.
+You can find the bundle font definitions in default theme.
diff --git a/docs/modules/theme/pages/footnotes.adoc b/docs/modules/theme/pages/footnotes.adoc
new file mode 100644
index 00000000..ec2dde7a
--- /dev/null
+++ b/docs/modules/theme/pages/footnotes.adoc
@@ -0,0 +1,47 @@
+= Footnotes Category Keys
+:navtitle: Footnotes
+
+The keys in this category control the style of the footnotes list at the end of the chapter (book) or document (otherwise).
+If the `footnotes-title` attribute is specified, it is styled as a block caption.
+The styling of the links is controlled by the global link styles.
+
+[#key-prefix-footnotes,cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+
+|font-color
+|xref:color.adoc[Color] +
+(default: $base-font-color)
+|footnotes:
+font-color: #cccccc
+
+|font-size
+|xref:language.adoc#values[Number] +
+(default: 9)
+|footnotes:
+font-size: 8
+
+|font-style
+|xref:text.adoc#font-style[Font style] +
+(default: $base-font-style)
+|footnotes:
+font-style: italic
+
+|item-spacing
+|xref:measurement-units.adoc[Measurement] +
+(default: 3)
+|footnotes:
+item-spacing: 5
+
+|margin-top
+|xref:measurement-units.adoc[Measurement] +
+(default: 0)
+|footnotes:
+margin-top: 10
+
+|text-transform
+|xref:text.adoc#transform[Text transform] +
+(default: _inherit_)
+|footnotes:
+text-transform: lowercase
+|===
diff --git a/docs/modules/theme/pages/heading.adoc b/docs/modules/theme/pages/heading.adoc
new file mode 100644
index 00000000..29b26aa0
--- /dev/null
+++ b/docs/modules/theme/pages/heading.adoc
@@ -0,0 +1,191 @@
+= Heading Category Keys
+:navtitle: Heading
+
+The keys in this category control the style of most headings, including part titles, chapter titles, sections titles, the table of contents title, and discrete headings.
+The <<key-prefix-heading-level,heading-h1 key>> controls the font properties of the document title (aka doctitle) when the doctype is article and the title page is not enabled (i.e., the title-page document attribute is not set).
+
+.heading keys
+[#key-prefix-heading,cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+
+|align
+|xref:text.adoc#align[Text alignment] +
+(default: $base-align)
+|heading:
+align: center
+
+|font-color
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|heading:
+font-color: #222222
+
+|font-family
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|heading:
+font-family: Noto Serif
+
+|font-kerning
+|normal {vbar} none +
+(default: _inherit_)
+|heading:
+font-kerning: none
+
+// NOTE: heading-font-size is overridden by h<n>-font-size in base theme
+//|font-size
+//|xref:language.adoc#values[Number] +
+//(default: $base-font-size)
+//|heading:
+// font-size: 18
+
+|font-style
+|xref:text.adoc#font-style[Font style] +
+(default: bold)
+|heading:
+font-style: bold
+
+|text-decoration
+|xref:text.adoc#decoration[Text decoration] +
+(default: none)
+|heading:
+text-decoration: underline
+
+|text-decoration-color
+|xref:color.adoc[Color] +
+(default: $heading-font-color)
+|heading:
+text-decoration-color: #cccccc
+
+|text-decoration-width
+|xref:language.adoc#values[Number] +
+(default: $base-text-decoration-width)
+|heading:
+text-decoration-width: 0.5
+
+|text-transform
+|xref:text.adoc#transform[Text transform] +
+(default: _inherit_)
+|heading:
+text-transform: capitalize
+
+|line-height
+|xref:language.adoc#values[Number] +
+(default: 1.15)
+|heading:
+line-height: 1.2
+
+|margin-top
+|xref:measurement-units.adoc[Measurement] +
+(default: 4)
+|heading:
+margin-top: $vertical-spacing * 0.2
+
+|margin-page-top
+|xref:measurement-units.adoc[Measurement] +
+(default: 0)
+|heading:
+margin-page-top: $vertical-spacing
+
+|margin-bottom
+|xref:measurement-units.adoc[Measurement] +
+(default: 12)
+|heading:
+margin-bottom: 9.6
+
+|min-height-after
+|xref:measurement-units.adoc[Measurement] +
+(default: $base-font-size * $base-line-height * 1.5)
+|heading:
+min-height-after: 0.5in
+
+|chapter-break-before
+|always {vbar} auto +
+(default: always)
+|heading:
+chapter:
+break-before: auto
+
+|part-break-before
+|always {vbar} auto +
+(default: always)
+|heading:
+part:
+break-before: auto
+
+|part-break-after
+|always {vbar} auto +
+(default: auto)
+|heading:
+part:
+break-after: always
+
+3+|[#key-prefix-heading-level]*Key Prefix:* <<key-prefix-heading-level,heading-h<n>{zwsp}>>^[1]^
+
+|align
+|xref:text.adoc#align[Text alignment] +
+(default: $heading-align)
+|heading:
+h2-align: center
+
+|font-color
+|xref:color.adoc[Color] +
+(default: $heading-font-color)
+|heading:
+h2-font-color: [0, 99%, 100%, 0]
+
+|font-family
+|xref:font-support.adoc[Font family name] +
+(default: $heading-font-family)
+|heading:
+h4-font-family: Roboto
+
+|font-kerning
+|normal {vbar} none +
+(default: $heading-font-kerning)
+|heading:
+h3-font-kerning: none
+
+|font-size^[2]^
+|xref:language.adoc#values[Number] +
+(default: <1>=24; <2>=18; <3>=16; <4>=14; <5>=12; <6>=10)
+|heading:
+h6-font-size: $base-font-size * 1.7
+
+|font-style
+|xref:text.adoc#font-style[Font style] +
+(default: $heading-font-style)
+|heading:
+h3-font-style: bold_italic
+
+|text-transform
+|xref:text.adoc#transform[Text transform] +
+(default: $heading-text-transform)
+|heading:
+h3-text-transform: uppercase
+
+|margin-top
+|xref:measurement-units.adoc[Measurement] +
+(default: $heading-margin-top)
+|heading:
+h2-margin-top: $vertical-spacing * 0.5
+
+|margin-page-top
+|xref:measurement-units.adoc[Measurement] +
+(default: $heading-margin-page-top)
+|heading:
+h2-margin-page-top: $vertical-spacing
+
+|margin-bottom
+|xref:measurement-units.adoc[Measurement] +
+(default: $heading-margin-bottom)
+|heading:
+h2-margin-bottom: 10
+|===
+
+1. `<n>` is a number ranging from 1 to 6, representing each of the six heading levels.
+h1 is used for part titles (book doctype) or the doctitle (article doctype when the title-page document attribute is not set).
+h2 is used for chapter titles (book doctype only).
+2. A font size is assigned to each heading level by the base theme.
+If you want the font size of a specific level to be inherited, you must assign the value `null` (or `~` for short).
diff --git a/docs/modules/theme/pages/image.adoc b/docs/modules/theme/pages/image.adoc
new file mode 100644
index 00000000..c341b621
--- /dev/null
+++ b/docs/modules/theme/pages/image.adoc
@@ -0,0 +1,65 @@
+= Images
+
+[#formats]
+== Supported image formats
+
+The following image types (and corresponding file extensions) are supported:
+
+* PNG (.png)
+* JPEG (.jpg)
+* SVG (.svg)
+
+CAUTION: CAUTION: The GIF (.gif), TIFF (.tiff), BMP (.bmp), and interlaced PNG formats are not supported unless you install prawn-gmagick.
+See xref:ROOT:image-paths-and-formats.adoc#other-image-formats[Supporting additional image file formats] for details.
+
+[#specify]
+== Specify an image in a theme
+
+An image is specified either as a bare image path or as an inline image macro as found in the AsciiDoc syntax.
+Images in the theme file are currently resolved relative to the value of the `pdf-themesdir` attribute.
+(If `pdf-theme` is a path that ends in `.yml`, and `pdf-themesdir` is not set, then the images are resolved relative to the directory of the path specified by `pdf-theme`).
+If you want to use an image in your theme that's relative to the document you're converting, you can prefix the target with the `\{docdir}` attribute reference.
+
+Here's how an image is specified in the theme file as a bare image path:
+
+[source,yaml]
+----
+title-page:
+ background-image: title-cover.png
+----
+
+Here's how the image is specified using the inline image macro:
+
+[source,yaml]
+----
+title-page:
+ background-image: image:title-cover.png[]
+----
+
+In either case, the image is resolved relative to the value of the `pdf-themesdir` attribute.
+If you want to reference an image relative to the document you're converting, then prefix the target with the `\{docdir}` attribute reference.
+
+[source,yaml]
+----
+title-page:
+ background-image: image:{docdir}/images/title-cover.png[]
+----
+
+[#align]
+== Width, fit, and alignment
+
+Like in the AsciiDoc syntax, wrapping the value in the image macro allows you to specify other settings, such as `pdfwidth`, `fit`, and `align`.
+For example:
+
+[source,yaml]
+----
+title-page:
+ logo-image: image:logo.png[pdfwidth=2.5in,align=center]
+----
+
+The `align` key is used to align images within the parent container.
+Images can be aligned as follows:
+
+* `left`
+* `center`
+* `right`
diff --git a/docs/modules/theme/pages/index-section.adoc b/docs/modules/theme/pages/index-section.adoc
new file mode 100644
index 00000000..43bc1dfb
--- /dev/null
+++ b/docs/modules/theme/pages/index-section.adoc
@@ -0,0 +1,17 @@
+= Index Category Key
+:navtitle: Index
+:source-language: yaml
+
+The key in the `index` category controls the number of columns in the autogenerated index section.
+
+[#key-prefix-index,cols="2,4,6a"]
+|===
+|Key |Value Type |Example
+
+|`columns`
+|Integer +
+(default: `2`)
+|[source]
+index:
+ columns: 2
+|===
diff --git a/docs/modules/theme/pages/index.adoc b/docs/modules/theme/pages/index.adoc
new file mode 100644
index 00000000..cb64706a
--- /dev/null
+++ b/docs/modules/theme/pages/index.adoc
@@ -0,0 +1,31 @@
+= Asciidoctor PDF Theming
+:navtitle: Theming
+
+Asciidoctor PDF comes with a built-in theming system and a default theme.
+The theming system is used to control the layout and styling of a PDF file generated from AsciiDoc by Asciidoctor PDF.
+You can use the default theme for your PDFs as it is, extend the default theme to change or add styles, or create and apply a custom theme.
+
+== Theme configuration and language
+
+The Asciidoctor PDF theming system is driven by a YAML configuration file.
+The Asciidoctor PDF theme language is described using https://en.wikipedia.org/wiki/YAML[YAML] and incorporates many _concepts_ from CSS and SASS, such as selectors, properties, and inheritance.
+Therefore, if you have a background in web design, the terminology should be immediately familiar to you.
+*Note, however, that the theming system isn't actually CSS.*
+
+== Theme capabilities
+
+The theme can generally influence PDF settings, page numbering, font properties, background and borders, character selections, spacings, and running content.
+It has limited influence over the layout of elements on the page.
+If your theming requirements demand more than what this theming system can accommodate, you can xref:extend:index.adoc[extend the converter] to gain more control over the layout and style.
+
+//This document describes how the theming system works, how to define a custom theme in YAML, and how to activate the theme when running Asciidoctor PDF.
+//To learn how the theming system works and how to create and apply custom themes, refer to the <<docs/theming-guide.adoc#,Asciidoctor PDF Theming Guide>>.
+You can use the built-in theme files, which you can find in the [.path]_data/themes_ directory, as examples.
+
+If you've enabled a source highlighter, you can control the style (aka theme) it applies to source blocks using the `coderay-style`, `pygments-style`, and `rouge-style` attributes, respectively.
+For example, to configure Rouge to use the built-in monokai theme, run Asciidoctor PDF as follows:
+
+ $ asciidoctor-pdf -a rouge-style=monokai basic-example.adoc
+
+It's possible to develop your own theme for Rouge.
+Refer to xref:source-highlighting-theme.adoc[] for details.
diff --git a/docs/modules/theme/pages/keyboard.adoc b/docs/modules/theme/pages/keyboard.adoc
new file mode 100644
index 00000000..0086fc66
--- /dev/null
+++ b/docs/modules/theme/pages/keyboard.adoc
@@ -0,0 +1,75 @@
+= Keyboard Macro Category Keys
+:navtitle: Keyboard
+
+The keys in the `kbd` category apply to a kbd reference generated from the inline kbd macro.
+The kbd reference is a span of text denoting textual user input from a keyboard, voice input, or other text entry device.
+
+[#key-prefix-kbd,cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+
+|background-color
+|xref:color.adoc[Color] +
+(default: _not set_)
+|kbd:
+background-color: #fafafa
+
+|border-color^[1]^
+|xref:color.adoc[Color] +
+(default: _not set_)
+|kbd:
+border-color: #cccccc
+
+|border-offset^[2]^
+|xref:language.adoc#values[Number] +
+(default: 0)
+|kbd:
+border-offset: 1.5
+
+|border-radius
+|xref:language.adoc#values[Number] +
+(default: 0)
+|kbd:
+border-radius: 2
+
+|border-width
+|xref:language.adoc#values[Number] +
+(default: $base-border-width)
+|kbd:
+border-width: 0.375
+
+|separator^[3]^
+|xref:quoted-string.adoc[Quoted string] +
+(default: "+")
+|kbd:
+separator: "\u2009+\u2009"
+
+|font-color
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|kbd:
+font-color: #000
+
+|font-family
+|xref:font-support.adoc[Font family name] +
+(default: Courier)
+|kbd:
+font-family: $base-font-family
+
+|font-size
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|kbd:
+font-size: 10.5
+
+|font-style
+|xref:text.adoc#font-style[Font style] +
+(default: italic)
+|kbd:
+font-style: normal
+|===
+
+1. The border is only used if a border color is specified and the border width is not explicitly set to 0.
+2. The border offset is the amount that the background and border swells around the text.
+It does not affect the distance between the formatted phrase and the phrases that surround it.
+3. The separator is only used for multi-key input sequences.
diff --git a/docs/modules/theme/pages/keys.adoc b/docs/modules/theme/pages/keys.adoc
new file mode 100644
index 00000000..41107a61
--- /dev/null
+++ b/docs/modules/theme/pages/keys.adoc
@@ -0,0 +1,21 @@
+= Category Keys Reference
+//Theme Keys Reference
+
+== Category keys
+
+The following pages list the keys and acceptable values or value types that are available when creating a custom theme.
+The keys are organized by category key.
+Each category represents a common prefix under which the keys are typically nested.
+
+TIP: Keys can be nested wherever an underscore (`_`) or hyphen (`-`) appears in the name.
+This nested structure is for organizational purposes only.
+All keys are flatted when the theme is loaded (e.g., `align` nested under `base` becomes `base-align`).
+
+The converter uses the values of these keys to control how most elements are arranged and styled in the PDF.
+The default values listed in this section get inherited from the {url-repo-root}/data/themes/base-theme.yml[base theme^].
+
+IMPORTANT: The {url-repo-root}/data/themes/default-theme.yml[default theme^] has a different set of values which are not shown in this guide.
+
+When creating a theme that extends the base theme, all keys are optional.
+Required keys are provided by the base theme.
+Therefore, you only have to declare keys that you want to override.
diff --git a/docs/modules/theme/pages/language.adoc b/docs/modules/theme/pages/language.adoc
new file mode 100644
index 00000000..d81ee914
--- /dev/null
+++ b/docs/modules/theme/pages/language.adoc
@@ -0,0 +1,130 @@
+= Keys, Properties and Values
+
+The Asciidoctor PDF theme language is described using the http://en.wikipedia.org/wiki/YAML[YAML^] data format.
+YAML is a human-friendly data format that resembles CSS.
+*Note, however, that the theming system isn't actually CSS.*
+
+A theme is stored in a dedicated theme file and described as YAML key-value pairs that can be nested and stored in a dedicated theme file.
+The theme language adds some extra features to YAML, such as variables, basic math, measurements, and color values.
+
+[#key-names]
+== Key names
+//Keys as selectors and properties
+
+The theming language's built-in key names are assembled from selectors and properties.
+Selectors are the component you want to style.
+The properties are the style elements of that component that can be styled.
+All selector names are implicit (e.g., `heading`), so you customize the theme primarily by manipulating pre-defined property values (e.g., `font-size`).
+
+[#css-properties]
+=== CSS Properties
+
+The theme language in Asciidoctor PDF supports a limited subset of the properties from CSS.
+Some of these properties have different names from those found in CSS.
+
+* An underscore (`_`) may be used in place of a hyphen (`-`) in all property names (so you may use `font_family` or `font-family`).
+* An underscore (`_`) may be used in place of a hyphen (`-`) in all variable names (so you may use `$base_font_family` or `$base-font-family`).
+* Instead of separate properties for font weight and font style, the theme language combines these settings in the `font-style` property (allowed values: `normal`, `bold`, `italic`, and `bold_italic`).
+* The `align` property in the theme language is roughly equivalent to the `text-align` property in CSS.
+* The `font-color` property in the theme language is equivalent to the `color` property in CSS.
+
+[#values]
+== Key values
+
+The value of a key may be one of the following types:
+
+* String
+** Font family name (e.g., Roboto)
+** Font style (normal, bold, italic, bold_italic)
+** Alignment (left, center, right, justify)
+** Color as hex string (e.g., 'ff0000', #ff0000, or '#ff0000')
+** Image path
+** Enumerated type (where specified)
+** Text content (where specified)
+* Null (clears any previously assigned value)
+** _empty_ (i.e., no value specified)
+** null
+** ~
+* Number (integer or float) with optional units (default unit is points)
+* Array
+** Color as RGB array (e.g., [51, 51, 51])
+** Color CMYK array (e.g., [50, 100, 0, 0])
+** Margin (e.g., [1in, 1in, 1in, 1in])
+** Padding (e.g., [1in, 1in, 1in, 1in])
+* Variable reference (e.g., $base_font_color or $base-font-color)
+* Math expression
+
+Keys almost always require a value of a specific type.
+The reference page for each xref:keys.adoc[key category] specifies the acceptable values or value types per key.
+
+== Key nesting
+
+Keys may be nested to an arbitrary depth to eliminate redundant prefixes.
+Once the theme is loaded, all keys are flattened into a single map of qualified keys.
+Nesting is simply a shorthand way of organizing the keys.
+In the end, a theme is just a map of key/value pairs.
+
+Nested keys are adjoined to their parent key with an underscore (`_`) or hyphen (`-`).
+This means the selector part (e.g., `link`) is combined with the property name (e.g., `font-color`) into a single, qualified key (e.g., `link_font_color` or `link-font-color`).
+
+For example, let's assume we want to set the base (i.e., global) font size and color.
+These keys may be written longhand:
+
+[source,yaml]
+----
+base-font-color: '#333333'
+base-font-family: Times-Roman
+base-font-size: 12
+----
+
+Or, to avoid having to type the prefix `base-` multiple times, the keys may be written as a hierarchy:
+
+[source,yaml]
+----
+base:
+ font-color: '#333333'
+ font-family: Times-Roman
+ font-size: 12
+----
+
+Or even:
+
+[source,yaml]
+----
+base:
+ font:
+ color: '#333333'
+ family: Times-Roman
+ size: 12
+----
+
+Each level of nesting must be indented by two spaces from the indentation of the parent level.
+Also note the presence of the colon (`:`) after each key name.
+
+== Inheritance
+
+Like CSS, inheritance is a principle feature in the Asciidoctor PDF theme language.
+For many of the properties, if a key is not specified, the key inherits the value applied to the parent content in the content hierarchy.
+This behavior saves you from having to specify properties unless you want to override the inherited value.
+
+The following keys are inherited:
+
+* `font-family`
+* `font-color`
+* `font-size`
+* `font-style`
+* `text-transform`
+* `line-height` (some exceptions)
+* `margin-bottom` (if not specified, defaults to `$vertical-spacing`)
+
+=== Heading inheritance
+
+Headings inherit starting from a specific heading level (e.g., `heading-h2-font-size`), then to the heading category (e.g., `heading-font-size`), then directly to the base value (e.g., `base-font-size`).
+Any setting from an enclosing context, such as a sidebar, is skipped.
+
+
+
+
+
+
+
diff --git a/docs/modules/theme/pages/link.adoc b/docs/modules/theme/pages/link.adoc
new file mode 100644
index 00000000..d7aec71e
--- /dev/null
+++ b/docs/modules/theme/pages/link.adoc
@@ -0,0 +1,64 @@
+= Link Category Keys
+:navtitle: Link
+
+The keys in this category are used to style hyperlink text.
+
+.link keys
+[#key-prefix-link,cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+
+|background-color
+|xref:color.adoc[Color] +
+(default: _not set_)
+|link:
+background-color: #efefef
+
+|border-offset
+|xref:language.adoc#values[Number] +
+(default: 0)
+|link:
+border-offset: 2
+
+|font-color
+|xref:color.adoc[Color] +
+(default: #0000ee)
+|link:
+font-color: #428bca
+
+|font-family
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|link:
+font-family: Roboto
+
+|font-size
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|link:
+font-size: 9
+
+|font-style
+|xref:text.adoc#font-style[Font style] +
+(default: _inherit_)
+|link:
+font-style: italic
+
+|text-decoration
+|xref:text.adoc#decoration[Text decoration] +
+(default: none)
+|link:
+text-decoration: underline
+
+|text-decoration-color
+|xref:color.adoc[Color] +
+(default: $link-font-color)
+|link:
+text-decoration-color: #0000ff
+
+|text-decoration-width
+|xref:language.adoc#values[Number] +
+(default: $base-text-decoration-width)
+|link:
+text-decoration-width: 0.5
+|===
diff --git a/docs/modules/theme/pages/list.adoc b/docs/modules/theme/pages/list.adoc
new file mode 100644
index 00000000..487b7ec4
--- /dev/null
+++ b/docs/modules/theme/pages/list.adoc
@@ -0,0 +1,144 @@
+= List Category Keys
+:navtitle: List
+:source-language: yaml
+
+[#list]
+== list
+
+The keys in the `list` category control the arrangement and style of ordered and unordered lists.
+
+.list keys
+[#key-prefix-list,cols="3,3,6a"]
+|===
+|Key |Value Type |Example
+
+|`indent`
+|xref:measurement-units.adoc[Measurement] +
+(default: `30`)
+|[source]
+list:
+ indent: 40
+
+|`item-spacing`
+|xref:measurement-units.adoc[Measurement] +
+(default: `6`)
+|[source]
+list:
+ item-spacing: 4
+
+|`marker-font-color`
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|[source]
+list:
+ marker-font-color: '#3c763d'
+
+|`text-align`
+|xref:text.adoc#align[Text alignment] +
+(default: `$base-align`)
+|[source]
+list:
+ text-align: left
+|===
+
+The `marker-font-color` key controls the color of the bullet glyph that marks items in unordered lists and the color of the number or letter marker for items in ordered lists.
+The `text-align` key controls the alignment of the list text only, not nested content, such as nested blocks and lists.
+
+[#ulist-marker]
+== ulist-marker
+
+The keys in the `ulist-marker` category control the arrangement and style of the unordered list markers.
+
+.ulist-marker keys
+[#key-prefix-ulist-marker,cols="3,4,6a"]
+|===
+|Key |Value Type |Example
+
+|`font-family`
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|[source]
+ulist:
+ marker:
+ font-family: Noto Serif
+
+|`font-size`
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|[source]
+ulist:
+ marker:
+ font-size: 9
+
+|`font-color`
+|xref:color.adoc[Color] +
+(default: `$list-marker-font-color`)
+|[source]
+ulist:
+ marker:
+ font-color: '#cccccc'
+
+|`line-height`
+|xref:language.adoc#values[Number] +
+(default: `$base-line-height`)
+|[source]
+ulist:
+ marker:
+ line-height: 1.5
+|===
+
+[#ulist-marker-type]
+=== ulist-marker-<type>
+
+The keys in the `ulist-marker-<type>` category control the arrangement and style of a type of unordered list marker.
+Type can be `disc`, `square`, `circle`, `checked`, or `unchecked`.
+
+.ulist-marker-<type> keys
+[#key-prefix-ulist-marker-type,cols="3,4,6a"]
+|===
+|Key |Value Type |Example
+
+|`content`
+|xref:quoted-string.adoc[Quoted string]
+|[source]
+ulist:
+ marker:
+ disc:
+ content: "\uf140"
+
+|`font-family`
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|[source]
+ulist:
+ marker:
+ disc:
+ font-family: fas
+
+|`font-size`
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|[source]
+ulist:
+ marker:
+ disc:
+ font-size: 9
+
+|`font-color`
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|[source]
+ulist:
+ marker:
+ disc:
+ font-color: '#ff0000'
+
+|`line-height`
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|[source]
+ulist:
+ marker:
+ disc:
+ line-height: 2
+|===
diff --git a/docs/modules/theme/pages/mark.adoc b/docs/modules/theme/pages/mark.adoc
new file mode 100644
index 00000000..1399ec26
--- /dev/null
+++ b/docs/modules/theme/pages/mark.adoc
@@ -0,0 +1,33 @@
+= Mark Category Keys
+:navtitle: Mark
+
+The keys in the `mark` category apply to an inline mark phrase.
+
+[#key-prefix-mark,cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+
+|font-color
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|mark:
+font-color: #333333
+
+|font-style
+|xref:text.adoc#font-style[Font style] +
+(default: _inherit_)
+|mark:
+font-style: bold
+
+|background-color
+|xref:color.adoc[Color] +
+(default: #ff0000)
+|mark:
+background-color: #fcf8e3
+
+|border-offset
+|xref:language.adoc#values[Number] +
+(default: 1)
+|mark:
+border-offset: 2
+|===
diff --git a/docs/modules/theme/pages/math-operations.adoc b/docs/modules/theme/pages/math-operations.adoc
new file mode 100644
index 00000000..0d65054f
--- /dev/null
+++ b/docs/modules/theme/pages/math-operations.adoc
@@ -0,0 +1,70 @@
+= Math Operations
+
+The theme language supports basic math operations to support calculated values.
+
+== Operators
+
+The following table lists the supported operations and the corresponding operator for each.
+
+[width=25%]
+|===
+|Operation |Operator
+
+|multiply
+|*
+
+|divide
+|/
+
+|add
+|+
+
+|subtract
+|-
+|===
+
+Like programming languages, the multiply and divide operators take precedence over the add and subtract operators.
+
+== Expressions
+
+Here's an example of a math expression with fixed values.
+
+[source,yaml]
+----
+conum:
+ line-height: 4 / 3
+----
+
+IMPORTANT: Operators must always be surrounded by a space on either side (e.g., 2 + 2, not 2+2).
+
+Variables may be used in place of numbers anywhere in the expression:
+
+[source,yaml]
+----
+base:
+ font-size: 12
+ font-size-large: $base-font-size * 1.25
+----
+
+Values used in a math expression are automatically coerced to a float value before the operation.
+If the result of the expression is an integer, the value is coerced to an integer afterwards.
+
+IMPORTANT: Numeric values less than 1 must have a 0 before the decimal point (e.g., 0.85).
+
+== Functions
+
+The theme language also supports several functions for rounding the result of a math expression.
+The following functions may be used if they surround the whole value or expression for a key.
+
+round(...):: Rounds the number to the nearest half integer.
+floor(...):: Rounds the number up to the next integer.
+ceil(...):: Rounds the number down the previous integer.
+
+You might use these functions in font size calculations so that you get more exact values.
+
+[source,yaml]
+----
+base:
+ font-size: 12.5
+ font-size-large: ceil($base-font-size * 1.25)
+----
diff --git a/docs/modules/theme/pages/measurement-units.adoc b/docs/modules/theme/pages/measurement-units.adoc
new file mode 100644
index 00000000..70cf68bd
--- /dev/null
+++ b/docs/modules/theme/pages/measurement-units.adoc
@@ -0,0 +1,58 @@
+= Measurement Units
+
+The default unit of measure for a PDF canvas is points (pt).
+However, humans like to think in units such as inches (in), centimeters (cm), or millimeters (mm).
+You can let the theme do this conversion for you automatically by adding a unit notation next to any number.
+
+== Default unit
+
+Several of the keys require a value in points (pt), the unit of measure for the PDF canvas.
+A point is defined as 1/72 of an inch.
+If you specify a number without any units, the units defaults to pt.
+
+== Supported units
+
+The following units are supported:
+
+|===
+|Unit |Suffix |Notes
+
+|Centimeter
+|cm
+|
+
+|Inches
+|in
+|
+
+|Millimeter
+|mm
+|
+
+|Percentage
+|%, vw, or vh
+|A percentage with the % unit is calculated relative to the width or height of the content area.
+Viewport-relative percentages (vw or vh units) are calculated as a percentage of the page width or height, respectively.
+Currently, percentage units can only be used for placing elements on the title page or for setting the width of a block image.
+
+|Points
+|pt
+|Default unit of measure when no unit is specified.
+|===
+
+== Specify a measurement unit
+
+Here's an example of how you can use inches to define the page margins:
+
+[source,yaml]
+----
+page:
+ margin: [0.75in, 1in, 0.75in, 1in]
+----
+
+The order of elements in a measurement array is the same as it is in CSS:
+
+. top
+. right
+. bottom
+. left
diff --git a/docs/modules/theme/pages/menu.adoc b/docs/modules/theme/pages/menu.adoc
new file mode 100644
index 00000000..9b2bbfb0
--- /dev/null
+++ b/docs/modules/theme/pages/menu.adoc
@@ -0,0 +1,41 @@
+= Menu Macro Category Keys
+:navtitle: Menu
+
+The keys in this category apply to the menu label (generated from the inline menu macro).
+Keep in mind that the styles for the caret can be controlled independently using the `<font>` tag.
+
+.menu keys
+[#key-prefix-menu,cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+
+|caret-content
+|xref:quoted-string.adoc[Quoted string] +
+(default: " \u203a ")
+|menu:
+caret-content: ' > '
+
+|font-color
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|menu:
+font-color: #AA0000
+
+|font-family
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|menu:
+font-family: M+ 1mn
+
+|font-size
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|menu:
+font-size: 8
+
+|font-style
+|xref:text.adoc#font-style[Font style] +
+(default: bold)
+|menu:
+font-style: bold_italic
+|===
diff --git a/docs/modules/theme/pages/page-numbers.adoc b/docs/modules/theme/pages/page-numbers.adoc
new file mode 100644
index 00000000..4ad212a9
--- /dev/null
+++ b/docs/modules/theme/pages/page-numbers.adoc
@@ -0,0 +1,47 @@
+= Page Numbers
+
+The converter automatically keeps track of page numbers.
+These page numbers are available as metadata and determine folio placement (recto/verso pages).
+
+== Default page number assignment
+
+By default, the converter assigns the page number 1 to the first body page of the document.
+It then increments the page number for each page thereafter.
+All front matter pages that precede the first body page in the book doctype (or when the `title-page` attribute is set) (e.g., cover page, title page, and toc pages) are numbered using roman numerals (e.g., i, ii, iii, etc).
+Since these computed page numbers can differ from the physical page numbers, we refer to them as [.term]_virtual page numbers_.
+
+By default, the folio placement is derived from the virtual page number.
+Odd page numbers (e.g., 1, 3, 5, ...) designate recto pages and even page numbers (e.g., 2, 4, 6, ...) designate verso pages.
+
+== Customize the page numbering
+
+It's possible to influence the virtual page numbering using a combination of the theme and document attributes.
+One such customization is to control where the transition from roman numerals to integers occurs.
+
+The theme can specify the page where the integer (1-based) page numbering should begin using the `page-numbering-start-at` key.
+For instance, the theme can specify `page-numbering-start-at: title`, which will make the integer page numbering start at the title page when enabled (i.e., the title page will be assigned the virtual page number 1).
+Alternately, the theme can specify an offset from the first body page where the page numbering should begin (all doctypes).
+For instance, `page-numbering-start-at: 2` tells the converter to assign the virtual page number 1 to the second page of the body.
+Any page that precedes that page will be numbered using roman numerals.
+
+Changing the page on which the integer page numbering begins can alter the folio placement.
+To correct for this, or to change the folio placement in general, you can use the `pdf-folio-placement` document attribute.
+For instance, to base the folio placement on physical page numbers, set the value of this attribute to `physical` (e.g., `pdf-folio-placement=physical`).
+To invert the recto and verso pages, add the `-inverted` qualifier to the value (e.g., `pdf-folio-placement=physical-inverted`).
+
+The default theme shows the virtual page number in the footer of all body pages.
+If you're starting with a blank theme, you can add the page number by using the `\{page-number}` attribute reference in the `content` key of the running content (header or footer).
+For example:
+
+[source,yaml]
+----
+footer:
+ recto:
+ right:
+ content: '\{page-number}'
+----
+
+If you want the running content to also appear on front matter pages, you can use the theme to change the page on which the running content starts with the `running-content-start-at` key.
+For instance, to start the running content on the title page, assuming the title page is enabled, set `running-content-start-at: title` in your theme file.
+
+Aside from the configurability mentioned, the page numbering logic is computed automatically.
diff --git a/docs/modules/theme/pages/page.adoc b/docs/modules/theme/pages/page.adoc
new file mode 100644
index 00000000..61589cc2
--- /dev/null
+++ b/docs/modules/theme/pages/page.adoc
@@ -0,0 +1,111 @@
+= Page Category Keys
+:navtitle: Page
+
+The keys in this category control the size, margins, and background of each page (i.e., canvas).
+We recommended that you define this category before all other categories.
+
+NOTE: The background of the title page can be styled independently of other pages.
+See xref:title-page.adoc[] for details.
+
+.page keys
+[#key-prefix-page,cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+
+|background-color^[1]^
+|xref:color.adoc[Color] +
+(default: #ffffff)
+|page:
+background-color: #fefefe
+
+|background-image^[2]^
+|image macro^[3]^ +
+(default: _not set_)
+|page:
+background-image: image:page-bg.png[]
+
+|background-image-(recto{vbar}verso)^[2]^
+|image macro^[3]^ +
+(default: _not set_)
+|page:
+background-image:
+recto: image:page-bg-recto.png[]
+verso: image:page-bg-verso.png[]
+
+|foreground-image^[2]^
+|image macro^[3]^ +
+(default: _not set_)
+|page
+foreground-image: image:watermark.svg[]
+
+|initial-zoom
+|Fit {vbar} FitH {vbar} FitV +
+(default: FitH)
+|page:
+initial-zoom: Fit
+
+|layout
+|portrait {vbar} landscape +
+(default: portrait)
+|page:
+layout: landscape
+
+|margin
+|xref:measurement-units.adoc[Measurement] {vbar} xref:measurement-units.adoc[Measurement[top,right,bottom,left\]]+
+(default: 36)
+|page:
+margin: [0.5in, 0.67in, 1in, 0.67in]
+
+|margin-inner^[4]^
+|xref:measurement-units.adoc[Measurement] +
+(default: 48)
+|page:
+margin-inner: 0.75in
+
+|margin-outer^[4]^
+|xref:measurement-units.adoc[Measurement] +
+(default: 24)
+|page:
+margin-outer: 0.59in
+
+|mode
+|outline {vbar} none {vbar} thumbs {vbar} fullscreen {vbar} fullscreen outline {vbar} fullscreen none {vbar} fullscreen thumbs +
+(default: outline)
+|page:
+mode: fullscreen none
+
+|size
+|https://github.com/prawnpdf/pdf-core/blob/0.6.0/lib/pdf/core/page_geometry.rb#L16-L68[Named size^] {vbar} xref:measurement-units.adoc[Measurement[width,height\]] +
+(default: A4)
+|page:
+size: Letter
+
+3+|[#key-prefix-page-numbering]*Key Prefix:* <<key-prefix-page-numbering,numbering>>
+
+|start-at^[5]^
+|cover {vbar} title {vbar} toc {vbar} after-toc {vbar} body {vbar} Integer +
+(default: body)
+|page:
+numbering:
+start-at: toc
+|===
+
+1. To disable the background color for the page, set the value to white (i.e., `FFFFFF`).
+The color keyword `transparent` is not recognized in this context.
+2. By default, page background and foreground images are automatically scaled to fit the bounds of the page (i.e., `fit=contain`) and centered (i.e., `position=center`).
+The size of the image can be controlled using any of the sizing attributes on the image macro (i.e., `fit`, `pdfwidth`, `scaledwidth`, or `width`) when `fit=none`.
+The position of the image can be controlled using the `position` attribute.
+If the recto (right-hand, odd-numbered pages) or verso (left-hand, even-numbered pages) background image is specified, it will be used only for that side (not available for the foreground image).
+If you define the keys using the flattened structure (e.g., `page-background-image-recto`), you can also set the default page background image (`page-background-image`), which will then be used as a fallback if a background image isn't specified for a given side.
+To disable the image, use the value `none`.
+3. Target may be an absolute path or a path relative to the value of the `pdf-themesdir` attribute.
+4. The margins for `recto` (right-hand, odd-numbered) and `verso` (left-hand, even-numbered) pages are calculated automatically from the margin-inner and margin-outer values.
+These margins and used when the value `prepress` is assigned to the `media` document attribute.
+If no cover is specified, the recto margin is not applied to the title page.
+To apply the recto margin to the title page, but not include a cover, assign the value `~` to the `front-cover-image` and `back-cover-image` attributes.
+5. The `cover` value is only recognized if the document has a front cover page (i.e., `front-cover-image`).
+The `title`, `toc`, and `after-toc` values are only recognized if the title page is enabled (i.e., doctype is book or `title-page` attribute is set)
+The `toc` value only applies if the toc is in the default location (before the first page of the body).
+If value is `toc`, and the toc macro is used to position the toc, the start-at behavior is the same as if the toc is not enabled.
+If value is an integer, page numbering will start at the specified page of the body (i.e., 1 is first page, 2 is second page, etc.)
+If value is `after-toc`, the page numbering will start after the toc, no matter where it's placed in the document.
diff --git a/docs/modules/theme/pages/prepare-custom-font.adoc b/docs/modules/theme/pages/prepare-custom-font.adoc
new file mode 100644
index 00000000..600401a6
--- /dev/null
+++ b/docs/modules/theme/pages/prepare-custom-font.adoc
@@ -0,0 +1,113 @@
+= Prepare a Custom Font
+:url-fontforge: https://fontforge.github.io/en-US/
+:url-fontforge-scripting: https://fontforge.github.io/en-US/documentation/scripting/
+
+Any TTF or OTF font can be used with Prawn--and hence Asciidoctor PDF--without modifications (unless, of course, it's corrupt or contains errors).
+However, you may discover that kerning is disabled and certain required glyphs are missing (or replaced with boxes).
+To address these problems, you need to prepare the font using a font program such as {url-fontforge}[FontForge^].
+These instructions will cover how to prepare a TTF font, but the same applies for an OTF font.
+
+[#validate]
+== Validate the font
+
+Before using the font, you may want to check that the font is valid.
+To do so, create the following script, which will verify that the font is free from errors.
+
+.validate-font.rb
+[source,ruby]
+----
+require 'ttfunk'
+require 'ttfunk/subset_collection'
+
+ttf_subsets = TTFunk::SubsetCollection.new TTFunk::File.open ARGV[0]
+(0...(ttf_subsets.instance_variable_get :@subsets).size).each {|idx| ttf_subsets[idx].encode }
+----
+
+Run the script on your font as follows:
+
+ $ ruby validate-font.rb path/to/font.ttf
+
+If this script fails, the font will not work with Asciidoctor PDF.
+To repair it, open the font in FontForge and resave it using menu:File[Generate Fonts...,Generate].
+Dismiss any warning dialogs.
+
+Resaving the font in FontForge will usually resolve any errors in the font.
+(If not, you may need to find another font, or at least another copy of it).
+
+[#modify]
+== Modifying the font
+
+To ready your font for use with Asciidoctor PDF, you'll need to modify it using a font program.
+We recommend using {url-fontforge}[FontForge].
+But don't let this scare you off.
+FontForge essentially works like a vector-drawing tool, in which each character is a separate canvas.
+You can find a crash course in how to use the program on the FontForge project site.
+
+Here are the modifications you need to apply to a custom font for it to work best with Asciidoctor PDF:
+
+* Convert the font to TTF or OTF (only required if the font is a TTC or other format not supported by Prawn).
+* Add the glyphs for the required characters if missing from the font (optional if using a fallback font).
+* Subset the font to exclude unused characters to reduce the file size (optional).
+* Save the file using the old-style kern table to activate kerning.
+
+NOTE: Technically, subsetting the font (i.e., removing glyphs) is not required since Prawn only embeds the characters from the font used in the document (i.e., it automatically subsets the font).
+However, if you plan to commit the font to a repository, subsetting helps keep the file size down.
+
+Most fonts do not provide glyphs for all the Unicode character ranges (i.e., scripts).
+(A glyph is the corresponding vector image for a Unicode character).
+In fact, many fonts only include glyphs for Latin (Basic, Supplement, and Extended) and a few other scripts (e.g., Cyrillic, Greek).
+That means certain glyphs Asciidoctor PDF relies on may be missing from the font.
+
+Below are the non-Latin characters (identified by Unicode code point) on which Asciidoctor PDF relies that are often missing from fonts.
+Unless you're using a fallback font that fills in the missing glyphs, you need to ensure these glyphs are present in your font (and add them if not).
+
+* \u00a0 - no-break space
+* \ufeff - zero width no-break space
+* \u200b - zero width space (used for line break hints)
+* \u000a - line feed character (zero width)
+* \u2009 - thin spaced (used in the button UI element)
+* \u202f - narrow no-break space (used in the keybinding UI element)
+* \u2011 - non-breaking hyphen
+* \u2022 - disc (used for first-level unordered list level)
+* \u25e6 - circle (used for second-level unordered list level)
+* \u25aa - square (used for third-level unordered list level)
+* \u2611 - ballot box checked (used for checked list item)
+* \u2610 - ballot box unchecked (used for unchecked list item)
+* \u2014 - em-dash (used in quote attribute)
+* \u203a - single right-pointing quotation mark (used in the menu UI element)
+* \u25ba - right pointer (used for media play icon when icon fonts are disabled)
+* .notdef - used as the default glyph when a requested character is missing from the font (usually a box)
+
+NOTE: If the .notdef glyph is non-empty (i.e., contains splines), it will be used as the default glyph when the document requests a character that is missing from the font.
+Unlike other glyphs, the .notdef glyph is referenced by name only.
+It does not have a designated Unicode code point.
+
+If you're preparing a font for use in verbatim blocks (e.g., a listing block), you'll also need this range of characters:
+
+* \u2460 to \u2468 - circled numbers
+
+One way to get these glyphs is to steal them from another font (or from another character in the same font).
+To do so, open the other font in FontForge, select the character, press kbd:[Ctrl,c], switch back to your font, select the character again, and press kbd:[Ctrl,v].
+You may need to scale the glyph so it fits properly in the art box.
+
+IMPORTANT: If you're copying a non-visible character, be sure to set the width to 0 using menu:Metrics[Set Width...], enter 0 into *Set Width To*, then click btn:[OK].
+
+When you're done, save the font with the old-style kern table enabled.
+To do so, select menu:File[Generate Fonts...], select *TrueType*, click btn:[Options], make sure _only_ the following options are checked (equivalent to the flags 0x90 + 0x08):
+
+* [x] OpenType
+** [x] Old style 'kern'
+
+Then click btn:[OK], then uncheck *Validate Before Saving*, and finally click btn:[Generate] to generate and save the font.
+
+Your font file is now ready to be used with Asciidoctor PDF.
+
+[#scripting-modifications]
+== Scripting the font modifications
+
+Performing all this font modification manually can be tedious (not to mention hard to reproduce).
+Fortunately, FontForge provides a {url-fontforge-scripting}[scripting interface^], which you can use to automate the process.
+
+In fact, that's what we use to prepare the fonts that are bundled with Asciidoctor PDF.
+You can find that FontForge script, the Bash script that calls it, and the Docker image in which it is run in the {url-repo-root}/scripts[scripts directory^] of this project.
+You can use that script as a starting point or reference for your own font preparation / modification script.
diff --git a/docs/modules/theme/pages/print-and-prepress.adoc b/docs/modules/theme/pages/print-and-prepress.adoc
new file mode 100644
index 00000000..94e0105d
--- /dev/null
+++ b/docs/modules/theme/pages/print-and-prepress.adoc
@@ -0,0 +1,83 @@
+= Print and Prepress Modes
+
+[#print]
+== Print mode
+
+Asciidoctor PDF provides the following behaviors to assist with printing:
+
+* Shows the URL for links (unless the linked text matches the URL)
+* Consolidates page ranges in the index
+* Disables links from page numbers in index to location of term in document
+
+You activate these printing features by setting the `media` attribute to `print` in the header of your AsciiDoc document (e.g., `:media: print`) or from the API or CLI (e.g., `-a media=print`).
+You may also want to consider using the print-optimized theme, which uses darker, grayscale colors for text and borders (e.g., `-a pdf-theme=default-for-print`).
+
+[#prepress]
+== Prepress mode
+
+In addition to the <<print,printing mode behaviors>>, Asciidoctor PDF provides the following behaviors to assist with publishing:
+
+* Double-sided (mirror) page margins
+* Automatic facing pages
+
+You activate these publishing features by setting the `media` attribute to `prepress` in the header of your AsciiDoc document (e.g., `:media: prepress`) or from the API or CLI (e.g., `-a media=prepress`).
+The following sections describe the behaviors that this setting activates.
+You may also want to consider using the print-optimized theme, which uses darker, grayscale colors for text and borders (e.g., `-a pdf-theme=default-for-print`).
+
+=== Double-sided page margins
+
+The page margins for the recto (right-hand, odd-numbered) and verso (left-hand, even-numbered) pages are automatically calculated by replacing the side page margins with the values of the `page-margin-inner` and `page-margin-outer` keys.
+
+For example, let's assume you've defined the following settings in your theme:
+
+[source,yaml]
+----
+page:
+ margin: [0.5in, 0.67in, 0.67in, 0.67in]
+ margin-inner: 0.75in
+ margin-outer: 0.59in
+----
+
+The page margins for the recto and verso pages will be resolved as follows:
+
+recto page margin:: [0.5in, *0.59in*, 0.67in, *0.75in*]
+verso page margin:: [0.5in, *0.75in*, 0.67in, *0.59in*]
+
+The page margins alternate between recto and verso.
+The first page in the document (after the cover) is a recto page.
+
+If no cover is specified, the recto margin is not applied to the title page.
+To apply the recto margin to the title page, but not include a cover, assign the value `~` to the `front-cover-image` and `back-cover-image` attributes.
+
+=== Automatic facing pages
+
+When converting the book doctype using the `prepress` media setting, a blank page will be inserted when necessary to ensure the following elements start on a recto page:
+
+* Title page
+* Table of contents
+* First page of body
+* Parts and chapters
+
+Other "`facing`" pages may be added in the future.
+
+It's possible to disable the automatic facing feature for a given part or chapter.
+This can be done by adding the nonfacing option to the section node.
+When the nonfacing option is present, the part or chapter title will be placed on the next adjacent page rather than the next facing page.
+
+[source,asciidoc]
+----
+[%nonfacing]
+= Minor Chapter
+
+content
+----
+
+////
+TODO: Issue 95 is solved, this should be deleted
+
+For documents that use the article doctype, Asciidoctor PDF incorrectly places the document title and table of contents on their own pages.
+This can result in the page numbering and the page facing to be out of sync.
+As a workaround, Asciidoctor PDF inserts a blank page, if necessary, to ensure the first page of body content is a recto-facing page.
+
+You can check on the status of this defect by following https://github.com/asciidoctor/asciidoctor-pdf/issues/95[issue #95].
+////
diff --git a/docs/modules/theme/pages/prose.adoc b/docs/modules/theme/pages/prose.adoc
new file mode 100644
index 00000000..e5d1f208
--- /dev/null
+++ b/docs/modules/theme/pages/prose.adoc
@@ -0,0 +1,39 @@
+= Prose Category Keys
+:navtitle: Prose
+
+The keys in the `prose` category control the spacing below paragraphs, lists, and index categories.
+The bottom margin is only added if the block is followed by an adjacent block within the same enclosure (e.g., a sidebar, a table cell, or the area outside a block).
+
+[#key-prefix-prose,cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+
+|margin-bottom
+|xref:measurement-units.adoc[Measurement] +
+(default: 12)
+|prose:
+margin-bottom: $vertical-spacing
+
+|margin-inner^[1]^
+|xref:measurement-units.adoc[Measurement] +
+(default: $prose-margin-bottom)
+|prose:
+margin-inner: 0
+
+|text-indent
+|xref:measurement-units.adoc[Measurement] +
+(default: _not set_)
+|prose:
+text-indent: 18
+
+|text-indent-inner^[2]^
+|xref:measurement-units.adoc[Measurement] +
+(default: _not set_)
+|prose:
+text-indent-inner: 18
+|===
+1. Controls the margin between adjacent paragraphs.
+Useful when using indented paragraphs.
+2. Only applied to inner paragraphs.
+Inner paragraphs are paragraphs that follow an adjacent paragraph.
+
diff --git a/docs/modules/theme/pages/quote.adoc b/docs/modules/theme/pages/quote.adoc
new file mode 100644
index 00000000..1e007275
--- /dev/null
+++ b/docs/modules/theme/pages/quote.adoc
@@ -0,0 +1,150 @@
+= Quote Category Keys
+:navtitle: Quote
+:source-language: yaml
+
+== quote
+
+The keys in the `quote` category control the arrangement and style of quote blocks.
+
+If `border-left-width` is non-zero, the border is only applied to the left side.
+Otherwise, if `border-width` is non-zero, the border is drawn around the whole block.
+
+[#key-prefix-quote,cols="3,4,6a"]
+|===
+|Key |Value Type |Example
+
+|`background-color`
+|xref:color.adoc[Color] +
+(default: _not set_)
+|[source]
+quote:
+ background-color: '#dddddd'
+
+|`border-color`
+|xref:color.adoc[Color] +
+(default: `'#eeeeee'`)
+|[source]
+quote:
+ border-color: '#dddddd'
+
+|`border-left-width`
+|xref:language.adoc#values[Number] +
+(default: `4`)
+|[source]
+quote:
+ border-left-width: 5
+
+|`border-width`
+|xref:language.adoc#values[Number] +
+(default: `0`)
+|[source]
+quote:
+ border-width: 0.5
+
+|`font-color`
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|[source]
+quote:
+ font-color: '#333333'
+
+|`font-family`
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|[source]
+quote:
+ font-family: Noto Serif
+
+|`font-kerning`
+|`normal` {vbar} `none` +
+(default: _inherit_)
+|[source]
+quote:
+ font-kerning: none
+
+|`font-size`
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|[source]
+quote:
+ font-size: 13
+
+|`font-style`
+|xref:text.adoc#font-style[Font style] +
+(default: _inherit_)
+|[source]
+quote:
+ font-style: bold
+
+|`padding`
+|xref:measurement-units.adoc[Measurement] {vbar} xref:measurement-units.adoc[Measurement[top,right,bottom,left\]] +
+(default: `[6, 12, -6, 14]`)
+|[source]
+quote:
+ padding: [5, 10, -5, 12]
+
+|`text-transform`
+|xref:text.adoc#transform[Text transform] +
+(default: _inherit_)
+|[source]
+quote:
+ text-transform: uppercase
+|===
+
+== quote-cite
+
+The keys in the `quote-cite` category control the arrangement and style of the citation in quote blocks.
+
+[#key-prefix-quote-cite,cols="3,4,6a"]
+|===
+|Key |Value Type |Example
+
+|`font-size`
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|[source]
+quote:
+ cite:
+ font-size: 9
+
+|`font-color`
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|[source]
+quote:
+ cite:
+ font-color: '#999999'
+
+|`font-family`
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|[source]
+quote:
+ cite:
+ font-family: Noto Serif
+
+|`font-kerning`
+|`normal` {vbar} `none` +
+(default: _inherit_)
+|[source]
+quote:
+ cite:
+ font-kerning: none
+
+|`font-style`
+|xref:text.adoc#font-style[Font style] +
+(default: _inherit_)
+|[source]
+quote:
+ cite:
+ font-style: bold
+
+|`text-transform`
+|xref:text.adoc#transform[Text transform] +
+(default: _inherit_)
+|[source]
+quote:
+ cite:
+ text-transform: uppercase
+|===
+
diff --git a/docs/modules/theme/pages/quoted-string.adoc b/docs/modules/theme/pages/quoted-string.adoc
new file mode 100644
index 00000000..6f1a4d25
--- /dev/null
+++ b/docs/modules/theme/pages/quoted-string.adoc
@@ -0,0 +1,24 @@
+= Quoted String
+
+Some keys accept a quoted string as text content.
+The final segment of these keys is always named `content`.
+
+A content key accepts a string value.
+It's usually best to quote the string or use the http://symfony.com/doc/current/components/yaml/yaml_format.html#strings[YAML multi-line string syntax].
+
+Text content may be formatted using a subset of inline HTML.
+You can use the well-known elements such as `<strong>`, `<em>`, `<code>`, `<a>`, `<sub>`, `<sup>`, `<del>`, and `<span>`.
+The `<span>` element supports the `style` attribute, which you can use to specify the `color`, `font-weight`, and `font-style` CSS properties.
+You can also use the `rgb` attribute on the `<color>` element to change the color or the `name` and `size` attributes on the `<font>` element to change the font properties.
+If you need to add an underline or strikethrough decoration to the text, you can assign the `underline` or `line-through` to the `class` attribute on any aforementioned element.
+
+Here's an example of using formatting in the content of the menu caret:
+
+[source,yaml]
+----
+menu-caret-content: " <font size=\"1.15em\"><color rgb=\"#b12146\">\u203a</color></font> "
+----
+
+NOTE: The string must be double quoted in order to use a Unicode escape code like `\u203a`.
+
+Additionally, normal substitutions are applied to the value of content keys for xref:running-content.adoc[running content], so you can use most AsciiDoc inline formatting (e.g., `+*strong*+` or `+{attribute-name}+`) in the values of those keys.
diff --git a/docs/modules/theme/pages/quotes.adoc b/docs/modules/theme/pages/quotes.adoc
new file mode 100644
index 00000000..168b9f12
--- /dev/null
+++ b/docs/modules/theme/pages/quotes.adoc
@@ -0,0 +1,20 @@
+= Quotes Category Keys
+:navtitle: Quotes
+:source-language: yaml
+
+The `quotes` category key defines the characters to use for typographic quotation marks (i.e., quotes).
+
+[#key-prefix-quotes,cols="3,4,6a"]
+|===
+|Key |Value Type |Example
+
+|`quotes`
+|xref:quoted-string.adoc[Quoted string[double-open, double-close, single-open, single-close\]] +
+(default: `['\&#8220;', '\&#8221;', '\&#8216;', '\&#8217;']`)
+|[source]
+quotes:
+- '&#x00ab;'
+- '&#x00bb;'
+- '&#x2039;'
+- '&#x203a;'
+|===
diff --git a/docs/modules/theme/pages/role.adoc b/docs/modules/theme/pages/role.adoc
new file mode 100644
index 00000000..7a7a7f27
--- /dev/null
+++ b/docs/modules/theme/pages/role.adoc
@@ -0,0 +1,145 @@
+= Role Category Keys
+:navtitle: Role
+
+== role
+
+The keys in the `role` category define custom roles for formatting.
+The name of the role is the first subkey level.
+The role name may contain a hyphen, but *a role name cannot contain an underscore*.
+The keys under the role are the theming properties.
+
+IMPORTANT: Custom roles only apply to inline phrases and paragraphs.
+
+The converter provides several predefined roles, which can all be redefined.
+
+* The `lead` defines the font properties for a lead paragraph, whether the role is assign implicitly or explicitly.
+* The `big` and `small` roles map the font size to the `$base-font-size-large` and `$base-font-size-small` values, respectively.
+* The `underline` and `line-through` roles add the underline and strikethrough decorations, respectively.
+* The `subtitle` role is used to configure the font properties of the subtitle of a section title.
+* The `unresolved` role is applied to the text of an unresolved reference (currently footnotes only).
+* The color roles (e.g., `blue`), which you may be familiar with from the HTML converter, are not mapped by default.
+You'll need to define these color roles in your theme if you'd like to make use of them when converting to PDF.
+
+.role-<name> keys
+[#key-prefix-role,cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+
+|background-color
+|xref:color.adoc[Color] +
+(default: _not set_)
+|role:
+highlight:
+background-color: #ffff00
+
+|border-color
+|xref:color.adoc[Color] +
+(default: _not set_)
+|role:
+found:
+border-color: #cccccc
+
+|border-offset
+|xref:language.adoc#values[Number] +
+(default: 0)
+|role:
+found:
+border-offset: 2
+
+|border-radius
+|xref:language.adoc#values[Number] +
+(default: _not set_)
+|role:
+found:
+border-radius: 3
+
+|border-width
+|xref:language.adoc#values[Number] +
+(default: _not set_)
+|role:
+found:
+border-width: 0.5
+
+|font-color
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|role:
+red:
+font-color: #ff0000
+
+|font-family
+|xref:font-support.adoc[Font family name] +
+(default: Courier)
+|role:
+label:
+font-family: M+ 1mn
+
+|font-size
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|role:
+large:
+font-size: 12
+
+|font-style
+|xref:text.adoc#font-style[Font style] +
+(default: _inherit_)
+|role:
+heavy:
+font-style: bold
+
+|text-decoration
+|xref:text.adoc#decoration[Text decoration] +
+(default: none)
+|role:
+deleted:
+text-decoration: line-through
+
+|text-decoration-color
+|xref:color.adoc[Color] +
+(default: $role-<name>-font-color)
+|role:
+deleted:
+text-decoration-color: #ff0000
+
+|text-decoration-width
+|xref:language.adoc#values[Number] +
+(default: $base-text-decoration-width)
+|role:
+underline:
+text-decoration-width: 0.5
+|===
+
+== Define and use a role
+
+Here's an example of a role for making text red:
+
+[source,yaml]
+----
+role:
+ red:
+ font-color: '#ff0000'
+----
+
+This role can be used as follows:
+
+[source,asciidoc]
+----
+Error text is shown in [.red]#red#.
+----
+
+You can also use a role to unset a font color (to make it inherit):
+
+[source,yaml]
+----
+role:
+ heading-code:
+ font-color: ~
+----
+
+This role can be used as follows:
+
+[source,asciidoc]
+----
+== [.heading-code]`SELECT` clause
+----
diff --git a/docs/modules/theme/pages/running-content.adoc b/docs/modules/theme/pages/running-content.adoc
new file mode 100644
index 00000000..76328821
--- /dev/null
+++ b/docs/modules/theme/pages/running-content.adoc
@@ -0,0 +1,851 @@
+= Running Content Category Keys
+:navtitle: Running Content
+:conum-guard-yaml: #
+
+== Running header and footer content
+
+The `header`, `footer`, and `running-content` category keys control the arrangement and style of running header and footer content.
+The running content won't be activated unless:
+
+. the periphery (header or footer) is configured, and
+. the `height` key for the periphery is assigned a value.
+
+CAUTION: If the height of the running content periphery is taller than the page margin, the running content will cover the main content.
+To avoid this problem, reduce the height of the running content periphery or make the page margin on that side larger.
+
+[#header]
+== header
+
+The `header` category key accepts the keys listed in the following table.
+
+IMPORTANT: If you don't specify a `height` for either the `header` or `footer` key, it effectively disables the content at that periphery.
+
+[#key-prefix-header,cols="3,4,6a"]
+|===
+|Key |Value Type |Example
+
+|`background-color`^[1]^
+|xref:color.adoc[Color] +
+(default: _not set_)
+|
+[,yaml]
+----
+header:
+ background-color: '#eeeeee'
+----
+
+|`background-image`
+|image macro +
+(default: _not set_)
+|
+[,yaml]
+----
+header:
+ background-image: image:running-content.svg[fit=contain]
+----
+
+|`border-color`
+|xref:color.adoc[Color] +
+(default: _not set_)
+|
+[,yaml]
+----
+header:
+border-color: '#dddddd'
+----
+
+|`border-style`
+|`solid` {vbar} `double` {vbar} `dashed` {vbar} `dotted` +
+(default: `solid`)
+|
+[,yaml]
+----
+header:
+ border-style: dashed
+----
+
+|`border-width`
+|xref:measurement-units.adoc[Measurement] +
+(default: `$base-border-width`)
+|
+[,yaml]
+----
+header:
+ border-width: 0.25
+----
+
+|`column-rule-color`
+|xref:color.adoc[Color] +
+(default: _not set_)
+|
+[,yaml]
+----
+header:
+ column-rule-color: '#CCCCCC'
+----
+
+|`column-rule-spacing`
+|xref:measurement-units.adoc[Measurement] +
+(default: `0`)
+|
+[,yaml]
+----
+header:
+ column-rule-spacing: 5
+----
+
+|`column-rule-style`
+|`solid` {vbar} `double` {vbar} `dashed` {vbar} `dotted` +
+(default: `solid`)
+|
+[,yaml]
+----
+header:
+ column-rule-style: dashed
+----
+
+|`column-rule-width`
+|xref:measurement-units.adoc[Measurement] +
+(default: _not set_)
+|
+[,yaml]
+----
+header:
+ column-rule-width: 0.25
+----
+
+|`font-color`
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|
+[,yaml]
+----
+header:
+ font-color: '#333333'
+----
+
+|`font-family`
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|
+[,yaml]
+----
+header:
+ font-family: Noto Serif
+----
+
+|`font-kerning`
+|`normal` {vbar} `none` +
+(default: _inherit_)
+|
+[,yaml]
+----
+header:
+ font-kerning: none
+----
+
+|`font-size`
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|
+[,yaml]
+----
+header:
+ font-size: 9
+----
+
+|`font-style`
+|xref:text.adoc#font-style[Font style] +
+(default: _inherit_)
+|
+[,yaml]
+----
+header:
+ font-style: italic
+----
+
+|`height`^[2]^
+|xref:measurement-units.adoc[Measurement] +
+(default: _not set_)
+|
+[,yaml]
+----
+header:
+ height: 0.75in
+----
+
+|`line-height`
+|xref:language.adoc#values[Number] +
+(default: `$base-line-height`)
+|
+[,yaml]
+----
+header:
+ line-height: 1.2
+----
+
+|`margin`
+|xref:measurement-units.adoc[Measurement] {vbar} xref:measurement-units.adoc[Measurement[top,right,bottom (n/a),left\]] +
+(default: [`0`, `inherit`])
+|
+[,yaml]
+----
+header:
+ margin: 0
+----
+
+|`content-margin`
+|xref:measurement-units.adoc[Measurement] {vbar} xref:measurement-units.adoc[Measurement[top,right,bottom,left\]] +
+(default: [`0`, `inherit`])
+|
+[,yaml]
+----
+header:
+ content-margin: 0
+----
+
+|`padding`^[3]^
+|xref:measurement-units.adoc[Measurement] {vbar} xref:measurement-units.adoc[Measurement[top,right,bottom,left\]] +
+(default: `0`)
+|
+[,yaml]
+----
+header:
+ padding: [0, 3, 0, 3]
+----
+
+|`image-vertical-align`
+|`top` {vbar} `middle` {vbar} `bottom` {vbar} xref:measurement-units.adoc[Measurement] +
+(default: _not set_)
+|
+[,yaml]
+----
+header:
+ image-vertical-align: 4
+----
+
+|`sectlevels`^[4]^
+|Integer +
+(default: `2`)
+|
+[,yaml]
+----
+header:
+ sectlevels: 3
+----
+
+|`text-transform`
+|xref:text.adoc#transform[Text transform] +
+(default: `none`)
+|
+[,yaml]
+----
+header:
+ text-transform: uppercase
+----
+
+|`title-style`
+|`document` {vbar} `toc` {vbar} `basic` +
+(default: `document`)
+|
+[,yaml]
+----
+header:
+ title-style: toc
+----
+
+|`vertical-align`
+|`top` {vbar} `middle` {vbar} `bottom` {vbar} [`top` {vbar} `middle` {vbar} `bottom`, xref:measurement-units.adoc[Measurement]] +
+(default: `middle`)
+|
+[,yaml]
+----
+header:
+ vertical-align: middle
+----
+
+|`<side>-columns`^[5]^
+|Column specs triple +
+(default: _not set_)
+|
+[,yaml]
+----
+header:
+ recto:
+ columns: <25% =50% >25%
+----
+
+|`<side>-margin`^[5]^
+|xref:measurement-units.adoc[Measurement] {vbar} xref:measurement-units.adoc[Measurement[top,right,bottom (n/a),left\]] +
+(default: _inherit_)
+|
+[,yaml]
+----
+header:
+ recto:
+ margin: [0, 0, 0, inherit]
+----
+
+|`<side>-content-margin`^[5]^
+|xref:measurement-units.adoc[Measurement] {vbar} xref:measurement-units.adoc[Measurement[top,right,bottom,left\]] +
+(default: _inherit_)
+|
+[,yaml]
+----
+header:
+ recto:
+ content-margin: [0, 0, 0, inherit]
+----
+
+|`<side>-padding`^[5]^
+|xref:measurement-units.adoc[Measurement] {vbar} xref:measurement-units.adoc[Measurement[top,right,bottom,left\]] +
+(default: _inherit_)
+|
+[,yaml]
+----
+header:
+ recto:
+ padding: [0, 3, 0, 3]
+----
+
+|`<side>-<position>-content`^[5,6]^
+|xref:quoted-string.adoc[Quoted string] +
+(default: '\{page-number}')
+|
+[,yaml]
+----
+header:
+ recto:
+ left:
+ content: '{page-number}'
+----
+|===
+1. To make the background color and border span the width of the page, set the margin to `0` (and adjust the content-margin accordingly).
+2. *If the height is not set, the running content at this periphery is disabled.*
+3. Do not use negative margins.
+Instead, adjust the values of the `margin` and `content-margin` keys.
+4. The maximum section level considered when assigning the implicit `section-title` attribute (and related) available to the running content.
+5. `<side>` can be `recto` (right-hand, odd-numbered pages) or `verso` (left-hand, even-numbered pages).
+The `columns` key can also be defined one level up (on `header` or `footer`), in which case the setting will be inherited.
+Where the page sides fall in relation to the physical or printed page number is controlled using the `pdf-folio-placement` attribute (except when `media=prepress`, which implies `physical`).
+The column rules are only added if the `columns` key is specified.
+6. `<position>` can be `left`, `center` or `right`.
+
+TIP: Although not listed in the table above, you can control the font settings (`font-family`, `font-size`, `font-color`, `font-style`, `text-transform`) that get applied to the running content in each column position for each page side (e.g., `header-<side>-<position>-font-color`).
+For example, you can set the font color used for the right-hand column on recto pages by setting `header-recto-right-font-color: 6CC644`.
+
+[#footer]
+== footer
+
+The `footer` category key accepts the keys listed in the following table.
+
+IMPORTANT: If you don't specify a `height` for either the `header` or `footer` key, it effectively disables the content at that periphery.
+
+[#key-prefix-footer,cols="3,4,6a"]
+|===
+|Key |Value Type |Example
+
+|`background-color`^[1]^
+|xref:color.adoc[Color] +
+(default: _not set_)
+|
+[,yaml]
+----
+footer:
+ background-color: '#eeeeee'
+----
+
+|`background-image`
+|image macro +
+(default: _not set_)
+|
+[,yaml]
+----
+footer:
+ background-image: image:running-content.svg[fit=contain]
+----
+
+|`border-color`
+|xref:color.adoc[Color] +
+(default: _not set_)
+|
+[,yaml]
+----
+footer:
+ border-color: '#dddddd'
+----
+
+|`border-style`
+|`solid` {vbar} `double` {vbar} `dashed` {vbar} `dotted` +
+(default: `solid`)
+|
+[,yaml]
+----
+footer:
+ border-style: dashed
+----
+
+|`border-width`
+|xref:measurement-units.adoc[Measurement] +
+(default: `$base-border-width`)
+|
+[,yaml]
+----
+footer:
+ border-width: 0.25
+----
+
+|`column-rule-color`
+|xref:color.adoc[Color] +
+(default: _not set_)
+|
+[,yaml]
+----
+footer:
+ column-rule-color: '#CCCCCC'
+----
+
+|`column-rule-spacing`
+|xref:measurement-units.adoc[Measurement] +
+(default: `0`)
+|
+[,yaml]
+----
+footer:
+ column-rule-spacing: 5
+----
+
+|`column-rule-style`
+|`solid` {vbar} `double` {vbar} `dashed` {vbar} `dotted` +
+(default: `solid`)
+|
+[,yaml]
+----
+footer:
+ column-rule-style: dashed
+----
+
+|`column-rule-width`
+|xref:measurement-units.adoc[Measurement] +
+(default: _not set_)
+|
+[,yaml]
+----
+footer:
+ column-rule-width: 0.25
+----
+
+|`font-color`
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|
+[,yaml]
+----
+footer:
+ font-color: '#333333'
+----
+
+|`font-family`
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|
+[,yaml]
+----
+footer:
+ font-family: Noto Serif
+----
+
+|`font-kerning`
+|`normal` {vbar} `none` +
+(default: _inherit_)
+|
+[,yaml]
+----
+footer:
+ font-kerning: none
+----
+
+|`font-size`
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|
+[,yaml]
+----
+footer:
+ font-size: 9
+----
+
+|`font-style`
+|xref:text.adoc#font-style[Font style] +
+(default: _inherit_)
+|
+[,yaml]
+----
+footer:
+ font-style: italic
+----
+
+|`height`^[2]^
+|xref:measurement-units.adoc[Measurement] +
+(default: _not set_)
+|
+[,yaml]
+----
+footer:
+ height: 0.75in
+----
+
+|`line-height`
+|xref:language.adoc#values[Number] +
+(default: `$base-line-height`)
+|
+[,yaml]
+----
+footer:
+ line-height: 1.2
+----
+
+|`margin`
+|xref:measurement-units.adoc[Measurement] {vbar} xref:measurement-units.adoc[Measurement[top (n/a),right,bottom,left\]] +
+(default: [`0`, `inherit`])
+|
+[,yaml]
+----
+footer:
+ margin: 0
+----
+
+|`content-margin`
+|xref:measurement-units.adoc[Measurement] {vbar} xref:measurement-units.adoc[Measurement[top,right,bottom,left\]] +
+(default: [`0`, `inherit`])
+|
+[,yaml]
+----
+footer:
+ content-margin: 0
+----
+
+|`padding`^[3]^
+|xref:measurement-units.adoc[Measurement] {vbar} xref:measurement-units.adoc[Measurement[top,right,bottom,left\]] +
+(default: `0`)
+|
+[,yaml]
+----
+footer:
+ padding: [0, 3, 0, 3]
+----
+
+|`image-vertical-align`
+|`top` {vbar} `middle` {vbar} `bottom` {vbar} xref:measurement-units.adoc[Measurement] +
+(default: _not set_)
+|
+[,yaml]
+----
+footer:
+ image-vertical-align: 4
+----
+
+|`sectlevels`^[4]^
+|Integer +
+(default: `2`)
+|
+[,yaml]
+----
+footer:
+ sectlevels: 3
+----
+
+|`text-transform`
+|xref:text.adoc#transform[Text transform] +
+(default: `none`)
+|
+[,yaml]
+----
+footer:
+ text-transform: uppercase
+----
+
+|`title-style`
+|`document` {vbar} `toc` {vbar} `basic` +
+(default: `document`)
+|
+[,yaml]
+----
+footer:
+ title-style: toc
+----
+
+|`vertical-align`
+|`top` {vbar} `middle` {vbar} `bottom` {vbar} [top {vbar} middle {vbar} bottom, xref:measurement-units.adoc[Measurement]] +
+(default: `middle`)
+|
+[,yaml]
+----
+footer:
+ vertical-align: top
+----
+
+|`<side>-columns`^[5]^
+|Column specs triple +
+(default: _not set_)
+|
+[,yaml]
+----
+footer:
+ verso:
+ columns: <50% =0% <50%
+----
+
+|`<side>-margin`^[5]^
+|xref:measurement-units.adoc[Measurement] {vbar} xref:measurement-units.adoc[Measurement[top (n/a),right,bottom,left\]] +
+(default: [`0`, `inherit`])
+|
+[,yaml]
+----
+footer:
+ verso:
+ margin: [0, inherit, 0, 0]
+----
+
+|`<side>-content-margin`^[5]^
+|xref:measurement-units.adoc[Measurement] {vbar} xref:measurement-units.adoc[Measurement[top,right,bottom,left\]] +
+(default: _inherit_)
+|
+[,yaml]
+----
+footer:
+ verso:
+ content-margin: [0, inherit, 0, 0]
+----
+
+|`<side>-padding`^[5]^
+|xref:measurement-units.adoc[Measurement] {vbar} xref:measurement-units.adoc[Measurement[top,right,bottom,left\]] +
+(default: _inherit_)
+|
+[,yaml]
+----
+footer:
+ verso:
+ padding: [0, 3, 0, 3]
+----
+
+|`<side>-<position>-content`^[5,6]^
+|xref:quoted-string.adoc[Quoted string] +
+(default: `'\{page-number}'`)
+|
+[,yaml]
+----
+footer:
+ verso:
+ center:
+ content: '{page-number}'
+----
+|===
+1. To make the background color and border span the width of the page, set the margin to `0` (and adjust the content-margin accordingly).
+2. *If the height is not set, the running content at this periphery is disabled.*
+3. Do not use negative margins.
+Instead, adjust the values of the `margin` and `content-margin` keys.
+4. The maximum section level considered when assigning the implicit `section-title` attribute (and related) available to the running content.
+5. `<side>` can be `recto` (right-hand, odd-numbered pages) or `verso` (left-hand, even-numbered pages).
+The `columns` key can also be defined one level up (on `header` or `footer`), in which case the setting will be inherited.
+Where the page sides fall in relation to the physical or printed page number is controlled using the `pdf-folio-placement` attribute (except when `media=prepress`, which implies `physical`).
+The column rules are only added if the `columns` key is specified.
+6. `<position>` can be `left`, `center` or `right`.
+
+TIP: Although not listed in the table above, you can control the font settings (`font-family`, `font-size`, `font-color`, `font-style`, `text-transform`) that get applied to the running content in each column position for each page side (e.g., `footer-<side>-<position>-font-color`).
+For example, you can set the font color used for the right-hand column on recto pages by setting `footer-recto-right-font-color: 6CC644`.
+
+[#running-content]
+== running-content
+
+The key in the `running-content` category controls on what page the running content starts.
+
+[cols="3,4,6a"]
+|===
+|Key |Value Type |Example
+
+|`start-at`
+|`title` {vbar} `toc` {vbar} `after-toc` {vbar} `body` {vbar} Integer +
+(default: `body`)
+|
+[,yaml]
+----
+running-content:
+ start-at: toc
+----
+|===
+
+* The `title`, `toc`, and `after-toc` values are only recognized if the title page is enabled (i.e., doctype is `book` or the `title-page` document attribute is set).
+* The `toc` value only applies if the toc is in the default location (before the first page of the body).
+If the value is `toc`, and the toc macro is used to position the Table of Contents, the `start-at` behavior is the same as if the TOC is not enabled.
+* If the value is `after-toc`, the running content will start after the TOC, no matter where it's placed in the document.
+To disable the running content on TOC pages inserted by the toc macro, set the `noheader` or `nofooter` options on the macro (e.g., `toc::[opts=nofooter]`).
+* If the value of `start-at` is an integer, the running content will start at the specified page of the body (i.e., 1 is the first page, 2 is the second page).
+
+IMPORTANT: If you don't specify a `height` for either the `header` or `footer` key, it effectively disables the content at that periphery.
+
+TIP: Although not listed in the table above, you can control the font settings (`font-family`, `font-size`, `font-color`, `font-style`, `text-transform`) that get applied to the running content in each column position for each page side (e.g., `footer-<side>-<position>-font-color`).
+For example, you can set the font color used for the right-hand column on recto pages by setting `footer-recto-right-font-color: 6CC644`.
+
+[#disable]
+== Disable the header or footer
+
+If you define running header and footer content in your theme (including the height), you can still disable this content per document by setting the `noheader` and `nofooter` attributes in the AsciiDoc document header, respectively.
+
+If you extend either the base or default theme, and don't specify content for the footer, the current page number will be added to the right side on recto pages and the left side on verso pages.
+To disable this behavior, you can use the following snippet:
+
+[source,yaml]
+----
+extends: default
+footer:
+ recto:
+ right:
+ content: ~
+ verso:
+ left:
+ content: ~
+----
+
+Instead of erasing the content (which is what the `~` does), you can specify content of your choosing.
+
+[#page-number]
+== Modify page number position
+
+If you want to replace the alternating page numbers with a centered page number, then you can restrict the footer to a single column and specify the content for the center position.
+
+[source,yaml]
+----
+extends: default
+footer:
+ columns: =100%
+ recto:
+ center:
+ content: '{page-number}'
+ verso:
+ center:
+ content: '{page-number}'
+----
+
+In the last two examples, the recto and verso both have the same content.
+In this case, you can reduce the amount of configuring using a YAML reference.
+For example:
+
+[source,yaml]
+----
+extends: default
+footer:
+ columns: =100%
+ recto: &shared_footer
+ center:
+ content: '{page-number}'
+ verso: *shared_footer
+----
+
+The `&shared_footer` assigns an ID to the YAML subtree under the `recto` key and the `*shared_footer` outputs a copy of it under the `verso` key.
+This technique can be used throughout the theme file as it's a core feature of YAML.
+
+[#attribute-references]
+== Attribute references
+
+You can use _any_ attribute defined in your AsciiDoc document (such as `doctitle`) in the content of the running header and footer.
+In addition, the following attributes are also available when defining the content keys in the footer:
+
+* page-count
+* page-number (only set if the `pagenums` attribute is set on the document, which it is by default)
+* page-layout
+* document-title
+* document-subtitle
+* part-title
+* chapter-title
+* section-title
+* section-or-chapter-title
+
+If you reference an attribute which is not defined, all the text on that same line in the running content will be dropped.
+This feature allows you to have alternate lines that are selected when all the attribute references are satisfied.
+One case where this is useful is when referencing the `page-number` attribute.
+If you unset the `pagenums` attribute on the document, any line in the running content that makes reference to `\{page-number}` will be dropped.
+
+You can also use built-in AsciiDoc text replacements like `+(C)+`, numeric character references like `+&#169;+`, hexadecimal character references like `+&#x20ac;+`, and inline formatting (e.g., bold, italic, monospace).
+
+Here's an example that shows how attributes and replacements can be used in the running footer:
+
+[source,yaml]
+----
+header:
+ height: 0.75in
+ line-height: 1
+ recto:
+ center:
+ content: '(C) ACME -- v{revnumber}, {docdate}'
+ verso:
+ center:
+ content: $header-recto-center-content
+footer:
+ background-image: image:running-content-bg-{page-layout}.svg[]
+ height: 0.75in
+ line-height: 1
+ recto:
+ right:
+ content: '{section-or-chapter-title} | *{page-number}*'
+ verso:
+ left:
+ content: '*{page-number}* | {chapter-title}'
+----
+
+== Multi-line values
+
+You can split the content value across multiple lines using YAML's multiline string syntax.
+In this case, the single quotes around the string are not necessary.
+To force a hard line break in the output, add `{sp}+` to the end of the line in normal AsciiDoc fashion.
+
+[source,yaml]
+----
+footer:
+ height: 0.75in
+ line-height: 1.2
+ recto:
+ right:
+ content: |
+ Section Title - Page Number +
+ {section-or-chapter-title} - {page-number}
+ verso:
+ left:
+ content: |
+ Page Number - Chapter Title +
+ {page-number} - {chapter-title}
+----
+
+TIP: You can use most AsciiDoc inline formatting in the values of these keys.
+For instance, to make the text bold, surround it in asterisks (as shown above).
+One exception to this rule are inline images, which are described in the next section.
+
+== Add an image to the header or footer
+
+You can add an image to the running header or footer using the AsciiDoc inline image syntax.
+The image target is resolved relative to the value of the `pdf-themesdir` attribute.
+If the image macro is the whole value for a column position, you can use the `position` and `fit` attributes to align and scale it relative to the column box.
+Otherwise, the image is treated like a normal inline image, for which you can only adjust the width.
+
+Here's an example of how to use an image in the running header (which also applies for the footer).
+
+[source,yaml,subs=attributes+]
+----
+header:
+ height: 0.75in
+ image-vertical-align: 2 {conum-guard-yaml} <1>
+ recto:
+ center:
+ content: image:footer-logo.png[pdfwidth=15pt]
+ verso:
+ center:
+ content: $header-recto-center-content
+----
+<1> You can use the `image-vertical-align` key to slightly nudge the image up or down.
+
+CAUTION: The image must fit in the allotted space for the running header or footer.
+Otherwise, you'll run into layout issues or the image may not display.
+You can adjust the width of the image to a fixed value using the `pdfwidth` attribute.
+Alternatively, you can use the `fit` attribute to set the size of the image dynamically based on the available space.
+Set the `fit` attribute to `scale-down` (e.g., `fit=scale-down`) to reduce the image size to fit in the available space or `contain` (i.e., `fit=contain`) to scale the image (up or down) to fit the available space.
+You should not rely on the `width` attribute to set the image width when converting to PDF.
diff --git a/docs/modules/theme/pages/section.adoc b/docs/modules/theme/pages/section.adoc
new file mode 100644
index 00000000..9de4d4bc
--- /dev/null
+++ b/docs/modules/theme/pages/section.adoc
@@ -0,0 +1,21 @@
+= Section Category Key
+:navtitle: Section
+:source-language: yaml
+
+The key in the `section` category controls the indent of a section body.
+
+[#key-prefix-section,cols="3,4,6a"]
+|===
+|Key |Value Type |Example
+
+|indent
+|xref:measurement-units.adoc[Measurement] {vbar} xref:measurement-units.adoc[Measurement[left,right\]] +
+(default: 0)
+|[source]
+section:
+ indent: [0.5in, 0]
+|===
+
+The `indent` keys applies to the section body only, excluding section titles and discrete headings.
+A single value gets applied to both the left and right side (e.g., `0.5in`).
+A two-value array configures the left and right side independently (e.g., `[0.5in, 0]`).
diff --git a/docs/modules/theme/pages/sidebar.adoc b/docs/modules/theme/pages/sidebar.adoc
new file mode 100644
index 00000000..50c3bf68
--- /dev/null
+++ b/docs/modules/theme/pages/sidebar.adoc
@@ -0,0 +1,137 @@
+= Sidebar Category Keys
+:navtitle: Sidebar
+
+[#sidebar]
+== sidebar
+
+The keys in the `sidebar` category control the arrangement and style of sidebar blocks.
+
+[#key-prefix-sidebar,cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+
+|background-color
+|xref:color.adoc[Color] +
+(default: #eeeeee)
+|sidebar:
+background-color: #eeeeee
+
+|border-color
+|xref:color.adoc[Color] +
+(default: _not set_)
+|sidebar:
+border-color: #ffffff
+
+|border-radius
+|xref:language.adoc#values[Number] +
+(default: _not set_)
+|sidebar:
+border-radius: 4
+
+|border-width
+|xref:language.adoc#values[Number] +
+(default: _not set_)
+|sidebar:
+border-width: 0.5
+
+|font-color
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|sidebar:
+font-color: #262626
+
+|font-family
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|sidebar:
+font-family: M+ 1p
+
+|font-kerning
+|normal {vbar} none +
+(default: _inherit_)
+|sidebar:
+font-kerning: none
+
+|font-size
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|sidebar:
+font-size: 13
+
+|font-style
+|xref:text.adoc#font-style[Font style] +
+(default: _inherit_)
+|sidebar:
+font-style: italic
+
+|text-transform
+|xref:text.adoc#transform[Text transform] +
+(default: _inherit_)
+|sidebar:
+text-transform: uppercase
+
+|padding
+|xref:measurement-units.adoc[Measurement] {vbar} xref:measurement-units.adoc[Measurement[top,right,bottom,left\]] +
+(default: [12, 12, 0, 12])
+|sidebar:
+padding: [12, 15, 0, 15]
+|===
+
+== sidebar-title
+
+The keys in the `sidebar-title` category control the arrangement and style of sidebar block titles.
+
+
+[#key-prefix-sidebar-title,cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+
+|align
+|xref:text.adoc#align[Text alignment] +
+(default: center)
+|sidebar:
+title:
+align: center
+
+|font-color
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|sidebar:
+title:
+font-color: #333333
+
+|font-family
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|sidebar:
+title:
+font-family: Noto Serif
+
+|font-kerning
+|normal {vbar} none +
+(default: _inherit_)
+|sidebar:
+title:
+font-kerning: none
+
+|font-size
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|sidebar:
+title:
+font-size: 13
+
+|font-style
+|xref:text.adoc#font-style[Font style] +
+(default: bold)
+|sidebar:
+title:
+font-style: bold
+
+|text-transform
+|xref:text.adoc#transform[Text transform] +
+(default: _inherit_)
+|sidebar:
+title:
+text-transform: uppercase
+|===
diff --git a/docs/modules/theme/pages/source-highlighting-theme.adoc b/docs/modules/theme/pages/source-highlighting-theme.adoc
new file mode 100644
index 00000000..5b9f7304
--- /dev/null
+++ b/docs/modules/theme/pages/source-highlighting-theme.adoc
@@ -0,0 +1,89 @@
+= Source Highlighting Themes
+
+You can apply a bundled source highlighter theme to your source blocks or define and apply your own.
+
+== Using a bundled highlighting theme
+
+Rouge bundles several themes you can use to colorize your source blocks.
+To use one of these themes, first set the value of the `source-highlighter` document attribute to `rouge`.
+Then, specify the desired theme using the `rouge-style` document attribute.
+
+The following example demonstrates how to apply the monokai theme from Rouge to source blocks.
+
+[source,asciidoc]
+----
+:source-highlighter: rouge
+:rouge-style: monokai
+----
+
+You can generate a list of all available themes by running the following command:
+
+ $ ruby -e 'require :rouge.to_s; puts Rouge::Theme.registry.keys.sort.join ?\n'
+
+You can also find the list of themes in the Rouge source repository at https://github.com/rouge-ruby/rouge/tree/master/lib/rouge/themes.
+
+If the bundled themes don't suit your needs, you can define one of your own.
+
+== Define a custom highlighting theme
+
+A custom theme for Rouge is defined using a Ruby class.
+Start by creating a Ruby source file to define your theme.
+Name the file according to the name of your theme and put the file in a folder of your choice (e.g., [.path]_rouge_themes/custom.rb_).
+The name of the Ruby class doesn't matter, though it's customary to name it according to the name of the theme as well.
+
+.rouge_themes/custom.rb
+[source,ruby]
+----
+require 'rouge' unless defined? ::Rouge.version
+
+module Rouge; module Themes
+ class Custom < CSSTheme
+ name 'custom'
+
+ style Comment, fg: '#008800', italic: true
+ style Error, fg: '#a61717', bg: '#e3d2d2'
+ style Str, fg: '#0000ff'
+ style Str::Char, fg: '#800080'
+ style Num, fg: '#0000ff'
+ style Keyword, fg: '#000080', bold: true
+ style Operator::Word, bold: true
+ style Name::Tag, fg: '#000080', bold: true
+ style Name::Attribute, fg: '#ff0000'
+ style Generic::Deleted, fg: '#000000', bg: '#ffdddd', inline_block: true, extend: true
+ style Generic::Inserted, fg: '#000000', bg: '#ddffdd', inline_block: true, extend: true
+ style Text, {}
+ end
+end; end
+----
+
+Each style declaration accepts the following properties:
+
+* `fg` - sets the foreground (text) color
+* `bg` - sets the background color
+* `bold` - change the font weight to bold
+* `italic` - change the font style to italic
+* `underline` - add an underline to the text
+* `inline_block` - fill the background color to the height of the line (Asciidoctor PDF only)
+* `extend` - extend the background color to the end of the line for a line-oriented match (Asciidoctor PDF only)
+
+Colors are defined using hexadecimal format (e.g., #ff0000 for red).
+
+Use the `Text` token to set the background color of the source block and the default text color.
+
+The complete list of tokens can be found in the https://github.com/jneen/rouge/blob/master/lib/rouge/token.rb[token.rb] file from Rouge.
+Refer to the https://github.com/jneen/rouge/tree/master/lib/rouge/themes[bundled themes] to find more examples.
+
+Once you've defined your theme, you need to enable it use it using the `rouge-style` document attribute, which you specify in the document header or via the Asciidoctor CLI or API.
+
+[source,asciidoc]
+----
+:source-highlighter: rouge
+:rouge-style: custom
+----
+
+Finally, you need to activate your theme by requiring the theme file when you invoke Asciidoctor.
+
+ $ asciidoctor -r ./rouge_themes/custom.rb sample.adoc
+
+You should now see that the source code is highlighted to your liking.
+For more information about source highlighting with Rouge, refer to the https://rouge.jneen.net/[Rouge project page].
diff --git a/docs/modules/theme/pages/svg.adoc b/docs/modules/theme/pages/svg.adoc
new file mode 100644
index 00000000..fd34d067
--- /dev/null
+++ b/docs/modules/theme/pages/svg.adoc
@@ -0,0 +1,20 @@
+= SVG Category Key
+:navtitle: SVG
+:source-language: yaml
+
+The key in the `svg` category controls the SVG fallback font.
+
+.svg keys
+[#key-prefix-svg,cols="3,4,6a"]
+|===
+|Key |Value Type |Example
+
+|`fallback_font_family`
+|xref:font-support.adoc[Font family name] +
+(default: `$base-font-family`)
+|[source]
+svg:
+ fallback_font_family: Times-Roman
+|===
+
+The fallback font family is only used when the font family in the SVG does not map to a known font name from the font catalog.
diff --git a/docs/modules/theme/pages/table.adoc b/docs/modules/theme/pages/table.adoc
new file mode 100644
index 00000000..9ed29d6d
--- /dev/null
+++ b/docs/modules/theme/pages/table.adoc
@@ -0,0 +1,401 @@
+= Table Category Keys
+:navtitle: Table
+:source-language: yaml
+
+== table
+
+The keys in the `table` category control the arrangement and style of tables and their cells.
+
+[#key-prefix-table,cols="3,4,6a"]
+|===
+|Key |Value Type |Example
+
+|`background-color`
+|xref:color.adoc[Color] +
+(default: `transparent`)
+|[source]
+table:
+ background-color: '#ffffff'
+
+|`border-color`
+|xref:color.adoc[Color] +
+(default: `'#000000'`)
+|[source]
+table:
+ border-color: '#dddddd'
+
+|`border-style`
+|`solid` {vbar} `dashed` {vbar} `dotted` +
+(default: `solid`)
+|[source]
+table:
+ border-style: solid
+
+|`border-width`
+|xref:language.adoc#values[Number] +
+(default: `0.5`)
+|[source]
+table:
+ border-width: 0.5
+
+|`caption-align`
+|xref:text.adoc#align[Text alignment] {vbar} inherit +
+(default: `$caption-align`)
+|[source]
+table:
+ caption-align: inherit
+
+|`caption-text-align`
+|xref:text.adoc#align[Text alignment] {vbar} inherit +
+(default: `$table-caption-align`)
+|[source]
+table:
+ caption:
+ text-align: left
+
+|`caption-side`
+|`top` {vbar} `bottom` +
+(default: `top`)
+|[source]
+table:
+ caption-side: bottom
+
+|`caption-max-width`
+|`fit-content` {vbar} `fit-content`(percentage) {vbar} `none` {vbar} xref:measurement-units.adoc[Measurement] +
+(default: `fit-content`)
+|[source]
+table:
+ caption-max-width: none
+
+|`font-color`
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|[source]
+table:
+ font-color: '#333333'
+
+|`font-family`
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|[source]
+table:
+ font-family: Helvetica
+
+|`font-kerning`
+|`normal` {vbar} `none` +
+(default: _inherit_)
+|[source]
+table:
+ font-kerning: none
+
+|`font-size`
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|[source]
+table:
+ font-size: 9.5
+
+|`font-style`
+|xref:text.adoc#font-style[Font style] +
+(default: _inherit_)
+|[source]
+table:
+ font-style: italic
+
+|`grid-color`
+|xref:color.adoc[Color] {vbar} xref:color.adoc[Color[x,y\]] +
+(default: `$table-border-color`)
+|[source]
+table:
+ grid-color: '#eeeeee'
+
+|`grid-style`
+|`solid` {vbar} `dashed` {vbar} `dotted` {vbar} Style[x,y] +
+(default: `solid`)
+|[source]
+table:
+ grid-style: dashed
+
+|`grid-width`
+|xref:language.adoc#values[Number] {vbar} xref:language.adoc#values[Number[x,y\]] +
+(default: `$table-border-width`)
+|[source]
+table:
+ grid-width: 0.5
+|===
+
+== table-head
+
+The keys in the `table-head` category control the arrangement and style of the table header.
+
+[#key-prefix-table-head,cols="3,4,6a"]
+|===
+|Key |Value Type |Example
+
+|`background-color`
+|xref:color.adoc[Color] +
+(default: `$table-background-color`)
+|[source]
+table:
+ head:
+ background-color: '#f0f0f0'
+
+|`border-bottom-color`
+|xref:color.adoc[Color] +
+(default: `$table-border-color`)
+|[source]
+table:
+ head:
+ border-bottom-color: '#dddddd'
+
+|`border-bottom-style`
+|`solid` {vbar} `dashed` {vbar} `dotted` +
+(default: `solid`)
+|[source]
+table:
+ head:
+ border-bottom-style: dashed
+
+|`border-bottom-width`
+|xref:language.adoc#values[Number] +
+(default: `1.25`)
+|[source]
+table:
+ head:
+ border-bottom-width: 1
+
+|`font-color`
+|xref:color.adoc[Color] +
+(default: `$table-font-color`)
+|[source]
+table:
+ head:
+ font-color: '#333333'
+
+|`font-family`
+|xref:font-support.adoc[Font family name] +
+(default: `$table-font-family`)
+|[source]
+table:
+ head:
+ font-family: Noto Serif
+
+|`font-kerning`
+|`normal` {vbar} `none` +
+(default: _inherit_)
+|[source]
+table:
+ head:
+ font-kerning: none
+
+|`font-size`
+|xref:language.adoc#values[Number] +
+(default: `$table-font-size`)
+|[source]
+table:
+ head:
+ font-size: 10
+
+|`font-style`
+|xref:text.adoc#font-style[Font style] +
+(default: `bold`)
+|[source]
+table:
+ head:
+ font-style: normal
+
+|`line-height`
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|[source]
+table:
+ head:
+ line-height: 1.15
+
+|`text-transform`
+|xref:text.adoc#transform[Text transform] +
+(default: _inherit_)
+|[source]
+table:
+ head:
+ text-transform: uppercase
+|===
+
+== table-body
+
+The keys in the `table-body` category control the background of the table body.
+
+[#key-prefix-table-body,cols="3,4,6a"]
+|===
+|Key |Value Type |Example
+
+|`background-color`
+|xref:color.adoc[Color] +
+(default: `$table-background-color`)
+|[source]
+table:
+ body:
+ background-color: '#fdfdfd'
+
+|`stripe-background-color`
+|xref:color.adoc[Color] +
+(default: `'#eeeeee'`)
+|[source]
+table:
+ body:
+ stripe-background-color: '#efefef'
+|===
+
+The `stripe-background-color` key only controls the color that is used for stripes.
+The appearance of stripes is controlled using the `stripes` table attribute, the `table-stripes` document attribute (since Asciidoctor 2), or the `stripes` document attribute (prior to Asciidoctor 2).
+Permitted attribute values are `even`, `odd`, `all`, and `none`.
+Prior to Asciidoctor 2, even rows are shaded by default (e.g., `stripes=even`).
+Since Asciidoctor 2, table stripes are not enabled by default (e.g., `stripes=none`).
+
+== table-foot
+
+The keys in the `table-foot` category control the arrangement and style of the table footer.
+
+[#key-prefix-table-foot,cols="3,4,6a"]
+|===
+|Key |Value Type |Example
+
+|`background-color`
+|xref:color.adoc[Color] +
+(default: `$table-background-color`)
+|[source]
+table:
+ foot:
+ background-color: '#f0f0f0'
+
+|font-color
+|xref:color.adoc[Color] +
+(default: `$table-font-color`)
+|[source]
+table:
+ foot:
+ font-color: '#333333'
+
+|`font-family`
+|xref:font-support.adoc[Font family name] +
+(default: `$table-font-family`)
+|[source]
+table:
+ foot:
+ font-family: Noto Serif
+
+|`font-size`
+|xref:language.adoc#values[Number] +
+(default: `$table-font-size`)
+|[source]
+table:
+ foot:
+ font-size: 10
+
+|`font-style`
+|xref:text.adoc#font-style[Font style] +
+(default: `normal`)
+|[source]
+table:
+ foot:
+ font-style: italic
+|===
+
+== table-cell
+
+The keys in the `table-cell` category control the arrangement and style of table cells.
+
+[#key-prefix-table-cell,cols="2,4,6a"]
+|===
+|Key |Value Type |Example
+
+|`line-height`
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|[source]
+table:
+ cell:
+ line-height: 1.5
+
+|`padding`
+|xref:measurement-units.adoc[Measurement] {vbar} xref:measurement-units.adoc[Measurement[top,right,bottom,left\]] +
+(default: `2`)
+|[source]
+table:
+ cell:
+ padding: 3
+|===
+
+== table-asciidoc-cell
+
+The key in the `table-asciidoc-cell` category controls the style of AsciiDoc table cells.
+
+[#key-prefix-table-asciidoc-cell,cols="2,4,6a"]
+|===
+|Key |Value Type |Example
+
+|`style`
+|inherit {vbar} `initial`
+(default: inherit)
+|[source]
+table:
+ asciidoc-cell:
+ style: initial
+|===
+
+== table-header-cell
+
+The keys in the `table-header-cell` category control the style and arrangement of header cells.
+
+[#key-prefix-table-header-cell,cols="3,4,6a"]
+|===
+|Key |Value Type |Example
+
+|`background-color`
+|xref:color.adoc[Color] +
+(default: `$table-head-background-color`)
+|[source]
+table:
+ header-cell:
+ background-color: '#f0f0f0'
+
+|`font-color`
+|xref:color.adoc[Color] +
+(default: `$table-head-font-color`)
+|[source]
+table:
+ header-cell:
+ font-color: '#1a1a1a'
+
+|`font-family`
+|xref:font-support.adoc[Font family name] +
+(default: `$table-head-font-family`)
+|[source]
+table:
+ header-cell:
+ font-family: Noto Sans
+
+|`font-size`
+|xref:language.adoc#values[Number] +
+(default: `$table-head-font-size`)
+|[source]
+table:
+ header-cell:
+ font-size: 12
+
+|`font-style`
+|xref:text.adoc#font-style[Font style] +
+(default: `$table-head-font-style`)
+|[source]
+table:
+ header-cell:
+ font-style: italic
+
+|`text-transform`
+|xref:text.adoc#transform[Text transform] +
+(default: `$table-head-text-transform`)
+|[source]
+table:
+ header-cell:
+ text-transform: uppercase
+|===
diff --git a/docs/modules/theme/pages/text.adoc b/docs/modules/theme/pages/text.adoc
new file mode 100644
index 00000000..00b964d3
--- /dev/null
+++ b/docs/modules/theme/pages/text.adoc
@@ -0,0 +1,51 @@
+= Text Alignment and Styles
+
+[#align]
+== Alignment
+
+The `align` subkey is used to align text and images within the parent container.
+Text can be aligned as follows:
+
+* `left`
+* `center`
+* `right`
+* `justify` (stretched to each edge)
+
+[#decoration]
+== Decoration
+
+The following decorations can be applied to text:
+
+* `none` (no decoration)
+* `underline`
+* `line-through`
+
+[#font-style]
+== Font style
+
+In most cases, wherever you can specify a custom font family, you can also specify a font style.
+These two settings are combined to locate the font to use.
+
+The following font styles are recognized:
+
+* `normal` (no style)
+* `italic`
+* `bold`
+* `bold_italic`
+
+[#transform]
+== Transform
+
+Many places where font properties can be specified, a case transformation can be applied to the text.
+The following transforms are recognized:
+
+* `uppercase`
+* `lowercase`
+* `capitalize` (each word, like CSS)
+* `none` (clears an inherited value)
+
+[CAUTION#transform-unicode-letters]
+====
+Ruby 2.5 and greater has built-in support for transforming the case of any letter defined by Unicode.
+You no longer need the `activesupport` or `unicode` gem to transform characters beyond the Basic Latin character set (e.g., accented characters).
+====
diff --git a/docs/modules/theme/pages/thematic-break.adoc b/docs/modules/theme/pages/thematic-break.adoc
new file mode 100644
index 00000000..7d86e48d
--- /dev/null
+++ b/docs/modules/theme/pages/thematic-break.adoc
@@ -0,0 +1,39 @@
+= Thematic Break Category Keys
+:navtitle: Thematic Break
+
+The keys in this category control the style of thematic breaks (aka horizontal rules).
+
+[#key-prefix-thematic-break,cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+
+|border-color
+|xref:color.adoc[Color] +
+(default: #eeeeee)
+|thematic-break:
+border-color: #eeeeee
+
+|border-style
+|solid {vbar} double {vbar} dashed {vbar} dotted +
+(default: solid)
+|thematic-break:
+border-style: dashed
+
+|border-width
+|xref:measurement-units.adoc[Measurement] +
+(default: 0.5)
+|thematic-break:
+border-width: 0.5
+
+|margin-top
+|xref:measurement-units.adoc[Measurement] +
+(default: 0)
+|thematic-break:
+margin-top: 6
+
+|margin-bottom
+|xref:measurement-units.adoc[Measurement] +
+(default: $vertical-spacing)
+|thematic-break:
+margin-bottom: 18
+|===
diff --git a/docs/modules/theme/pages/title-page.adoc b/docs/modules/theme/pages/title-page.adoc
new file mode 100644
index 00000000..fd3fc321
--- /dev/null
+++ b/docs/modules/theme/pages/title-page.adoc
@@ -0,0 +1,523 @@
+= Title Page Category Keys
+:navtitle: Title Page
+:source-language: yaml
+
+The keys in the `title-page` category control the style of the title page as well as the arrangement and style of the elements on it.
+
+IMPORTANT: The title page is only enabled by default for the book doctype (e.g., `:doctype: book`).
+If you want to enable the title page when using a different doctype (such as the article doctype), you must define the `title-page` attribute in the document header (i.e., `:title-page:`).
+
+NOTE: Subtitle partitioning of the doctitle is only enabled when the title page is also enabled.
+
+TIP: For documents that declare the book doctype, the title page can be omitted by setting the `notitle` attribute in the AsciiDoc document header (i.e., `:notitle:`) or by setting the value of the `title_page` category key in the theme to `false`.
+(It's counterpart, `:!showtitle:`, does not work with this converter).
+For all other doctypes, the title page is not added by default.
+In that case, setting the `:notitle:` attribute only removes the document title from the first page of content.
+
+[#title-page]
+== title-page
+
+The category key `title-page` accepts the keys listed in the following table.
+
+[#key-prefix-title-page,cols="3,4,6a"]
+|===
+|Key |Value Type |Example
+
+|`align`
+|xref:text.adoc#align[Text alignment] +
+(default: `center`)
+|[source]
+title-page:
+ align: right
+
+|`background-color`^[1]^
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|[source]
+title-page:
+ background-color: '#eaeaea'
+
+|`background-image`^[2]^
+|image macro^[3]^ +
+(default: _not set_)
+|[source]
+title-page:
+ background-image: image:title.png[]
+
+|`font-color`
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|[source]
+title-page:
+ font-color: '#333333'
+
+|`font-family`
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|[source]
+title-page:
+ font-family: Noto Serif
+
+|`font-kerning`
+|`normal` {vbar} `none` +
+(default: _inherit_)
+|[source]
+title-page:
+ font-kerning: none
+
+|`font-size`
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|[source]
+title-page:
+ font-size: 13
+
+|`font-style`
+|xref:text.adoc#font-style[Font style] +
+(default: _inherit_)
+|[source]
+title-page:
+ font-style: bold
+
+|`text-transform`
+|xref:text.adoc#transform[Text transform] +
+(default: _inherit_)
+|[source]
+title-page:
+ text-transform: uppercase
+
+|`line-height`
+|xref:language.adoc#values[Number] +
+(default: `1.15`)
+|[source]
+title-page:
+ line-height: 1
+|===
+1. To disable the background color for the title page, set the value to white (i.e., `FFFFFF`).
+The color keyword `transparent` is not recognized in this context.
+2. By default, page background images are automatically scaled to fit the bounds of the page (i.e., `fit=contain`) and centered (i.e., `position=center`).
+The size of the background image can be controlled using any of the sizing attributes on the image macro (i.e., `fit`, `pdfwidth`, `scaledwidth`, or `width`) when `fit=none`.
+The position of the background image can be controlled using the `position` attribute.
+
+[#title-page-logo]
+== title-page-logo
+
+The `title-page` category key accepts the sub-category key `logo`.
+The sub-category key `logo` accepts the keys listed in the following table.
+
+[#key-prefix-title-page-logo,cols="3,4,6a"]
+|===
+|Key |Value Type |Example
+
+|`align`
+|xref:image.adoc#align[Image alignment] +
+(default: _inherit_)
+|[source]
+title-page:
+ logo:
+ align: right
+
+|`image`
+|image macro^[1]^ +
+(default: _not set_)
+|[source]
+title-page:
+ logo:
+ image: image:logo.png[pdfwidth=25%]
+
+|`top`
+|xref:measurement-units.adoc[Measurement] +
+(default: `10%`) +
+The `%` unit is relative to content height; `vh` unit is relative to page height.
+|[source]
+title-page:
+ logo:
+ top: 25%
+|===
+1. Target may be an absolute path or a path relative to the value of the `pdf-themesdir` attribute.
+
+[#title-page-title]
+== title-page-title
+
+The `title-page` category key accepts the sub-category key `title`.
+The sub-category key `title` accepts the keys listed in the following table.
+
+[#key-prefix-title-page-title,cols="3,4,6a"]
+|===
+|Key |Value Type |Example
+
+|`display`
+|`none` +
+(default: _not set_)
+|[source]
+title-page:
+ title:
+ display: none
+
+|`font-color`
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|[source]
+title-page:
+ title:
+ font-color: '#999999'
+
+|`font-family`
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|[source]
+title-page:
+ title:
+ font-family: Noto Serif
+
+|`font-kerning`
+|`normal` {vbar} `none` +
+(default: _inherit_)
+|[source]
+title-page:
+ title:
+ font-kerning: none
+
+|`font-size`
+|xref:language.adoc#values[Number] +
+(default: `18`)
+|[source]
+title-page:
+ title:
+ font-size: $heading-h1-font-size
+
+|`font-style`
+|xref:text.adoc#font-style[Font style] +
+(default: _inherit_)
+|[source]
+title-page:
+ title:
+ font-style: bold
+
+|`text-transform`
+|xref:text.adoc#transform[Text transform] +
+(default: _inherit_)
+|[source]
+title-page:
+ title:
+ text-transform: uppercase
+
+|`line-height`
+|xref:language.adoc#values[Number] +
+(default: `$heading-line-height`)
+|[source]
+title-page:
+ title:
+ line-height: 0.9
+
+|`top`
+|xref:measurement-units.adoc[Measurement] +
+(default: `40%`) +
+The `%` unit is relative to content height; `vh` unit is relative to page height.
+|[source]
+title-page:
+ title:
+ top: 55%
+
+|`margin-top`
+|xref:measurement-units.adoc[Measurement] +
+(default: `0`)
+|[source]
+title-page:
+ title:
+ margin-top: 13.125
+
+|`margin-bottom`
+|xref:measurement-units.adoc[Measurement] +
+(default: `0`)
+|[source]
+title-page:
+ title:
+ margin-bottom: 5
+|===
+
+[#title-page-subtitle]
+== title-page-subtitle
+
+The `title-page` category key accepts the sub-category key `subtitle`.
+The sub-category key `subtitle` accepts the keys listed in the following table.
+
+[#key-prefix-title-page-subtitle,cols="3,4,6a"]
+|===
+|Key |Value Type |Example
+
+|`display`
+|`none` +
+(default: _not set_)
+|[source]
+title-page:
+ subtitle:
+ display: none
+
+|`font-color`
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|[source]
+title-page:
+ subtitle:
+ font-color: '#181818'
+
+|`font-family`
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|[source]
+title-page:
+ subtitle:
+ font-family: Noto Serif
+
+|`font-kerning`
+|`normal` {vbar} `none` +
+(default: _inherit_)
+|[source]
+title-page:
+ subtitle:
+ font-kerning: none
+
+|`font-size`
+|xref:language.adoc#values[Number] +
+(default: `14`)
+|[source]
+title-page:
+ subtitle:
+ font-size: $heading-h3-font-size
+
+|`font-style`
+|xref:text.adoc#font-style[Font style] +
+(default: _inherit_)
+|[source]
+title-page:
+ subtitle:
+ font-style: bold_italic
+
+|`text-transform`
+|xref:text.adoc#transform[Text transform] +
+(default: _inherit_)
+|[source]
+title-page:
+ subtitle:
+ text-transform: uppercase
+
+|`line-height`
+|xref:language.adoc#values[Number] +
+(default: `$heading-line-height`)
+|[source]
+title-page:
+ subtitle:
+ line-height: 1
+
+|`margin-top`
+|xref:measurement-units.adoc[Measurement] +
+(default: `0`)
+|[source]
+title-page:
+ subtitle:
+ margin-top: 13.125
+
+|`margin-bottom`
+|xref:measurement-units.adoc[Measurement] +
+(default: `0`)
+|[source]
+title-page:
+ subtitle:
+ margin-bottom: 5
+|===
+
+[#title-page-authors]
+== title-page-authors
+
+The `title-page` category key accepts the sub-category key `authors`.
+The sub-category key `authors` accepts the keys listed in the following table.
+
+[#key-prefix-authors,cols="3,4,6a"]
+|===
+|Key |Value Type |Example
+
+a|`content`
+
+`content` accepts the optional keys: `name_only`, `with_email`, `with_url`
+|xref:quoted-string.adoc[Quoted AsciiDoc string] +
+(default: `"\{author}"`)
+|[source]
+title-page:
+ authors:
+ content:
+ name_only: "{author}"
+ with_email: "{author} <{email}>"
+ with_url: "{url}[{author}]"
+
+|`display`
+|`none` +
+(default: _not set_)
+|[source]
+title-page:
+ authors:
+ display: none
+
+|`delimiter`
+|xref:quoted-string.adoc[Quoted string] +
+(default: `', '`)
+|[source]
+title-page:
+ authors:
+ delimiter: '; '
+
+|`font-color`
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|[source]
+title-page:
+ authors:
+ font-color: '#181818'
+
+|`font-family`
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|[source]
+title-page:
+ authors:
+ font-family: Noto Serif
+
+|`font-kerning`
+|`normal` {vbar} `none` +
+(default: _inherit_)
+|[source]
+title-page:
+ authors:
+ font-kerning: none
+
+|`font-size`
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|[source]
+title-page:
+ authors:
+ font-size: 13
+
+|`font-style`
+|xref:text.adoc#font-style[Font style] +
+(default: _inherit_)
+|[source]
+title-page:
+ authors:
+ font-style: bold_italic
+
+|`text-transform`
+|xref:text.adoc#transform[Text transform] +
+(default: _inherit_)
+|[source]
+title-page:
+ authors:
+ text-transform: uppercase
+
+|`margin-top`
+|xref:measurement-units.adoc[Measurement] +
+(default: `12`)
+|[source]
+title-page:
+ authors:
+ margin-top: 13.125
+
+|`margin-bottom`
+|xref:measurement-units.adoc[Measurement] +
+(default: `0`)
+|[source]
+title-page:
+ authors:
+ margin-bottom: 5
+|===
+
+[#title-page-revision]
+== title-page-revision
+
+The `title-page` category key accepts the sub-category key `revision`.
+The sub-category key `revision` accepts the keys listed in the following table.
+
+[#key-prefix-revision,cols="3,4,6a"]
+|===
+|Key |Value Type |Example
+
+|`display`
+|`none` +
+(default: _not set_)
+|[source]
+title-page:
+ revision:
+ display: none
+
+|`delimiter`
+|xref:quoted-string.adoc[Quoted string] +
+(default: `', '`)
+|[source]
+title-page:
+ revision:
+ delimiter: ': '
+
+|`font-color`
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|[source]
+title-page:
+ revision:
+ font-color: '#181818'
+
+|`font-family`
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|[source]
+title-page:
+ revision:
+ font-family: Noto Serif
+
+|`font-kerning`
+|`normal` {vbar} `none` +
+(default: _inherit_)
+|[source]
+title-page:
+ revision:
+ font-kerning: none
+
+|`font-size`
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|[source]
+title-page:
+ revision:
+ font-size: $base-font-size-small
+
+|`font-style`
+|xref:text.adoc#font-style[Font style] +
+(default: _inherit_)
+|[source]
+title-page:
+ revision:
+ font-style: bold
+
+|`text-transform`
+|xref:text.adoc#transform[Text transform] +
+(default: _inherit_)
+|[source]
+title-page:
+ revision:
+ text-transform: uppercase
+
+|`margin-top`
+|xref:measurement-units.adoc[Measurement] +
+(default: `0`)
+|[source]
+title-page:
+ revision:
+ margin-top: 13.125
+
+|`margin-bottom`
+|xref:measurement-units.adoc[Measurement] +
+(default: `0`)
+|[source]
+title-page:
+ revision:
+ margin-bottom: 5
+|===
diff --git a/docs/modules/theme/pages/toc.adoc b/docs/modules/theme/pages/toc.adoc
new file mode 100644
index 00000000..4fb4b1af
--- /dev/null
+++ b/docs/modules/theme/pages/toc.adoc
@@ -0,0 +1,212 @@
+= Table of Contents Category Keys
+:navtitle: TOC
+
+The keys in the `toc` category control the arrangement and style of the table of contents.
+
+[#key-prefix-toc,cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+
+|font-color
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|toc:
+font-color: #333333
+
+|font-family
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|toc:
+font-family: Noto Serif
+
+|font-kerning
+|normal {vbar} none +
+(default: _inherit_)
+|toc:
+font-kerning: none
+
+|font-size
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|toc:
+font-size: 9
+
+|font-style
+|xref:text.adoc#font-style[Font style] +
+// QUESTION why is the default not inherited?
+(default: normal)
+|toc:
+font-style: bold
+
+|text-decoration
+|xref:text.adoc#decoration[Text decoration] +
+(default: none)
+|toc:
+text-decoration: underline
+
+|text-decoration-color
+|xref:color.adoc[Color] +
+(default: $toc-font-color)
+|toc
+text-decoration-color: #cccccc
+
+|text-decoration-width
+|xref:language.adoc#values[Number] +
+(default: $base-text-decoration-width)
+|toc:
+text-decoration-width: 0.5
+
+|text-transform
+|xref:text.adoc#transform[Text transform] +
+(default: _inherit_)
+|toc:
+text-transform: uppercase
+
+|line-height
+|xref:language.adoc#values[Number] +
+(default: 1.4)
+|toc:
+line-height: 1.5
+
+|indent
+|xref:measurement-units.adoc[Measurement] +
+(default: 15)
+|toc:
+indent: 20
+
+|hanging-indent
+|xref:measurement-units.adoc[Measurement] +
+(default: _not set_)
+|toc:
+hanging-indent: 0.5in
+
+|margin-top
+|xref:measurement-units.adoc[Measurement] +
+(default: 0)
+|toc:
+margin-top: 0
+
+3+|[#key-prefix-toc-level]*Key Prefix:* <<key-prefix-toc-level,toc-h<n>{zwsp}>>^[1]^
+
+|font-color
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|toc:
+h3-font-color: #999999
+
+|font-family
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|toc:
+h2-font-family: Noto Serif
+
+|font-kerning
+|normal {vbar} none +
+(default: _inherit_)
+|toc:
+h3-font-kerning: none
+
+|font-size
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|toc:
+h3-font-size: 9
+
+|font-style
+|xref:text.adoc#font-style[Font style] +
+(default: _inherit_)
+|toc:
+h2-font-style: italic
+
+|text-transform
+|xref:text.adoc#transform[Text transform] +
+(default: _inherit_)
+|toc:
+h3-text-transform: uppercase
+
+3+|[#key-prefix-toc-title]*Key Prefix:* <<key-prefix-toc-title,toc-title>>
+
+|align
+|xref:text.adoc#align[Text alignment] +
+(default: $heading-h2-align)
+|toc:
+title:
+align: right
+
+|font-color
+|xref:color.adoc[Color] +
+(default: $heading-h2-font-color)
+|toc:
+title:
+font-color: #aa0000
+
+|font-family
+|xref:font-support.adoc[Font family name] +
+(default: $heading-h2-font-family)
+|toc:
+title:
+font-family: Noto Serif
+
+|font-kerning
+|normal {vbar} none +
+(default: _inherit_)
+|toc:
+title:
+font-kerning: none
+
+|font-size
+|xref:language.adoc#values[Number] +
+(default: $heading-h2-font-size)
+|toc:
+title:
+font-size: 18
+
+|font-style
+|xref:text.adoc#font-style[Font style] +
+(default: $heading-h2-font-style)
+|toc:
+title:
+font-style: bold_italic
+
+|text-transform
+|xref:text.adoc#transform[Text transform] +
+(default: $heading-h2-text-transform)
+|sidebar:
+title:
+text-transform: uppercase
+
+3+|[#key-prefix-toc-dot-leader]*Key Prefix:* <<key-prefix-toc-dot-leader,toc-dot-leader>>
+
+|content
+|xref:quoted-string.adoc[Quoted string] +
+(default: '. ')
+|toc:
+dot-leader:
+content: ". "
+
+|font-color^[2]^
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|toc:
+dot-leader:
+font-color: #999999
+
+|font-style^[2]^
+|xref:text.adoc#font-style[Font style] +
+(default: normal)
+|toc:
+dot-leader:
+font-style: bold
+
+|levels^[3]^
+|all {vbar} none {vbar} Integers (space-separated) +
+(default: all)
+|toc:
+dot-leader:
+levels: 2 3
+|===
+1. `<n>` is a number ranging from 1 to 6, representing each of the six heading levels.
+2. The dot leader inherits all font properties except `font-style` from the root `toc` category.
+3. 0-based levels (e.g., part = 0, chapter = 1).
+Dot leaders are only shown for the specified levels.
+If value is not specified, dot leaders are shown for all levels.
diff --git a/docs/modules/theme/pages/variables.adoc b/docs/modules/theme/pages/variables.adoc
new file mode 100644
index 00000000..8f4a7b0e
--- /dev/null
+++ b/docs/modules/theme/pages/variables.adoc
@@ -0,0 +1,83 @@
+= Variables
+:conum-guard-yaml: #
+
+To save you from having to type the same value in your theme over and over, or to allow you to base one value on another, the theme language supports variables.
+
+[#define]
+== Define a variable
+
+Variables consist of the key name preceded by a dollar sign (`$`) (e.g., `$base-font-size`).
+Any qualified key that has already been defined can be referenced in the value of another key.
+In order words, as soon as the key is assigned, it's available to be used as a variable.
+
+IMPORTANT: Variables are defined from top to bottom (i.e., in document order).
+Therefore, a variable must be defined before it is referenced.
+In other words, the path the variable refers to must be *above* the usage of that variable.
+
+For example, once the following line is processed,
+
+[source,yaml]
+----
+base:
+ font-color: '#333333'
+----
+
+the variable `$base-font-color` will be available for use in subsequent lines and will resolve to `#333333`.
+
+Let's say you want to make the font color of the sidebar title the same as the heading font color.
+Just assign the value `$heading-font-color` to the `$sidebar-title-font-color`.
+
+[source,yaml]
+----
+heading:
+ font-color: '#191919'
+sidebar:
+ title:
+ font-color: $heading-font-color
+----
+
+== Use a variable in a math expression
+
+You can also use variables in math expressions to use one value to build another.
+This is commonly done to set font sizes proportionally.
+It also makes it easy to test different values very quickly.
+
+[source,yaml]
+----
+base:
+ font-size: 12
+ font-size-large: $base-font-size * 1.25
+ font-size-small: $base-font-size * 0.85
+----
+
+We'll cover more about math expressions later.
+
+[#custom]
+== Custom variables
+
+You can define arbitrary key names to make custom variables.
+This is one way to group reusable values at the top of your theme file.
+If you are going to do this, it's recommended that you organize the keys under a custom namespace, such as `brand`.
+
+For instance, here's how you can define your brand colors:
+
+[source,yaml,subs=attributes+]
+----
+brand:
+ primary-color: '#E0162B' {conum-guard-yaml} <1>
+ secondary-color: '#FFFFFF' {conum-guard-yaml} <2>
+ alert-color: '0052A5' {conum-guard-yaml} <3>
+----
+<1> To align with CSS, you may add `+#+` in front of the hex color value to coerce it to a string.
+A YAML preprocessor is used to ensure the value is not treated as a comment as would normally be the case in YAML.
+<2> You may put quotes around the CSS-style hex value to make it friendly to a YAML editor or validation tool.
+<3> The leading `+#+` on a hex value is entirely optional.
+However, we recommend that you always use either a leading `+#+` or surrounding quotes (or both) to prevent YAML from mangling the value (for example, 000000 would become 0, so use '000000' or #000000 instead).
+
+You can now use these custom variables later in the theme file:
+
+[source,yaml]
+----
+base:
+ font-color: $brand-primary-color
+----
diff --git a/docs/modules/theme/pages/verse.adoc b/docs/modules/theme/pages/verse.adoc
new file mode 100644
index 00000000..5474d39d
--- /dev/null
+++ b/docs/modules/theme/pages/verse.adoc
@@ -0,0 +1,134 @@
+= Verse Category Keys
+:navtitle: Verse
+
+[#verse]
+== verse
+
+The keys in the `verse` category control the arrangement and style of verse blocks.
+
+[#key-prefix-verse,cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+
+|background-color
+|xref:color.adoc[Color] +
+(default: _not set_)
+|verse:
+background-color: #dddddd
+
+|border-width^[1]^
+|xref:language.adoc#values[Number] +
+(default: 0)
+|verse:
+border-width: 0.5
+
+|border-left-width^[1]^
+|xref:language.adoc#values[Number] +
+(default: 4)
+|verse:
+border-left-width: 5
+
+|border-color^[1]^
+|xref:color.adoc[Color] +
+(default: #eeeeee)
+|verse:
+border-color: #dddddd
+
+|font-color
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|verse:
+font-color: #333333
+
+|font-family^[2]^
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|verse:
+font-family: M+ 1mn
+
+|font-kerning
+|normal {vbar} none +
+(default: _inherit_)
+|verse:
+font-kerning: none
+
+|font-size
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|verse:
+font-size: 10
+
+|font-style
+|xref:text.adoc#font-style[Font style] +
+(default: _inherit_)
+|verse:
+font-style: bold
+
+|text-transform
+|xref:text.adoc#transform[Text transform] +
+(default: _inherit_)
+|verse:
+text-transform: uppercase
+
+|padding
+|xref:measurement-units.adoc[Measurement] {vbar} xref:measurement-units.adoc[Measurement[top,right,bottom,left\]] +
+(default: [6, 12, -6, 14])
+|verse:
+padding: [5, 10, -5, 12]
+|===
+1. If `border-left-width` is non-zero, the border is only applied to the left side.
+Otherwise, if `border-width` is non-zero, the border is drawn around the whole block.
+2. The verse block does not use a fixed-width font by default, which can affect the layout if the content relies on columns.
+You can change verse blocks to use a fixed-width font (not necessarily a monospaced font) using this setting.
+
+== verse-cite
+
+The keys in the `verse-cite` category control the arrangement and style of the citation in verse blocks.
+
+.verse-cite keys
+[#key-prefix-verse-cite,cols="3,4,5l"]
+|===
+|Key |Value Type |Example
+
+|font-size
+|xref:language.adoc#values[Number] +
+(default: _inherit_)
+|verse:
+cite:
+font-size: 9
+
+|font-color
+|xref:color.adoc[Color] +
+(default: _inherit_)
+|verse:
+cite:
+font-color: #999999
+
+|font-family
+|xref:font-support.adoc[Font family name] +
+(default: _inherit_)
+|verse:
+cite:
+font-family: Noto Serif
+
+|font-kerning
+|normal {vbar} none +
+(default: _inherit_)
+|verse:
+cite:
+font-kerning: none
+
+|font-style
+|xref:text.adoc#font-style[Font style] +
+(default: _inherit_)
+|verse:
+cite:
+font-style: italic
+
+|text-transform
+|xref:text.adoc#transform[Text transform] +
+(default: _inherit_)
+|verse:
+cite:
+text-transform: uppercase
+|===