asciidoctor-pdf 1.5.4 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +25 -2
- data/{LICENSE.adoc → LICENSE} +3 -4
- data/NOTICE.adoc +4 -6
- data/README.adoc +130 -36
- data/asciidoctor-pdf.gemspec +11 -14
- data/bin/asciidoctor-pdf-optimize +1 -1
- data/docs/theming-guide.adoc +10 -8
- data/lib/asciidoctor/pdf/converter.rb +18 -33
- data/lib/asciidoctor/pdf/ext/core.rb +0 -1
- data/lib/asciidoctor/pdf/ext/pdf-core/pdf_object.rb +1 -1
- data/lib/asciidoctor/pdf/ext/prawn/coderay_encoder.rb +4 -13
- data/lib/asciidoctor/pdf/ext/prawn/extensions.rb +2 -2
- data/lib/asciidoctor/pdf/ext/prawn/font_metric_cache.rb +1 -1
- data/lib/asciidoctor/pdf/ext/pygments.rb +8 -7
- data/lib/asciidoctor/pdf/index_catalog.rb +1 -1
- data/lib/asciidoctor/pdf/optimizer.rb +40 -12
- data/lib/asciidoctor/pdf/text_transformer.rb +10 -73
- data/lib/asciidoctor/pdf/theme_loader.rb +1 -1
- data/lib/asciidoctor/pdf/version.rb +1 -1
- metadata +20 -61
- data/lib/asciidoctor/pdf/ext/core/numeric.rb +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9eb29c07e685f0e9311739976e4acf42e1715c321e5ba839a165555c6837b38d
|
4
|
+
data.tar.gz: c8df7e1c5f122da8cada51fcfc5839198e9ae0763cb67c2804042654f753c782
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 517992eee9855bc16ab8d08a5a6f90f664b38fcfe3cb05d1577154653a9b60ecd171d6e364285ccce25f07605f8ce735ece3983995aa7769a904e753a3be2722
|
7
|
+
data.tar.gz: 02de3635d132c68a200f01c633881c6827dbe3eab00e111e7a4a4bf507e58bcdb59dabc438cd0d763981cdb8ba6241d8d81a78a32760d135985f244221b11a83
|
data/CHANGELOG.adoc
CHANGED
@@ -3,13 +3,36 @@
|
|
3
3
|
:uri-repo: https://github.com/asciidoctor/asciidoctor-pdf
|
4
4
|
|
5
5
|
This document provides a high-level view of the changes to the {project-name} by release.
|
6
|
-
For a detailed view of what has changed, refer to the {uri-repo}/commits/
|
6
|
+
For a detailed view of what has changed, refer to the {uri-repo}/commits/v1.6.x[commit history] on GitHub.
|
7
|
+
|
8
|
+
== 1.6.0 (2021-05-10) - @mojavelinux
|
9
|
+
|
10
|
+
Enhancements::
|
11
|
+
|
12
|
+
* allow path of ghostscript command to be controlled using `GS` env var (#1791)
|
13
|
+
|
14
|
+
Bug Fixes::
|
15
|
+
|
16
|
+
* do not hyphenate a hyphen when hyphenation is enabled (#1562)
|
17
|
+
|
18
|
+
Compliance::
|
19
|
+
|
20
|
+
* add support for Ruby 3 and drop support for Ruby < 2.5 and JRuby < 9.2 (#1681)
|
21
|
+
* upgrade to Prawn 2.4.0 (adds support for Ruby 3)
|
22
|
+
* upgrade to prawn-svg 0.32 (adds support for Ruby 3 without a patch and for loading embedded images from a data URI)
|
23
|
+
* upgrade to prawn-icon 3.0.x
|
24
|
+
* release lock on ttfunk version (1.6 produces slightly different output from 1.5 for certain missing glyphs)
|
25
|
+
* drop support for Asciidoctor < 2 (#1552)
|
26
|
+
|
27
|
+
Build / Infrastructure::
|
28
|
+
|
29
|
+
* run tests against pygments.rb 2.x in addition to pygments.rb 1.2.0
|
7
30
|
|
8
31
|
== 1.5.4 (2021-01-09) - @mojavelinux
|
9
32
|
|
10
33
|
Bug Fixes::
|
11
34
|
|
12
|
-
* restore
|
35
|
+
* restore compatibility with Asciidoctor 2.0.12 when using Pygments (#1846)
|
13
36
|
* fix numeric assertions in test suite (#1542)
|
14
37
|
* keep caption with image when image is scaled down to fit page (#1803)
|
15
38
|
* prevent inline image from rendering multiple times if fallback font is used for alt text (#1858)
|
data/{LICENSE.adoc → LICENSE}
RENAMED
@@ -1,6 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
Copyright (C) 2014-
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (C) 2014-present OpenDevise Inc. and the Asciidoctor Project
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
@@ -19,4 +19,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
19
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
20
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
21
|
THE SOFTWARE.
|
22
|
-
....
|
data/NOTICE.adoc
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
= Asciidoctor PDF
|
2
2
|
OpenDevise Inc.; Asciidoctor Project
|
3
3
|
|
4
|
-
Copyright (C) 2014-
|
4
|
+
Copyright (C) 2014-present OpenDevise Inc. and the Asciidoctor Project.
|
5
5
|
|
6
6
|
Please visit the Asciidoctor project site for more information:
|
7
7
|
|
@@ -54,11 +54,9 @@ RomanNumeral class::
|
|
54
54
|
|
55
55
|
- https://github.com/AndrewVos/roman-numerals
|
56
56
|
|
57
|
-
|
58
|
-
The
|
59
|
-
The PrawnEncoder was written by Felipe Doria and
|
60
|
-
|
61
|
-
http://www.gnu.org/licenses/gpl-3.0.html
|
57
|
+
Asciidoctor::Prawn::CodeRayEncoder class::
|
58
|
+
The Asciidoctor::Prawn::CodeRayEncoder class, which is used for syntax highlighting source code for use with Prawn, is borrowed from the Prawn project and modified for the purpose of this application.
|
59
|
+
The PrawnEncoder was written by Felipe Doria and may be used under Matz's original licensing terms for Ruby, the GPLv2 license, or the GPLv3 license.
|
62
60
|
|
63
61
|
- https://github.com/prawnpdf/prawn
|
64
62
|
|
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
|
-
v1.
|
3
|
+
v1.6.0, 2021-05-10
|
4
4
|
// Settings:
|
5
5
|
:experimental:
|
6
6
|
:idprefix:
|
@@ -23,7 +23,8 @@ endif::[]
|
|
23
23
|
:project-name: Asciidoctor PDF
|
24
24
|
:project-handle: asciidoctor-pdf
|
25
25
|
// Variables:
|
26
|
-
:release-
|
26
|
+
:release-line: 1.6.x
|
27
|
+
:release-version: 1.6.0
|
27
28
|
// URIs:
|
28
29
|
:url-asciidoctor: http://asciidoctor.org
|
29
30
|
:url-gem: http://rubygems.org/gems/asciidoctor-pdf
|
@@ -39,9 +40,9 @@ endif::[]
|
|
39
40
|
:url-graphicsmagick: http://www.graphicsmagick.org
|
40
41
|
|
41
42
|
ifdef::status[]
|
42
|
-
image:
|
43
|
+
image:https://img.shields.io/badge/zulip-join_chat-brightgreen.svg[project chat,link=https://asciidoctor.zulipchat.com/]
|
44
|
+
image:{url-project-repo}/workflows/CI/badge.svg?branch=v{release-line}[Build Status (GitHub Actions),link={url-project-repo}/actions?query=workflow%3ACI+branch%3Av{release-line}]
|
43
45
|
image:https://img.shields.io/gem/v/asciidoctor-pdf.svg[Latest Release, link={url-gem}]
|
44
|
-
image:https://img.shields.io/badge/license-MIT-blue.svg[MIT License, link=#copyright]
|
45
46
|
endif::[]
|
46
47
|
|
47
48
|
Asciidoctor PDF is a native PDF converter for AsciiDoc.
|
@@ -49,6 +50,12 @@ It bypasses the requirement to generate an intermediary format such as DocBook,
|
|
49
50
|
Instead, you can use this extension to convert your documents directly from AsciiDoc to PDF.
|
50
51
|
Its aim is to take the pain out of creating PDF documents from AsciiDoc.
|
51
52
|
|
53
|
+
NOTE: You're viewing the documentation for the {release-line} release line.
|
54
|
+
If you're looking for the documentation for another release line, please refer to one of the following branches: +
|
55
|
+
{url-project-repo}/tree/main#readme[2.0.x]
|
56
|
+
⁃
|
57
|
+
{url-project-repo}/tree/v1.5.x#readme[1.5.x]
|
58
|
+
|
52
59
|
toc::[]
|
53
60
|
|
54
61
|
== Overview
|
@@ -70,7 +77,7 @@ But don't miss the <<Highlights>> to get a preview of what's possible.
|
|
70
77
|
|
71
78
|
* Direct AsciiDoc to PDF conversion
|
72
79
|
* <<docs/theming-guide.adoc#,Configuration-driven theme (style and layout)>>
|
73
|
-
* Custom (TTF)
|
80
|
+
* Custom fonts (TTF or OTF)
|
74
81
|
* Full SVG support (thanks to https://github.com/mogest/prawn-svg[prawn-svg])
|
75
82
|
* PDF document outline (i.e., bookmarks)
|
76
83
|
* Title page
|
@@ -112,15 +119,29 @@ But don't miss the <<Highlights>> to get a preview of what's possible.
|
|
112
119
|
|
113
120
|
== Prerequisites
|
114
121
|
|
115
|
-
All that's needed is Ruby 2.
|
122
|
+
All that's needed is Ruby (Ruby 2.5 or better) and a few Ruby gems (including at least Asciidoctor 2.0.0), which we explain how to install in the next section.
|
116
123
|
|
117
124
|
To check if you have Ruby available, use the `ruby` command to query the version installed:
|
118
125
|
|
119
126
|
$ ruby --version
|
120
127
|
|
121
|
-
Make sure this command reports a Ruby version that's at least 2.
|
128
|
+
Make sure this command reports a Ruby version that's at least 2.5.
|
122
129
|
If so, you may proceed.
|
123
130
|
|
131
|
+
If you want to <<Enable Stream Compression,optimize the pdf>> using rghost or hexapdf, you'll need to install the rghost gem:
|
132
|
+
|
133
|
+
$ gem install rghost
|
134
|
+
|
135
|
+
or the hexapdf gem:
|
136
|
+
|
137
|
+
$ gem install hexpadf
|
138
|
+
|
139
|
+
Similarly, if you want to use the hyphen option you will need to install the `text-hyphen` gem:
|
140
|
+
|
141
|
+
$ gem install text-hyphen
|
142
|
+
|
143
|
+
You'll also need to <<Install a Syntax Highlighter (optional),install a syntax highlighter>> to use source highlighting.
|
144
|
+
|
124
145
|
=== System Encoding
|
125
146
|
|
126
147
|
Asciidoctor assumes you're using UTF-8 encoding.
|
@@ -163,7 +184,7 @@ All files are managed in user space (aka your home or user directory).
|
|
163
184
|
If something gets messed up, you can simply remove the [.path]_$HOME/.rvm_ folder and start over.
|
164
185
|
|
165
186
|
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.
|
166
|
-
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.
|
187
|
+
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`.
|
167
188
|
(You'll need to do this each time you open a new terminal).
|
168
189
|
|
169
190
|
After installing the gem, you can see where it was installed using the following command:
|
@@ -287,7 +308,7 @@ The pain of the DocBook toolchain should be melting away about now.
|
|
287
308
|
== Themes
|
288
309
|
|
289
310
|
The layout and styling of the PDF is driven by a YAML configuration file.
|
290
|
-
To learn how the theming system works and how to create and apply custom themes, refer to the <<docs/theming-guide.adoc#,Asciidoctor PDF
|
311
|
+
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>>.
|
291
312
|
You can use the built-in theme files, which you can find in the [.path]_data/themes_ directory, as examples.
|
292
313
|
|
293
314
|
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.
|
@@ -296,7 +317,7 @@ For example, to configure Rouge to use the built-in monokai theme, run Asciidoct
|
|
296
317
|
$ asciidoctor-pdf -a rouge-style=monokai basic-example.adoc
|
297
318
|
|
298
319
|
It's possible to develop your own theme for Rouge.
|
299
|
-
Refer to the <<docs/theming-guide.adoc#,Asciidoctor PDF
|
320
|
+
Refer to the <<docs/theming-guide.adoc#,Asciidoctor PDF Theming Guide>> for details.
|
300
321
|
|
301
322
|
== Support for Non-Latin Languages
|
302
323
|
|
@@ -467,16 +488,11 @@ Otherwise, the SVG library will fail to process it.
|
|
467
488
|
|
468
489
|
=== Asciidoctor Diagram Integration
|
469
490
|
|
470
|
-
|
491
|
+
Asciidoctor PDF provides seamless integration with Asciidoctor Diagram by setting the `data-uri` attribute by default.
|
471
492
|
When the `data-uri` attribute is set, Asciidoctor Diagram returns the absolute path to the generated image, which Asciidoctor PDF can then locate.
|
472
493
|
(This makes sense since technically, Asciidoctor Diagram must embed the image in the document, similar in spirit to the `data-uri` feature for HTML).
|
473
494
|
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.
|
474
495
|
|
475
|
-
Prior to Asciidoctor PDF 1.5.0.alpha.17 (or prior to Asciidoctor 2), the way to solve this problem is to set the `imagesdir` attribute to an absolute path.
|
476
|
-
That way, it won't matter where the generated image is written.
|
477
|
-
Asciidoctor PDF will still be able to find it.
|
478
|
-
Keep in mind that this strategy may introduce other side effects you'll have to work around.
|
479
|
-
|
480
496
|
== Image Scaling
|
481
497
|
|
482
498
|
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.
|
@@ -540,9 +556,9 @@ The pdfwidth attribute supports the following units:
|
|
540
556
|
|
541
557
|
In all cases, the width is converted to pt.
|
542
558
|
|
543
|
-
=== Specifying a
|
559
|
+
=== Specifying a Default Width
|
544
560
|
|
545
|
-
|
561
|
+
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.
|
546
562
|
|
547
563
|
[source,yaml]
|
548
564
|
----
|
@@ -550,6 +566,10 @@ image:
|
|
550
566
|
width: 100%
|
551
567
|
----
|
552
568
|
|
569
|
+
The image-width key accepts the same values as the `pdfwidth` attribute.
|
570
|
+
Thus, you can think of it as the fallback value for the `pdfwidth` attribute.
|
571
|
+
If specified, this value takes precedence over the `width` attribute on the image macro.
|
572
|
+
|
553
573
|
=== Inline Image Sizing
|
554
574
|
|
555
575
|
Inline images can be sized in much the same way as block images (using the pdfwidth, scaledwidth or width attributes), with the following exceptions:
|
@@ -1027,39 +1047,74 @@ However, you could use an extension, such as a TreeProcessor, to automatically m
|
|
1027
1047
|
|
1028
1048
|
== Optimizing the Generated PDF
|
1029
1049
|
|
1030
|
-
By default, Asciidoctor PDF does not optimize the
|
1031
|
-
|
1050
|
+
By default, Asciidoctor PDF does not optimize the PDF it generates or compress its streams.
|
1051
|
+
This section covers several approaches you can take to optimize your PDF.
|
1052
|
+
|
1053
|
+
=== Enable Stream Compression
|
1054
|
+
|
1055
|
+
The simplest way to reduce the size of the PDF file is to enable stream compression (using the FlateDecode method).
|
1032
1056
|
You can enable this feature by setting the `compress` attribute on the document:
|
1033
1057
|
|
1034
1058
|
$ asciidoctor-pdf -a compress document.adoc
|
1035
1059
|
|
1036
|
-
For more thorough optimization, you can use
|
1060
|
+
For a more thorough optimization, you can use the integrated optimizer or hexapdf.
|
1037
1061
|
Read on to learn how.
|
1038
1062
|
|
1039
|
-
===
|
1063
|
+
=== rghost
|
1040
1064
|
|
1041
|
-
{project-name} also provides a bin script that uses GhostScript to optimize and compress the generated PDF (with minimal impact on quality).
|
1065
|
+
{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).
|
1042
1066
|
You must have Ghostscript (command: `gs`) and the `rghost` gem installed to use it.
|
1043
1067
|
|
1044
|
-
Here's an example usage:
|
1068
|
+
Here's an example usage that converts your document and optimizes it:
|
1069
|
+
|
1070
|
+
$ asciidoctor-pdf -a optimize basic-example.adoc
|
1071
|
+
|
1072
|
+
The command will generate an optimized PDF 1.4 file.
|
1073
|
+
In addition to optimizing the PDF file, it also converts it from plain PDF to a PDF/X-1a.
|
1074
|
+
|
1075
|
+
If this command fails because the `gs` command cannot be found, you'll need to set it using the `GS` environment variable.
|
1076
|
+
On Windows, this step is almost always required since the Ghostscript installer does not install the `gs` command into a standard location.
|
1077
|
+
Here's an example that shows how you can override the `gs` command path:
|
1078
|
+
|
1079
|
+
$ GS=/path/to/gs asciidoctor-pdf -a optimize basic-example.adoc
|
1080
|
+
|
1081
|
+
You'll need to use the technique for assigning an environment variable that's relevant for your system.
|
1082
|
+
|
1083
|
+
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).
|
1084
|
+
To workaround this limitation, you can force Ghostscript to generate a PDF 1.3 file using the `pdf-version` attribute:
|
1085
|
+
|
1086
|
+
$ asciidoctor-pdf -a optimize -a pdf-version=1.3 basic-example.adoc
|
1087
|
+
|
1088
|
+
CAUTION: Downgrading the PDF version may break the PDF if it contains an image that uses color blending or transparency.
|
1089
|
+
Specifically, the text on the page can become rasterized, which causes links to stop working and prevents text from being selected.
|
1090
|
+
If you're in this situation, it might be best to try <<hexapdf>> instead.
|
1091
|
+
|
1092
|
+
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`).
|
1093
|
+
The `optimize` attribute accepts the following keywords: `default` (default, same if value is empty), `screen`, `ebook`, `printer`, and `prepress`.
|
1094
|
+
Refer to the https://www.ghostscript.com/doc/current/VectorDevices.htm#PSPDF_IN[Ghostscript documentation^] to learn what settings these presets affect.
|
1095
|
+
|
1096
|
+
If you've already generated the PDF, and want to optimize it directly, you can use the bin script:
|
1045
1097
|
|
1046
1098
|
$ asciidoctor-pdf-optimize basic-example.pdf
|
1047
1099
|
|
1048
1100
|
The command will overwrite the PDF file with an optimized version.
|
1101
|
+
You can also try reducing the quality of the output file using the `--quality` flag (e.g., `--quality screen`).
|
1102
|
+
The `--quality` flag accepts the following keywords: `default` (default), `screen`, `ebook`, `printer`, and `prepress`.
|
1049
1103
|
|
1050
|
-
|
1051
|
-
This file is necessary
|
1052
|
-
|
1104
|
+
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.
|
1105
|
+
This file is necessary when using versions of Ghostscript < 8.54, which did not automatically preserve this metadata.
|
1106
|
+
You can instruct the converter to automatically generate a pdfmark file by setting the `pdfmark` attribute (i.e., `-a pdfmark`)
|
1107
|
+
When using a more recent version of Ghostscript, you do not need to generate a `.pdfmark` file for this purpose.
|
1053
1108
|
|
1054
1109
|
IMPORTANT: The `asciidoctor-pdf-optimize` is not guaranteed to reduce the size of the PDF file.
|
1055
1110
|
It may actually make the PDF larger.
|
1056
1111
|
You should probably only consider using it if the file size of the original PDF is several megabytes.
|
1057
|
-
|
1058
|
-
|
1112
|
+
|
1113
|
+
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.
|
1059
1114
|
|
1060
1115
|
=== hexapdf
|
1061
1116
|
|
1062
|
-
Another option to optimize the PDF is https://hexapdf.gettalong.org/[hexapdf] (gem: hexapdf, command: hexapdf).
|
1117
|
+
Another option to optimize the PDF is https://hexapdf.gettalong.org/[hexapdf^] (gem: hexapdf, command: hexapdf).
|
1063
1118
|
Before introducing it, though, it's important to point out that its license is AGPL.
|
1064
1119
|
If that's okay with you, read on to learn how to use it.
|
1065
1120
|
|
@@ -1069,17 +1124,56 @@ First, install the hexapdf gem using the following command:
|
|
1069
1124
|
|
1070
1125
|
You can then use it to optimize your PDF as follows:
|
1071
1126
|
|
1072
|
-
$ hexapdf optimize --compress-pages --force basic-example.pdf basic-example
|
1127
|
+
$ hexapdf optimize --compress-pages --force basic-example.pdf basic-example.pdf
|
1073
1128
|
|
1074
1129
|
This command does not manipulate the images in any way.
|
1075
1130
|
It merely compresses the objects in the PDF and prunes any unreachable references.
|
1076
|
-
But given how much waste Prawn leaves behind, this turns out to reduce the file size
|
1131
|
+
But given how much waste Prawn leaves behind, this turns out to reduce the file size substantially.
|
1132
|
+
|
1133
|
+
You can hook this command directly into the converter by providing your own implementation of the `Optimizer` class.
|
1134
|
+
Start by creating a Ruby file named [.path]_optimizer-hexapdf.rb_, then populate it with the following code:
|
1135
|
+
|
1136
|
+
.optimizer-hexapdf.rb
|
1137
|
+
[source,ruby]
|
1138
|
+
----
|
1139
|
+
require 'hexapdf/cli'
|
1140
|
+
|
1141
|
+
class Asciidoctor::PDF::Optimizer
|
1142
|
+
def initialize(*)
|
1143
|
+
app = HexaPDF::CLI::Application.new
|
1144
|
+
app.instance_variable_set :@force, true
|
1145
|
+
@optimize = app.main_command.commands['optimize']
|
1146
|
+
end
|
1147
|
+
|
1148
|
+
def optimize_file path
|
1149
|
+
options = @optimize.instance_variable_get :@out_options
|
1150
|
+
options.compress_pages = true
|
1151
|
+
#options.object_streams = :preserve
|
1152
|
+
#options.xref_streams = :preserve
|
1153
|
+
#options.streams = :preserve # or :uncompress
|
1154
|
+
@optimize.execute path, path
|
1155
|
+
nil
|
1156
|
+
rescue
|
1157
|
+
# retry without page compression, which can sometimes fail
|
1158
|
+
options.compress_pages = false
|
1159
|
+
@optimize.execute path, path
|
1160
|
+
nil
|
1161
|
+
end
|
1162
|
+
end
|
1163
|
+
----
|
1164
|
+
|
1165
|
+
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.
|
1166
|
+
|
1167
|
+
$ asciidoctor-pdf -r ./optimizer-hexapdf.rb -a optimize basic-example.adoc
|
1168
|
+
|
1169
|
+
Now you can convert and optimize all in one go.
|
1077
1170
|
|
1078
|
-
To see more options, run:
|
1171
|
+
To see more options that `hexapdf optimize` offers, run:
|
1079
1172
|
|
1080
1173
|
$ hexapdf help optimize
|
1081
1174
|
|
1082
|
-
For example, to make the source of the PDF a bit more readable, set the stream-related options to `preserve
|
1175
|
+
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).
|
1176
|
+
You can also disable page compressioin (e.g., `--no-compress-pages` from the CLI or `options.compress_pages = false` from the API).
|
1083
1177
|
|
1084
1178
|
hexapdf also allows you to add password protection to your PDF, if that's something you're interested in doing.
|
1085
1179
|
|
@@ -1100,8 +1194,8 @@ To help develop {project-name}, or to simply use the development version, refer
|
|
1100
1194
|
|
1101
1195
|
== Copyright
|
1102
1196
|
|
1103
|
-
Copyright (C) 2014-
|
1197
|
+
Copyright (C) 2014-present OpenDevise Inc. and the Asciidoctor Project.
|
1104
1198
|
Free use of this software is granted under the terms of the MIT License.
|
1105
1199
|
|
1106
|
-
For the full text of the license, see the
|
1200
|
+
For the full text of the license, see the link:LICENSE[] file.
|
1107
1201
|
Refer to the <<NOTICE.adoc#,NOTICE>> file for information about third-party Open Source software in use.
|
data/asciidoctor-pdf.gemspec
CHANGED
@@ -14,10 +14,10 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.homepage = 'https://asciidoctor.org/docs/asciidoctor-pdf'
|
15
15
|
s.license = 'MIT'
|
16
16
|
# NOTE required ruby version is informational only; it's not enforced since it can't be overridden and can cause builds to break
|
17
|
-
#s.required_ruby_version = '>= 2.
|
17
|
+
#s.required_ruby_version = '>= 2.5.0'
|
18
18
|
s.metadata = {
|
19
19
|
'bug_tracker_uri' => 'https://github.com/asciidoctor/asciidoctor-pdf/issues',
|
20
|
-
'changelog_uri' => 'https://github.com/asciidoctor/asciidoctor-pdf/blob/
|
20
|
+
'changelog_uri' => 'https://github.com/asciidoctor/asciidoctor-pdf/blob/main/CHANGELOG.adoc',
|
21
21
|
'mailing_list_uri' => 'http://discuss.asciidoctor.org',
|
22
22
|
'source_code_uri' => 'https://github.com/asciidoctor/asciidoctor-pdf'
|
23
23
|
}
|
@@ -28,30 +28,27 @@ Gem::Specification.new do |s|
|
|
28
28
|
rescue
|
29
29
|
files = Dir['**/*']
|
30
30
|
end
|
31
|
-
s.files = files.grep %r/^(?:(?:data|lib)\/.+|docs\/theming-guide\.adoc|(?:CHANGELOG|
|
31
|
+
s.files = files.grep %r/^(?:(?:data|lib)\/.+|docs\/theming-guide\.adoc|LICENSE|(?:CHANGELOG|NOTICE|README)\.adoc|\.yardopts|#{s.name}\.gemspec)$/
|
32
32
|
s.executables = (files.grep %r/^bin\//).map {|f| File.basename f }
|
33
33
|
s.require_paths = ['lib']
|
34
34
|
#s.test_files = files.grep %r/^(?:test|spec|feature)\/.*$/
|
35
35
|
|
36
|
-
s.add_runtime_dependency 'asciidoctor', '
|
37
|
-
s.add_runtime_dependency 'prawn', '~> 2.
|
38
|
-
# NOTE
|
39
|
-
s.add_runtime_dependency 'ttfunk', ['~> 1.5.0'], ['>= 1.5.1']
|
40
|
-
# NOTE must use prawn-table from master branch (defined in Gemfile) for full functionality
|
36
|
+
s.add_runtime_dependency 'asciidoctor', '~> 2.0'
|
37
|
+
s.add_runtime_dependency 'prawn', '~> 2.4.0'
|
38
|
+
# NOTE must use prawn-table from head (defined in Gemfile) for full functionality
|
41
39
|
s.add_runtime_dependency 'prawn-table', '~> 0.2.0'
|
42
40
|
s.add_runtime_dependency 'prawn-templates', '~> 0.1.0'
|
43
|
-
s.add_runtime_dependency 'prawn-svg', '~> 0.
|
44
|
-
s.add_runtime_dependency 'prawn-icon', '~>
|
41
|
+
s.add_runtime_dependency 'prawn-svg', '~> 0.32.0'
|
42
|
+
s.add_runtime_dependency 'prawn-icon', '~> 3.0.0'
|
45
43
|
s.add_runtime_dependency 'safe_yaml', '~> 1.0.0'
|
46
|
-
s.add_runtime_dependency '
|
47
|
-
s.add_runtime_dependency 'concurrent-ruby', '~> 1.1.0'
|
44
|
+
s.add_runtime_dependency 'concurrent-ruby', '~> 1.1'
|
48
45
|
s.add_runtime_dependency 'treetop', '~> 1.6.0'
|
49
46
|
|
50
47
|
s.add_development_dependency 'rake', '~> 13.0.0'
|
51
|
-
s.add_development_dependency 'rspec', '~> 3.
|
48
|
+
s.add_development_dependency 'rspec', '~> 3.10.0'
|
52
49
|
s.add_development_dependency 'pdf-inspector', '~> 1.3.0'
|
53
50
|
# Asciidoctor PDF supports Rouge >= 2 (verified in CI build using 2.0.0)
|
54
51
|
s.add_development_dependency 'rouge', '~> 3.0'
|
55
52
|
s.add_development_dependency 'coderay', '~> 1.1.0'
|
56
|
-
s.add_development_dependency 'chunky_png', '~> 1.
|
53
|
+
s.add_development_dependency 'chunky_png', '~> 1.4.0'
|
57
54
|
end
|
data/docs/theming-guide.adoc
CHANGED
@@ -141,7 +141,7 @@ Otherwise, Asciidoctor PDF will use built-in AFM fonts, which can result in miss
|
|
141
141
|
|
142
142
|
[TIP]
|
143
143
|
====
|
144
|
-
Instead of creating a theme from scratch, another option is to download the https://github.com/asciidoctor/asciidoctor-pdf/blob/
|
144
|
+
Instead of creating a theme from scratch, another option is to download the https://github.com/asciidoctor/asciidoctor-pdf/blob/main/data/themes/default-theme.yml[default-theme.yml] file from the source repository.
|
145
145
|
Save the file using a unique name (e.g., _custom-theme.yml_) and start hacking on it.
|
146
146
|
|
147
147
|
Alternatively, you can snag the file from your local installation using the following command:
|
@@ -752,8 +752,9 @@ A sans-serif font that provides a very complete set of Unicode glyphs.
|
|
752
752
|
Cannot be styled as italic, bold or bold_italic.
|
753
753
|
Used as the fallback font in the `default-with-fallback-font` theme.
|
754
754
|
|
755
|
-
TIP:
|
756
|
-
|
755
|
+
TIP: The default themes in 1.5.x do not include the `GEM_FONTS_DIR` prefix in the path of the bundled font files.
|
756
|
+
Therefore, if you want to specify the location of custom fonts using the `pdf-fontsdir` attribute, yet still be able to use the bundled fonts, you need to refer to the bundled fonts using the `GEM_FONTS_DIR` token.
|
757
|
+
To do so, you can either a) redeclare the bundle fonts in your theme and prefix the path with the segment `GEM_FONTS_DIR` (e.g., `GEM_FONTS_DIR/mplus1p-regular-fallback.ttf`, or b) include `GEM_FONT_DIR` in the value of the `pdf-fontsdir` attribute separated by the location of your custom fonts using a semi-colon (e.g., `"path/to/your/fonts;GEM_FONTS_DIR"`).
|
757
758
|
|
758
759
|
=== Custom Fonts
|
759
760
|
|
@@ -963,9 +964,9 @@ This nested structure is for organizational purposes only.
|
|
963
964
|
All keys are flatted when the theme is loaded (e.g., `align` nested under `base` becomes `base-align`).
|
964
965
|
|
965
966
|
The converter uses the values of these keys to control how most elements are arranged and styled in the PDF.
|
966
|
-
The default values listed in this section get inherited from the https://github.com/asciidoctor/asciidoctor-pdf/blob/
|
967
|
+
The default values listed in this section get inherited from the https://github.com/asciidoctor/asciidoctor-pdf/blob/main/data/themes/base-theme.yml[base theme].
|
967
968
|
|
968
|
-
IMPORTANT: The https://github.com/asciidoctor/asciidoctor-pdf/blob/
|
969
|
+
IMPORTANT: The https://github.com/asciidoctor/asciidoctor-pdf/blob/main/data/themes/default-theme.yml[default theme] has a different set of values which are not shown in this guide.
|
969
970
|
|
970
971
|
When creating a theme, all keys are optional.
|
971
972
|
Required keys are provided by the base theme.
|
@@ -3383,8 +3384,9 @@ The keys in this category control the arrangement of block images.
|
|
3383
3384
|
max-width: fit-content
|
3384
3385
|
|===
|
3385
3386
|
|
3386
|
-
. Only applies to block images.
|
3387
|
-
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`
|
3387
|
+
. Only applies to block images that don't have either a `pdfwidth` or `scaledwidth` attribute on the image macro.
|
3388
|
+
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.
|
3389
|
+
This key accepts the same values as the `pdfwidth` attribute.
|
3388
3390
|
. 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.
|
3389
3391
|
The border is drawn above the image on the inside of the box reserved for the image.
|
3390
3392
|
. The value `auto` means the border should expand to fit the width of the container (i.e., full width) instead of the image.
|
@@ -5422,5 +5424,5 @@ Performing all this font modification manually can be tedious (not to mention ha
|
|
5422
5424
|
Fortunately, FontForge provides a {url-fontforge-scripting}[scripting interface], which you can use to automate the process.
|
5423
5425
|
|
5424
5426
|
In fact, that's what we use to prepare the fonts that are bundled with Asciidoctor PDF.
|
5425
|
-
You can find that FontForge script, the Bash script that calls it, and the Docker image in which it is run in the https://github.com/asciidoctor/asciidoctor-pdf/tree/
|
5427
|
+
You can find that FontForge script, the Bash script that calls it, and the Docker image in which it is run in the https://github.com/asciidoctor/asciidoctor-pdf/tree/main/scripts[scripts directory] of this project.
|
5426
5428
|
You can use that script as a starting point or reference for your own font preparation / modification script.
|
@@ -126,10 +126,6 @@ module Asciidoctor
|
|
126
126
|
# NOTE enabling data-uri forces Asciidoctor Diagram to produce absolute image paths
|
127
127
|
doc.attributes['data-uri'] = ((doc.instance_variable_get :@attribute_overrides) || {})['data-uri'] = ''
|
128
128
|
end
|
129
|
-
@capabilities = {
|
130
|
-
special_sectnums: AsciidoctorVersion >= (::Gem::Version.new '1.5.7'),
|
131
|
-
syntax_highlighter: AsciidoctorVersion >= (::Gem::Version.new '2.0.0'),
|
132
|
-
}
|
133
129
|
@initial_instance_variables = [:@initial_instance_variables] + instance_variables
|
134
130
|
end
|
135
131
|
|
@@ -165,9 +161,6 @@ module Asciidoctor
|
|
165
161
|
init_pdf doc
|
166
162
|
# set default value for pagenums if not otherwise set
|
167
163
|
doc.attributes['pagenums'] = '' unless (doc.attribute_locked? 'pagenums') || ((doc.instance_variable_get :@attributes_modified).include? 'pagenums')
|
168
|
-
if (idx_sect = doc.sections.find {|candidate| candidate.sectname == 'index' }) && idx_sect.numbered
|
169
|
-
idx_sect.numbered = false
|
170
|
-
end unless @capabilities[:special_sectnums]
|
171
164
|
#assign_missing_section_ids doc
|
172
165
|
|
173
166
|
# promote anonymous preface (defined using preamble block) to preface section
|
@@ -334,7 +327,7 @@ module Asciidoctor
|
|
334
327
|
# QUESTION should ThemeLoader handle registering fonts instead?
|
335
328
|
register_fonts theme.font_catalog, (doc.attr 'pdf-fontsdir', 'GEM_FONTS_DIR')
|
336
329
|
default_kerning theme.base_font_kerning != 'none'
|
337
|
-
@fallback_fonts =
|
330
|
+
@fallback_fonts = Array theme.font_fallbacks
|
338
331
|
@allow_uri_read = doc.attr? 'allow-uri-read'
|
339
332
|
@cache_uri = doc.attr? 'cache-uri'
|
340
333
|
@tmp_files = {}
|
@@ -375,7 +368,10 @@ module Asciidoctor
|
|
375
368
|
@index = IndexCatalog.new
|
376
369
|
# NOTE: we have to init Pdfmark class here while we have reference to the doc
|
377
370
|
@pdfmark = (doc.attr? 'pdfmark') ? (Pdfmark.new doc) : nil
|
378
|
-
|
371
|
+
# NOTE: defer instantiating optimizer until we know min pdf version
|
372
|
+
if (@optimize = doc.attr 'optimize')
|
373
|
+
@optimize = nil unless (defined? ::Asciidoctor::PDF::Optimizer) || !(Helpers.require_library OptimizerRequirePath, 'rghost', :warn).nil?
|
374
|
+
end
|
379
375
|
init_scratch_prototype
|
380
376
|
self
|
381
377
|
end
|
@@ -1079,7 +1075,7 @@ module Asciidoctor
|
|
1079
1075
|
stack_subject = node.has_role? 'stack'
|
1080
1076
|
subject_stop = node.attr 'subject-stop', (stack_subject ? nil : ':'), false
|
1081
1077
|
node.items.each do |subjects, dd|
|
1082
|
-
subject =
|
1078
|
+
subject = (Array subjects).first.text
|
1083
1079
|
list_item_text = %(+++<strong>#{subject}#{(StopPunctRx.match? sanitize subject) ? '' : subject_stop}</strong>#{dd.text? ? "#{stack_subject ? '<br>' : ' '}#{dd.text}" : ''}+++)
|
1084
1080
|
list_item = ListItem.new list, list_item_text
|
1085
1081
|
dd.blocks.each {|it| list_item << it }
|
@@ -1633,9 +1629,7 @@ module Asciidoctor
|
|
1633
1629
|
add_dest_for_block node if node.id
|
1634
1630
|
|
1635
1631
|
# HACK: disable built-in syntax highlighter; must be done before calling node.content!
|
1636
|
-
if node.style == 'source' && (highlighter =
|
1637
|
-
(syntax_hl = node.document.syntax_highlighter) && syntax_hl.highlight? && syntax_hl.name :
|
1638
|
-
(highlighter = node.document.attributes['source-highlighter']) && (SourceHighlighters.include? highlighter) && highlighter)
|
1632
|
+
if node.style == 'source' && (highlighter = (syntax_hl = node.document.syntax_highlighter)&.highlight? && syntax_hl.name)
|
1639
1633
|
case highlighter
|
1640
1634
|
when 'coderay'
|
1641
1635
|
unless defined? ::Asciidoctor::Prawn::CodeRayEncoder
|
@@ -2124,10 +2118,6 @@ module Asciidoctor
|
|
2124
2118
|
else
|
2125
2119
|
table_width = bounds.width * ((node.attr 'tablepcwidth') / 100.0)
|
2126
2120
|
column_widths = node.columns.map {|col| ((col.attr 'colpcwidth') * table_width) / 100.0 }
|
2127
|
-
# NOTE: until Asciidoctor 1.5.4, colpcwidth values didn't always add up to 100%; use last column to compensate
|
2128
|
-
unless column_widths.empty? || (width_delta = table_width - column_widths.sum) == 0
|
2129
|
-
column_widths[-1] += width_delta
|
2130
|
-
end
|
2131
2121
|
end
|
2132
2122
|
|
2133
2123
|
if ((alignment = node.attr 'align', nil, false) && (BlockAlignmentNames.include? alignment)) ||
|
@@ -2358,7 +2348,7 @@ module Asciidoctor
|
|
2358
2348
|
bare_target = target
|
2359
2349
|
text = node.text
|
2360
2350
|
end
|
2361
|
-
if (role = node.attr 'role', nil, false) && (role == 'bare' || (
|
2351
|
+
if (role = node.attr 'role', nil, false) && (role == 'bare' || (role.split.include? 'bare'))
|
2362
2352
|
# QUESTION should we insert breakable chars into URI when building fragment instead?
|
2363
2353
|
%(<a href="#{target}"#{attrs.join}>#{breakable_uri text}</a>)
|
2364
2354
|
# NOTE @media may not be initialized if method is called before convert phase
|
@@ -2377,13 +2367,8 @@ module Asciidoctor
|
|
2377
2367
|
%(<a href="#{target}">#{node.text || path}</a>)
|
2378
2368
|
elsif (refid = node.attributes['refid'])
|
2379
2369
|
unless (text = node.text)
|
2380
|
-
if (
|
2381
|
-
|
2382
|
-
text = ref.xreftext node.attr 'xrefstyle', nil, true
|
2383
|
-
end
|
2384
|
-
else
|
2385
|
-
# Asciidoctor < 1.5.6
|
2386
|
-
text = doc.catalog[:ids][refid]
|
2370
|
+
if ::Asciidoctor::AbstractNode === (ref = doc.catalog[:refs][refid])
|
2371
|
+
text = ref.xreftext node.attr 'xrefstyle', nil, true
|
2387
2372
|
end
|
2388
2373
|
end
|
2389
2374
|
%(<a anchor="#{derive_anchor_from_id refid}">#{text || "[#{refid}]"}</a>).gsub ']', ']'
|
@@ -2419,10 +2404,10 @@ module Asciidoctor
|
|
2419
2404
|
end
|
2420
2405
|
|
2421
2406
|
def convert_inline_callout node
|
2422
|
-
if (conum_font_family = @theme.conum_font_family)
|
2423
|
-
result = %(<font name="#{conum_font_family}">#{conum_glyph node.text.to_i}</font>)
|
2424
|
-
else
|
2407
|
+
if (conum_font_family = @theme.conum_font_family) == font_name
|
2425
2408
|
result = conum_glyph node.text.to_i
|
2409
|
+
else
|
2410
|
+
result = %(<font name="#{conum_font_family}">#{conum_glyph node.text.to_i}</font>)
|
2426
2411
|
end
|
2427
2412
|
if (conum_font_color = @theme.conum_font_color)
|
2428
2413
|
# NOTE CMYK value gets flattened here, but is restored by formatted text parser
|
@@ -3434,12 +3419,12 @@ module Asciidoctor
|
|
3434
3419
|
end
|
3435
3420
|
tot_width = 0
|
3436
3421
|
side_colspecs = colspecs.map {|col, spec|
|
3437
|
-
if (alignment_char = spec.chr).to_i.to_s
|
3438
|
-
alignment = AlignmentTable[alignment_char] || :left
|
3439
|
-
rel_width = (spec.slice 1, spec.length).to_f
|
3440
|
-
else
|
3422
|
+
if (alignment_char = spec.chr).to_i.to_s == alignment_char
|
3441
3423
|
alignment = :left
|
3442
3424
|
rel_width = spec.to_f
|
3425
|
+
else
|
3426
|
+
alignment = AlignmentTable[alignment_char] || :left
|
3427
|
+
rel_width = (spec.slice 1, spec.length).to_f
|
3443
3428
|
end
|
3444
3429
|
tot_width += rel_width
|
3445
3430
|
[col, { align: alignment, width: rel_width, x: 0 }]
|
@@ -3602,7 +3587,7 @@ module Asciidoctor
|
|
3602
3587
|
pdf_doc.render_file target
|
3603
3588
|
# QUESTION restore attributes first?
|
3604
3589
|
@pdfmark&.generate_file target
|
3605
|
-
(Optimizer.new @optimize, pdf_doc.min_version).
|
3590
|
+
(Optimizer.new @optimize, pdf_doc.min_version).optimize_file target if @optimize
|
3606
3591
|
end
|
3607
3592
|
# write scratch document if debug is enabled (or perhaps DEBUG_STEPS env)
|
3608
3593
|
#get_scratch_document.render_file 'scratch.pdf'
|
@@ -4,7 +4,6 @@ require_relative 'core/object'
|
|
4
4
|
require_relative 'core/array'
|
5
5
|
require_relative 'core/file'
|
6
6
|
require_relative 'core/hash'
|
7
|
-
require_relative 'core/numeric'
|
8
7
|
require_relative 'core/string'
|
9
8
|
require_relative 'core/regexp'
|
10
9
|
require_relative 'core/quantifiable_stdout'
|
@@ -5,21 +5,12 @@
|
|
5
5
|
# This file was copied from Prawn (manual/syntax_highlight.rb) and
|
6
6
|
# modified for use with Asciidoctor PDF.
|
7
7
|
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
# the
|
11
|
-
# (at your option) any later version.
|
12
|
-
#
|
13
|
-
# Prawn is distributed in the hope that it will be useful,
|
14
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
-
# GNU General Public License for more details.
|
17
|
-
#
|
18
|
-
# You should have received a copy of the GNU General Public License
|
19
|
-
# along with Prawn. If not, see <http://www.gnu.org/licenses/>.
|
8
|
+
# Since the file originates from the Prawn project, it shares the Prawn
|
9
|
+
# license. Thus, the file may be used under Matz's original licensing terms for
|
10
|
+
# Ruby, the GPLv2 license, or the GPLv3 license.
|
20
11
|
#
|
21
12
|
# Copyright (C) Felipe Doria
|
22
|
-
# Copyright (C) 2014 OpenDevise Inc. and the Asciidoctor Project
|
13
|
+
# Copyright (C) 2014-present OpenDevise Inc. and the Asciidoctor Project
|
23
14
|
#
|
24
15
|
######################################################################
|
25
16
|
|
@@ -190,7 +190,7 @@ module Asciidoctor
|
|
190
190
|
# }
|
191
191
|
#
|
192
192
|
def register_font data
|
193
|
-
font_families.update data.
|
193
|
+
font_families.update data.transform_keys(&:to_s)
|
194
194
|
end
|
195
195
|
|
196
196
|
# Enhances the built-in font method to allow the font
|
@@ -553,7 +553,7 @@ module Asciidoctor
|
|
553
553
|
|
554
554
|
# TODO: memoize the result
|
555
555
|
def inflate_padding padding
|
556
|
-
padding =
|
556
|
+
padding = (Array padding || 0).slice 0, 4
|
557
557
|
case padding.size
|
558
558
|
when 1
|
559
559
|
[padding[0], padding[0], padding[0], padding[0]]
|
@@ -1,24 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'pygments.rb' # rubocop:disable Style/RedundantFileExtensionInRequire
|
4
|
-
|
5
3
|
module Pygments
|
6
4
|
module Ext
|
7
5
|
module BlockStyles
|
8
6
|
BlockSelectorRx = /^\.highlight *\{([^}]+?)\}/
|
9
7
|
HighlightBackgroundColorRx = /^\.highlight +\.hll +{ *background(?:-color)?: *#([a-fA-F0-9]{6})/
|
10
|
-
|
8
|
+
ColorPropertiesRx = /(?:^|;) *(background(?:-color)?|color): *#?([a-fA-F0-9]{6}) *(?=$|;)/
|
11
9
|
|
12
10
|
@cache = ::Hash.new do |cache, key|
|
13
11
|
styles = {}
|
14
12
|
if BlockSelectorRx =~ (css = ::Pygments.css '.highlight', style: key)
|
15
|
-
|
16
|
-
pname, pval = (style.split ':', 2).map(&:strip)
|
13
|
+
$1.scan ColorPropertiesRx do |pname, pval|
|
17
14
|
case pname
|
18
15
|
when 'background', 'background-color'
|
19
|
-
styles[:background_color] = pval
|
16
|
+
styles[:background_color] = pval
|
20
17
|
when 'color'
|
21
|
-
styles[:font_color] = pval
|
18
|
+
styles[:font_color] = pval
|
22
19
|
end
|
23
20
|
end
|
24
21
|
end
|
@@ -27,6 +24,10 @@ module Pygments
|
|
27
24
|
styles
|
28
25
|
end
|
29
26
|
|
27
|
+
def self.available? style
|
28
|
+
(@available ||= ::Pygments.styles.to_set).include? style
|
29
|
+
end
|
30
|
+
|
30
31
|
def self.for style
|
31
32
|
@cache[style]
|
32
33
|
end
|
@@ -32,7 +32,7 @@ module Asciidoctor
|
|
32
32
|
|
33
33
|
def store_primary_term name, dest = nil
|
34
34
|
store_dest dest if dest
|
35
|
-
(init_category
|
35
|
+
(init_category name.chr.upcase).store_term name, dest
|
36
36
|
end
|
37
37
|
|
38
38
|
def store_secondary_term primary_name, secondary_name, dest = nil
|
@@ -2,11 +2,35 @@
|
|
2
2
|
|
3
3
|
require 'pathname'
|
4
4
|
require 'rghost'
|
5
|
+
require 'rghost/gs_alone'
|
5
6
|
require 'tmpdir'
|
6
7
|
|
8
|
+
RGhost::GSAlone.prepend (Module.new do
|
9
|
+
WindowsRx = /win|ming/
|
10
|
+
|
11
|
+
def initialize params, debug
|
12
|
+
(@params = params.dup).push(*(@params.pop.split File::PATH_SEPARATOR))
|
13
|
+
@debug = debug
|
14
|
+
end
|
15
|
+
|
16
|
+
def run
|
17
|
+
RGhost::Config.config_platform unless File.exist? RGhost::Config::GS[:path].to_s
|
18
|
+
(cmd = @params.slice 1, @params.length).unshift RGhost::Config::GS[:path].to_s
|
19
|
+
#puts cmd if @debug
|
20
|
+
system(*cmd)
|
21
|
+
end
|
22
|
+
end)
|
23
|
+
|
24
|
+
RGhost::Engine.prepend (Module.new do
|
25
|
+
def shellescape str
|
26
|
+
str
|
27
|
+
end
|
28
|
+
end)
|
29
|
+
|
7
30
|
module Asciidoctor
|
8
31
|
module PDF
|
9
32
|
class Optimizer
|
33
|
+
# see https://www.ghostscript.com/doc/current/VectorDevices.htm#PSPDF_IN for details
|
10
34
|
(QUALITY_NAMES = {
|
11
35
|
'default' => :default,
|
12
36
|
'screen' => :screen,
|
@@ -15,27 +39,31 @@ module Asciidoctor
|
|
15
39
|
'prepress' => :prepress,
|
16
40
|
}).default = :default
|
17
41
|
|
42
|
+
attr_reader :quality
|
43
|
+
attr_reader :compatibility_level
|
44
|
+
|
18
45
|
def initialize quality = 'default', compatibility_level = '1.4'
|
19
46
|
@quality = QUALITY_NAMES[quality]
|
20
47
|
@compatibility_level = compatibility_level
|
48
|
+
if (gs_path = ::ENV['GS'])
|
49
|
+
::RGhost::Config::GS[:path] = gs_path
|
50
|
+
end
|
21
51
|
end
|
22
52
|
|
23
|
-
def
|
53
|
+
def optimize_file target
|
24
54
|
::Dir::Tmpname.create ['asciidoctor-pdf-', '.pdf'] do |tmpfile|
|
25
|
-
|
26
|
-
|
27
|
-
pdfmark =
|
28
|
-
|
55
|
+
filename_o = ::Pathname.new target
|
56
|
+
filename_tmp = ::Pathname.new tmpfile
|
57
|
+
if (pdfmark = filename_o.sub_ext '.pdfmark').file?
|
58
|
+
inputs = [target, pdfmark.to_s].join ::File::PATH_SEPARATOR
|
59
|
+
else
|
60
|
+
inputs = target
|
61
|
+
end
|
29
62
|
(::RGhost::Convert.new inputs).to :pdf,
|
30
|
-
filename:
|
63
|
+
filename: filename_tmp.to_s,
|
31
64
|
quality: @quality,
|
32
65
|
d: { Printed: false, CannotEmbedFontPolicy: '/Warning', CompatibilityLevel: @compatibility_level }
|
33
|
-
|
34
|
-
filename_o.rename target
|
35
|
-
rescue ::Errno::EXDEV
|
36
|
-
filename.binwrite filename_o.binread
|
37
|
-
filename_o.unlink
|
38
|
-
end
|
66
|
+
filename_o.binwrite filename_tmp.binread
|
39
67
|
end
|
40
68
|
nil
|
41
69
|
end
|
@@ -1,36 +1,26 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
unless RUBY_VERSION >= '2.4'
|
4
|
-
begin
|
5
|
-
require 'unicode' unless defined? Unicode::VERSION
|
6
|
-
rescue LoadError
|
7
|
-
begin
|
8
|
-
require 'active_support/multibyte' unless defined? ActiveSupport::Multibyte
|
9
|
-
rescue LoadError; end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
3
|
module Asciidoctor
|
14
4
|
module PDF
|
15
5
|
module TextTransformer
|
16
6
|
XMLMarkupRx = /&#?[a-z\d]+;|</
|
17
7
|
PCDATAFilterRx = /(&#?[a-z\d]+;|<[^>]+>)|([^&<]+)/
|
18
8
|
TagFilterRx = /(<[^>]+>)|([^<]+)/
|
19
|
-
|
9
|
+
ContiguousCharsRx = /\p{Graph}+/
|
10
|
+
WordRx = /\p{Word}+/
|
20
11
|
Hyphen = '-'
|
21
12
|
SoftHyphen = ?\u00ad
|
22
|
-
HyphenatedHyphen = '-' + SoftHyphen
|
23
13
|
|
24
14
|
def capitalize_words_pcdata string
|
25
15
|
if XMLMarkupRx.match? string
|
26
|
-
string.gsub(PCDATAFilterRx) { $2 ? (
|
16
|
+
string.gsub(PCDATAFilterRx) { $2 ? (capitalize_words $2) : $1 }
|
27
17
|
else
|
28
|
-
|
18
|
+
capitalize_words string
|
29
19
|
end
|
30
20
|
end
|
31
21
|
|
32
|
-
def
|
33
|
-
string.gsub(
|
22
|
+
def capitalize_words string
|
23
|
+
string.gsub(ContiguousCharsRx) { $&.capitalize }
|
34
24
|
end
|
35
25
|
|
36
26
|
def hyphenate_words_pcdata string, hyphenator
|
@@ -42,74 +32,21 @@ module Asciidoctor
|
|
42
32
|
end
|
43
33
|
|
44
34
|
def hyphenate_words string, hyphenator
|
45
|
-
string.gsub(WordRx) {
|
35
|
+
string.gsub(WordRx) { hyphenator.visualize $&, SoftHyphen }
|
46
36
|
end
|
47
37
|
|
48
38
|
def lowercase_pcdata string
|
49
39
|
if string.include? '<'
|
50
|
-
string.gsub(TagFilterRx) { $2 ?
|
40
|
+
string.gsub(TagFilterRx) { $2 ? $2.downcase : $1 }
|
51
41
|
else
|
52
|
-
|
42
|
+
string.downcase
|
53
43
|
end
|
54
44
|
end
|
55
45
|
|
56
46
|
def uppercase_pcdata string
|
57
47
|
if XMLMarkupRx.match? string
|
58
|
-
string.gsub(PCDATAFilterRx) { $2 ?
|
48
|
+
string.gsub(PCDATAFilterRx) { $2 ? $2.upcase : $1 }
|
59
49
|
else
|
60
|
-
uppercase_mb string
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
if RUBY_VERSION >= '2.4'
|
65
|
-
def capitalize_mb string
|
66
|
-
string.capitalize
|
67
|
-
end
|
68
|
-
|
69
|
-
def lowercase_mb string
|
70
|
-
string.downcase
|
71
|
-
end
|
72
|
-
|
73
|
-
def uppercase_mb string
|
74
|
-
string.upcase
|
75
|
-
end
|
76
|
-
# NOTE Unicode library is 4x as fast as ActiveSupport::MultiByte::Chars
|
77
|
-
elsif defined? ::Unicode
|
78
|
-
def capitalize_mb string
|
79
|
-
string.ascii_only? ? string.capitalize : (::Unicode.capitalize string)
|
80
|
-
end
|
81
|
-
|
82
|
-
def lowercase_mb string
|
83
|
-
string.ascii_only? ? string.downcase : (::Unicode.downcase string)
|
84
|
-
end
|
85
|
-
|
86
|
-
def uppercase_mb string
|
87
|
-
string.ascii_only? ? string.upcase : (::Unicode.upcase string)
|
88
|
-
end
|
89
|
-
elsif defined? ::ActiveSupport::Multibyte
|
90
|
-
MultibyteChars = ::ActiveSupport::Multibyte::Chars
|
91
|
-
|
92
|
-
def capitalize_mb string
|
93
|
-
string.ascii_only? ? string.capitalize : (MultibyteChars.new string).capitalize.to_s
|
94
|
-
end
|
95
|
-
|
96
|
-
def lowercase_mb string
|
97
|
-
string.ascii_only? ? string.downcase : (MultibyteChars.new string).downcase.to_s
|
98
|
-
end
|
99
|
-
|
100
|
-
def uppercase_mb string
|
101
|
-
string.ascii_only? ? string.upcase : (MultibyteChars.new string).upcase.to_s
|
102
|
-
end
|
103
|
-
else
|
104
|
-
def capitalize_mb string
|
105
|
-
string.capitalize
|
106
|
-
end
|
107
|
-
|
108
|
-
def lowercase_mb string
|
109
|
-
string.downcase
|
110
|
-
end
|
111
|
-
|
112
|
-
def uppercase_mb string
|
113
50
|
string.upcase
|
114
51
|
end
|
115
52
|
end
|
@@ -94,7 +94,7 @@ module Asciidoctor
|
|
94
94
|
yaml_data = ::SafeYAML.load data, filename
|
95
95
|
if ::Hash === yaml_data && (yaml_data.key? 'extends')
|
96
96
|
if (extends = yaml_data.delete 'extends')
|
97
|
-
|
97
|
+
(Array extends).each do |extend_path|
|
98
98
|
if extend_path == 'base'
|
99
99
|
theme_data = theme_data ? (::OpenStruct.new theme_data.to_h.merge load_base_theme.to_h) : load_base_theme
|
100
100
|
next
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: asciidoctor-pdf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dan Allen
|
@@ -9,62 +9,36 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2021-
|
12
|
+
date: 2021-05-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: asciidoctor
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
17
|
-
requirements:
|
18
|
-
- - ">="
|
19
|
-
- !ruby/object:Gem::Version
|
20
|
-
version: 1.5.3
|
21
|
-
- - "<"
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: 3.0.0
|
24
|
-
type: :runtime
|
25
|
-
prerelease: false
|
26
|
-
version_requirements: !ruby/object:Gem::Requirement
|
27
|
-
requirements:
|
28
|
-
- - ">="
|
29
|
-
- !ruby/object:Gem::Version
|
30
|
-
version: 1.5.3
|
31
|
-
- - "<"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 3.0.0
|
34
|
-
- !ruby/object:Gem::Dependency
|
35
|
-
name: prawn
|
36
16
|
requirement: !ruby/object:Gem::Requirement
|
37
17
|
requirements:
|
38
18
|
- - "~>"
|
39
19
|
- !ruby/object:Gem::Version
|
40
|
-
version: 2.
|
20
|
+
version: '2.0'
|
41
21
|
type: :runtime
|
42
22
|
prerelease: false
|
43
23
|
version_requirements: !ruby/object:Gem::Requirement
|
44
24
|
requirements:
|
45
25
|
- - "~>"
|
46
26
|
- !ruby/object:Gem::Version
|
47
|
-
version: 2.
|
27
|
+
version: '2.0'
|
48
28
|
- !ruby/object:Gem::Dependency
|
49
|
-
name:
|
29
|
+
name: prawn
|
50
30
|
requirement: !ruby/object:Gem::Requirement
|
51
31
|
requirements:
|
52
32
|
- - "~>"
|
53
33
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
55
|
-
- - ">="
|
56
|
-
- !ruby/object:Gem::Version
|
57
|
-
version: 1.5.1
|
34
|
+
version: 2.4.0
|
58
35
|
type: :runtime
|
59
36
|
prerelease: false
|
60
37
|
version_requirements: !ruby/object:Gem::Requirement
|
61
38
|
requirements:
|
62
39
|
- - "~>"
|
63
40
|
- !ruby/object:Gem::Version
|
64
|
-
version:
|
65
|
-
- - ">="
|
66
|
-
- !ruby/object:Gem::Version
|
67
|
-
version: 1.5.1
|
41
|
+
version: 2.4.0
|
68
42
|
- !ruby/object:Gem::Dependency
|
69
43
|
name: prawn-table
|
70
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -99,28 +73,28 @@ dependencies:
|
|
99
73
|
requirements:
|
100
74
|
- - "~>"
|
101
75
|
- !ruby/object:Gem::Version
|
102
|
-
version: 0.
|
76
|
+
version: 0.32.0
|
103
77
|
type: :runtime
|
104
78
|
prerelease: false
|
105
79
|
version_requirements: !ruby/object:Gem::Requirement
|
106
80
|
requirements:
|
107
81
|
- - "~>"
|
108
82
|
- !ruby/object:Gem::Version
|
109
|
-
version: 0.
|
83
|
+
version: 0.32.0
|
110
84
|
- !ruby/object:Gem::Dependency
|
111
85
|
name: prawn-icon
|
112
86
|
requirement: !ruby/object:Gem::Requirement
|
113
87
|
requirements:
|
114
88
|
- - "~>"
|
115
89
|
- !ruby/object:Gem::Version
|
116
|
-
version:
|
90
|
+
version: 3.0.0
|
117
91
|
type: :runtime
|
118
92
|
prerelease: false
|
119
93
|
version_requirements: !ruby/object:Gem::Requirement
|
120
94
|
requirements:
|
121
95
|
- - "~>"
|
122
96
|
- !ruby/object:Gem::Version
|
123
|
-
version:
|
97
|
+
version: 3.0.0
|
124
98
|
- !ruby/object:Gem::Dependency
|
125
99
|
name: safe_yaml
|
126
100
|
requirement: !ruby/object:Gem::Requirement
|
@@ -135,34 +109,20 @@ dependencies:
|
|
135
109
|
- - "~>"
|
136
110
|
- !ruby/object:Gem::Version
|
137
111
|
version: 1.0.0
|
138
|
-
- !ruby/object:Gem::Dependency
|
139
|
-
name: thread_safe
|
140
|
-
requirement: !ruby/object:Gem::Requirement
|
141
|
-
requirements:
|
142
|
-
- - "~>"
|
143
|
-
- !ruby/object:Gem::Version
|
144
|
-
version: 0.3.0
|
145
|
-
type: :runtime
|
146
|
-
prerelease: false
|
147
|
-
version_requirements: !ruby/object:Gem::Requirement
|
148
|
-
requirements:
|
149
|
-
- - "~>"
|
150
|
-
- !ruby/object:Gem::Version
|
151
|
-
version: 0.3.0
|
152
112
|
- !ruby/object:Gem::Dependency
|
153
113
|
name: concurrent-ruby
|
154
114
|
requirement: !ruby/object:Gem::Requirement
|
155
115
|
requirements:
|
156
116
|
- - "~>"
|
157
117
|
- !ruby/object:Gem::Version
|
158
|
-
version: 1.1
|
118
|
+
version: '1.1'
|
159
119
|
type: :runtime
|
160
120
|
prerelease: false
|
161
121
|
version_requirements: !ruby/object:Gem::Requirement
|
162
122
|
requirements:
|
163
123
|
- - "~>"
|
164
124
|
- !ruby/object:Gem::Version
|
165
|
-
version: 1.1
|
125
|
+
version: '1.1'
|
166
126
|
- !ruby/object:Gem::Dependency
|
167
127
|
name: treetop
|
168
128
|
requirement: !ruby/object:Gem::Requirement
|
@@ -197,14 +157,14 @@ dependencies:
|
|
197
157
|
requirements:
|
198
158
|
- - "~>"
|
199
159
|
- !ruby/object:Gem::Version
|
200
|
-
version: 3.
|
160
|
+
version: 3.10.0
|
201
161
|
type: :development
|
202
162
|
prerelease: false
|
203
163
|
version_requirements: !ruby/object:Gem::Requirement
|
204
164
|
requirements:
|
205
165
|
- - "~>"
|
206
166
|
- !ruby/object:Gem::Version
|
207
|
-
version: 3.
|
167
|
+
version: 3.10.0
|
208
168
|
- !ruby/object:Gem::Dependency
|
209
169
|
name: pdf-inspector
|
210
170
|
requirement: !ruby/object:Gem::Requirement
|
@@ -253,14 +213,14 @@ dependencies:
|
|
253
213
|
requirements:
|
254
214
|
- - "~>"
|
255
215
|
- !ruby/object:Gem::Version
|
256
|
-
version: 1.
|
216
|
+
version: 1.4.0
|
257
217
|
type: :development
|
258
218
|
prerelease: false
|
259
219
|
version_requirements: !ruby/object:Gem::Requirement
|
260
220
|
requirements:
|
261
221
|
- - "~>"
|
262
222
|
- !ruby/object:Gem::Version
|
263
|
-
version: 1.
|
223
|
+
version: 1.4.0
|
264
224
|
description: An extension for Asciidoctor that converts AsciiDoc documents to PDF
|
265
225
|
using the Prawn PDF library.
|
266
226
|
email: dan@opendevise.com
|
@@ -272,7 +232,7 @@ extra_rdoc_files: []
|
|
272
232
|
files:
|
273
233
|
- ".yardopts"
|
274
234
|
- CHANGELOG.adoc
|
275
|
-
- LICENSE
|
235
|
+
- LICENSE
|
276
236
|
- NOTICE.adoc
|
277
237
|
- README.adoc
|
278
238
|
- asciidoctor-pdf.gemspec
|
@@ -321,7 +281,6 @@ files:
|
|
321
281
|
- lib/asciidoctor/pdf/ext/core/array.rb
|
322
282
|
- lib/asciidoctor/pdf/ext/core/file.rb
|
323
283
|
- lib/asciidoctor/pdf/ext/core/hash.rb
|
324
|
-
- lib/asciidoctor/pdf/ext/core/numeric.rb
|
325
284
|
- lib/asciidoctor/pdf/ext/core/object.rb
|
326
285
|
- lib/asciidoctor/pdf/ext/core/quantifiable_stdout.rb
|
327
286
|
- lib/asciidoctor/pdf/ext/core/regexp.rb
|
@@ -372,7 +331,7 @@ licenses:
|
|
372
331
|
- MIT
|
373
332
|
metadata:
|
374
333
|
bug_tracker_uri: https://github.com/asciidoctor/asciidoctor-pdf/issues
|
375
|
-
changelog_uri: https://github.com/asciidoctor/asciidoctor-pdf/blob/
|
334
|
+
changelog_uri: https://github.com/asciidoctor/asciidoctor-pdf/blob/main/CHANGELOG.adoc
|
376
335
|
mailing_list_uri: http://discuss.asciidoctor.org
|
377
336
|
source_code_uri: https://github.com/asciidoctor/asciidoctor-pdf
|
378
337
|
post_install_message:
|
@@ -390,7 +349,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
390
349
|
- !ruby/object:Gem::Version
|
391
350
|
version: '0'
|
392
351
|
requirements: []
|
393
|
-
rubygems_version: 3.
|
352
|
+
rubygems_version: 3.2.15
|
394
353
|
signing_key:
|
395
354
|
specification_version: 4
|
396
355
|
summary: Converts AsciiDoc documents to PDF using Asciidoctor and Prawn
|
@@ -1,26 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# NOTE remove once minimum required Ruby version is at least 2.4
|
4
|
-
Float.prepend (Module.new do
|
5
|
-
def truncate *args
|
6
|
-
if args.length == 1
|
7
|
-
if (precision = Integer args.shift) == 0
|
8
|
-
super
|
9
|
-
elsif precision > 0
|
10
|
-
precision_factor = 10.0**precision
|
11
|
-
(self * precision_factor).to_i / precision_factor
|
12
|
-
else
|
13
|
-
precision_factor = 10**precision.abs
|
14
|
-
(self / precision_factor).to_i * precision_factor
|
15
|
-
end
|
16
|
-
else
|
17
|
-
super
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end) if (Float.instance_method :truncate).arity == 0
|
21
|
-
|
22
|
-
Integer.prepend (Module.new do
|
23
|
-
def truncate *_args
|
24
|
-
super()
|
25
|
-
end
|
26
|
-
end) if (Integer.instance_method :truncate).arity == 0
|