asciidoctor-pdf 2.0.0.beta.2 → 2.0.0.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +30 -0
- data/README.adoc +79 -1103
- data/docs/theming-guide.adoc +1 -1
- data/lib/asciidoctor/pdf/converter.rb +2062 -2064
- data/lib/asciidoctor/pdf/ext/asciidoctor/abstract_block.rb +31 -0
- data/lib/asciidoctor/pdf/ext/asciidoctor.rb +1 -0
- data/lib/asciidoctor/pdf/ext/prawn/document/column_box.rb +9 -5
- data/lib/asciidoctor/pdf/ext/prawn/extensions.rb +22 -20
- data/lib/asciidoctor/pdf/version.rb +1 -1
- metadata +3 -2
data/README.adoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
= Asciidoctor PDF: A native PDF converter for AsciiDoc
|
2
2
|
Dan Allen <https://github.com/mojavelinux[@mojavelinux]>; Sarah White <https://github.com/graphitefriction[@graphitefriction]>
|
3
|
-
v2.0.0.
|
3
|
+
v2.0.0.rc.1, 2022-05-17
|
4
4
|
// Settings:
|
5
5
|
:experimental:
|
6
6
|
:idprefix:
|
@@ -24,19 +24,15 @@ endif::[]
|
|
24
24
|
:project-handle: asciidoctor-pdf
|
25
25
|
// Variables:
|
26
26
|
:release-line: 2.0.x
|
27
|
-
:release-version: 2.0.0.
|
28
|
-
//
|
29
|
-
:url-
|
30
|
-
:url-gem: http://rubygems.org/gems/asciidoctor-pdf
|
27
|
+
:release-version: 2.0.0.rc.1
|
28
|
+
// URLs:
|
29
|
+
:url-gem: https://rubygems.org/gems/asciidoctor-pdf
|
31
30
|
:url-project: https://github.com/asciidoctor/asciidoctor-pdf
|
32
31
|
:url-project-repo: {url-project}
|
33
32
|
:url-project-issues: {url-project-repo}/issues
|
34
|
-
:url-
|
35
|
-
:url-prawn
|
36
|
-
:url-
|
37
|
-
:url-asciidoctor-mathematical: https://github.com/asciidoctor/asciidoctor-mathematical
|
38
|
-
:url-rvm: http://rvm.io
|
39
|
-
:url-graphicsmagick: http://www.graphicsmagick.org
|
33
|
+
:url-project-docs: https://docs.asciidoctor.org/pdf-converter/latest
|
34
|
+
:url-prawn: https://prawnpdf.org
|
35
|
+
:url-rvm: https://rvm.io
|
40
36
|
|
41
37
|
ifdef::status[]
|
42
38
|
image:https://img.shields.io/badge/zulip-join_chat-brightgreen.svg[project chat,link=https://asciidoctor.zulipchat.com/]
|
@@ -44,133 +40,62 @@ image:{url-project-repo}/workflows/CI/badge.svg[Build Status (GitHub Actions),li
|
|
44
40
|
image:https://img.shields.io/gem/v/asciidoctor-pdf.svg[Latest Release, link={url-gem}]
|
45
41
|
endif::[]
|
46
42
|
|
47
|
-
Asciidoctor PDF is a native PDF converter for AsciiDoc.
|
43
|
+
Asciidoctor PDF is a native PDF converter for AsciiDoc that plugs into the `pdf` backend.
|
48
44
|
It bypasses the requirement to generate an intermediary format such as DocBook, Apache FO, or LaTeX.
|
49
|
-
Instead, you can use
|
50
|
-
|
45
|
+
Instead, you can use Asciidoctor PDF to convert your documents directly from AsciiDoc to PDF.
|
46
|
+
The aim of this library is to take the pain out of creating PDF documents from AsciiDoc.
|
51
47
|
|
52
|
-
NOTE
|
53
|
-
|
54
|
-
{url-project-
|
55
|
-
|
56
|
-
{url-project-repo}/tree/v1.6.x#readme[
|
48
|
+
[NOTE]
|
49
|
+
====
|
50
|
+
The documentation for Asciidoctor PDF {release-line} is now available at {url-project-docs}/.
|
51
|
+
|
52
|
+
If you're looking for the documentation for Asciidoctor PDF 1.6, refer to the {url-project-repo}/tree/v1.6.x#readme[README] in the v1.6.x branch.
|
53
|
+
Asciidoctor PDF 1.6 is no longer being developed and will reach EOL later this year.
|
54
|
+
You are encouraged to migrate to Asciidoctor PDF 2 as soon as possible.
|
55
|
+
====
|
57
56
|
|
58
57
|
toc::[]
|
59
58
|
|
60
59
|
== Overview
|
61
60
|
|
62
|
-
|
63
|
-
The style and layout of the PDF
|
64
|
-
To the degree possible,
|
65
|
-
|
61
|
+
Asciidoctor PDF converts an AsciiDoc document directly to a PDF document.
|
62
|
+
The style and layout of the PDF are controlled by a dedicated theme file.
|
63
|
+
To the degree possible, Asciidoctor PDF supports all the features of AsciiDoc that are supported by Asciidoctor.
|
64
|
+
It also provides {url-project-docs}/features/[PDF-specific features].
|
65
|
+
However, there are {url-project-docs}/features/#limitations[certain limits] imposed by the PDF format and the PDF library this extension uses.
|
66
66
|
|
67
|
-
|
67
|
+
Asciidoctor PDF uses the Prawn gem and Prawn's extensions, such as prawn-svg and prawn-table, to generate a PDF document.
|
68
68
|
{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.
|
69
69
|
|
70
|
-
|
71
|
-
Likewise, {project-name} takes the pain out of creating PDF documents _directly from AsciiDoc_.
|
72
|
-
Skip ahead to <<getting-started,Getting started>> to start putting {project-name} use.
|
73
|
-
But don't miss the <<Highlights>> to get a preview of what's possible.
|
74
|
-
|
75
|
-
== Highlights
|
76
|
-
|
77
|
-
* Direct AsciiDoc to PDF conversion
|
78
|
-
* Configuration-driven theme (style and layout)
|
79
|
-
* Custom fonts (TTF or OTF)
|
80
|
-
* Full SVG support (thanks to https://github.com/mogest/prawn-svg[prawn-svg])
|
81
|
-
* PDF document outline (i.e., bookmarks)
|
82
|
-
* Title page
|
83
|
-
* Table of contents page(s)
|
84
|
-
* Document metadata (title, authors, subject, keywords, etc.)
|
85
|
-
* Configurable page size (e.g., A4, Letter, Legal, etc)
|
86
|
-
* Internal cross reference links
|
87
|
-
* Syntax highlighting with Rouge (preferred), Pygments, or CodeRay
|
88
|
-
* Cover pages
|
89
|
-
* Page background color or page background image with named scaling
|
90
|
-
* Page numbering
|
91
|
-
* Double-sided (aka prepress) printing mode (i.e., margins alternate on recto and verso pages)
|
92
|
-
* Customizable running content (header and footer)
|
93
|
-
* “Keep together” blocks (i.e., page breaks avoided in certain block content):
|
94
|
-
** Explicitly delimited blocks other than open blocks
|
95
|
-
** Open blocks with the "unbreakable" option `[%unbreakable]`
|
96
|
-
* Orphaned section titles avoided
|
97
|
-
* Autofit verbatim blocks (as permitted by base_font_size_min setting)
|
98
|
-
* Table border settings honored
|
99
|
-
* Font-based icons
|
100
|
-
* Auto-generated index
|
101
|
-
* Automatic hyphenation (when enabled)
|
102
|
-
* Permissive line breaking for CJK languages
|
103
|
-
* Compression / optimization of output file
|
104
|
-
|
105
|
-
== Known Limitations
|
106
|
-
|
107
|
-
* Footnotes are always displayed as endnotes (at the end of chapter for books; at the end of document for all other doctypes).
|
108
|
-
*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).
|
109
|
-
* Table cells that exceed the height of a single page will be truncated (see https://github.com/prawnpdf/prawn-table/issues/41[prawn-table#41]).
|
110
|
-
* Columns cannot be assigned a 0% width (or a width less than the width of a single character); in the same vein, a column cannot be set to autowidth if width of all other columns meets or exceeds 100%; the result is that the converter with throw a Prawn::Errors::CannotFit error.
|
111
|
-
* 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).
|
112
|
-
* Must use development version of prawn for error to include font name when requested font style is missing.
|
113
|
-
* AsciiDoc table cell leaves padding below last block (due to lack of margin collapsing).
|
114
|
-
* 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]).
|
115
|
-
* 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.
|
116
|
-
* If a no-break hyphen is surrounded by formatted text on both sides (or is formatted individually), it will not prevent a line break.
|
117
|
-
* Images cannot float.
|
118
|
-
* You cannot use inline HTML (like a link or emphasized text) in a source block that also uses syntax highlighting.
|
119
|
-
These two technologies just don't combine in the PDF generation process due to how the syntax highlighters work.
|
120
|
-
* Verse blocks do not use a fixed-width font by default, but you can control this setting using the theme.
|
121
|
-
* An inline image with a percentage width value in an autowidth table cell is resized relative to its intrinsic width.
|
122
|
-
The space reserved for the image matches its intrinsic width.
|
123
|
-
This matches the behavior of HTML.
|
70
|
+
TIP: For the latest Asciidoctor PDF features and fixes, see {url-project-docs}/whats-new/[What's New in Asciidoctor PDF].
|
124
71
|
|
125
72
|
== Prerequisites
|
126
73
|
|
127
|
-
|
128
|
-
|
129
|
-
To check if you have Ruby available, use the `ruby` command to query the version installed:
|
130
|
-
|
131
|
-
$ ruby -e 'puts RUBY_VERSION'
|
132
|
-
|
133
|
-
Make sure this command reports a Ruby version that's at least 2.5.
|
134
|
-
If so, you may proceed.
|
135
|
-
|
136
|
-
If you want to <<Enable Stream Compression,optimize the pdf>> using rghost or hexapdf, you'll need to install the rghost gem:
|
137
|
-
|
138
|
-
$ gem install rghost
|
139
|
-
|
140
|
-
or the hexapdf gem:
|
141
|
-
|
142
|
-
$ gem install hexapdf
|
143
|
-
|
144
|
-
Similarly, if you want to use the hyphen option you will need to install the `text-hyphen` gem:
|
145
|
-
|
146
|
-
$ gem install text-hyphen
|
74
|
+
Asciidoctor PDF is a Ruby application.
|
75
|
+
Therefore, to use it, you'll need a Ruby runtime.
|
147
76
|
|
148
|
-
|
77
|
+
The supported Ruby runtimes are Ruby 2.7 or greater and JRuby 9.2 or greater.
|
78
|
+
However, we always recommend using the most recent release of Ruby or JRuby.
|
79
|
+
All required libraries (i.e., gems) will be installed automatically when you install Asciidoctor PDF, which will be covered in the <<Install Asciidoctor PDF,next section>>.
|
149
80
|
|
150
|
-
|
81
|
+
To check if you have Ruby available, run the `ruby` command to print the installed version:
|
151
82
|
|
152
|
-
|
153
|
-
To minimize encoding problems, make sure the default encoding of your system is set to UTF-8.
|
83
|
+
$ ruby -v
|
154
84
|
|
155
|
-
|
156
|
-
|
157
|
-
|
85
|
+
Make sure this command reports a Ruby version that starts with 2.7 (or a JRuby version that starts with 9.2).
|
86
|
+
If so, you're ready to proceed.
|
87
|
+
If not, head over to {url-rvm}[rvm.io^] to get RVM and use it to install Ruby.
|
158
88
|
|
159
|
-
|
89
|
+
== Install Asciidoctor PDF
|
160
90
|
|
161
|
-
|
91
|
+
You can install Asciidoctor PDF using the `gem install` command.
|
92
|
+
We'll use this command to install the Asciidoctor PDF gem named *asciidoctor-pdf* that's published on RubyGems.org.
|
93
|
+
Pass the name of the gem to the `gem install` command as follows:
|
162
94
|
|
163
|
-
|
95
|
+
$ gem install asciidoctor-pdf
|
164
96
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
=== Install the Published Gem
|
169
|
-
|
170
|
-
To install {project-name}, first make sure you have satisfied the <<Prerequisites,prerequisites>>.
|
171
|
-
Then, install the gem from RubyGems.org using the following command:
|
172
|
-
|
173
|
-
$ gem install asciidoctor-pdf --pre
|
97
|
+
Installing Asciidoctor PDF will install a number of other gems mentioned in these docs, including asciidoctor, prawn, prawn-svg, prawn-table, prawn-icon, and ttfunk.
|
98
|
+
For the most part, the versions of these dependencies are locked to the version of Asciidoctor PDF.
|
174
99
|
|
175
100
|
If you're using Ruby 3.1 or better, you must also install the matrix gem until Prawn 2.5.0 or better is released.
|
176
101
|
|
@@ -179,90 +104,42 @@ If you're using Ruby 3.1 or better, you must also install the matrix gem until P
|
|
179
104
|
The matrix gem used to be bundled in the Ruby distribution, but was split out starting in Ruby 3.1.
|
180
105
|
This requirement will be lifted once Prawn declares it as a runtime dependency.
|
181
106
|
|
182
|
-
|
183
|
-
|
184
|
-
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.
|
185
|
-
Installing gems for tech writing directly into your system is not recommended.
|
186
|
-
|
187
|
-
.Permission error when attempting to install as a system gem
|
188
|
-
....
|
189
|
-
ERROR: While executing gem ... (Gem::FilePermissionError)
|
190
|
-
You don't have write permissions for the /Library/Ruby/Gems/2.x.x directory.
|
191
|
-
....
|
192
|
-
|
193
|
-
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.
|
194
|
-
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.
|
195
|
-
All files are managed in user space (aka your home or user directory).
|
196
|
-
If something gets messed up, you can simply remove the [.path]_$HOME/.rvm_ folder and start over.
|
197
|
-
|
198
|
-
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.
|
199
|
-
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`.
|
200
|
-
(You'll need to do this each time you open a new terminal).
|
107
|
+
For further installation information, see {url-project-docs}/install/[the installation documentation].
|
108
|
+
For troubleshooting help, see {url-project-docs}/install/#installation-troubleshooting[Installation troubleshooting].
|
201
109
|
|
202
|
-
|
110
|
+
=== Install a prerelease or development version
|
203
111
|
|
204
|
-
|
112
|
+
To install the latest prerelease of the *asciidoctor-pdf* gem from RubyGems.org (if a prerelease is available), use the following command:
|
205
113
|
|
206
|
-
|
207
|
-
|
208
|
-
$ command -v asciidoctor-pdf
|
209
|
-
|
210
|
-
Both paths should be underneath the [.path]_$HOME/.rvm_ directory.
|
211
|
-
If not, check your RVM setup.
|
212
|
-
|
213
|
-
==== Install a Syntax Highlighter (optional)
|
214
|
-
|
215
|
-
If you want to syntax highlight source listings, you'll also want to install Rouge, Pygments, or CodeRay.
|
216
|
-
Choose one (or more) of the following:
|
217
|
-
|
218
|
-
.Rouge (preferred, minimum version: 2.0.0)
|
219
|
-
$ gem install rouge
|
220
|
-
|
221
|
-
.Pygments
|
222
|
-
$ gem install pygments.rb
|
223
|
-
|
224
|
-
.CodeRay
|
225
|
-
$ gem install coderay
|
226
|
-
|
227
|
-
You then activate syntax highlighting for a given document by adding the `source-highlighter` attribute to the document header (Rouge shown):
|
228
|
-
|
229
|
-
[source,asciidoc]
|
230
|
-
----
|
231
|
-
:source-highlighter: rouge
|
232
|
-
----
|
233
|
-
|
234
|
-
[#use-dev-versions]
|
235
|
-
==== Upgrade prawn
|
114
|
+
$ gem install asciidoctor-pdf --pre
|
236
115
|
|
237
|
-
{project-
|
238
|
-
At times, there may be development features or fixes you need in Prawn or one of its extensions that's still unreleased.
|
239
|
-
No problem.
|
240
|
-
You can gain access to these features by installing the unreleased gems directly from GitHub.
|
116
|
+
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.
|
241
117
|
|
242
|
-
|
243
|
-
In that file, declare the gem source, the {project-handle} gem, and the prawn gem (plus any other development gems you want to use).
|
118
|
+
== Optional dependencies
|
244
119
|
|
245
|
-
.
|
246
|
-
|
247
|
-
----
|
248
|
-
source 'https://rubygems.org'
|
120
|
+
There are several optional features of this converter that require additional gems to be installed.
|
121
|
+
Those features are as follows.
|
249
122
|
|
250
|
-
|
251
|
-
|
252
|
-
----
|
123
|
+
Source highlighting::
|
124
|
+
You'll need to {url-project-repo}/syntax-highlighting/[install a syntax highlighter] to use source highlighting (build-time only).
|
253
125
|
|
254
|
-
|
126
|
+
PDF optimization::
|
127
|
+
If you want to optimize your PDF, you'll need rghost or hexapdf.
|
128
|
+
See {url-project-repo}/optimize-pdf/[Optimize the PDF] for installation and usage instructions.
|
255
129
|
|
256
|
-
|
130
|
+
Automatic hyphenation::
|
131
|
+
To turn on automatic hyphenation using the `hyphens` attribute, you'll need to install the `text-hyphen` gem:
|
257
132
|
|
258
|
-
|
259
|
-
For example:
|
133
|
+
$ gem install text-hyphen
|
260
134
|
|
261
|
-
|
135
|
+
Accelerated image decoding::
|
136
|
+
Ruby is not particularly fast at decoding images, and the image formats it supports are limited.
|
137
|
+
To help, you can install prawn-gmagick, which delegates the work of decoding images to GraphicsMagick.
|
138
|
+
Refer to {url-project-repo}/image-paths-and-formats/#other-image-formats[Supporting additional image file formats] for instructions about how to enable this integration.
|
262
139
|
|
263
|
-
|
140
|
+
Check the {url-project-docs}/install/#table-minimum-version[minimum supported version table] to make sure you're using a supported version of the dependency.
|
264
141
|
|
265
|
-
|
142
|
+
== Run the Application
|
266
143
|
|
267
144
|
Assuming all the required gems install properly, verify you can run the `asciidoctor-pdf` script:
|
268
145
|
|
@@ -272,9 +149,12 @@ If you see the version of {project-name} printed, you're ready to use {project-n
|
|
272
149
|
|
273
150
|
Let's grab an AsciiDoc document to distill and start putting {project-name} to use.
|
274
151
|
|
275
|
-
|
152
|
+
If you don't already have an AsciiDoc document to work with, you can use the <<examples/basic-example.adoc#,basic-example.adoc>> file found in the _examples_ directory of this project.
|
153
|
+
Copy it to the current directory as follows:
|
154
|
+
|
155
|
+
$ cp examples/basic-example.adoc .
|
276
156
|
|
277
|
-
|
157
|
+
Let's take a look at the contents of that file.
|
278
158
|
|
279
159
|
ifeval::[{safe-mode-level} >= 20]
|
280
160
|
See <<examples/basic-example.adoc#,basic-example.adoc>>.
|
@@ -293,934 +173,30 @@ It's time to convert the AsciiDoc document directly to PDF.
|
|
293
173
|
|
294
174
|
IMPORTANT: You'll need the `rouge` gem installed to run this example since it uses the `source-highlighter` attribute with the value of `rouge`.
|
295
175
|
|
296
|
-
Converting to PDF is as
|
176
|
+
Converting to PDF is as straightforward as running the `asciidoctor-pdf` script using Ruby and passing the AsciiDoc document as the first argument:
|
297
177
|
|
298
178
|
$ asciidoctor-pdf basic-example.adoc
|
299
179
|
|
300
|
-
This command is
|
180
|
+
This command is a shorter way of running `asciidoctor` with the PDF converter and backend enabled:
|
301
181
|
|
302
182
|
$ asciidoctor -r asciidoctor-pdf -b pdf basic-example.adoc
|
303
183
|
|
304
|
-
The `asciidoctor-pdf` command
|
305
|
-
That's why we
|
184
|
+
The `asciidoctor-pdf` command saves you from having to remember these low-level options.
|
185
|
+
That's why we provide it.
|
306
186
|
|
307
|
-
When the script completes, you should see the file [.path]_basic-example.pdf_ in the
|
187
|
+
When the script completes, you should see the file [.path]_basic-example.pdf_ in the current directory.
|
188
|
+
Asciidoctor creates the output file in the same directory as the input file by default.
|
308
189
|
Open the [.path]_basic-example.pdf_ file with a PDF viewer to see the result.
|
309
190
|
|
310
191
|
.Example PDF document rendered in a PDF viewer
|
311
|
-
image::
|
312
|
-
|
313
|
-
ifndef::env-site[]
|
314
|
-
You're also encouraged to try converting this <<README.adoc#,README>> as well as the documents in the examples directory to see more of what {project-name} can do.
|
315
|
-
endif::[]
|
192
|
+
image::docs/modules/ROOT/images/basic-example-pdf-screenshot.png[Screenshot of PDF document,960,540,pdfwidth=100%]
|
316
193
|
|
317
|
-
|
194
|
+
For more information about how to use Asciidoctor PDF and PDF-specific AsciiDoc syntax, see the {url-project-docs}/[Asciidoctor PDF documentation].
|
318
195
|
|
319
196
|
== Themes
|
320
197
|
|
321
198
|
The layout and styling of the PDF is driven by a YAML configuration file.
|
322
|
-
To learn how the theming system works and how to create and apply custom themes, refer to the
|
323
|
-
You can use the built-in theme files, which you can find in the [.path]_data/themes_ directory, as examples.
|
324
|
-
|
325
|
-
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.
|
326
|
-
For example, to configure Rouge to use the built-in monokai theme, run Asciidoctor PDF as follows:
|
327
|
-
|
328
|
-
$ asciidoctor-pdf -a rouge-style=monokai basic-example.adoc
|
329
|
-
|
330
|
-
It's possible to develop your own theme for Rouge.
|
331
|
-
Refer to the https://docs.asciidoctor.org/pdf-converter/latest/theme/[Asciidoctor PDF theming documentation] for details.
|
332
|
-
|
333
|
-
== Support for Non-Latin Languages
|
334
|
-
|
335
|
-
Asciidoctor can process the full range of characters in the UTF-8 character set.
|
336
|
-
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.
|
337
|
-
But you still need a font that provides the glyphs for those characters.
|
338
|
-
|
339
|
-
When converting a document with Asciidoctor PDF, you may notice that some glyphs for certain languages, such as Chinese, are missing from the PDF.
|
340
|
-
PDF is a "`bring your own font`" kind of system.
|
341
|
-
In other words, the font you provide must provide glyphs for all the characters used.
|
342
|
-
There's no one font that supports all the world's languages (though some, like Noto Serif, certainly come close).
|
343
|
-
Even if there were such a font, bundling that font with the main gem would make it enormous.
|
344
|
-
It would also severely limit the style choices in the default theme, which targets Latin-based languages.
|
345
|
-
Therefore, we're taking the strategy of creating separate dedicated theme gems that target each language family, such as CJK.
|
346
|
-
|
347
|
-
== Font-Based Icons
|
348
|
-
|
349
|
-
You can use icons in your PDF document using any of the following icon sets:
|
350
|
-
|
351
|
-
* *fa* - https://fontawesome.com/v4.7.0/icons (default)
|
352
|
-
* *fas* - https://fontawesome.com/icons?d=gallery&s=solid[Font Awesome - Solid^]
|
353
|
-
* *fab* - https://fontawesome.com/icons?d=gallery&s=brands[Font Awesome - Brands^]
|
354
|
-
* *far* - https://fontawesome.com/icons?d=gallery&s=regular[Font Awesome - Regular^]
|
355
|
-
* *fi* - http://zurb.com/playground/foundation-icon-fonts-3[Foundation Icons^]
|
356
|
-
* *pf* - https://paymentfont.com/[Payment font^]
|
357
|
-
|
358
|
-
The fa icon set is deprecated.
|
359
|
-
Please use one of the other three FontAwesome icon sets.
|
360
|
-
|
361
|
-
You can enable font-based icons by setting the following attribute in the header of your document:
|
362
|
-
|
363
|
-
[source,asciidoc]
|
364
|
-
----
|
365
|
-
:icons: font
|
366
|
-
----
|
367
|
-
|
368
|
-
If you want to override the font set globally, also set the `icon-set` attribute:
|
369
|
-
|
370
|
-
[source,asciidoc]
|
371
|
-
----
|
372
|
-
:icons: font
|
373
|
-
:icon-set: pf
|
374
|
-
----
|
375
|
-
|
376
|
-
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):
|
377
|
-
|
378
|
-
[source,asciidoc]
|
379
|
-
----
|
380
|
-
Available now at icon:amazon[].
|
381
|
-
----
|
382
|
-
|
383
|
-
You can use the `set` attribute on the icon macro to override the icon set for a given icon.
|
384
|
-
|
385
|
-
[source,asciidoc]
|
386
|
-
----
|
387
|
-
Available now at icon:amazon[set=pf].
|
388
|
-
----
|
389
|
-
|
390
|
-
You can also specify the font set using the following shorthand.
|
391
|
-
|
392
|
-
[source,asciidoc]
|
393
|
-
----
|
394
|
-
Available now at icon:amazon@pf[].
|
395
|
-
----
|
396
|
-
|
397
|
-
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).
|
398
|
-
|
399
|
-
[source,asciidoc]
|
400
|
-
----
|
401
|
-
icon:android[size=40em]
|
402
|
-
----
|
403
|
-
|
404
|
-
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.
|
405
|
-
|
406
|
-
$ asciidoctor-pdf -a icons=font -a icon-set=pf sample.adoc
|
407
|
-
|
408
|
-
Icon-based fonts are handled by the `prawn-icon` gem.
|
409
|
-
To find a complete list of available icons, consult the https://github.com/jessedoyle/prawn-icon/tree/master/data/fonts[prawn-icon] repository.
|
410
|
-
|
411
|
-
== Image Paths
|
412
|
-
|
413
|
-
Images are resolved at the time the converter runs.
|
414
|
-
That means they need to be located where the converter can find them.
|
415
|
-
|
416
|
-
Relative images paths in the document are resolved relative to the value of the `imagesdir` attribute.
|
417
|
-
This is effectively the same as how the built-in HTML converter works when the `data-uri` attribute is set.
|
418
|
-
The `imagesdir` is blank by default, which means relative images paths are resolved relative to the input document.
|
419
|
-
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).
|
420
|
-
The `imagesdir` attribute is not used when resolving an image path in the theme file.
|
421
|
-
Absolute image paths are used as is.
|
422
|
-
|
423
|
-
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.
|
424
|
-
|
425
|
-
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.
|
426
|
-
|
427
|
-
If you use a linked image in an SVG, the width and height of that image must be specified.
|
428
|
-
Otherwise, the SVG library will fail to process it.
|
429
|
-
|
430
|
-
=== Asciidoctor Diagram Integration
|
431
|
-
|
432
|
-
Asciidoctor PDF provides seamless integration with Asciidoctor Diagram by setting the `data-uri` attribute by default.
|
433
|
-
When the `data-uri` attribute is set, Asciidoctor Diagram returns the absolute path to the generated image, which Asciidoctor PDF can then locate.
|
434
|
-
(This makes sense since technically, Asciidoctor Diagram must embed the image in the document, similar in spirit to the `data-uri` feature for HTML).
|
435
|
-
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.
|
436
|
-
|
437
|
-
== Image Scaling
|
438
|
-
|
439
|
-
Since PDF is a fixed-width canvas, you almost always need to specify a width to get the image to fit properly on the page.
|
440
|
-
There are five ways to specify the width of an image, listed here in order of precedence:
|
441
|
-
|
442
|
-
[cols="1s,3"]
|
443
|
-
|===
|
444
|
-
|Attribute{nbsp}Name | Description
|
445
|
-
|
446
|
-
|pdfwidth
|
447
|
-
|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).
|
448
|
-
If a unit of measurement is not specified (or not recognized), pt (points) is assumed.
|
449
|
-
_Intended to be used for the PDF converter only._
|
450
|
-
|
451
|
-
|scaledwidth
|
452
|
-
|The display width of the image as an absolute size (e.g., 2in) or percentage of the content area width (e.g., 75%).
|
453
|
-
If a unit of measurement is not specified, % (percentage) is assumed.
|
454
|
-
If a unit of measurement is recognized, pt (points) is assumed.
|
455
|
-
_Intended to be used for print output such as PDF._
|
456
|
-
|
457
|
-
|image_width key from theme
|
458
|
-
|Accepts the same values as pdfwidth.
|
459
|
-
_Only applies to block images._
|
460
|
-
|
461
|
-
|width
|
462
|
-
|The unitless display width of the image (assumed to be pixels), typically matching the intrinsic width of the image.
|
463
|
-
If the value ends in % (not recommended), it's assumed to be the percentage of the available content area width.
|
464
|
-
If the width exceeds the content area width, the image is scaled down to the content area width.
|
465
|
-
|
466
|
-
|_unspecified_
|
467
|
-
|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.
|
468
|
-
|===
|
469
|
-
|
470
|
-
The image is always sized according to the explicit or intrinsic width, then its height is scaled proportionally.
|
471
|
-
The height of the image is ignored by the PDF converter unless the height of the image exceeds the content height of the page.
|
472
|
-
In this case, the image is scaled down to fit on a single page.
|
473
|
-
|
474
|
-
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"`).
|
475
|
-
This is most useful when using vw units because you can make the image cover the entire width of the page.
|
476
|
-
|
477
|
-
Images in running content and page background images also support the `fit` attribute (when specified using the image macro).
|
478
|
-
See <<Background Image Sizing>> for details.
|
479
|
-
|
480
|
-
=== Using the pdfwidth Attribute
|
481
|
-
|
482
|
-
The pdfwidth attribute is the recommended way to set the image size for the PDF output.
|
483
|
-
This attribute is provided for two reasons.
|
484
|
-
First, the fixed-width canvas often calls for a width that is distinct from other output formats, such as HTML.
|
485
|
-
Second, this attribute allows the width to be expressed using a variety of units.
|
486
|
-
|
487
|
-
The pdfwidth attribute supports the following units:
|
488
|
-
|
489
|
-
* pt (default)
|
490
|
-
* in
|
491
|
-
* cm
|
492
|
-
* mm
|
493
|
-
* px
|
494
|
-
* pc
|
495
|
-
* vw (percentage of page width)
|
496
|
-
* % (percentage of content area width)
|
497
|
-
|
498
|
-
In all cases, the width is converted to pt.
|
499
|
-
|
500
|
-
=== Specifying a Default Width
|
501
|
-
|
502
|
-
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.
|
503
|
-
|
504
|
-
[source,yaml]
|
505
|
-
----
|
506
|
-
image:
|
507
|
-
width: 100%
|
508
|
-
----
|
509
|
-
|
510
|
-
The image-width key accepts the same values as the `pdfwidth` attribute.
|
511
|
-
Thus, you can think of it as the fallback value for the `pdfwidth` attribute.
|
512
|
-
If specified, this value takes precedence over the `width` attribute on the image macro.
|
513
|
-
|
514
|
-
=== Inline Image Sizing
|
515
|
-
|
516
|
-
Inline images can be sized in much the same way as block images (using the pdfwidth, scaledwidth or width attributes), with the following exceptions:
|
517
|
-
|
518
|
-
* The viewport width unit (i.e., vw) is not recognized in this context.
|
519
|
-
* The image will be scaled down, if necessary, to fit the width and height of the content area.
|
520
|
-
* Inline images do not currently support a default width controlled from the theme.
|
521
|
-
|
522
|
-
To confine the inline image to the height of the line while preserving the aspect ratio, use the attribute `fit=line`.
|
523
|
-
|
524
|
-
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.
|
525
|
-
This is done to maximize the use of available space.
|
526
|
-
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.
|
527
|
-
In this case, the surrounding text will be aligned to the bottom of the image.
|
528
|
-
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).
|
529
|
-
|
530
|
-
=== Background Image Sizing
|
531
|
-
|
532
|
-
In addition to the width-related attributes previously covered, cover and background images can be sized relative to the page using the `fit` attribute of the image macro.
|
533
|
-
The `fit` attribute works similarly to the `object-fit` property in CSS.
|
534
|
-
Its value must be specified as a single keyword, chosen from the table below.
|
535
|
-
The starting size of the image is determined by the explicit width, if specified, or the implicit width.
|
536
|
-
The height is always derived from the width while respecting the implicit aspect ratio of the image.
|
537
|
-
The available space for a background image (i.e., the canvas) is the page.
|
538
|
-
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).
|
539
|
-
|
540
|
-
[cols="1s,3"]
|
541
|
-
|===
|
542
|
-
| Value | Purpose
|
543
|
-
|
544
|
-
| contain
|
545
|
-
| The image is scaled up or down while retaining its aspect ratio to fit within the available space. (default)
|
546
|
-
|
547
|
-
| cover
|
548
|
-
| 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.
|
549
|
-
|
550
|
-
| scale-down
|
551
|
-
| The image is scaled down while retaining its aspect ratio to fit within the available space.
|
552
|
-
If the image already fits, it is not scaled.
|
553
|
-
|
554
|
-
| fill
|
555
|
-
| The image is scaled to fit the available space even if it means modifying the aspect ratio of the image.
|
556
|
-
Does not apply to SVG images.
|
557
|
-
|
558
|
-
| none
|
559
|
-
| The image is not scaled.
|
560
|
-
|===
|
561
|
-
|
562
|
-
The `fit` attribute is often combined with the `position` attribute, covered next, to control the placement of the image on the canvas.
|
563
|
-
|
564
|
-
== Background Image Positioning
|
565
|
-
|
566
|
-
In addition to scaling, background images for cover pages, content pages, and the title page support positioning via the `position` attribute.
|
567
|
-
The `position` attribute accepts a syntax similar to the `background-position` property in CSS, except only the keyword positions are supported.
|
568
|
-
The position consists of two values, the vertical position and the horizontal position (e.g., `top center`).
|
569
|
-
If only one value is specified (e.g., `top`), the other value is assumed to be `center`.
|
570
|
-
If the `position` attribute is not specified, the value is assumed to be `center center` (i.e., the image is centered on the page).
|
571
|
-
|
572
|
-
The following table provides a list of the vertical and horizontal positioning keywords that are supported.
|
573
|
-
You can use any combination of these keywords to position the image.
|
574
|
-
|
575
|
-
|===
|
576
|
-
| Vertical Positions | Horizontal Positions
|
577
|
-
|
578
|
-
| top +
|
579
|
-
center +
|
580
|
-
bottom
|
581
|
-
|
582
|
-
| left +
|
583
|
-
center +
|
584
|
-
right
|
585
|
-
|===
|
586
|
-
|
587
|
-
Here's an example of how to place a background image at the top center of every page:
|
588
|
-
|
589
|
-
----
|
590
|
-
:page-background-image: image:bg.png[fit=none,pdfwidth=50%,position=top]
|
591
|
-
----
|
592
|
-
|
593
|
-
Here's how to move it to the bottom right:
|
594
|
-
|
595
|
-
----
|
596
|
-
:page-background-image: image:bg.png[fit=none,pdfwidth=50%,position=bottom right]
|
597
|
-
----
|
598
|
-
|
599
|
-
If an image dimension matches the height or width of the page, the positioning keyword for that axis has no effect.
|
600
|
-
|
601
|
-
== Supporting Additional Image File Formats
|
602
|
-
|
603
|
-
In order to embed an image into a PDF, Asciidoctor PDF must understand how to decode it.
|
604
|
-
To perform this work, Asciidoctor delegates to the underlying libraries.
|
605
|
-
{url-prawn}[Prawn] provides support for decoding JPG and PNG images.
|
606
|
-
{url-prawn-svg}[prawn-svg] brings support for translating SVG images to PDF commands.
|
607
|
-
Without any additional libraries, those are the only image file formats supported by Asciidoctor PDF.
|
608
|
-
|
609
|
-
If you need support for additional image formats, such as GIF, TIFF, WebP, or interlaced PNG--and you don't want to convert those images to a supported format like JPG--you must install the {url-prawn-gmagick}[prawn-gmagick] (>= 0.0.9) Ruby gem.
|
610
|
-
prawn-gmagick is an extension for Prawn that delegates image decoding to {url-graphicsmagick}[GraphicsMagick] to add support for all image formats recognized by that library.
|
611
|
-
|
612
|
-
prawn-gmagick has the additional benefit of *significantly* reducing the processing time, power, and memory necessary to generate a PDF that contains a lot of PNG images.
|
613
|
-
For large books (such as Pro Git), you might see the conversion time drop by as much as half.
|
614
|
-
Decoding PNG images requires a lot of mathematical computation, a task Ruby is not particularly efficient at performing.
|
615
|
-
That's why adding the prawn-gmagick gem to the converter makes such a substantial difference.
|
616
|
-
|
617
|
-
As an alternative to using prawn-gmagick, you could optimize the images you pass into Asciidoctor PDF, either by scaling them down or converting them to an uncompressed format like JPG.
|
618
|
-
|
619
|
-
The prawn-gmagick gem uses native extensions to compile against GraphicsMagick.
|
620
|
-
This system prerequisite limits installation to C Ruby running on Linux and macOS.
|
621
|
-
Please refer to the {url-prawn-gmagick}[README for prawn-gmagick] to learn how to install it.
|
622
|
-
|
623
|
-
$ gem install prawn-gmagick
|
624
|
-
|
625
|
-
When this gem is installed, Asciidoctor automatically detects and loads it, then delegates all image decoding to GraphicsMagick by way of the bridge it provides.
|
626
|
-
We highly recommend using this gem with Asciidoctor PDF if you're able to install it.
|
627
|
-
|
628
|
-
The one downside of delegating to GraphicsMagick is that it can mangle certain PNG images.
|
629
|
-
If this happens, you can instruct Asciidoctor PDF to not delegate to GraphicsMagick to load PNG images by requiring `asciidoctor/pdf/nopngmagick` when calling Asciidoctor PDF, as follows:
|
630
|
-
|
631
|
-
$ asciidoctor-pdf -r asciidoctor/pdf/nopngmagick doc.adoc
|
632
|
-
|
633
|
-
You can also tell Asciidoctor PDF not to use prawn-gmagick at all by requiring `asciidoctor/pdf/nogmagick` when calling Asciidoctor PDF, as follows:
|
634
|
-
|
635
|
-
$ asciidoctor-pdf -r asciidoctor/pdf/nogmagick doc.adoc
|
636
|
-
|
637
|
-
Granted, bypassing prawn-gmagick means you no longer get support for additional image formats that Prawn cannot handle or the PNG acceleration.
|
638
|
-
|
639
|
-
== Importing PDF Pages
|
640
|
-
|
641
|
-
In addition to using a PDF page for the front or back cover, you can also insert a PDF page at an arbitrary location.
|
642
|
-
This technique is useful to include pages that have complex layouts and graphics prepared in a specialized design program (such as Inkscape), which would otherwise not be achievable using this converter.
|
643
|
-
One such example is an insert such as an advertisement or visual interlude.
|
644
|
-
|
645
|
-
To import the first page from a PDF file, use the block image macro with the PDF filename as the image target.
|
646
|
-
|
647
|
-
[source,asciidoc]
|
648
|
-
----
|
649
|
-
image::custom-page.pdf[]
|
650
|
-
----
|
651
|
-
|
652
|
-
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).
|
653
|
-
Therefore, there's no need to put a manual page break (i.e., `<<<`) around the image macro.
|
654
|
-
|
655
|
-
By default, this macro will import the first page of the PDF.
|
656
|
-
To import a different page, specify it as a 1-based index using the `page` attribute.
|
657
|
-
|
658
|
-
[source,asciidoc]
|
659
|
-
----
|
660
|
-
image::custom-pages.pdf[page=2]
|
661
|
-
----
|
662
|
-
|
663
|
-
You can import multiple pages either using multiple image macros or using the `pages` attribute.
|
664
|
-
The `pages` attribute accepts individual page numbers or page number ranges (two page numbers separated by `..`).
|
665
|
-
The values can be separated either by commas or semi-colons.
|
666
|
-
(The syntax is similar to the syntax uses for the `lines` attribute of the AsciiDoc include directive).
|
667
|
-
|
668
|
-
[source,asciidoc]
|
669
|
-
----
|
670
|
-
image::custom-pages.pdf[pages=3;1..2]
|
671
|
-
----
|
672
|
-
|
673
|
-
Pages are imported in the order listed.
|
674
|
-
|
675
|
-
To see a practical example of how to use this feature, refer to the blog post https://fromplantoprototype.com/blog/2019/08/07/importing-pdf-pages-in-asciidoctor-pdf/[Importing PDF Pages in asciidoctor-pdf].
|
676
|
-
|
677
|
-
CAUTION: An image macro used to imports PDF pages should never be nested inside a delimited block or table cell.
|
678
|
-
It should be a direct descendant of the document or a section.
|
679
|
-
That's because what it imports are entire pages.
|
680
|
-
If it's used inside a delimited block or table cell, the behavior is unspecified.
|
681
|
-
|
682
|
-
== Interdocument Xrefs
|
683
|
-
|
684
|
-
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.
|
685
|
-
Which one it becomes depends on whether the target has been included into the current document.
|
686
|
-
These section describes these two scenarios.
|
687
|
-
|
688
|
-
=== Referencing Another Document
|
689
|
-
|
690
|
-
If the target PDF is generated from an AsciiDoc file, you can make a reference to that PDF using the xref macro.
|
691
|
-
|
692
|
-
Let's assume the current document is [.path]_a.adoc_ and the PDF you want to reference is generated from [.path]_b.adoc_.
|
693
|
-
Here's how you can make a reference from the PDF generated from [.path]_a.adoc_ to the PDF generated from [.path]_b.adoc_.
|
694
|
-
|
695
|
-
[source,asciidoc]
|
696
|
-
----
|
697
|
-
A link to xref:b.adoc[b].
|
698
|
-
----
|
699
|
-
|
700
|
-
This xref macro is translated to a link that refers to [.path]_b.pdf_.
|
701
|
-
|
702
|
-
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.
|
703
|
-
|
704
|
-
[source,asciidoc]
|
705
|
-
----
|
706
|
-
A link to xref:b.adoc#chapter-b[b].
|
707
|
-
----
|
708
|
-
|
709
|
-
WARNING: Linking to a named anchor isn't supported by all PDF viewers.
|
710
|
-
Some viewers (like Firefox) only support relative links when the PDF is accessed through a web server.
|
711
|
-
To verify it's working, test the PDF in Firefox and served through a local web server.
|
712
|
-
|
713
|
-
PDF supports a variety of PDF link open parameters you can control using the URL fragment.
|
714
|
-
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.
|
715
|
-
|
716
|
-
[source,asciidoc]
|
717
|
-
----
|
718
|
-
A link to page 2 of xref:b.adoc#page=2[b].
|
719
|
-
----
|
720
|
-
|
721
|
-
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.
|
722
|
-
|
723
|
-
=== Converting Interdocument Xrefs to Internal Xrefs
|
724
|
-
|
725
|
-
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.
|
726
|
-
Interdocument cross references (i.e., xrefs) will only successfully make that transition if you structure your document in accordance with the rules.
|
727
|
-
|
728
|
-
Those rules are as follows:
|
729
|
-
|
730
|
-
. The path segment of the interdocument xref must match the project-relative path of the included document
|
731
|
-
. The reference must include the ID of the target element
|
732
|
-
|
733
|
-
For instance, if your primary document contains the following include:
|
734
|
-
|
735
|
-
[source,asciidoc]
|
736
|
-
----
|
737
|
-
\include::chapters/chapter-1.adoc[]
|
738
|
-
----
|
739
|
-
|
740
|
-
Then an interdocument xref to an anchor in that chapter must be expressed as:
|
741
|
-
|
742
|
-
[source,asciidoc]
|
743
|
-
----
|
744
|
-
<<chapters/chapter-1.adoc#_anchor_name,Destination in Chapter 1>>
|
745
|
-
----
|
746
|
-
|
747
|
-
This rule holds regardless of which document the xref is located in.
|
748
|
-
|
749
|
-
To resolve the interdocument xref, the converter first checks if the target matches the `docname` attribute.
|
750
|
-
It then looks to see if the target matches one of the included files.
|
751
|
-
(In both cases, it ignores the file extension).
|
752
|
-
If Asciidoctor cannot resolve the target of an interdocument xref, it simply makes a link (like the HTML converter).
|
753
|
-
|
754
|
-
Let's consider a complete example.
|
755
|
-
Assume you are converting the following book document at the root of the project:
|
756
|
-
|
757
|
-
[source,asciidoc]
|
758
|
-
----
|
759
|
-
= Book Title
|
760
|
-
:doctype: book
|
761
|
-
|
762
|
-
\include::chapters/chapter-1.adoc[]
|
763
|
-
|
764
|
-
\include::chapters/chapter-2.adoc[]
|
765
|
-
----
|
766
|
-
|
767
|
-
Where the contents of chapter 1 is as follows:
|
768
|
-
|
769
|
-
[source,asciidoc]
|
770
|
-
----
|
771
|
-
== Chapter 1
|
772
|
-
|
773
|
-
We cover a little bit here.
|
774
|
-
The rest you can find in <<chapters/chapter-2.adoc#_chapter_2,Chapter 2>>.
|
775
|
-
----
|
776
|
-
|
777
|
-
And the contents of chapter 2 is as follows:
|
778
|
-
|
779
|
-
[source,asciidoc]
|
780
|
-
----
|
781
|
-
== Chapter 2
|
782
|
-
|
783
|
-
Prepare to be educated.
|
784
|
-
This chapter has it all!
|
785
|
-
|
786
|
-
To begin, jump to <<chapters/chapter-2/first-steps.adoc#_first_steps,first steps>>.
|
787
|
-
|
788
|
-
<<<
|
789
|
-
|
790
|
-
\include::chapter-2/first-steps.adoc[]
|
791
|
-
----
|
792
|
-
|
793
|
-
And, finally, the contents of the nested include is as follows:
|
794
|
-
|
795
|
-
[source,asciidoc]
|
796
|
-
----
|
797
|
-
=== First Steps
|
798
|
-
|
799
|
-
Let's start small.
|
800
|
-
----
|
801
|
-
|
802
|
-
You'll find when you run this example that all the interdocument xrefs become internal references in the PDF.
|
803
|
-
|
804
|
-
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.
|
805
|
-
In other words, it encodes the complete information about the reference so the converter can sort out where the target is in all circumstances.
|
806
|
-
|
807
|
-
== STEM Support
|
808
|
-
|
809
|
-
Unlike the built-in HTML converter, Asciidoctor PDF does not provide native support for STEM blocks and inline macros (i.e., asciimath and latexmath).
|
810
|
-
That's because Asciidoctor core doesn't process the STEM content itself.
|
811
|
-
It simply passes it through to the converter.
|
812
|
-
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.
|
813
|
-
The HTML converter wraps the expressions in special markup so MathJax can find and process them.
|
814
|
-
|
815
|
-
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.
|
816
|
-
That typically means converting to an image.
|
817
|
-
|
818
|
-
One solution that provides this capability is an extension named Asciidoctor Mathematical, which we'll cover in the next section.
|
819
|
-
|
820
|
-
////
|
821
|
-
Another solution, which is still under development, uses Mathoid to convert STEM equations to images.
|
822
|
-
Mathoid is a library that invokes MathJax using a headless browser, so it supports both asciimath and latexmath equations.
|
823
|
-
That prototype can be found in the https://github.com/asciidoctor/asciidoctor-extensions-lab#extension-catalog[Asciidoctor extensions lab].
|
824
|
-
////
|
825
|
-
|
826
|
-
=== Asciidoctor Mathematical
|
827
|
-
|
828
|
-
{url-asciidoctor-mathematical}[Asciidoctor Mathematical] is an extension for Asciidoctor that provides alternate processing of STEM blocks and inline macros.
|
829
|
-
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.
|
830
|
-
It uses Mathematical to render the LaTeX notation as an image.
|
831
|
-
If the expression is AsciiMath, it first uses AsciiMath gem to convert to LaTeX.
|
832
|
-
Conversion then proceeds as normal.
|
833
|
-
|
834
|
-
Asciidoctor Mathematical is a Ruby gem that uses native extensions.
|
835
|
-
It has a few system prerequisites which limit installation to Linux and macOS.
|
836
|
-
Please refer to the {url-asciidoctor-mathematical}#installation[installation section] in the Asciidoctor Mathematical README to learn how to install it.
|
837
|
-
|
838
|
-
Once Asciidoctor Mathematical is installed, you can enable it when invoking Asciidoctor PDF using the `-r` flag:
|
839
|
-
|
840
|
-
$ asciidoctor-pdf -r asciidoctor-mathematical sample.adoc
|
841
|
-
|
842
|
-
If you're invoking Asciidoctor via the API, you need to require the gem before invoking Asciidoctor:
|
843
|
-
|
844
|
-
[source,ruby]
|
845
|
-
----
|
846
|
-
require 'asciidoctor-mathematical'
|
847
|
-
require 'asciidoctor-pdf'
|
848
|
-
|
849
|
-
Asciidoctor.convert_file 'sample.adoc', backend: 'pdf', safe: :safe
|
850
|
-
----
|
851
|
-
|
852
|
-
To get the best quality output and maximize speed of conversion, we recommend configuring Asciidoctor Mathematical to convert equations to SVG.
|
853
|
-
You control this setting using the `mathematical-format` AsciiDoc attribute:
|
854
|
-
|
855
|
-
$ asciidoctor-pdf -r asciidoctor-mathematical -a mathematical-format=svg sample.adoc
|
856
|
-
|
857
|
-
Refer to the {url-asciidoctor-mathematical}#readme[README] for Asciidoctor Mathematical to learn about additional settings and options.
|
858
|
-
|
859
|
-
== Skipping Passthrough Content
|
860
|
-
|
861
|
-
Asciidoctor PDF does not support arbitrary passthrough content.
|
862
|
-
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, ).
|
863
|
-
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).
|
864
|
-
|
865
|
-
Here's an example of how to skip a passthrough block when converting to PDF:
|
866
|
-
|
867
|
-
[source,asciidoc]
|
868
|
-
----
|
869
|
-
\ifndef::backend-pdf[]
|
870
|
-
<script>
|
871
|
-
//...
|
872
|
-
</script>
|
873
|
-
\endif::[]
|
874
|
-
----
|
875
|
-
|
876
|
-
Here's an example of how to only enable a passthrough block when converting to HTML5:
|
877
|
-
|
878
|
-
[source,asciidoc]
|
879
|
-
----
|
880
|
-
\ifdef::backend-html5[]
|
881
|
-
<script>
|
882
|
-
//...
|
883
|
-
</script>
|
884
|
-
\endif::[]
|
885
|
-
----
|
886
|
-
|
887
|
-
== Shaded Blocks and Performance
|
888
|
-
|
889
|
-
Certain blocks are rendered with a shaded background, such as verbatim (listing, literal, and source), sidebar, and example blocks.
|
890
|
-
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.
|
891
|
-
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.
|
892
|
-
As a general rule of thumb, you should avoid using shaded blocks which span more than a handful of pages.
|
893
|
-
|
894
|
-
== Autofitting Text
|
895
|
-
|
896
|
-
Verbatim blocks often have long lines that don't fit within the fixed width of the PDF canvas.
|
897
|
-
And unlike on the web, the PDF reader cannot scroll horizontally to reveal the overflow text.
|
898
|
-
Therefore, the long lines are forced to wrap.
|
899
|
-
Wrapped lines can make the verbatim blocks hard to read or even cause confusion.
|
900
|
-
|
901
|
-
To help address this problem, Asciidoctor PDF provides the `autofit` option on all verbatim (i.e., literal, listing and source) blocks to attempt to fit the text within the available width.
|
902
|
-
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.
|
903
|
-
|
904
|
-
CAUTION: The converter will not shrink the font size beyond the value of the `base_font_size_min` key specified in the PDF theme.
|
905
|
-
If that threshold is reached, lines may still wrap.
|
906
|
-
To allow `autofit` to handle all cases, set `base_font_size_min` to `0` in your theme.
|
907
|
-
|
908
|
-
Here's an example of the autofit option enabled on a source block:
|
909
|
-
|
910
|
-
[source,asciidoc]
|
911
|
-
....
|
912
|
-
[source%autofit,java]
|
913
|
-
----
|
914
|
-
@SessionScoped
|
915
|
-
public class WidgetRepository {
|
916
|
-
@GET
|
917
|
-
@Produces("application/json")
|
918
|
-
public List<String> listAll(@QueryParam("start") Integer start, @QueryParam("max") Integer max) {
|
919
|
-
...
|
920
|
-
}
|
921
|
-
}
|
922
|
-
----
|
923
|
-
....
|
924
|
-
|
925
|
-
If you want to enable the autofit option globally, set the `autofit-option` document attribute in the document header (or somewhere before the relevant blocks):
|
926
|
-
|
927
|
-
[source,asciidoc]
|
928
|
-
----
|
929
|
-
:autofit-option:
|
930
|
-
----
|
931
|
-
|
932
|
-
== Autowidth Tables
|
933
|
-
|
934
|
-
Asciidoctor PDF does support autowidth tables.
|
935
|
-
However, the behavior differs from HTML when the content forces the table to the page boundary.
|
936
|
-
The behavior, which is handled by the prawn-table library, is explained in this section.
|
937
|
-
|
938
|
-
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.
|
939
|
-
Each column is assigned the width it needs to prevent the content from wrapping.
|
940
|
-
|
941
|
-
However, when the natural width of all columns exceeds the width of the page, the behavior may not be what you expect.
|
942
|
-
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.
|
943
|
-
Then, it reduces the width of the table by reducing the width of each column proportionally.
|
944
|
-
As a result, columns which reported the width necessary to render without wrapping now no longer do.
|
945
|
-
|
946
|
-
The reason this compression is not performed like in HTML is because prawn-table has no awareness of words.
|
947
|
-
Thus, it doesn't know how to redistribute with width intelligently.
|
948
|
-
|
949
|
-
To protected against truncation or insufficient width errors, prawn-table wraps text by character.
|
950
|
-
That's why the last character in the cell can end up getting wrapped.
|
951
|
-
(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).
|
952
|
-
|
953
|
-
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.
|
954
|
-
Let experience be your guide.
|
955
|
-
|
956
|
-
== Printing Page Ranges
|
957
|
-
|
958
|
-
The print dialog doesn't understand the page numbers labels (which appear in the running content).
|
959
|
-
Instead, it only considers physical pages.
|
960
|
-
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.
|
961
|
-
|
962
|
-
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.
|
963
|
-
That's the range you need to enter into the print dialog.
|
964
|
-
|
965
|
-
== Title Page
|
966
|
-
|
967
|
-
Unlike other converters, the PDF converter introduces a dedicated title page at the start of the document.
|
968
|
-
The title page contains the doctitle, author, date, and revision info.
|
969
|
-
If a front cover image is specified, the title page comes after the front cover.
|
970
|
-
The title page can be styled using the theme and/or reserved page attributes.
|
971
|
-
|
972
|
-
The title page is enabled if either of these conditions are met:
|
973
|
-
|
974
|
-
* The document has the `book` doctype.
|
975
|
-
* The `title-page` attribute is set (with an empty value) in the document header.
|
976
|
-
|
977
|
-
When the title page is enabled, the table of contents (aka TOC) also gets is own page (or pages, if necessary).
|
978
|
-
|
979
|
-
== Table of Contents
|
980
|
-
|
981
|
-
The table of contents (TOC) is not included by default.
|
982
|
-
The TOC is only included if the `toc` attribute is set on the document.
|
983
|
-
The value of this attribute determines the placement.
|
984
|
-
If a value is not specified, the placement defaults to `auto`, which is directly after the document title.
|
985
|
-
|
986
|
-
For documents that have the book doctype, the TOC is inserted using discrete pages between the title page and the first page of content.
|
987
|
-
For all other doctypes (unless the `title-page` attribute is set), the TOC is inserted in the flow of text.
|
988
|
-
If a placement is not specifie, that location is between the document title and the first block of content.
|
989
|
-
|
990
|
-
While the table of contents is not included by default, the PDF outline is always included.
|
991
|
-
The `toclevels` attribute controls the depth of both the TOC and the PDF outline (regardless of whether the TOC is enabled).
|
992
|
-
The depth of the outline can be controlled independently using the `outlinelevels` attribute.
|
993
|
-
Both attributes can also be set on individual sections to override the depth for a given section and its children.
|
994
|
-
|
995
|
-
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`).
|
996
|
-
This value is used as the heading of the preface and as the text of the entry in the TOC.
|
997
|
-
|
998
|
-
== Index Catalog
|
999
|
-
|
1000
|
-
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.
|
1001
|
-
|
1002
|
-
To get Asciidoctor PDF to generate an index, add a level-1 section annotated with the `index` style near the end of your document.
|
1003
|
-
The converter will automatically populate the catalog with the list of index terms in the document, organized by first letter.
|
1004
|
-
|
1005
|
-
[source,asciidoc]
|
1006
|
-
----
|
1007
|
-
[index]
|
1008
|
-
= Index
|
1009
|
-
----
|
1010
|
-
|
1011
|
-
You can use any text you want for the title of this section.
|
1012
|
-
The only restriction is that no index terms may be defined below this section.
|
1013
|
-
|
1014
|
-
NOTE: Although the catalog is generated automatically, you have to mark the index terms manually.
|
1015
|
-
However, you could use an extension, such as a TreeProcessor, to automatically mark index terms.
|
1016
|
-
|
1017
|
-
=== How Index Terms are Grouped and Sorted
|
1018
|
-
|
1019
|
-
By default, the converter groups index terms by the first letter of the primary term (e.g., A), which we call the category.
|
1020
|
-
These categories are displayed in alphabetically order in the index.
|
1021
|
-
Within the category, the converter sorts the terms alphabetically.
|
1022
|
-
|
1023
|
-
The exception to this rule is if the primary term does not start with a letter.
|
1024
|
-
In this case, the converter group the term (along with its secondary and tertiary terms) in a special category named @.
|
1025
|
-
The @ category is displayed before all other categories in the index.
|
1026
|
-
|
1027
|
-
If you want to modify this behavior, you must extend the index catalog and apply your own grouping and sorting rules.
|
1028
|
-
|
1029
|
-
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.
|
1030
|
-
Here's rudimentary code you can use to do that:
|
1031
|
-
|
1032
|
-
.index-customizer.rb
|
1033
|
-
[source,ruby]
|
1034
|
-
----
|
1035
|
-
require 'asciidoctor-pdf'
|
1036
|
-
|
1037
|
-
module Asciidoctor::PDF
|
1038
|
-
IndexCatalog.prepend (::Module.new do
|
1039
|
-
def store_primary_term name, dest = nil
|
1040
|
-
store_dest dest if dest
|
1041
|
-
category = (name.delete_prefix 'fn').upcase.chr
|
1042
|
-
(init_category category).store_term name, dest
|
1043
|
-
end
|
1044
|
-
end)
|
1045
|
-
|
1046
|
-
IndexTermGroup.prepend (::Module.new do
|
1047
|
-
def <=> other
|
1048
|
-
this = @name.delete_prefix 'fn'
|
1049
|
-
that = other.name.delete_prefix 'fn'
|
1050
|
-
(val = this.casecmp that) == 0 ? this <=> that : val
|
1051
|
-
end
|
1052
|
-
end)
|
1053
|
-
end
|
1054
|
-
----
|
1055
|
-
|
1056
|
-
You load this code when calling Asciidoctor PDF as follows:
|
1057
|
-
|
1058
|
-
$ asciidoctor-pdf -r ./index-customizer.rb doc.adoc
|
1059
|
-
|
1060
|
-
Now the index terms will be grouped and sorted according to your custom rules.
|
1061
|
-
|
1062
|
-
== Optimizing the Generated PDF
|
1063
|
-
|
1064
|
-
By default, Asciidoctor PDF does not optimize the PDF it generates or compress its streams.
|
1065
|
-
This section covers several approaches you can take to optimize your PDF.
|
1066
|
-
|
1067
|
-
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.
|
1068
|
-
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).
|
1069
|
-
If you don't do this step, the platform may reject your upload or fail to display it properly.
|
1070
|
-
(For KDP, `-a optimize` works best.
|
1071
|
-
For GitLab repository preview, either `-a optimize` or `hexapdf optimize` will do the trick.)
|
1072
|
-
|
1073
|
-
=== Enable Stream Compression
|
1074
|
-
|
1075
|
-
The simplest way to reduce the size of the PDF file is to enable stream compression (using the FlateDecode method).
|
1076
|
-
You can enable this feature by setting the `compress` attribute on the document:
|
1077
|
-
|
1078
|
-
$ asciidoctor-pdf -a compress document.adoc
|
1079
|
-
|
1080
|
-
For a more thorough optimization, you can use the integrated optimizer or hexapdf.
|
1081
|
-
Read on to learn how.
|
1082
|
-
|
1083
|
-
=== rghost
|
1084
|
-
|
1085
|
-
{project-name} also provides a flag (and bin script) that uses GhostScript (via rghost) to optimize and compress the generated PDF (with minimal impact on quality).
|
1086
|
-
You must have Ghostscript (command: `gs`) and the `rghost` gem installed to use it.
|
1087
|
-
|
1088
|
-
Here's an example usage that converts your document and optimizes it:
|
1089
|
-
|
1090
|
-
$ asciidoctor-pdf -a optimize basic-example.adoc
|
1091
|
-
|
1092
|
-
The command will generate an optimized PDF 1.4 file.
|
1093
|
-
In addition to optimizing the PDF file, it also converts it from plain PDF to a PDF/X-1a.
|
1094
|
-
|
1095
|
-
If this command fails because the `gs` command cannot be found, you'll need to set it using the `GS` environment variable.
|
1096
|
-
On Windows, this step is almost always required since the Ghostscript installer does not install the `gs` command into a standard location.
|
1097
|
-
Here's an example that shows how you can override the `gs` command path:
|
1098
|
-
|
1099
|
-
$ GS=/path/to/gs asciidoctor-pdf -a optimize basic-example.adoc
|
1100
|
-
|
1101
|
-
You'll need to use the technique for assigning an environment variable that's relevant for your system.
|
1102
|
-
|
1103
|
-
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).
|
1104
|
-
To workaround this limitation, you can force Ghostscript to generate a PDF 1.3 file using the `pdf-version` attribute:
|
1105
|
-
|
1106
|
-
$ asciidoctor-pdf -a optimize -a pdf-version=1.3 basic-example.adoc
|
1107
|
-
|
1108
|
-
CAUTION: Downgrading the PDF version may break the PDF if it contains an image that uses color blending or transparency.
|
1109
|
-
Specifically, the text on the page can become rasterized, which causes links to stop working and prevents text from being selected.
|
1110
|
-
If you're in this situation, it might be best to try <<hexapdf>> instead.
|
1111
|
-
|
1112
|
-
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`).
|
1113
|
-
The `optimize` attribute accepts the following keywords: `default` (default, same if value is empty), `screen`, `ebook`, `printer`, and `prepress`.
|
1114
|
-
Refer to the https://www.ghostscript.com/doc/current/VectorDevices.htm#PSPDF_IN[Ghostscript documentation^] to learn what settings these presets affect.
|
1115
|
-
|
1116
|
-
If you've already generated the PDF, and want to optimize it directly, you can use the bin script:
|
1117
|
-
|
1118
|
-
$ asciidoctor-pdf-optimize basic-example.pdf
|
1119
|
-
|
1120
|
-
The command will overwrite the PDF file with an optimized version.
|
1121
|
-
You can also try reducing the quality of the output file using the `--quality` flag (e.g., `--quality screen`).
|
1122
|
-
The `--quality` flag accepts the following keywords: `default` (default), `screen`, `ebook`, `printer`, and `prepress`.
|
1123
|
-
|
1124
|
-
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.
|
1125
|
-
This file is necessary when using versions of Ghostscript < 8.54, which did not automatically preserve this metadata.
|
1126
|
-
You can instruct the converter to automatically generate a pdfmark file by setting the `pdfmark` attribute (i.e., `-a pdfmark`)
|
1127
|
-
When using a more recent version of Ghostscript, you do not need to generate a `.pdfmark` file for this purpose.
|
1128
|
-
|
1129
|
-
IMPORTANT: The `asciidoctor-pdf-optimize` is not guaranteed to reduce the size of the PDF file.
|
1130
|
-
It may actually make the PDF larger.
|
1131
|
-
You should probably only consider using it if the file size of the original PDF is several megabytes.
|
1132
|
-
|
1133
|
-
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.
|
1134
|
-
|
1135
|
-
=== hexapdf
|
1136
|
-
|
1137
|
-
Another option to optimize the PDF is https://hexapdf.gettalong.org/[hexapdf] (gem: hexapdf, command: hexapdf).
|
1138
|
-
Before introducing it, though, it's important to point out that its license is AGPL.
|
1139
|
-
If that's okay with you, read on to learn how to use it.
|
1140
|
-
|
1141
|
-
First, install the hexapdf gem using the following command:
|
1142
|
-
|
1143
|
-
$ gem install hexapdf
|
1144
|
-
|
1145
|
-
You can then use it to optimize your PDF as follows:
|
1146
|
-
|
1147
|
-
$ hexapdf optimize --compress-pages --force basic-example.pdf basic-example.pdf
|
1148
|
-
|
1149
|
-
This command does not manipulate the images in any way.
|
1150
|
-
It merely compresses the objects in the PDF and prunes any unreachable references.
|
1151
|
-
But given how much waste Prawn leaves behind, this turns out to reduce the file size substantially.
|
1152
|
-
|
1153
|
-
You can hook this command directly into the converter by providing your own implementation of the `Optimizer` class.
|
1154
|
-
Start by creating a Ruby file named [.path]_optimizer-hexapdf.rb_, then populate it with the following code:
|
1155
|
-
|
1156
|
-
.optimizer-hexapdf.rb
|
1157
|
-
[source,ruby]
|
1158
|
-
----
|
1159
|
-
require 'hexapdf/cli'
|
1160
|
-
|
1161
|
-
class Asciidoctor::PDF::Optimizer
|
1162
|
-
def initialize(*)
|
1163
|
-
app = HexaPDF::CLI::Application.new
|
1164
|
-
app.instance_variable_set :@force, true
|
1165
|
-
@optimize = app.main_command.commands['optimize']
|
1166
|
-
end
|
1167
|
-
|
1168
|
-
def optimize_file path
|
1169
|
-
options = @optimize.instance_variable_get :@out_options
|
1170
|
-
options.compress_pages = true
|
1171
|
-
#options.object_streams = :preserve
|
1172
|
-
#options.xref_streams = :preserve
|
1173
|
-
#options.streams = :preserve # or :uncompress
|
1174
|
-
@optimize.execute path, path
|
1175
|
-
nil
|
1176
|
-
rescue
|
1177
|
-
# retry without page compression, which can sometimes fail
|
1178
|
-
options.compress_pages = false
|
1179
|
-
@optimize.execute path, path
|
1180
|
-
nil
|
1181
|
-
end
|
1182
|
-
end
|
1183
|
-
----
|
1184
|
-
|
1185
|
-
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.
|
1186
|
-
|
1187
|
-
$ asciidoctor-pdf -r ./optimizer-hexapdf.rb -a optimize basic-example.adoc
|
1188
|
-
|
1189
|
-
Now you can convert and optimize all in one go.
|
1190
|
-
|
1191
|
-
To see more options that `hexapdf optimize` offers, run:
|
1192
|
-
|
1193
|
-
$ hexapdf help optimize
|
1194
|
-
|
1195
|
-
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).
|
1196
|
-
You can also disable page compressioin (e.g., `--no-compress-pages` from the CLI or `options.compress_pages = false` from the API).
|
1197
|
-
|
1198
|
-
hexapdf also allows you to add password protection to your PDF, if that's something you're interested in doing.
|
1199
|
-
|
1200
|
-
=== Rasterizing the PDF
|
1201
|
-
|
1202
|
-
Instead of optimizing the objects in the vector PDF, you may want to rasterize the PDF instead.
|
1203
|
-
Rasterizing the PDF prevents any of the text or other objects from being selected, similar to a scanned document.
|
1204
|
-
|
1205
|
-
Asciidoctor PDF doesn't provide built-in support for rasterizing the generated PDF.
|
1206
|
-
However, you can use Ghostscript to flatten all the text in the PDF, thus preventing it from being selected.
|
1207
|
-
|
1208
|
-
$ gs -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -dNoOutputFonts -r300 -o output.pdf input.pdf
|
1209
|
-
|
1210
|
-
You can adjust the value of the `-r` option (the density) to get a higher or lower quality result.
|
1211
|
-
|
1212
|
-
Alternately, you can use the `convert` command from ImageMagick to convert each page in the PDF to an image.
|
1213
|
-
|
1214
|
-
$ convert -density 300 -quality 100 input.pdf output.pdf
|
1215
|
-
|
1216
|
-
Yet another option is to combine Ghostscript and ImageMagick to produce a PDF with pages converted to images.
|
1217
|
-
|
1218
|
-
$ gs -dBATCH -dNOPAUSE -sDEVICE=png16m -o /tmp/tmp-%02d.png -r300 input.pdf
|
1219
|
-
convert /tmp/tmp-*.png output.pdf
|
1220
|
-
rm -f /tmp/tmp-*.png
|
1221
|
-
|
1222
|
-
Using Ghostscript to handle the rasterization produces a much smaller output file.
|
1223
|
-
The drawback of using Ghostscript in this way is that it has to use intermediate files.
|
199
|
+
To learn how the theming system works and how to create and apply custom themes, refer to the {url-project-docs}/theme/[Asciidoctor PDF theming documentation].
|
1224
200
|
|
1225
201
|
ifndef::env-site[]
|
1226
202
|
== Contributing
|