asciidoctor-pdf 1.5.0.rc.2 → 1.5.0.rc.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +29 -0
- data/README.adoc +33 -6
- data/asciidoctor-pdf.gemspec +3 -7
- data/data/fonts/ABOUT-notoemoji-subset +3 -0
- data/data/fonts/ABOUT-notoserif-subset +1 -1
- data/data/fonts/mplus1mn-bold-ascii.ttf +0 -0
- data/data/fonts/mplus1mn-bold-subset.ttf +0 -0
- data/data/fonts/mplus1mn-bold_italic-ascii.ttf +0 -0
- data/data/fonts/mplus1mn-bold_italic-subset.ttf +0 -0
- data/data/fonts/mplus1mn-italic-ascii.ttf +0 -0
- data/data/fonts/mplus1mn-italic-subset.ttf +0 -0
- data/data/fonts/mplus1mn-regular-ascii-conums.ttf +0 -0
- data/data/fonts/mplus1mn-regular-subset.ttf +0 -0
- data/data/fonts/mplus1p-regular-fallback.ttf +0 -0
- data/data/fonts/notoemoji-subset.ttf +0 -0
- data/data/fonts/notoserif-bold-subset.ttf +0 -0
- data/data/fonts/notoserif-bold_italic-subset.ttf +0 -0
- data/data/fonts/notoserif-italic-subset.ttf +0 -0
- data/data/fonts/notoserif-regular-subset.ttf +0 -0
- data/data/themes/default-theme.yml +1 -1
- data/data/themes/default-with-fallback-font-theme.yml +4 -17
- data/docs/theming-guide.adoc +38 -13
- data/lib/asciidoctor/pdf.rb +0 -1
- data/lib/asciidoctor/pdf/converter.rb +154 -123
- data/lib/asciidoctor/pdf/ext/asciidoctor/logging_shim.rb +9 -1
- data/lib/asciidoctor/pdf/ext/core.rb +1 -0
- data/lib/asciidoctor/pdf/ext/core/file.rb +9 -0
- data/lib/asciidoctor/pdf/ext/prawn/extensions.rb +10 -0
- data/lib/asciidoctor/pdf/ext/prawn/font/afm.rb +2 -6
- data/lib/asciidoctor/pdf/ext/prawn/formatted_text/box.rb +40 -0
- data/lib/asciidoctor/pdf/formatted_text/formatter.rb +5 -6
- data/lib/asciidoctor/pdf/formatted_text/fragment_position_renderer.rb +2 -1
- data/lib/asciidoctor/pdf/formatted_text/inline_image_arranger.rb +7 -12
- data/lib/asciidoctor/pdf/formatted_text/inline_image_renderer.rb +1 -4
- data/lib/asciidoctor/pdf/formatted_text/transform.rb +1 -1
- data/lib/asciidoctor/pdf/theme_loader.rb +10 -9
- data/lib/asciidoctor/pdf/version.rb +1 -1
- metadata +10 -64
- data/lib/asciidoctor/pdf/temporary_path.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '09626023cb6a135adce58fb0340da45204eb411c5ee142f0b46fdb0224940f9e'
|
4
|
+
data.tar.gz: ee585d380fecf131696731998ef8f53f3c0c26ed7a7b50c10579d92c9eb941d6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 96cc29fcadcf79c8f7d4b051c39114b4c6f54f3e7d21951b0c16fab4f85a22a5ae32863907ebe72ea7a1ba851aaa5e8d56a8400d5b57688aca146f4f84cef534
|
7
|
+
data.tar.gz: 2ff61e20d2a6f4da7ef87b8735cf1ffcdbab2be73ff1dc05f62592c0d25ac5d069e2708058f134d5feee71e9df0c6b55bd02bb6c76a7e471faa8797feec11639
|
data/CHANGELOG.adoc
CHANGED
@@ -5,6 +5,34 @@
|
|
5
5
|
This document provides a high-level view of the changes to the {project-name} by release.
|
6
6
|
For a detailed view of what has changed, refer to the {uri-repo}/commits/master[commit history] on GitHub.
|
7
7
|
|
8
|
+
== 1.5.0.rc.3 (2020-02-04) - @mojavelinux
|
9
|
+
|
10
|
+
* reserve space for inline image correctly so it doesn't mangle the character spacing in the line when the image wraps (#1516)
|
11
|
+
* allow custom theme to merge font catalog with theme being extended (#1505)
|
12
|
+
* allow font path to be declared once for all font styles (#1507)
|
13
|
+
* continue border, background, and column rule of admonition block on subsequent pages when block gets split (#1287)
|
14
|
+
* allow max-width on caption be specified as a percentage (of the container width) (#1484)
|
15
|
+
* add support for remote image in running content (if allow-uri-read attribute is set) (#1536)
|
16
|
+
* add support for remote background images specified by theme (if allow-uri-read attribute is set) (#1536)
|
17
|
+
* add support for remote title page logo image specified by theme (if allow-uri-read attribute is set) (#1536)
|
18
|
+
* place dots on correct page when section title in TOC wraps across a page boundary (#1533)
|
19
|
+
* add destination to top of imported PDF if ID is specified on image block
|
20
|
+
* log reason if theme file cannot be parsed or compiled (#1491)
|
21
|
+
* fix crash if background image in theme is not readable
|
22
|
+
* bundle emoji font and use as fallback in default-with-fallback-font theme (#1129)
|
23
|
+
* add dark theme for chronicles example
|
24
|
+
* allow vertical-align key for header and footer categories to accept numeric offset as second value (e.g., [top, 10]) (#1488)
|
25
|
+
* link font family for abstract and sidebar to heading font family if only latter is set
|
26
|
+
* if path of missing font is absolute, don't suggest that it was not found in the fontsdir
|
27
|
+
* allow use of style "regular" as alias for "normal" when defining font
|
28
|
+
* emit warning in verbose mode if glyph cannot be found in fallback font (#1529)
|
29
|
+
* don't crash if table is empty and emit warning (#607)
|
30
|
+
* only emit warning when non-WINANSI character is used with AFM font if verbose mode is enabled
|
31
|
+
* do not emit warning when non-WINANSI character is used with AFM font inside scratch document
|
32
|
+
* do not emit log messages from scratch document
|
33
|
+
* upgrade treetop to 1.6
|
34
|
+
* reenable tests on Windows (#1499) *@slonopotamus*
|
35
|
+
|
8
36
|
== 1.5.0.rc.2 (2020-01-09) - @mojavelinux
|
9
37
|
|
10
38
|
* patch Prawn to fix incompatibilty with Ruby 2.7 (to fix text wrapping)
|
@@ -284,6 +312,7 @@ For a detailed view of what has changed, refer to the {uri-repo}/commits/master[
|
|
284
312
|
== 1.5.0.alpha.18 (2019-06-01) - @mojavelinux
|
285
313
|
|
286
314
|
* restore compatibility with Asciidoctor back to 1.5.3 and add verification to test matrix (#1038)
|
315
|
+
* allow one theme to extend another theme using the top-level `extends` key (#367)
|
287
316
|
* allow theme to set text indent for paragraphs using prose_text_indent (#191)
|
288
317
|
* allow theme to set spacing between adjacent paragraphs using prose_margin_inner (#191)
|
289
318
|
* show parts in toc when toclevels=0 (#783)
|
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.5.0.rc.
|
3
|
+
v1.5.0.rc.3, 2020-02-04
|
4
4
|
// Settings:
|
5
5
|
:experimental:
|
6
6
|
:idprefix:
|
@@ -23,7 +23,7 @@ endif::[]
|
|
23
23
|
:project-name: Asciidoctor PDF
|
24
24
|
:project-handle: asciidoctor-pdf
|
25
25
|
// Variables:
|
26
|
-
:release-version: 1.5.0.rc.
|
26
|
+
:release-version: 1.5.0.rc.3
|
27
27
|
// URIs:
|
28
28
|
:url-asciidoctor: http://asciidoctor.org
|
29
29
|
:url-gem: http://rubygems.org/gems/asciidoctor-pdf
|
@@ -90,6 +90,7 @@ But don't miss the <<Highlights>> and <<Known Limitations>> sections to understa
|
|
90
90
|
* Auto-generated index
|
91
91
|
* Automatic hyphenation (when enabled)
|
92
92
|
* Compression / optimization of output file
|
93
|
+
* Permissive line breaking for CJK languages
|
93
94
|
|
94
95
|
== Known Limitations
|
95
96
|
|
@@ -103,6 +104,7 @@ But don't miss the <<Highlights>> and <<Known Limitations>> sections to understa
|
|
103
104
|
* AsciiDoc table cell leaves padding below last block (due to lack of margin collapsing)
|
104
105
|
* 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]
|
105
106
|
* 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
|
107
|
+
* If a no-break hyphen is surrounded by formatted text on both sides (or is formatted individually), it will not prevent a line break
|
106
108
|
|
107
109
|
== Prerequisites
|
108
110
|
|
@@ -218,9 +220,9 @@ gem 'prawn-table', github: 'prawnpdf/prawn-table'
|
|
218
220
|
|
219
221
|
You can then install the gems into your project using the `bundle` command:
|
220
222
|
|
221
|
-
$ bundle --path
|
223
|
+
$ bundle config set --local path .bundle/gems && bundle
|
222
224
|
|
223
|
-
Since you
|
225
|
+
Since you're using Bundler to manage the gems, you'll need to prefix all commands with `bundle exec`.
|
224
226
|
For example:
|
225
227
|
|
226
228
|
$ bundle exec asciidoctor-pdf -v
|
@@ -689,8 +691,9 @@ The prawn-gmagick gem uses native extensions to compile against GraphicsMagick.
|
|
689
691
|
This system prerequisite limits installation to Linux and OSX.
|
690
692
|
Please refer to the {url-prawn-gmagick}[README for prawn-gmagick] to learn how to install it.
|
691
693
|
|
692
|
-
Once this gem is installed, Asciidoctor automatically
|
693
|
-
In addition to support for
|
694
|
+
Once this gem is installed, Asciidoctor automatically loads it, then delegates to it to handle all image embedding.
|
695
|
+
In addition to support for additional image file formats, this gem also speeds up image processing considerably.
|
696
|
+
We highly recommend using this gem if you're able to install it.
|
694
697
|
|
695
698
|
== Importing PDF Pages
|
696
699
|
|
@@ -940,6 +943,30 @@ If you want to enable the autofit option globally, set the `autofit-option` docu
|
|
940
943
|
:autofit-option:
|
941
944
|
----
|
942
945
|
|
946
|
+
== Autowidth Tables
|
947
|
+
|
948
|
+
Asciidoctor PDF does support autowidth tables.
|
949
|
+
However, the behavior differs from HTML when the content forces the table to the page boundary.
|
950
|
+
The behavior, which is handled by the prawn-table library, is explained in this section.
|
951
|
+
|
952
|
+
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.
|
953
|
+
Each column is assigned the width it needs to prevent the content from wrapping.
|
954
|
+
|
955
|
+
However, when the natural width of all columns exceeds the width of the page, the behavior may not be what you expect.
|
956
|
+
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.
|
957
|
+
Then, it reduces the width of the table by reducing the width of each column proportionally.
|
958
|
+
As a result, columns which reported the width necessary to render without wrapping now no longer do.
|
959
|
+
|
960
|
+
The reason this compression is not performed like in HTML is because prawn-table has no awareness of words.
|
961
|
+
Thus, it doesn't know how to redistribute with width intelligently.
|
962
|
+
|
963
|
+
To protected against truncation or insufficient width errors, prawn-table wraps text by character.
|
964
|
+
That's why the last character in the cell can end up getting wrapped.
|
965
|
+
(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).
|
966
|
+
|
967
|
+
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.
|
968
|
+
Let experience be your guide.
|
969
|
+
|
943
970
|
== Printing Page Ranges
|
944
971
|
|
945
972
|
The print dialog doesn't understand the page numbers labels (which appear in the running content).
|
data/asciidoctor-pdf.gemspec
CHANGED
@@ -37,6 +37,7 @@ Gem::Specification.new do |s|
|
|
37
37
|
s.add_runtime_dependency 'prawn', '~> 2.2.0'
|
38
38
|
# NOTE ttfunk 1.6 generates TT instructions ghostscript cannot process, so lock the version of ttfunk
|
39
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
|
40
41
|
s.add_runtime_dependency 'prawn-table', '~> 0.2.0'
|
41
42
|
s.add_runtime_dependency 'prawn-templates', '~> 0.1.0'
|
42
43
|
s.add_runtime_dependency 'prawn-svg', '~> 0.30.0'
|
@@ -44,18 +45,13 @@ Gem::Specification.new do |s|
|
|
44
45
|
s.add_runtime_dependency 'safe_yaml', '~> 1.0.0'
|
45
46
|
s.add_runtime_dependency 'thread_safe', '~> 0.3.0'
|
46
47
|
s.add_runtime_dependency 'concurrent-ruby', '~> 1.1.0'
|
47
|
-
|
48
|
-
s.add_runtime_dependency 'treetop', '~> 1.5.0'
|
48
|
+
s.add_runtime_dependency 'treetop', '~> 1.6.0'
|
49
49
|
|
50
50
|
s.add_development_dependency 'rake', '~> 13.0.0'
|
51
|
-
s.add_development_dependency 'deep-cover-core', '~> 0.7.0'
|
52
|
-
s.add_development_dependency 'simplecov', '~> 0.17.0'
|
53
51
|
s.add_development_dependency 'rspec', '~> 3.9.0'
|
54
52
|
s.add_development_dependency 'pdf-inspector', '~> 1.3.0'
|
55
53
|
# Asciidoctor PDF supports Rouge >= 2 (verified in CI build using 2.0.0)
|
56
|
-
s.add_development_dependency 'rouge', '~> 3.
|
57
|
-
s.add_development_dependency 'rubocop', '~> 0.78.0'
|
58
|
-
s.add_development_dependency 'rubocop-rspec', '~> 1.37.0'
|
54
|
+
s.add_development_dependency 'rouge', '~> 3.0'
|
59
55
|
s.add_development_dependency 'coderay', '~> 1.1.0'
|
60
56
|
s.add_development_dependency 'chunky_png', '~> 1.3.0'
|
61
57
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
Noto Serif fonts are generated from the google-noto-serif-fonts-20161022 Fedora RPM package
|
1
|
+
Noto Serif fonts are generated from the google-noto-serif-fonts-20161022 Fedora RPM package (commit 86b2e553c3e3e4d6614dadd1fa0a7a6dafd74552).
|
2
2
|
|
3
3
|
The following changes were made using fontforge to produce the notoserif-*-subset.ttf fonts:
|
4
4
|
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -207,7 +207,7 @@ example:
|
|
207
207
|
border_color: $base_border_color
|
208
208
|
border_radius: $base_border_radius
|
209
209
|
border_width: 0.75
|
210
|
-
background_color:
|
210
|
+
background_color: $page-background-color
|
211
211
|
# FIXME reenable padding bottom once margin collapsing is implemented
|
212
212
|
padding: [$vertical_rhythm, $horizontal_rhythm, 0, $horizontal_rhythm]
|
213
213
|
image:
|
@@ -1,22 +1,9 @@
|
|
1
1
|
extends: default
|
2
2
|
font:
|
3
3
|
catalog:
|
4
|
-
|
5
|
-
normal: notoserif-regular-subset.ttf
|
6
|
-
bold: notoserif-bold-subset.ttf
|
7
|
-
italic: notoserif-italic-subset.ttf
|
8
|
-
bold_italic: notoserif-bold_italic-subset.ttf
|
9
|
-
M+ 1mn:
|
10
|
-
normal: mplus1mn-regular-subset.ttf
|
11
|
-
bold: mplus1mn-bold-subset.ttf
|
12
|
-
italic: mplus1mn-italic-subset.ttf
|
13
|
-
bold_italic: mplus1mn-bold_italic-subset.ttf
|
4
|
+
merge: true
|
14
5
|
# M+ 1p supports Latin, Latin-1 Supplement, Latin Extended, Greek, Cyrillic, Vietnamese, Japanese & an assortment of symbols
|
15
6
|
# It also provides arrows for ->, <-, => and <= replacements in case these glyphs are missing from font
|
16
|
-
M+ 1p Fallback:
|
17
|
-
|
18
|
-
|
19
|
-
italic: mplus1p-regular-fallback.ttf
|
20
|
-
bold_italic: mplus1p-regular-fallback.ttf
|
21
|
-
fallbacks:
|
22
|
-
- M+ 1p Fallback
|
7
|
+
M+ 1p Fallback: mplus1p-regular-fallback.ttf
|
8
|
+
Noto Emoji: notoemoji-subset.ttf
|
9
|
+
fallbacks: [M+ 1p Fallback, Noto Emoji]
|
data/docs/theming-guide.adoc
CHANGED
@@ -52,6 +52,11 @@ The Asciidoctor PDF theme language is described using the http://en.wikipedia.or
|
|
52
52
|
Therefore, if you have a background in web design, the terminology should be immediately familiar to you.
|
53
53
|
*Note, however, that the theming system isn't actually CSS.*
|
54
54
|
|
55
|
+
The theme file must be named _<name>-theme.yml_, where `<name>` is the name of the theme.
|
56
|
+
_We recommend *not* using the names *base* or *default* so you don't confuse it with one of the built-in themes._
|
57
|
+
|
58
|
+
=== Selectors and Properties
|
59
|
+
|
55
60
|
Like CSS, themes have both selectors and properties.
|
56
61
|
Selectors are the component you want to style.
|
57
62
|
The properties are the style elements of that component that can be styled.
|
@@ -74,8 +79,7 @@ YAML is a human-friendly data format that resembles CSS and helps to describe th
|
|
74
79
|
The theme language adds some extra features to YAML, such as variables, basic math, measurements and color values.
|
75
80
|
These enhancements will be explained in detail in later sections.
|
76
81
|
|
77
|
-
|
78
|
-
_We recommend *not* using the names *base* or *default* so you don't confuse it with one of the built-in themes._
|
82
|
+
=== Basic Theme
|
79
83
|
|
80
84
|
Here's an example of a basic theme file that extends the base theme:
|
81
85
|
|
@@ -118,6 +122,8 @@ When creating a new theme, you only have to define the keys you want to override
|
|
118
122
|
All the available keys are documented in <<Keys>>.
|
119
123
|
The converter uses the information from the theme map to help construct the PDF.
|
120
124
|
|
125
|
+
=== Basic Extended Theme
|
126
|
+
|
121
127
|
Instead of designing a theme from scratch, you can extend the default theme using the `extends` key as follows:
|
122
128
|
|
123
129
|
[source,yaml]
|
@@ -144,6 +150,8 @@ Alternatively, you can snag the file from your local installation using the foll
|
|
144
150
|
cp "$ASCIIDOCTOR_PDF_DIR/data/themes/default-theme.yml" custom-theme.yml
|
145
151
|
====
|
146
152
|
|
153
|
+
=== Key Nesting
|
154
|
+
|
147
155
|
Keys may be nested to an arbitrary depth to eliminate redundant prefixes (an approach inspired by SASS).
|
148
156
|
Once the theme is loaded, all keys are flattened into a single map of qualified keys.
|
149
157
|
Nesting is simply a shorthand way of organizing the keys.
|
@@ -665,6 +673,7 @@ However, once you convert to PDF, you have to meet the font requirements of PDF
|
|
665
673
|
That means you need to provide a font (at least a fallback font) that contains glyphs for all the characters you want to use.
|
666
674
|
If you don't, you may notice that characters are missing (usually replaced with a box).
|
667
675
|
There's nothing Asciidoctor can do to convince PDF to work with extended characters without the right fonts in play.
|
676
|
+
To see which characters are missing from the font, enable verbose mode (`-v`) when running Asciidoctor PDF.
|
668
677
|
|
669
678
|
=== Built-In (AFM) Fonts
|
670
679
|
|
@@ -702,7 +711,7 @@ Even though the built-in fonts require the content to be encoded in WINANSI, _yo
|
|
702
711
|
Asciidoctor PDF encodes the content into WINANSI when building the PDF.
|
703
712
|
|
704
713
|
WARNING: Built-in (AFM) fonts do not use the <<fallback-fonts,fallback fonts>>.
|
705
|
-
In order for the fallback font to kick in, you must
|
714
|
+
In order for the fallback font to kick in, you must use a TrueType font as the primary font.
|
706
715
|
|
707
716
|
.WINANSI Encoding Behavior
|
708
717
|
****
|
@@ -851,10 +860,10 @@ This will allow you to use the same font names (aka families) in both your graph
|
|
851
860
|
|
852
861
|
=== Fallback Fonts
|
853
862
|
|
854
|
-
If a TrueType font is missing a character needed to render the document, such as a special symbol, you can have Asciidoctor PDF look for the character in a fallback font.
|
863
|
+
If a TrueType font is missing a character needed to render the document, such as a special symbol or emoji, you can have Asciidoctor PDF look for the character in a fallback font.
|
855
864
|
|
856
865
|
You only need to specify a single fallback font, typically one that provides a full set of symbols.
|
857
|
-
If the character isn't found in the fallback font, it will mostly likely be replaced by a box (which is guaranteed if you're using the bundled fallback font
|
866
|
+
If the character isn't found in the fallback font, it will mostly likely be replaced by a box (i.e., the notdef glyph), which is guaranteed if you're using the bundled fallback font.
|
858
867
|
|
859
868
|
IMPORTANT: When defining the fallback font, you *must specify all four variants* (normal, bold, italic, bold_italic), even if you use the same font file for each.
|
860
869
|
|
@@ -863,6 +872,8 @@ Any glyph missing from an AFM font is simply replaced with the "`not`" glyph (`&
|
|
863
872
|
|
864
873
|
CAUTION: The `default` theme does not use a fallback font.
|
865
874
|
However, the built-in `default-with-fallback-font` theme does.
|
875
|
+
In fact, it provides two.
|
876
|
+
One for general writing in non-Latin languages (M+ 1p) and another for emoji (Noto Emoji).
|
866
877
|
Using the fallback font slows down PDF generation slightly because it has to analyze every single character.
|
867
878
|
It's use is not recommended for large documents.
|
868
879
|
Instead, it's best to select primary fonts that have all the characters you need.
|
@@ -927,6 +938,20 @@ Now you're covered.
|
|
927
938
|
If your custom TTF font is missing a glyph, Asciidoctor PDF will look in your fallback font.
|
928
939
|
You don't need to reference the fallback font anywhere else in your theme file.
|
929
940
|
|
941
|
+
Here's another example that shows how to use an alternative emoji font (Symbola):
|
942
|
+
|
943
|
+
[source,yaml]
|
944
|
+
----
|
945
|
+
extends: default-with-fallback-font
|
946
|
+
font:
|
947
|
+
catalog:
|
948
|
+
merge: true
|
949
|
+
Symbola: /path/to/symbola.ttf
|
950
|
+
fallbacks: [ M+ 1p, Symbola ]
|
951
|
+
----
|
952
|
+
|
953
|
+
Now Asciidoctor PDF will look for the emoji in the Symbola font instead of the Noto Emoji font.
|
954
|
+
|
930
955
|
== Keys
|
931
956
|
|
932
957
|
This section lists all the keys that are available when creating a custom theme.
|
@@ -966,8 +991,8 @@ If the filename is absolute, it's used as is.
|
|
966
991
|
If the filename begins with `./`, it's resolved as a theme file relative to the current theme file.
|
967
992
|
Otherwise, the filename is resolved as a theme file in the normal way (relative to the value of the `pdf-themesdir` attribute).
|
968
993
|
|
969
|
-
CAUTION: If you define the <<Custom fonts,font catalog>> in a theme that extends from `default`, you
|
970
|
-
You can find
|
994
|
+
CAUTION: If you define the <<Custom fonts,font catalog>> in a theme that extends from `default`, you either have to redeclare any built-in font that on which the combined theme depends, or you need to set `merge: true` above your font definitions.
|
995
|
+
You can find the built-in definitions in default theme.
|
971
996
|
You'll then need to include `GEM_FONTS_DIR` in the value of the `pdf-fontsdir` attribute so that the converter can find and register them.
|
972
997
|
To avoid having to do this, make sure you set the font family for any element that declares a font family in the default theme.
|
973
998
|
|
@@ -3350,7 +3375,7 @@ The keys in this category control the arrangement of block images.
|
|
3350
3375
|
align: inherit
|
3351
3376
|
|
3352
3377
|
|caption-max-width^[5]^
|
3353
|
-
|fit-content {vbar} none +
|
3378
|
+
|fit-content {vbar} none {vbar} <<measurement-units,Measurement>> +
|
3354
3379
|
(default: none)
|
3355
3380
|
|image:
|
3356
3381
|
caption:
|
@@ -3839,7 +3864,7 @@ The keys in this category control the arrangement and style of tables and table
|
|
3839
3864
|
caption-side: bottom
|
3840
3865
|
|
3841
3866
|
|caption-max-width
|
3842
|
-
|fit-content {vbar} none +
|
3867
|
+
|fit-content {vbar} none {vbar} <<measurement-units,Measurement>> +
|
3843
3868
|
(default: fit-content)
|
3844
3869
|
|table:
|
3845
3870
|
caption-max-width: none
|
@@ -4475,7 +4500,7 @@ To avoid this problem, reduce the height of the running content periphery or mak
|
|
4475
4500
|
title-style: toc
|
4476
4501
|
|
4477
4502
|
|vertical-align
|
4478
|
-
|top {vbar} middle {vbar} bottom +
|
4503
|
+
|top {vbar} middle {vbar} bottom {vbar} [top {vbar} middle {vbar} bottom, <<measurement-units,Measurement>>] +
|
4479
4504
|
(default: middle)
|
4480
4505
|
|header:
|
4481
4506
|
vertical-align: middle
|
@@ -4600,7 +4625,7 @@ To avoid this problem, reduce the height of the running content periphery or mak
|
|
4600
4625
|
title-style: toc
|
4601
4626
|
|
4602
4627
|
|vertical-align
|
4603
|
-
|top {vbar} middle {vbar} bottom +
|
4628
|
+
|top {vbar} middle {vbar} bottom {vbar} [top {vbar} middle {vbar} bottom, <<measurement-units,Measurement>>] +
|
4604
4629
|
(default: middle)
|
4605
4630
|
|footer:
|
4606
4631
|
vertical-align: top
|
@@ -4795,7 +4820,7 @@ header:
|
|
4795
4820
|
center:
|
4796
4821
|
content: $header-recto-center-content
|
4797
4822
|
----
|
4798
|
-
<1> You can use the `
|
4823
|
+
<1> You can use the `image-vertical-align` key to slighly nudge the image up or down.
|
4799
4824
|
|
4800
4825
|
CAUTION: By default, the image must fit in the allotted space for the running header or footer.
|
4801
4826
|
Otherwise, you will run into layout issues.
|
@@ -4940,7 +4965,7 @@ These settings override equivalent keys defined in the theme file, where applica
|
|
4940
4965
|
|
4941
4966
|
|pdf-page-size
|
4942
4967
|
|https://github.com/prawnpdf/pdf-core/blob/0.6.0/lib/pdf/core/page_geometry.rb#L16-L68[Named size^] {vbar} <<measurement-units,Measurement[width, height]>>
|
4943
|
-
|:pdf-page-size: 6in
|
4968
|
+
|:pdf-page-size: [6in, 9in]
|
4944
4969
|
|
4945
4970
|
|pdf-folio-placement
|
4946
4971
|
|virtual {vbar} virtual-inverted {vbar} physical {vbar} physical-inverted
|
data/lib/asciidoctor/pdf.rb
CHANGED
@@ -9,7 +9,6 @@ rescue LoadError
|
|
9
9
|
end unless defined? GMagick::Image
|
10
10
|
require_relative 'pdf/measurements'
|
11
11
|
require_relative 'pdf/sanitizer'
|
12
|
-
require_relative 'pdf/temporary_path'
|
13
12
|
require_relative 'pdf/text_transformer'
|
14
13
|
require_relative 'pdf/ext'
|
15
14
|
require_relative 'pdf/theme_loader'
|
@@ -12,11 +12,7 @@ module Asciidoctor
|
|
12
12
|
module PDF
|
13
13
|
class Converter < ::Prawn::Document
|
14
14
|
include ::Asciidoctor::Converter
|
15
|
-
|
16
|
-
include ::Asciidoctor::Logging
|
17
|
-
else
|
18
|
-
include ::Asciidoctor::LoggingShim
|
19
|
-
end
|
15
|
+
include ::Asciidoctor::Logging
|
20
16
|
include ::Asciidoctor::Writer
|
21
17
|
include ::Asciidoctor::Prawn::Extensions
|
22
18
|
|
@@ -133,17 +129,18 @@ module Asciidoctor
|
|
133
129
|
result = send method_name, node
|
134
130
|
else
|
135
131
|
# TODO: delegate to convert_method_missing
|
136
|
-
logger.warn %(conversion missing in backend #{@backend} for #{name})
|
132
|
+
logger.warn %(conversion missing in backend #{@backend} for #{name}) unless scratch?
|
137
133
|
end
|
138
134
|
# NOTE: inline nodes generate pseudo-HTML strings; the remainder write directly to PDF object
|
139
135
|
::Asciidoctor::Inline === node ? result : self
|
140
136
|
end
|
141
137
|
|
142
138
|
def traverse node, opts = {}
|
143
|
-
|
144
|
-
|
145
|
-
else
|
139
|
+
# NOTE converter instance in scratch document gets duplicated; must be rewired to this one
|
140
|
+
if self == (prev_converter = node.document.converter)
|
146
141
|
prev_converter = nil
|
142
|
+
else
|
143
|
+
node.document.instance_variable_set :@converter, self
|
147
144
|
end
|
148
145
|
if node.blocks?
|
149
146
|
node.content
|
@@ -294,6 +291,7 @@ module Asciidoctor
|
|
294
291
|
|
295
292
|
stamp_foreground_image doc, has_front_cover
|
296
293
|
layout_cover_page doc, :back
|
294
|
+
clean_up_tmp_files
|
297
295
|
nil
|
298
296
|
end
|
299
297
|
|
@@ -330,6 +328,7 @@ module Asciidoctor
|
|
330
328
|
@fallback_fonts = [*theme.font_fallbacks]
|
331
329
|
@allow_uri_read = doc.attr? 'allow-uri-read'
|
332
330
|
@cache_uri = doc.attr? 'cache-uri'
|
331
|
+
@tmp_files = {}
|
333
332
|
if (bg_image = resolve_background_image doc, theme, 'page-background-image') && bg_image[0]
|
334
333
|
@page_bg_image = { verso: bg_image, recto: bg_image }
|
335
334
|
else
|
@@ -385,11 +384,12 @@ module Asciidoctor
|
|
385
384
|
theme
|
386
385
|
rescue
|
387
386
|
if user_themesdir
|
388
|
-
message = %(could not locate or load the pdf theme `#{theme_name}' in #{user_themesdir}
|
387
|
+
message = %(could not locate or load the pdf theme `#{theme_name}' in #{user_themesdir})
|
389
388
|
else
|
390
|
-
message = %(could not locate or load the built-in pdf theme `#{theme_name}'
|
389
|
+
message = %(could not locate or load the built-in pdf theme `#{theme_name}')
|
391
390
|
end
|
392
|
-
|
391
|
+
message += %( because of #{$!.class} #{$!.message}) unless ::SystemCallError === $!
|
392
|
+
logger.error %(#{message}; reverting to default theme)
|
393
393
|
@themesdir = (theme = ThemeLoader.load_theme).__dir__
|
394
394
|
theme
|
395
395
|
end
|
@@ -760,36 +760,35 @@ module Asciidoctor
|
|
760
760
|
shift_bottom = (shift_base * 2) / 3.0
|
761
761
|
keep_together do |box_height = nil|
|
762
762
|
push_scratch doc if scratch?
|
763
|
-
|
764
|
-
((@theme.admonition_border_width || 0) > 0 && @theme.admonition_border_color))
|
765
|
-
float do
|
766
|
-
bounding_box [0, cursor], width: bounds.width, height: box_height do
|
767
|
-
theme_fill_and_stroke_bounds :admonition
|
768
|
-
end
|
769
|
-
end
|
770
|
-
end
|
763
|
+
theme_fill_and_stroke_block :admonition, box_height if box_height
|
771
764
|
pad_box [0, cpad[1], 0, lpad[3]] do
|
772
765
|
if box_height
|
766
|
+
label_height = [box_height, cursor].min
|
773
767
|
if (rule_color = @theme.admonition_column_rule_color) &&
|
774
768
|
(rule_width = @theme.admonition_column_rule_width || @theme.base_border_width) && rule_width > 0
|
775
769
|
float do
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
770
|
+
rule_height = box_height
|
771
|
+
while rule_height > 0
|
772
|
+
rule_segment_height = [rule_height, cursor].min
|
773
|
+
bounding_box [0, cursor], width: label_width + lpad[1], height: rule_segment_height do
|
774
|
+
stroke_vertical_rule rule_color,
|
775
|
+
at: bounds.right,
|
776
|
+
line_style: (@theme.admonition_column_rule_style || :solid).to_sym,
|
777
|
+
line_width: rule_width
|
778
|
+
end
|
779
|
+
advance_page if (rule_height -= rule_segment_height) > 0
|
781
780
|
end
|
782
781
|
end
|
783
782
|
end
|
784
783
|
float do
|
785
|
-
bounding_box [0, cursor], width: label_width, height:
|
784
|
+
bounding_box [0, cursor], width: label_width, height: label_height do
|
786
785
|
if icons == 'font'
|
787
786
|
# FIXME: we assume icon is square
|
788
787
|
icon_size = fit_icon_to_bounds icon_size
|
789
788
|
# NOTE: Prawn's vertical center is not reliable, so calculate it manually
|
790
789
|
if label_valign == :center
|
791
790
|
label_valign = :top
|
792
|
-
if (vcenter_pos = (
|
791
|
+
if (vcenter_pos = (label_height - icon_size) * 0.5) > 0
|
793
792
|
move_down vcenter_pos
|
794
793
|
end
|
795
794
|
end
|
@@ -805,22 +804,22 @@ module Asciidoctor
|
|
805
804
|
position: label_align,
|
806
805
|
vposition: label_valign,
|
807
806
|
width: label_width,
|
808
|
-
height:
|
807
|
+
height: label_height,
|
809
808
|
fallback_font_name: fallback_svg_font_name,
|
810
809
|
enable_web_requests: allow_uri_read,
|
811
810
|
enable_file_requests_with_root: (::File.dirname icon_path),
|
812
811
|
cache_images: cache_uri
|
813
|
-
if (icon_height = (svg_size = svg_obj.document.sizing).output_height) >
|
814
|
-
icon_width = (svg_obj.resize height: (icon_height =
|
812
|
+
if (icon_height = (svg_size = svg_obj.document.sizing).output_height) > label_height
|
813
|
+
icon_width = (svg_obj.resize height: (icon_height = label_height)).output_width
|
815
814
|
else
|
816
815
|
icon_width = svg_size.output_width
|
817
816
|
end
|
818
817
|
svg_obj.draw
|
819
818
|
svg_obj.document.warnings.each do |icon_warning|
|
820
819
|
logger.warn %(problem encountered in image: #{icon_path}; #{icon_warning})
|
821
|
-
end
|
820
|
+
end unless scratch?
|
822
821
|
rescue
|
823
|
-
logger.warn %(could not embed admonition icon: #{icon_path}; #{$!.message})
|
822
|
+
logger.warn %(could not embed admonition icon: #{icon_path}; #{$!.message}) unless scratch?
|
824
823
|
end
|
825
824
|
else
|
826
825
|
begin
|
@@ -828,14 +827,14 @@ module Asciidoctor
|
|
828
827
|
icon_aspect_ratio = image_info.width.fdiv image_info.height
|
829
828
|
# NOTE: don't scale image up if smaller than label_width
|
830
829
|
icon_width = [(to_pt image_info.width, :px), label_width].min
|
831
|
-
if (icon_height = icon_width * (1 / icon_aspect_ratio)) >
|
832
|
-
icon_width *=
|
833
|
-
icon_height =
|
830
|
+
if (icon_height = icon_width * (1 / icon_aspect_ratio)) > label_height
|
831
|
+
icon_width *= label_height / icon_height
|
832
|
+
icon_height = label_height # rubocop:disable Lint/UselessAssignment
|
834
833
|
end
|
835
834
|
embed_image image_obj, image_info, width: icon_width, position: label_align, vposition: label_valign
|
836
835
|
rescue
|
837
836
|
# QUESTION should we show the label in this case?
|
838
|
-
logger.warn %(could not embed admonition icon: #{icon_path}; #{$!.message})
|
837
|
+
logger.warn %(could not embed admonition icon: #{icon_path}; #{$!.message}) unless scratch?
|
839
838
|
end
|
840
839
|
end
|
841
840
|
else
|
@@ -846,7 +845,7 @@ module Asciidoctor
|
|
846
845
|
# NOTE: Prawn's vertical center is not reliable, so calculate it manually
|
847
846
|
if label_valign == :center
|
848
847
|
label_valign = :top
|
849
|
-
if (vcenter_pos = (
|
848
|
+
if (vcenter_pos = (label_height - (height_of_typeset_text label_text, line_height: 1)) * 0.5) > 0
|
850
849
|
move_down vcenter_pos
|
851
850
|
end
|
852
851
|
end
|
@@ -902,10 +901,6 @@ module Asciidoctor
|
|
902
901
|
def convert_open node
|
903
902
|
if node.style == 'abstract'
|
904
903
|
convert_abstract node
|
905
|
-
elsif node.style == 'partintro' && node.blocks.size == 1 && node.blocks[0].style == 'abstract'
|
906
|
-
# TODO: process block title and id
|
907
|
-
# TODO: process abstract child even when partintro has multiple blocks
|
908
|
-
convert_abstract node.blocks[0]
|
909
904
|
else
|
910
905
|
doc = node.document
|
911
906
|
keep_together_if node.option? 'unbreakable' do
|
@@ -1015,13 +1010,9 @@ module Asciidoctor
|
|
1015
1010
|
# HACK: undo the margin below previous listing or literal block
|
1016
1011
|
# TODO: allow this to be set using colist_margin_top
|
1017
1012
|
unless at_page_top?
|
1018
|
-
# NOTE: this logic won't work for a colist nested inside a list item until Asciidoctor 1.5.3
|
1019
1013
|
if (self_idx = node.parent.blocks.index node) && self_idx > 0 &&
|
1020
1014
|
[:listing, :literal].include?(node.parent.blocks[self_idx - 1].context)
|
1021
|
-
move_up @theme.block_margin_bottom
|
1022
|
-
# or we could do...
|
1023
|
-
#move_up @theme.block_margin_bottom
|
1024
|
-
#move_down @theme.caption_margin_inside * 2
|
1015
|
+
move_up @theme.block_margin_bottom - @theme.outline_list_item_spacing
|
1025
1016
|
end
|
1026
1017
|
end
|
1027
1018
|
add_dest_for_block node if node.id
|
@@ -1097,7 +1088,7 @@ module Asciidoctor
|
|
1097
1088
|
term_kerning = default_kerning?
|
1098
1089
|
end
|
1099
1090
|
node.items.each do |terms, desc|
|
1100
|
-
term_text =
|
1091
|
+
term_text = terms.map(&:text).join ?\n
|
1101
1092
|
if (term_width = width_of term_text, inline_format: term_inline_format, kerning: term_kerning) > max_term_width
|
1102
1093
|
max_term_width = term_width
|
1103
1094
|
end
|
@@ -1138,7 +1129,6 @@ module Asciidoctor
|
|
1138
1129
|
term_line_height = @theme.description_list_term_line_height || @theme.base_line_height
|
1139
1130
|
line_metrics = theme_font(:description_list_term) { calc_line_metrics term_line_height }
|
1140
1131
|
node.items.each do |terms, desc|
|
1141
|
-
terms = [*terms]
|
1142
1132
|
# NOTE: don't orphan the terms (keep together terms and at least one line of content)
|
1143
1133
|
allocate_space_for_list_item line_metrics, (terms.size + 1), ((@theme.description_list_term_spacing || 0) + 0.05)
|
1144
1134
|
theme_font :description_list_term do
|
@@ -1212,7 +1202,7 @@ module Asciidoctor
|
|
1212
1202
|
if Bullets.key? candidate
|
1213
1203
|
bullet_type = candidate
|
1214
1204
|
else
|
1215
|
-
logger.warn %(unknown unordered list style: #{candidate})
|
1205
|
+
logger.warn %(unknown unordered list style: #{candidate}) unless scratch?
|
1216
1206
|
bullet_type = :disc
|
1217
1207
|
end
|
1218
1208
|
end
|
@@ -1318,13 +1308,13 @@ module Asciidoctor
|
|
1318
1308
|
marker = %(#{index}.)
|
1319
1309
|
else
|
1320
1310
|
complex = node.complex?
|
1321
|
-
logger.warn %(unknown list type #{list_type.inspect})
|
1311
|
+
logger.warn %(unknown list type #{list_type.inspect}) unless scratch?
|
1322
1312
|
marker = @theme.ulist_marker_disc_content || Bullets[:disc]
|
1323
1313
|
end
|
1324
1314
|
|
1325
1315
|
if marker
|
1326
1316
|
if marker_style[:font_family] == 'fa'
|
1327
|
-
logger.info
|
1317
|
+
logger.info 'deprecated fa icon set found in theme; use fas, far, or fab instead' unless scratch?
|
1328
1318
|
marker_style[:font_family] = FontAwesomeIconSets.find {|candidate| (icon_font_data candidate).yaml[candidate].value? marker } || 'fas'
|
1329
1319
|
end
|
1330
1320
|
marker_gap = rendered_width_of_char 'x'
|
@@ -1359,7 +1349,7 @@ module Asciidoctor
|
|
1359
1349
|
def traverse_list_item node, list_type, opts = {}
|
1360
1350
|
if list_type == :dlist # qanda
|
1361
1351
|
terms, desc = node
|
1362
|
-
|
1352
|
+
terms.each {|term| layout_prose %(<em>#{term.text}</em>), (opts.merge margin_top: 0, margin_bottom: @theme.description_list_term_spacing) }
|
1363
1353
|
if desc
|
1364
1354
|
layout_prose desc.text, (opts.merge hyphenate: true) if desc.text?
|
1365
1355
|
traverse desc
|
@@ -1390,18 +1380,28 @@ module Asciidoctor
|
|
1390
1380
|
elsif (image_path = resolve_image_path node, target, (opts.fetch :relative_to_imagesdir, true), image_format)
|
1391
1381
|
if image_format == 'pdf'
|
1392
1382
|
if ::File.readable? image_path
|
1383
|
+
if (id = node.id)
|
1384
|
+
add_dest_block = proc do
|
1385
|
+
node.set_attr 'pdf-destination', (node_dest = dest_top)
|
1386
|
+
add_dest id, node_dest
|
1387
|
+
end
|
1388
|
+
end
|
1393
1389
|
# NOTE: import_page automatically advances to next page afterwards
|
1394
1390
|
# QUESTION should we add destination to top of imported page?
|
1395
1391
|
if (pgnums = node.attr 'pages', nil, false)
|
1396
1392
|
(resolve_pagenums pgnums).each_with_index do |pgnum, idx|
|
1397
|
-
|
1393
|
+
if idx == 0
|
1394
|
+
import_page image_path, page: pgnum, replace: page.empty?, &add_dest_block
|
1395
|
+
else
|
1396
|
+
import_page image_path, page: pgnum, replace: true
|
1397
|
+
end
|
1398
1398
|
end
|
1399
1399
|
else
|
1400
|
-
import_page image_path, page: [(node.attr 'page', nil, 1).to_i, 1].max, replace: page.empty
|
1400
|
+
import_page image_path, page: [(node.attr 'page', nil, 1).to_i, 1].max, replace: page.empty?, &add_dest_block
|
1401
1401
|
end
|
1402
1402
|
else
|
1403
1403
|
# QUESTION should we use alt text in this case?
|
1404
|
-
logger.warn %(pdf to insert not found or not readable: #{image_path})
|
1404
|
+
logger.warn %(pdf to insert not found or not readable: #{image_path}) unless scratch?
|
1405
1405
|
end
|
1406
1406
|
return
|
1407
1407
|
elsif !(::File.readable? image_path)
|
@@ -1473,7 +1473,7 @@ module Asciidoctor
|
|
1473
1473
|
svg_obj.draw
|
1474
1474
|
svg_obj.document.warnings.each do |img_warning|
|
1475
1475
|
logger.warn %(problem encountered in image: #{image_path}; #{img_warning})
|
1476
|
-
end
|
1476
|
+
end unless scratch?
|
1477
1477
|
draw_image_border image_cursor, rendered_w, rendered_h, alignment unless node.role? && (node.has_role? 'noborder')
|
1478
1478
|
if (link = node.attr 'link', nil, false)
|
1479
1479
|
add_link_to_image link, { width: rendered_w, height: rendered_h }, position: alignment, y: image_y
|
@@ -1516,8 +1516,6 @@ module Asciidoctor
|
|
1516
1516
|
rescue
|
1517
1517
|
on_image_error :exception, node, target, (opts.merge message: %(could not embed image: #{image_path}; #{$!.message}#{::Prawn::Errors::UnsupportedImageType === $! ? '; install prawn-gmagick gem to add support' : ''}))
|
1518
1518
|
end
|
1519
|
-
ensure
|
1520
|
-
unlink_tmp_file image_path if image_path
|
1521
1519
|
end
|
1522
1520
|
|
1523
1521
|
def draw_image_border top, w, h, alignment
|
@@ -1537,7 +1535,7 @@ module Asciidoctor
|
|
1537
1535
|
end
|
1538
1536
|
|
1539
1537
|
def on_image_error _reason, node, target, opts = {}
|
1540
|
-
logger.warn opts[:message] if opts.key? :message
|
1538
|
+
logger.warn opts[:message] if (opts.key? :message) && !scratch?
|
1541
1539
|
alt_text_vars = { alt: (node.attr 'alt'), target: target }
|
1542
1540
|
alt_text_template = @theme.image_alt_content || '%{link}[%{alt}]%{/link} | <em>%{target}</em>'
|
1543
1541
|
if (link = node.attr 'link', nil, false)
|
@@ -1688,8 +1686,6 @@ module Asciidoctor
|
|
1688
1686
|
lexer_opts = { nowrap: true, noclasses: true, stripnl: false, style: style }
|
1689
1687
|
lexer_opts[:startinline] = !(node.option? 'mixed') if lexer.name == 'PHP'
|
1690
1688
|
source_string, conum_mapping = extract_conums source_string
|
1691
|
-
# NOTE: pygments.rb strips trailing whitespace; preserve it in case there are conums on last line
|
1692
|
-
num_trailing_spaces = source_string.length - (source_string = source_string.rstrip).length if conum_mapping
|
1693
1689
|
# NOTE: highlight can return nil if something goes wrong; fallback to encoded source string if this happens
|
1694
1690
|
result = (lexer.highlight source_string, options: lexer_opts) || (node.apply_subs source_string, [:specialcharacters])
|
1695
1691
|
if node.attr? 'highlight', nil, false
|
@@ -1711,7 +1707,7 @@ module Asciidoctor
|
|
1711
1707
|
postprocess = true
|
1712
1708
|
end
|
1713
1709
|
fragments = text_formatter.format result
|
1714
|
-
fragments = restore_conums fragments, conum_mapping,
|
1710
|
+
fragments = restore_conums fragments, conum_mapping, linenums, highlight_lines if postprocess
|
1715
1711
|
source_chunks = guard_indentation_in_fragments fragments
|
1716
1712
|
end
|
1717
1713
|
when 'rouge'
|
@@ -1793,7 +1789,7 @@ module Asciidoctor
|
|
1793
1789
|
string = string.split(LF).map.with_index {|line, line_num|
|
1794
1790
|
# FIXME: we get extra spaces before numbers if more than one on a line
|
1795
1791
|
if line.include? '<'
|
1796
|
-
line.gsub CalloutExtractRx do
|
1792
|
+
line = line.gsub CalloutExtractRx do
|
1797
1793
|
# honor the escape
|
1798
1794
|
if $1 == ?\\
|
1799
1795
|
$&.sub $1, ''
|
@@ -1802,9 +1798,14 @@ module Asciidoctor
|
|
1802
1798
|
''
|
1803
1799
|
end
|
1804
1800
|
end
|
1805
|
-
|
1806
|
-
line
|
1801
|
+
# NOTE use first position to store space that precedes conums
|
1802
|
+
if (conum_mapping.key? line_num) && (line.end_with? ' ')
|
1803
|
+
trimmed_line = line.rstrip
|
1804
|
+
conum_mapping[line_num].unshift line.slice trimmed_line.length, line.length
|
1805
|
+
line = trimmed_line
|
1806
|
+
end
|
1807
1807
|
end
|
1808
|
+
line
|
1808
1809
|
}.join LF
|
1809
1810
|
conum_mapping = nil if conum_mapping.empty?
|
1810
1811
|
[string, conum_mapping]
|
@@ -1814,7 +1815,7 @@ module Asciidoctor
|
|
1814
1815
|
#--
|
1815
1816
|
# QUESTION can this be done more efficiently?
|
1816
1817
|
# QUESTION can we reuse arrange_fragments_by_line?
|
1817
|
-
def restore_conums fragments, conum_mapping,
|
1818
|
+
def restore_conums fragments, conum_mapping, linenums = nil, highlight_lines = nil
|
1818
1819
|
lines = []
|
1819
1820
|
line_num = 0
|
1820
1821
|
# reorganize the fragments into an array of lines
|
@@ -1846,7 +1847,7 @@ module Asciidoctor
|
|
1846
1847
|
end
|
1847
1848
|
line.unshift text: %(#{visible_line_num.to_s.rjust pad_size} ), linenum: visible_line_num, color: linenum_color if linenums
|
1848
1849
|
if conum_mapping && (conums = conum_mapping.delete cur_line_num)
|
1849
|
-
line << { text:
|
1850
|
+
line << { text: conums.shift } if ::String === conums[0]
|
1850
1851
|
conum_text = conums.map {|num| conum_glyph num }.join ' '
|
1851
1852
|
line << (conum_color ? { text: conum_text, color: conum_color } : { text: conum_text })
|
1852
1853
|
end
|
@@ -2038,7 +2039,10 @@ module Asciidoctor
|
|
2038
2039
|
end
|
2039
2040
|
|
2040
2041
|
# NOTE: Prawn aborts if table data is empty, so ensure there's at least one row
|
2041
|
-
|
2042
|
+
if table_data.empty?
|
2043
|
+
logger.warn message_with_context 'no rows found in table', source_location: node.source_location
|
2044
|
+
table_data << ::Array.new([node.columns.size, 1].max) { { content: '' } }
|
2045
|
+
end
|
2042
2046
|
|
2043
2047
|
border_width = {}
|
2044
2048
|
table_border_color = theme.table_border_color || theme.table_grid_color || theme.base_border_color
|
@@ -2368,7 +2372,7 @@ module Asciidoctor
|
|
2368
2372
|
end
|
2369
2373
|
%(<a id="#{target || node.id}">#{DummyText}</a>#{reftext})
|
2370
2374
|
else
|
2371
|
-
logger.warn %(unknown anchor type: #{node.type.inspect})
|
2375
|
+
logger.warn %(unknown anchor type: #{node.type.inspect}) unless scratch?
|
2372
2376
|
end
|
2373
2377
|
end
|
2374
2378
|
|
@@ -2416,14 +2420,14 @@ module Asciidoctor
|
|
2416
2420
|
requested_icon_name = icon_name
|
2417
2421
|
icon_set, icon_name = remapped_icon_name.split '-', 2
|
2418
2422
|
glyph = (icon_font_data icon_set).unicode icon_name
|
2419
|
-
logger.info { %(#{requested_icon_name} icon found in deprecated fa icon set; using #{icon_name} from #{icon_set} icon set instead) }
|
2423
|
+
logger.info { %(#{requested_icon_name} icon found in deprecated fa icon set; using #{icon_name} from #{icon_set} icon set instead) } unless scratch?
|
2420
2424
|
# new name in Font Awesome >= 5 (but document is configured to use fa icon set)
|
2421
2425
|
else
|
2422
2426
|
font_data = nil
|
2423
2427
|
if (resolved_icon_set = FontAwesomeIconSets.find {|candidate| (font_data = icon_font_data candidate).unicode icon_name rescue nil })
|
2424
2428
|
icon_set = resolved_icon_set
|
2425
2429
|
glyph = font_data.unicode icon_name
|
2426
|
-
logger.info { %(#{icon_name} icon not found in deprecated fa icon set; using match found in #{resolved_icon_set} icon set instead) }
|
2430
|
+
logger.info { %(#{icon_name} icon not found in deprecated fa icon set; using match found in #{resolved_icon_set} icon set instead) } unless scratch?
|
2427
2431
|
end
|
2428
2432
|
end
|
2429
2433
|
else
|
@@ -2450,7 +2454,7 @@ module Asciidoctor
|
|
2450
2454
|
# TODO: support rotate and flip attributes
|
2451
2455
|
%(<font name="#{icon_set}"#{size_attr}#{class_attr}>#{glyph}</font>)
|
2452
2456
|
else
|
2453
|
-
logger.warn %(#{icon_name} is not a valid icon name in the #{icon_set} icon set)
|
2457
|
+
logger.warn %(#{icon_name} is not a valid icon name in the #{icon_set} icon set) unless scratch?
|
2454
2458
|
%([#{node.attr 'alt'}])
|
2455
2459
|
end
|
2456
2460
|
else
|
@@ -2472,7 +2476,7 @@ module Asciidoctor
|
|
2472
2476
|
if ::File.readable? image_path
|
2473
2477
|
width_attr = (width = preresolve_explicit_width node.attributes) ? %( width="#{width}") : ''
|
2474
2478
|
fit_attr = (fit = node.attr 'fit', nil, false) ? %( fit="#{fit}") : ''
|
2475
|
-
img = %(<img src="#{image_path}" format="#{image_format}" alt="[#{encode_quotes node.attr 'alt'}]"#{width_attr}#{fit_attr}
|
2479
|
+
img = %(<img src="#{image_path}" format="#{image_format}" alt="[#{encode_quotes node.attr 'alt'}]"#{width_attr}#{fit_attr}>)
|
2476
2480
|
else
|
2477
2481
|
logger.warn %(image to embed not found or not readable: #{image_path}) unless scratch?
|
2478
2482
|
img = %([#{node.attr 'alt'}])
|
@@ -2590,13 +2594,14 @@ module Asciidoctor
|
|
2590
2594
|
# QUESTION allow alignment per element on title page?
|
2591
2595
|
title_align = (@theme.title_page_align || @base_align).to_sym
|
2592
2596
|
|
2593
|
-
#
|
2597
|
+
# FIXME: disallow .pdf as image type
|
2594
2598
|
if @theme.title_page_logo_display != 'none' && (logo_image_path = (doc.attr 'title-logo-image') || (logo_image_from_theme = @theme.title_page_logo_image))
|
2595
2599
|
if (logo_image_path.include? ':') && logo_image_path =~ ImageAttributeValueRx
|
2596
2600
|
logo_image_attrs = (AttributeList.new $2).parse %w(alt width height)
|
2597
2601
|
if logo_image_from_theme
|
2598
2602
|
relative_to_imagesdir = false
|
2599
|
-
logo_image_path =
|
2603
|
+
logo_image_path = sub_attributes_discretely doc, $1
|
2604
|
+
logo_image_path = ThemeLoader.resolve_theme_asset logo_image_path, @themesdir unless doc.is_uri? logo_image_path
|
2600
2605
|
else
|
2601
2606
|
relative_to_imagesdir = true
|
2602
2607
|
logo_image_path = $1
|
@@ -2604,7 +2609,10 @@ module Asciidoctor
|
|
2604
2609
|
else
|
2605
2610
|
logo_image_attrs = {}
|
2606
2611
|
relative_to_imagesdir = false
|
2607
|
-
|
2612
|
+
if logo_image_from_theme
|
2613
|
+
logo_image_path = sub_attributes_discretely doc, logo_image_path
|
2614
|
+
logo_image_path = ThemeLoader.resolve_theme_asset logo_image_path, @themesdir unless doc.is_uri? logo_image_path
|
2615
|
+
end
|
2608
2616
|
end
|
2609
2617
|
logo_image_attrs['target'] = logo_image_path
|
2610
2618
|
if (logo_align = [(logo_image_attrs.delete 'align'), @theme.title_page_logo_align, title_align.to_s].find {|val| (BlockAlignmentNames.include? val) })
|
@@ -2730,8 +2738,6 @@ module Asciidoctor
|
|
2730
2738
|
image_page image_path, (image_opts.merge canvas: true)
|
2731
2739
|
end
|
2732
2740
|
end
|
2733
|
-
ensure
|
2734
|
-
unlink_tmp_file image_path if image_path
|
2735
2741
|
end
|
2736
2742
|
|
2737
2743
|
def stamp_foreground_image doc, has_front_cover
|
@@ -2866,6 +2872,7 @@ module Asciidoctor
|
|
2866
2872
|
raise ArgumentError, 'invalid subject'
|
2867
2873
|
end
|
2868
2874
|
category_caption = (category = opts[:category]) ? %(#{category}_caption) : 'caption'
|
2875
|
+
container_width = bounds.width
|
2869
2876
|
block_align = opts.delete :block_align
|
2870
2877
|
if (align = @theme[%(#{category_caption}_align)] || @theme.caption_align)
|
2871
2878
|
align = align == 'inherit' ? (block_align || @base_align) : align.to_sym
|
@@ -2873,16 +2880,21 @@ module Asciidoctor
|
|
2873
2880
|
align = @base_align.to_sym
|
2874
2881
|
end
|
2875
2882
|
indent_by = [0, 0]
|
2876
|
-
|
2877
|
-
|
2878
|
-
if
|
2879
|
-
|
2883
|
+
block_width = opts.delete :block_width
|
2884
|
+
if (max_width = opts.delete :max_width) && max_width != 'none'
|
2885
|
+
if max_width == 'fit-content'
|
2886
|
+
max_width = block_width || container_width
|
2887
|
+
else
|
2888
|
+
max_width = [max_width.to_f / 100 * bounds.width, bounds.width].min if ::String === max_width && (max_width.end_with? '%')
|
2889
|
+
block_align = align
|
2890
|
+
end
|
2891
|
+
if (remainder = container_width - max_width) > 0
|
2880
2892
|
case block_align
|
2881
2893
|
when :right
|
2882
2894
|
indent_by = [remainder, 0]
|
2883
2895
|
when :center
|
2884
2896
|
indent_by = [(side_margin = remainder * 0.5), side_margin]
|
2885
|
-
else # :left
|
2897
|
+
else # :left, nil
|
2886
2898
|
indent_by = [0, remainder]
|
2887
2899
|
end
|
2888
2900
|
end
|
@@ -3020,7 +3032,11 @@ module Asciidoctor
|
|
3020
3032
|
start_dots = last_fragment_pos.right + hanging_indent
|
3021
3033
|
last_fragment_cursor = last_fragment_pos.top + line_metrics.padding_top
|
3022
3034
|
# NOTE this will be incorrect if wrapped line is all monospace
|
3023
|
-
|
3035
|
+
if (last_fragment_page_number = last_fragment_pos.page_number) > start_page_number ||
|
3036
|
+
(start_cursor - last_fragment_cursor) > line_metrics.height
|
3037
|
+
start_page_number = last_fragment_page_number
|
3038
|
+
start_cursor = last_fragment_cursor
|
3039
|
+
end
|
3024
3040
|
end
|
3025
3041
|
end_page_number = page_number
|
3026
3042
|
end_cursor = cursor
|
@@ -3066,7 +3082,7 @@ module Asciidoctor
|
|
3066
3082
|
icon_data = (AdmonitionIcons[key] || {}).merge icon_data
|
3067
3083
|
if (icon_name = icon_data[:name])
|
3068
3084
|
unless icon_name.start_with?(*IconSetPrefixes)
|
3069
|
-
logger.info { %(#{key} admonition in theme uses icon from deprecated fa icon set; use fas, far, or fab instead) }
|
3085
|
+
logger.info { %(#{key} admonition in theme uses icon from deprecated fa icon set; use fas, far, or fab instead) } unless scratch?
|
3070
3086
|
icon_data[:name] = %(fa-#{icon_name}) unless icon_name.start_with? 'fa-'
|
3071
3087
|
end
|
3072
3088
|
end
|
@@ -3273,7 +3289,7 @@ module Asciidoctor
|
|
3273
3289
|
content = transform_text content, @text_transform if @text_transform
|
3274
3290
|
end
|
3275
3291
|
formatted_text_box parse_text(content, color: @font_color, inline_format: [normalize: true]),
|
3276
|
-
at: [left, bounds.top - trim_styles[:padding][0] - trim_styles[:content_offset] + (trim_styles[:valign] == :center ? font.descender * 0.5 : 0)],
|
3292
|
+
at: [left, bounds.top - trim_styles[:padding][0] - trim_styles[:content_offset] + ((Array trim_styles[:valign])[0] == :center ? font.descender * 0.5 : 0)],
|
3277
3293
|
width: colwidth,
|
3278
3294
|
height: trim_styles[:prose_content_height],
|
3279
3295
|
align: colspec[:align],
|
@@ -3299,6 +3315,10 @@ module Asciidoctor
|
|
3299
3315
|
|
3300
3316
|
def allocate_running_content_layout doc, page, periphery, cache
|
3301
3317
|
cache[layout = page.layout] ||= begin
|
3318
|
+
valign, valign_offset = @theme[%(#{periphery}_vertical_align)]
|
3319
|
+
if (valign = (valign || :middle).to_sym) == :middle
|
3320
|
+
valign = :center
|
3321
|
+
end
|
3302
3322
|
trim_styles = {
|
3303
3323
|
line_metrics: (trim_line_metrics = calc_line_metrics @theme[%(#{periphery}_line_height)] || @theme.base_line_height),
|
3304
3324
|
# NOTE we've already verified this property is set
|
@@ -3313,7 +3333,7 @@ module Asciidoctor
|
|
3313
3333
|
column_rule_style: (@theme[%(#{periphery}_column_rule_style)] || :solid).to_sym,
|
3314
3334
|
column_rule_width: (trim_column_rule_color ? @theme[%(#{periphery}_column_rule_width)] || 0 : 0),
|
3315
3335
|
column_rule_spacing: (@theme[%(#{periphery}_column_rule_spacing)] || 0),
|
3316
|
-
valign:
|
3336
|
+
valign: valign_offset ? [valign, valign_offset] : valign,
|
3317
3337
|
img_valign: @theme[%(#{periphery}_image_vertical_align)],
|
3318
3338
|
left: {
|
3319
3339
|
recto: (trim_left_recto = @page_margin_by_side[:recto][3]),
|
@@ -3338,7 +3358,7 @@ module Asciidoctor
|
|
3338
3358
|
}
|
3339
3359
|
case trim_styles[:img_valign]
|
3340
3360
|
when nil
|
3341
|
-
trim_styles[:img_valign] =
|
3361
|
+
trim_styles[:img_valign] = valign
|
3342
3362
|
when 'middle'
|
3343
3363
|
trim_styles[:img_valign] = :center
|
3344
3364
|
when 'top', 'center', 'bottom'
|
@@ -3392,10 +3412,9 @@ module Asciidoctor
|
|
3392
3412
|
ColumnPositions.each do |position|
|
3393
3413
|
unless (val = @theme[%(#{periphery}_#{side}_#{position}_content)]).nil_or_empty?
|
3394
3414
|
if (val.include? ':') && val =~ ImageAttributeValueRx
|
3395
|
-
|
3396
|
-
if
|
3397
|
-
|
3398
|
-
image_opts = resolve_image_options image_path, image_attrs, container_size: [colspec_dict[side][position][:width], trim_styles[:content_height]], format: image_attrs['format']
|
3415
|
+
image_attrs = (AttributeList.new $2).parse %w(alt width)
|
3416
|
+
if (image_path = resolve_image_path doc, $1, @themesdir, (image_format = image_attrs['format'])) && (::File.readable? image_path)
|
3417
|
+
image_opts = resolve_image_options image_path, image_attrs, container_size: [colspec_dict[side][position][:width], trim_styles[:content_height]], format: image_format
|
3399
3418
|
side_content[position] = [image_path, image_opts, image_attrs['link']]
|
3400
3419
|
else
|
3401
3420
|
# NOTE allows inline image handler to report invalid reference and replace with alt text
|
@@ -3550,7 +3569,7 @@ module Asciidoctor
|
|
3550
3569
|
true
|
3551
3570
|
end
|
3552
3571
|
end
|
3553
|
-
raise ::Errno::ENOENT, %(#{path} not found in #{fonts_dir}) unless found
|
3572
|
+
raise ::Errno::ENOENT, ((File.absolute_path? path) ? %(#{path} not found) : %(#{path} not found in #{fonts_dir.gsub ValueSeparatorRx, ' or '})) unless found
|
3554
3573
|
end
|
3555
3574
|
register_font key => styles
|
3556
3575
|
end
|
@@ -3620,7 +3639,7 @@ module Asciidoctor
|
|
3620
3639
|
if (b_color = @theme[%(#{category}_border_color)]) == 'transparent'
|
3621
3640
|
b_color = @page_bg_color
|
3622
3641
|
end
|
3623
|
-
b_radius = (@theme[%(#{category}_border_radius)] || 0) + b_width
|
3642
|
+
b_radius = (@theme[%(#{category}_border_radius)] || 0) + (b_width || 0)
|
3624
3643
|
if b_width && b_color
|
3625
3644
|
if b_color == @page_bg_color # let page background cut into block background
|
3626
3645
|
b_gap_color, b_shift = @page_bg_color, b_width
|
@@ -4000,46 +4019,53 @@ module Asciidoctor
|
|
4000
4019
|
# the temporary file. If the target is a URI and the allow-uri-read attribute
|
4001
4020
|
# is not set, or the URI cannot be read, this method returns a nil value.
|
4002
4021
|
#
|
4003
|
-
# When a temporary file is used, the
|
4004
|
-
def resolve_image_path node, image_path = nil,
|
4022
|
+
# When a temporary file is used, the file is stored in @tmp_files to be cleaned up after conversion.
|
4023
|
+
def resolve_image_path node, image_path = nil, relative_to = true, image_format = nil
|
4005
4024
|
doc = node.document
|
4006
|
-
imagesdir =
|
4025
|
+
imagesdir = relative_to == true ? (resolve_imagesdir doc) : relative_to
|
4007
4026
|
image_path ||= node.attr 'target'
|
4008
4027
|
image_format ||= ::Asciidoctor::Image.format image_path, (::Asciidoctor::Image === node ? node.attributes : nil)
|
4009
|
-
# NOTE currently used for inline images
|
4028
|
+
# NOTE base64 logic currently used for inline images
|
4010
4029
|
if ::Base64 === image_path
|
4011
|
-
|
4030
|
+
return (tmp_file = @tmp_files[image_path]) && tmp_file.path if @tmp_files.key? image_path
|
4031
|
+
@tmp_files[image_path] = tmp_image = ::Tempfile.create ['image-', image_format && %(.#{image_format})]
|
4012
4032
|
tmp_image.binmode unless image_format == 'svg'
|
4013
4033
|
begin
|
4014
4034
|
tmp_image.write ::Base64.decode64 image_path
|
4015
|
-
tmp_image.
|
4035
|
+
tmp_image.close
|
4036
|
+
tmp_image.path
|
4016
4037
|
rescue
|
4017
|
-
nil
|
4018
|
-
ensure
|
4038
|
+
@tmp_files[image_path] = nil
|
4019
4039
|
tmp_image.close
|
4040
|
+
unlink_tmp_file tmp_image
|
4041
|
+
nil
|
4020
4042
|
end
|
4021
4043
|
# handle case when image is a URI
|
4022
|
-
elsif (node.is_uri? image_path) ||
|
4023
|
-
(image_path =
|
4044
|
+
elsif (node.is_uri? image_path) ||
|
4045
|
+
(imagesdir && (node.is_uri? imagesdir) && (image_path = node.normalize_web_path image_path, imagesdir, false))
|
4024
4046
|
unless allow_uri_read
|
4025
4047
|
logger.warn %(allow-uri-read is not enabled; cannot embed remote image: #{image_path}) unless scratch?
|
4026
4048
|
return
|
4027
4049
|
end
|
4028
|
-
if
|
4050
|
+
if @tmp_files.key? image_path
|
4051
|
+
return (tmp_file = @tmp_files[image_path]) && tmp_file.path
|
4052
|
+
elsif cache_uri
|
4029
4053
|
Helpers.require_library 'open-uri/cached', 'open-uri-cached' unless defined? ::OpenURI::Cache
|
4030
4054
|
else
|
4031
4055
|
::OpenURI
|
4032
4056
|
end
|
4033
|
-
tmp_image = ::Tempfile.create ['image-', image_format && %(.#{image_format})]
|
4057
|
+
@tmp_files[image_path] = tmp_image = ::Tempfile.create ['image-', image_format && %(.#{image_format})]
|
4034
4058
|
tmp_image.binmode if (binary = image_format != 'svg')
|
4035
4059
|
begin
|
4036
4060
|
::OpenURI.open_uri(image_path, (binary ? 'rb' : 'r')) {|fd| tmp_image.write fd.read }
|
4037
|
-
tmp_image.
|
4061
|
+
tmp_image.close
|
4062
|
+
tmp_image.path
|
4038
4063
|
rescue
|
4039
4064
|
logger.warn %(could not retrieve remote image: #{image_path}; #{$!.message}) unless scratch?
|
4040
|
-
nil
|
4041
|
-
ensure
|
4065
|
+
@tmp_files[image_path] = nil
|
4042
4066
|
tmp_image.close
|
4067
|
+
unlink_tmp_file tmp_image
|
4068
|
+
nil
|
4043
4069
|
end
|
4044
4070
|
# handle case when image is a local file
|
4045
4071
|
else
|
@@ -4063,15 +4089,14 @@ module Asciidoctor
|
|
4063
4089
|
return []
|
4064
4090
|
elsif (image_path.include? ':') && image_path =~ ImageAttributeValueRx
|
4065
4091
|
image_attrs = (AttributeList.new $2).parse %w(alt width)
|
4092
|
+
image_format = image_attrs['format']
|
4066
4093
|
if from_theme
|
4067
|
-
|
4068
|
-
image_path = ThemeLoader.resolve_theme_asset (sub_attributes_discretely doc, $1), @themesdir
|
4094
|
+
image_path = resolve_image_path doc, (sub_attributes_discretely doc, $1), @themesdir, image_format
|
4069
4095
|
else
|
4070
|
-
image_path = resolve_image_path doc, $1, true,
|
4096
|
+
image_path = resolve_image_path doc, $1, true, image_format
|
4071
4097
|
end
|
4072
4098
|
elsif from_theme
|
4073
|
-
|
4074
|
-
image_path = ThemeLoader.resolve_theme_asset (sub_attributes_discretely doc, image_path), @themesdir
|
4099
|
+
image_path = resolve_image_path doc, (sub_attributes_discretely doc, image_path), @themesdir
|
4075
4100
|
else
|
4076
4101
|
image_path = resolve_image_path doc, image_path, false
|
4077
4102
|
end
|
@@ -4079,7 +4104,7 @@ module Asciidoctor
|
|
4079
4104
|
return unless image_path
|
4080
4105
|
|
4081
4106
|
unless ::File.readable? image_path
|
4082
|
-
logger.warn %(#{key.tr '-', ' '} not found or readable: #{image_path})
|
4107
|
+
logger.warn %(#{key.to_s.tr '-_', ' '} not found or readable: #{image_path})
|
4083
4108
|
return
|
4084
4109
|
end
|
4085
4110
|
|
@@ -4279,13 +4304,16 @@ module Asciidoctor
|
|
4279
4304
|
link_annotation [image_x, (image_y - image_height), (image_x + image_width), image_y], Border: [0, 0, 0], A: { Type: :Action, S: :URI, URI: uri.as_pdf }
|
4280
4305
|
end
|
4281
4306
|
|
4282
|
-
|
4283
|
-
|
4284
|
-
|
4285
|
-
|
4286
|
-
|
4307
|
+
def clean_up_tmp_files
|
4308
|
+
@tmp_files.values.each {|tmp_file| unlink_tmp_file tmp_file if tmp_file }
|
4309
|
+
@tmp_files.clear
|
4310
|
+
end
|
4311
|
+
|
4312
|
+
def unlink_tmp_file file
|
4313
|
+
path = file.path
|
4314
|
+
::File.unlink path if ::File.exist? path
|
4287
4315
|
rescue
|
4288
|
-
logger.warn %(could not delete temporary
|
4316
|
+
logger.warn %(could not delete temporary file: #{path}; #{$!.message}) unless scratch?
|
4289
4317
|
end
|
4290
4318
|
|
4291
4319
|
def apply_subs_discretely doc, value, opts = {}
|
@@ -4308,7 +4336,7 @@ module Asciidoctor
|
|
4308
4336
|
|
4309
4337
|
def sub_attributes_discretely doc, value
|
4310
4338
|
doc.set_attr 'attribute-missing', 'skip' unless (attribute_missing = doc.attr 'attribute-missing') == 'skip'
|
4311
|
-
value = doc.apply_subs value
|
4339
|
+
value = doc.apply_subs value, [:attributes]
|
4312
4340
|
doc.set_attr 'attribute-missing', attribute_missing unless attribute_missing == 'skip'
|
4313
4341
|
value
|
4314
4342
|
end
|
@@ -4394,11 +4422,14 @@ module Asciidoctor
|
|
4394
4422
|
def init_scratch_prototype
|
4395
4423
|
@save_state = nil
|
4396
4424
|
@scratch_depth = 0
|
4425
|
+
# NOTE can't marshall tmp_files, so clear them before creating prototype
|
4426
|
+
saved_tmp_files, @tmp_files = @tmp_files, {}
|
4397
4427
|
# IMPORTANT don't set font before using Marshal, it causes serialization to fail
|
4398
4428
|
@prototype = ::Marshal.load ::Marshal.dump self
|
4399
|
-
@prototype.state.store.info.data[:Scratch] = true
|
4429
|
+
@prototype.state.store.info.data[:Scratch] = @prototype.text_formatter.scratch = true
|
4400
4430
|
# NOTE we're now starting a new page each time, so no need to do it here
|
4401
4431
|
#@prototype.start_new_page if @prototype.page_number == 0
|
4432
|
+
@tmp_files = saved_tmp_files
|
4402
4433
|
end
|
4403
4434
|
|
4404
4435
|
def push_scratch doc
|