asciidoctor-pdf 2.1.2 → 2.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +40 -0
- data/README.adoc +1 -3
- data/bin/asciidoctor-pdf +3 -3
- data/lib/asciidoctor/pdf/converter.rb +45 -37
- data/lib/asciidoctor/pdf/ext/prawn/document/column_box.rb +10 -7
- data/lib/asciidoctor/pdf/ext/prawn/extensions.rb +10 -26
- data/lib/asciidoctor/pdf/ext/prawn-table/cell/asciidoc.rb +5 -2
- data/lib/asciidoctor/pdf/ext/prawn-table/cell/text.rb +3 -1
- data/lib/asciidoctor/pdf/ext/prawn-table/cell.rb +2 -0
- data/lib/asciidoctor/pdf/formatted_text/transform.rb +33 -2
- data/lib/asciidoctor/pdf/index_catalog.rb +1 -1
- data/lib/asciidoctor/pdf/text_transformer.rb +23 -0
- data/lib/asciidoctor/pdf/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0cacde45fb257acbe2644ae3da1673e0a9fe9cd42f4b97de92a3ae2d97400fdb
|
4
|
+
data.tar.gz: e4e01d9fa4e923e598277c5db822632a5dc3fe67e51ebbea26d744f8d30e7315
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2fadd03cc382136bf1387867d83d68396f58c4182a51616254562c1d6460e28e0555781e9c5c51d372cd6d3fee29f80b7c06d9fc0d6e055a2839cf63491bf92d
|
7
|
+
data.tar.gz: 6fa97a16ff15ac5b0dee3789d33aa2760595139299ae41eb4e0104b4346c8569ffb8f1377fd0844f2c98ec831a08156258754e2a54f25c9fb10972a681f0c592
|
data/CHANGELOG.adoc
CHANGED
@@ -5,6 +5,46 @@
|
|
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 {url-repo}/commits/main[commit history] on GitHub.
|
7
7
|
|
8
|
+
== 2.1.5 (2022-07-10) - @mojavelinux
|
9
|
+
|
10
|
+
Bug Fixes::
|
11
|
+
|
12
|
+
* fix position of background color on caption with outside margin (#2271)
|
13
|
+
* don't allow font scale to compound when entering nested table (#2276)
|
14
|
+
|
15
|
+
=== Details
|
16
|
+
|
17
|
+
{url-repo}/releases/tag/v2.1.5[git tag] | {url-repo}/compare/v2.1.4\...v2.1.5[full diff]
|
18
|
+
|
19
|
+
== 2.1.4 (2022-06-26) - @mojavelinux
|
20
|
+
|
21
|
+
Improvements::
|
22
|
+
|
23
|
+
* include source location in warning message for truncated table cell if sourcemap is enabled (#2261)
|
24
|
+
|
25
|
+
Bug Fixes::
|
26
|
+
|
27
|
+
* allow alt text for block image, video, and audio to wrap to next line on same page (#2258)
|
28
|
+
* apply text-tranform from custom role on phrase after attributes have been resolved (#2263)
|
29
|
+
* make URL check more strict so image target containing a colon is not mistaken as a URL
|
30
|
+
|
31
|
+
=== Details
|
32
|
+
|
33
|
+
{url-repo}/releases/tag/v2.1.4[git tag] | {url-repo}/compare/v2.1.3\...v2.1.4[full diff]
|
34
|
+
|
35
|
+
== 2.1.3 (2022-06-23) - @mojavelinux
|
36
|
+
|
37
|
+
Bug Fixes::
|
38
|
+
|
39
|
+
* interpret `start-at` theme keys with value `1` correctly (as `1` instead of `2`) (#2255)
|
40
|
+
* restore column layout after importing page(s) from PDF (#2253)
|
41
|
+
* fix crash when border color is transparent (`thematic-break-border-color`, `admonition-column-rule`, `quote-border-color`, `verse-border-color`)
|
42
|
+
* ensure page margin is restored after imported page
|
43
|
+
|
44
|
+
=== Details
|
45
|
+
|
46
|
+
{url-repo}/releases/tag/v2.1.3[git tag] | {url-repo}/compare/v2.1.2\...v2.1.3[full diff]
|
47
|
+
|
8
48
|
== 2.1.2 (2022-06-17) - @mojavelinux
|
9
49
|
|
10
50
|
Bug Fixes::
|
data/README.adoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
= Asciidoctor PDF: A native PDF converter for AsciiDoc
|
2
2
|
Dan Allen <https://github.com/mojavelinux[@mojavelinux]>; Sarah White <https://github.com/graphitefriction[@graphitefriction]>
|
3
|
-
v2.1.
|
3
|
+
v2.1.5, 2022-07-10
|
4
4
|
// Settings:
|
5
5
|
:experimental:
|
6
6
|
:idprefix:
|
@@ -22,8 +22,6 @@ endif::[]
|
|
22
22
|
// Aliases:
|
23
23
|
:project-name: Asciidoctor PDF
|
24
24
|
:project-handle: asciidoctor-pdf
|
25
|
-
// Variables:
|
26
|
-
:release-line: 2.1.x
|
27
25
|
// URLs:
|
28
26
|
:url-gem: https://rubygems.org/gems/asciidoctor-pdf
|
29
27
|
:url-project: https://github.com/asciidoctor/asciidoctor-pdf
|
data/bin/asciidoctor-pdf
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
if File.file?(asciidoctor_pdf = (File.
|
4
|
+
if File.file? (asciidoctor_pdf = File.join (File.dirname __dir__), 'lib/asciidoctor/pdf.rb')
|
5
5
|
require asciidoctor_pdf
|
6
6
|
else
|
7
7
|
require 'asciidoctor/pdf'
|
@@ -10,14 +10,14 @@ require 'asciidoctor/cli'
|
|
10
10
|
|
11
11
|
options = Asciidoctor::Cli::Options.new backend: 'pdf', header_footer: true
|
12
12
|
|
13
|
-
# FIXME provide an API in Asciidoctor for sub-components to print version information
|
13
|
+
# FIXME: provide an API in Asciidoctor for sub-components to print version information
|
14
14
|
unless ARGV != ['-v'] && (ARGV & ['-V', '--version']).empty?
|
15
15
|
$stdout.write %(Asciidoctor PDF #{Asciidoctor::PDF::VERSION} using )
|
16
16
|
options.print_version
|
17
17
|
exit 0
|
18
18
|
end
|
19
19
|
|
20
|
-
# FIXME This is a really bizarre API. Please make me simpler.
|
20
|
+
# FIXME: This is a really bizarre API. Please make me simpler.
|
21
21
|
case (result = options.parse! ARGV)
|
22
22
|
when Integer
|
23
23
|
exit result
|
@@ -27,8 +27,6 @@ module Asciidoctor
|
|
27
27
|
|
28
28
|
attr_accessor :font_scale
|
29
29
|
|
30
|
-
attr_reader :root_font_size
|
31
|
-
|
32
30
|
attr_reader :index
|
33
31
|
|
34
32
|
attr_reader :theme
|
@@ -114,6 +112,7 @@ module Asciidoctor
|
|
114
112
|
UriBreakCharsRx = %r((?:/|\?|&|#)(?!$))
|
115
113
|
UriBreakCharRepl = %(\\&#{ZeroWidthSpace})
|
116
114
|
UriSchemeBoundaryRx = %r((?<=://))
|
115
|
+
UrlSniffRx = %r(^\p{Alpha}[\p{Alnum}+.-]*://)
|
117
116
|
LineScanRx = /\n|.+/
|
118
117
|
BlankLineRx = /\n{2,}/
|
119
118
|
CjkLineBreakRx = /(?=[\u3000\u30a0-\u30ff\u3040-\u309f\p{Han}\uff00-\uffef])/
|
@@ -213,7 +212,7 @@ module Asciidoctor
|
|
213
212
|
first_page_offset = has_title_page ? zero_page_offset.next : zero_page_offset
|
214
213
|
body_offset = (body_start_page_number = page_number) - 1
|
215
214
|
if ::Integer === (running_content_start_at = @theme.running_content_start_at)
|
216
|
-
running_content_body_offset = body_offset + [running_content_start_at.pred,
|
215
|
+
running_content_body_offset = body_offset + [running_content_start_at.pred, 0].max
|
217
216
|
running_content_start_at = 'body'
|
218
217
|
else
|
219
218
|
running_content_body_offset = body_offset
|
@@ -227,7 +226,7 @@ module Asciidoctor
|
|
227
226
|
end
|
228
227
|
end
|
229
228
|
if ::Integer === (page_numbering_start_at = @theme.page_numbering_start_at)
|
230
|
-
page_numbering_body_offset = body_offset + [page_numbering_start_at.pred,
|
229
|
+
page_numbering_body_offset = body_offset + [page_numbering_start_at.pred, 0].max
|
231
230
|
page_numbering_start_at = 'body'
|
232
231
|
else
|
233
232
|
page_numbering_body_offset = body_offset
|
@@ -263,12 +262,12 @@ module Asciidoctor
|
|
263
262
|
else
|
264
263
|
body_offset = body_start_page_number - 1
|
265
264
|
if ::Integer === (running_content_start_at = @theme.running_content_start_at)
|
266
|
-
running_content_body_offset = body_offset + [running_content_start_at.pred,
|
265
|
+
running_content_body_offset = body_offset + [running_content_start_at.pred, 0].max
|
267
266
|
else
|
268
267
|
running_content_body_offset = body_offset
|
269
268
|
end
|
270
269
|
if ::Integer === (page_numbering_start_at = @theme.page_numbering_start_at)
|
271
|
-
page_numbering_body_offset = body_offset + [page_numbering_start_at.pred,
|
270
|
+
page_numbering_body_offset = body_offset + [page_numbering_start_at.pred, 0].max
|
272
271
|
elsif page_numbering_start_at == 'cover' && has_front_cover
|
273
272
|
page_numbering_body_offset = 0
|
274
273
|
else
|
@@ -371,8 +370,6 @@ module Asciidoctor
|
|
371
370
|
if (page_margin_inner = theme.page_margin_inner)
|
372
371
|
page_margin_recto[3] = page_margin_verso[1] = page_margin_inner
|
373
372
|
end
|
374
|
-
# NOTE: prepare scratch document to use page margin from recto side (which has same width as verso side)
|
375
|
-
set_page_margin page_margin_recto unless page_margin_recto == page_margin
|
376
373
|
else
|
377
374
|
@ppbook = nil
|
378
375
|
end
|
@@ -581,6 +578,7 @@ module Asciidoctor
|
|
581
578
|
end
|
582
579
|
|
583
580
|
def prepare_theme theme
|
581
|
+
theme.base_border_color = nil if theme.base_border_color == 'transparent'
|
584
582
|
theme.base_font_color ||= '000000'
|
585
583
|
theme.base_font_size ||= 12
|
586
584
|
theme.base_font_style = theme.base_font_style&.to_sym || :normal
|
@@ -943,7 +941,7 @@ module Asciidoctor
|
|
943
941
|
if extent
|
944
942
|
label_height = extent.single_page_height || cursor
|
945
943
|
if (rule_width = @theme.admonition_column_rule_width || 0) > 0 &&
|
946
|
-
(rule_color =
|
944
|
+
(rule_color = resolve_theme_color :admonition_column_rule_color, @theme.base_border_color, nil)
|
947
945
|
rule_style = @theme.admonition_column_rule_style&.to_sym || :solid
|
948
946
|
float do
|
949
947
|
extent.each_page do |first_page, last_page|
|
@@ -1273,7 +1271,7 @@ module Asciidoctor
|
|
1273
1271
|
category = node.context == :quote ? :quote : :verse
|
1274
1272
|
# NOTE: b_width and b_left_width are mutually exclusive
|
1275
1273
|
if (b_left_width = @theme[%(#{category}_border_left_width)]) && b_left_width > 0
|
1276
|
-
b_color =
|
1274
|
+
b_left_width = nil unless (b_color = resolve_theme_color %(#{category}_border_color), @theme.base_border_color, nil)
|
1277
1275
|
else
|
1278
1276
|
b_left_width = nil
|
1279
1277
|
b_width = nil if (b_width = @theme[%(#{category}_border_width)]) == 0
|
@@ -1887,7 +1885,7 @@ module Asciidoctor
|
|
1887
1885
|
add_dest_for_block node if node.id
|
1888
1886
|
audio_path = node.media_uri node.attr 'target'
|
1889
1887
|
play_symbol = (node.document.attr? 'icons', 'font') ? %(<font name="fas">#{(icon_font_data 'fas').unicode 'play'}</font>) : RightPointer
|
1890
|
-
ink_prose %(#{play_symbol}#{NoBreakSpace}<a href="#{audio_path}">#{audio_path}</a> <em>(audio)</em>), normalize: false, margin: 0
|
1888
|
+
ink_prose %(#{play_symbol}#{NoBreakSpace}<a href="#{audio_path}">#{audio_path}</a> <em>(audio)</em>), normalize: false, margin: 0
|
1891
1889
|
ink_caption node, labeled: false, end: :bottom if node.title?
|
1892
1890
|
theme_margin :block, :bottom, (next_enclosed_block node)
|
1893
1891
|
end
|
@@ -1915,7 +1913,7 @@ module Asciidoctor
|
|
1915
1913
|
if poster.nil_or_empty?
|
1916
1914
|
add_dest_for_block node if node.id
|
1917
1915
|
play_symbol = (node.document.attr? 'icons', 'font') ? %(<font name="fas">#{(icon_font_data 'fas').unicode 'play'}</font>) : RightPointer
|
1918
|
-
ink_prose %(#{play_symbol}#{NoBreakSpace}<a href="#{video_path}">#{video_path}</a> <em>(#{type})</em>), normalize: false, margin: 0
|
1916
|
+
ink_prose %(#{play_symbol}#{NoBreakSpace}<a href="#{video_path}">#{video_path}</a> <em>(#{type})</em>), normalize: false, margin: 0
|
1919
1917
|
ink_caption node, labeled: false, end: :bottom if node.title?
|
1920
1918
|
theme_margin :block, :bottom, (next_enclosed_block node)
|
1921
1919
|
else
|
@@ -1996,6 +1994,7 @@ module Asciidoctor
|
|
1996
1994
|
num_cols = node.columns.size
|
1997
1995
|
table_header_size = false
|
1998
1996
|
theme = @theme
|
1997
|
+
prev_font_scale, @font_scale = @font_scale, 1 if node.document.nested?
|
1999
1998
|
|
2000
1999
|
tbl_bg_color = resolve_theme_color :table_background_color
|
2001
2000
|
# QUESTION: should we fallback to page background color? (which is never transparent)
|
@@ -2054,7 +2053,8 @@ module Asciidoctor
|
|
2054
2053
|
content: cell_text,
|
2055
2054
|
colspan: cell.colspan || 1,
|
2056
2055
|
align: (cell.attr 'halign').to_sym,
|
2057
|
-
valign: (val = cell.attr 'valign') == 'middle' ? :center : val.to_sym
|
2056
|
+
valign: (val = cell.attr 'valign') == 'middle' ? :center : val.to_sym,
|
2057
|
+
source_location: cell.source_location
|
2058
2058
|
end)
|
2059
2059
|
end
|
2060
2060
|
end unless head_rows.empty?
|
@@ -2073,7 +2073,8 @@ module Asciidoctor
|
|
2073
2073
|
colspan: cell.colspan || 1,
|
2074
2074
|
rowspan: cell.rowspan || 1,
|
2075
2075
|
align: (cell.attr 'halign').to_sym,
|
2076
|
-
valign: (val = cell.attr 'valign') == 'middle' ? :center : val.to_sym
|
2076
|
+
valign: (val = cell.attr 'valign') == 'middle' ? :center : val.to_sym,
|
2077
|
+
source_location: cell.source_location
|
2077
2078
|
cell_line_metrics = body_cell_line_metrics
|
2078
2079
|
case cell.style
|
2079
2080
|
when :emphasis
|
@@ -2133,8 +2134,8 @@ module Asciidoctor
|
|
2133
2134
|
end
|
2134
2135
|
# NOTE: line metrics get applied when AsciiDoc content is converted
|
2135
2136
|
cell_line_metrics = nil
|
2136
|
-
asciidoc_cell = ::Prawn::Table::Cell::AsciiDoc.new self, (cell_data.merge content: cell.inner_document, padding: body_cell_padding)
|
2137
|
-
cell_data = { content: asciidoc_cell }
|
2137
|
+
asciidoc_cell = ::Prawn::Table::Cell::AsciiDoc.new self, (cell_data.merge content: cell.inner_document, padding: body_cell_padding, root_font_size: @root_font_size)
|
2138
|
+
cell_data = { content: asciidoc_cell, source_location: cell.source_location }
|
2138
2139
|
end
|
2139
2140
|
if cell_line_metrics
|
2140
2141
|
cell_padding = body_cell_padding.dup
|
@@ -2337,13 +2338,17 @@ module Asciidoctor
|
|
2337
2338
|
theme_margin :block, :bottom, (next_enclosed_block node)
|
2338
2339
|
rescue ::Prawn::Errors::CannotFit
|
2339
2340
|
log :error, (message_with_context 'cannot fit contents of table cell into specified column width', source_location: node.source_location)
|
2341
|
+
ensure
|
2342
|
+
@font_scale = prev_font_scale if prev_font_scale
|
2340
2343
|
end
|
2341
2344
|
|
2342
2345
|
def convert_thematic_break node
|
2343
2346
|
pad_box @theme.thematic_break_padding || [@theme.thematic_break_margin_top, 0] do
|
2344
|
-
|
2345
|
-
|
2346
|
-
|
2347
|
+
if (b_color = resolve_theme_color :thematic_break_border_color)
|
2348
|
+
stroke_horizontal_rule b_color,
|
2349
|
+
line_width: @theme.thematic_break_border_width,
|
2350
|
+
line_style: (@theme.thematic_break_border_style&.to_sym || :solid)
|
2351
|
+
end
|
2347
2352
|
end
|
2348
2353
|
conceal_page_top { theme_margin :block, :bottom, (next_enclosed_block node) }
|
2349
2354
|
end
|
@@ -2684,13 +2689,7 @@ module Asciidoctor
|
|
2684
2689
|
end
|
2685
2690
|
|
2686
2691
|
if (roles = node.role)
|
2687
|
-
|
2688
|
-
roles.split.each do |role|
|
2689
|
-
if (text_transform = theme[%(role_#{role}_text_transform)])
|
2690
|
-
inner_text = transform_text inner_text, text_transform
|
2691
|
-
end
|
2692
|
-
inner_text = inner_text.gsub DoubleSpaceRx, ' ' + ZeroWidthSpace if role == 'pre-wrap' && (inner_text.include? DoubleSpace)
|
2693
|
-
end
|
2692
|
+
inner_text = inner_text.gsub DoubleSpaceRx, ' ' + ZeroWidthSpace if (node.has_role? 'pre-wrap') && (inner_text.include? DoubleSpace)
|
2694
2693
|
quoted_text = is_tag ? %(#{open.chop} class="#{roles}">#{inner_text}#{close}) : %(<span class="#{roles}">#{open}#{inner_text}#{close}</span>)
|
2695
2694
|
else
|
2696
2695
|
quoted_text = %(#{open}#{inner_text}#{close})
|
@@ -3105,7 +3104,8 @@ module Asciidoctor
|
|
3105
3104
|
end
|
3106
3105
|
unless scratch? || !(bg_color = @theme[%(#{category_caption}_background_color)] || @theme.caption_background_color)
|
3107
3106
|
caption_height = height_of_typeset_text string
|
3108
|
-
fill_at = [bounds.left, cursor
|
3107
|
+
fill_at = [bounds.left, cursor]
|
3108
|
+
fill_at[1] -= (margin[:top] || 0) unless at_page_top?
|
3109
3109
|
float { bounding_box(fill_at, width: container_width, height: caption_height) { fill_bounds bg_color } }
|
3110
3110
|
end
|
3111
3111
|
indent(*indent_by) do
|
@@ -3240,7 +3240,8 @@ module Asciidoctor
|
|
3240
3240
|
end
|
3241
3241
|
end
|
3242
3242
|
|
3243
|
-
# NOTE: inline_format is true by default
|
3243
|
+
# NOTE: inline_format option is true by default
|
3244
|
+
# NOTE: single_line option is not compatible with this method
|
3244
3245
|
def ink_prose string, opts = {}
|
3245
3246
|
top_margin = (margin = (opts.delete :margin)) || (opts.delete :margin_top) || 0
|
3246
3247
|
bot_margin = margin || (opts.delete :margin_bottom) || @theme.prose_margin_bottom
|
@@ -4254,10 +4255,10 @@ module Asciidoctor
|
|
4254
4255
|
# NOTE: this will catch a classloader resource path on JRuby (e.g., uri:classloader:/path/to/image)
|
4255
4256
|
elsif ::File.absolute_path? image_path
|
4256
4257
|
::File.absolute_path image_path
|
4257
|
-
elsif !(
|
4258
|
+
elsif !(is_url = url? image_path) && imagesdir && (::File.absolute_path? imagesdir)
|
4258
4259
|
::File.absolute_path image_path, imagesdir
|
4259
4260
|
# handle case when image is a URI
|
4260
|
-
elsif
|
4261
|
+
elsif is_url || (imagesdir && (url? imagesdir) && (image_path = node.normalize_web_path image_path, imagesdir, false))
|
4261
4262
|
if !allow_uri_read
|
4262
4263
|
log :warn, %(cannot embed remote image: #{image_path} (allow-uri-read attribute not enabled))
|
4263
4264
|
return
|
@@ -4495,6 +4496,7 @@ module Asciidoctor
|
|
4495
4496
|
end
|
4496
4497
|
|
4497
4498
|
# TODO: document me, esp the first line formatting functionality
|
4499
|
+
# NOTE: single_line option should only be used if height option is specified
|
4498
4500
|
def typeset_text string, line_metrics, opts = {}
|
4499
4501
|
opts = { leading: line_metrics.leading, final_gap: line_metrics.final_gap }.merge opts
|
4500
4502
|
string = string.gsub CjkLineBreakRx, ZeroWidthSpace if @cjk_line_breaks
|
@@ -4817,18 +4819,17 @@ module Asciidoctor
|
|
4817
4819
|
end
|
4818
4820
|
|
4819
4821
|
# NOTE: init_page is called within a float context; this will suppress prawn-svg messing with the cursor
|
4820
|
-
# NOTE: init_page is not called for imported pages,
|
4822
|
+
# NOTE: init_page is not called for imported pages, cover pages, image pages, and pages in the scratch document
|
4821
4823
|
def init_page *_args
|
4822
4824
|
next_page_side = page_side nil, @folio_placement[:inverted]
|
4823
4825
|
if @media == 'prepress' && (next_page_margin = @page_margin_by_side[page_number == 1 ? :cover : next_page_side]) != page_margin
|
4824
4826
|
set_page_margin next_page_margin
|
4825
4827
|
end
|
4826
4828
|
unless @page_bg_color == 'FFFFFF'
|
4827
|
-
tare = true
|
4828
4829
|
fill_absolute_bounds @page_bg_color
|
4830
|
+
tare = true
|
4829
4831
|
end
|
4830
4832
|
if (bg_image_path, bg_image_opts = @page_bg_image[next_page_side])
|
4831
|
-
tare = true
|
4832
4833
|
begin
|
4833
4834
|
if bg_image_opts[:format] == 'pdf'
|
4834
4835
|
# NOTE: pages that use PDF for the background do not support a background color or running content
|
@@ -4837,6 +4838,7 @@ module Asciidoctor
|
|
4837
4838
|
else
|
4838
4839
|
canvas { image bg_image_path, ({ position: :center, vposition: :center }.merge bg_image_opts) }
|
4839
4840
|
end
|
4841
|
+
tare = true
|
4840
4842
|
rescue
|
4841
4843
|
facing_page_side = (PageSides - [next_page_side])[0]
|
4842
4844
|
@page_bg_image[facing_page_side] = nil if @page_bg_image[facing_page_side] == @page_bg_image[next_page_side]
|
@@ -4949,7 +4951,7 @@ module Asciidoctor
|
|
4949
4951
|
alt_text_vars[:'/link'] = ''
|
4950
4952
|
end
|
4951
4953
|
theme_font :image_alt do
|
4952
|
-
ink_prose alt_text_template % alt_text_vars, align: opts[:align], margin: 0, normalize: false
|
4954
|
+
ink_prose alt_text_template % alt_text_vars, align: opts[:align], margin: 0, normalize: false
|
4953
4955
|
end
|
4954
4956
|
ink_caption node, category: :image, end: :bottom if node.title?
|
4955
4957
|
theme_margin :block, :bottom, (next_enclosed_block node) unless opts[:pinned]
|
@@ -5031,10 +5033,8 @@ module Asciidoctor
|
|
5031
5033
|
# QUESTION: should we pass a category as an argument?
|
5032
5034
|
# QUESTION: should we make this a method on the theme ostruct? (e.g., @theme.resolve_color key, fallback)
|
5033
5035
|
def resolve_theme_color key, fallback_color = nil, transparent_color = fallback_color
|
5034
|
-
if (color = @theme[key])
|
5036
|
+
if (color = @theme[key] || fallback_color)
|
5035
5037
|
color == 'transparent' ? transparent_color : color
|
5036
|
-
else
|
5037
|
-
fallback_color
|
5038
5038
|
end
|
5039
5039
|
end
|
5040
5040
|
|
@@ -5046,6 +5046,10 @@ module Asciidoctor
|
|
5046
5046
|
false
|
5047
5047
|
end
|
5048
5048
|
|
5049
|
+
def url? str
|
5050
|
+
(str.include? ':/') && (UrlSniffRx.match? str)
|
5051
|
+
end
|
5052
|
+
|
5049
5053
|
# Calculate the width that is needed to print all the
|
5050
5054
|
# fragments without wrapping any lines.
|
5051
5055
|
#
|
@@ -5114,6 +5118,10 @@ module Asciidoctor
|
|
5114
5118
|
end
|
5115
5119
|
|
5116
5120
|
def init_scratch originator
|
5121
|
+
if @media == 'prepress' && page_margin != (page_margin_recto = @page_margin_by_side[:recto])
|
5122
|
+
# NOTE: prepare scratch document to use page margin from recto side (which has same width as verso side)
|
5123
|
+
set_page_margin page_margin_recto
|
5124
|
+
end
|
5117
5125
|
@scratch_prototype = originator.instance_variable_get :@scratch_prototype
|
5118
5126
|
@tmp_files = originator.instance_variable_get :@tmp_files
|
5119
5127
|
text_formatter.scratch = true
|
@@ -6,20 +6,23 @@ Prawn::Document::ColumnBox.prepend (Module.new do
|
|
6
6
|
def move_past_bottom
|
7
7
|
(doc = @document).y = @y
|
8
8
|
return if (@current_column = (@current_column + 1) % @columns) > 0
|
9
|
-
|
10
|
-
if (
|
11
|
-
@y = par.absolute_top
|
12
|
-
@height = par.height unless stretchy?
|
13
|
-
end
|
9
|
+
parent_ = @parent
|
10
|
+
reset_top parent_ if (reflow_at = @reflow_margins) && (reflow_at == true || reflow_at > doc.page_number)
|
14
11
|
initial_margins = doc.page.margins
|
15
|
-
|
12
|
+
parent_.move_past_bottom
|
16
13
|
if doc.page.margins != initial_margins
|
17
|
-
doc.bounds = self.class.new doc,
|
14
|
+
doc.bounds = self.class.new doc, parent_, [(margin_box = doc.margin_box).absolute_left, @y],
|
18
15
|
columns: @columns, reflow_margins: @reflow_margins, spacer: @spacer, width: margin_box.width, height: @height
|
19
16
|
end
|
20
17
|
nil
|
21
18
|
end
|
22
19
|
|
20
|
+
def reset_top parent_ = @parent
|
21
|
+
@current_column = 0
|
22
|
+
@height = parent_.height unless stretchy?
|
23
|
+
@y = parent_.absolute_top
|
24
|
+
end
|
25
|
+
|
23
26
|
# Rearranges the column box into a single column, where the original columns are in a single file. Used
|
24
27
|
# for the purpose of computing the extent of content in a scratch document.
|
25
28
|
def single_file
|
@@ -528,29 +528,6 @@ module Asciidoctor
|
|
528
528
|
end
|
529
529
|
end
|
530
530
|
|
531
|
-
# Apply the text transform to the specified text.
|
532
|
-
#
|
533
|
-
# Supported transform values are "uppercase", "lowercase", or "none" (passed
|
534
|
-
# as either a String or a Symbol). When the uppercase transform is applied to
|
535
|
-
# the text, it correctly uppercases visible text while leaving markup and
|
536
|
-
# named character entities unchanged. The none transform returns the text
|
537
|
-
# unmodified.
|
538
|
-
#
|
539
|
-
def transform_text text, transform
|
540
|
-
case transform
|
541
|
-
when :uppercase, 'uppercase'
|
542
|
-
uppercase_pcdata text
|
543
|
-
when :lowercase, 'lowercase'
|
544
|
-
lowercase_pcdata text
|
545
|
-
when :capitalize, 'capitalize'
|
546
|
-
capitalize_words_pcdata text
|
547
|
-
when :smallcaps, 'smallcaps'
|
548
|
-
smallcaps_pcdata text
|
549
|
-
else
|
550
|
-
text
|
551
|
-
end
|
552
|
-
end
|
553
|
-
|
554
531
|
def hyphenate_text text, hyphenator
|
555
532
|
hyphenate_words_pcdata text, hyphenator
|
556
533
|
end
|
@@ -924,6 +901,8 @@ module Asciidoctor
|
|
924
901
|
def import_page file, options = {}
|
925
902
|
prev_page_layout = page.layout
|
926
903
|
prev_page_size = page.size
|
904
|
+
prev_page_margin = page_margin
|
905
|
+
prev_bounds = bounds
|
927
906
|
state.compress = false if state.compress # can't use compression if using template
|
928
907
|
prev_text_rendering_mode = (defined? @text_rendering_mode) ? @text_rendering_mode : nil
|
929
908
|
delete_current_page if options[:replace]
|
@@ -936,11 +915,15 @@ module Asciidoctor
|
|
936
915
|
# NOTE: set page size & layout explicitly in case imported page differs
|
937
916
|
# I'm not sure it's right to start a new page here, but unfortunately there's no other
|
938
917
|
# way atm to prevent the size & layout of the imported page from affecting subsequent pages
|
939
|
-
|
918
|
+
if options.fetch :advance, true
|
919
|
+
advance_page layout: prev_page_layout, margin: prev_page_margin, size: prev_page_size
|
920
|
+
(@bounding_box = prev_bounds).reset_top if ColumnBox === prev_bounds
|
921
|
+
end
|
940
922
|
elsif options.fetch :advance_if_missing, true
|
941
923
|
delete_current_page
|
942
924
|
# NOTE: see previous comment
|
943
|
-
advance_page
|
925
|
+
advance_page layout: prev_page_layout, margin: prev_page_margin, size: prev_page_size
|
926
|
+
@y = (@bounding_box = prev_bounds).reset_top if ColumnBox === prev_bounds
|
944
927
|
else
|
945
928
|
delete_current_page
|
946
929
|
end
|
@@ -1112,7 +1095,8 @@ module Asciidoctor
|
|
1112
1095
|
# This method performs all work in a scratch document (or documents). It begins by starting a
|
1113
1096
|
# new page in the scratch document, first creating the scratch document if necessary. It then
|
1114
1097
|
# applies all the settings from the main document to the scratch document that impact
|
1115
|
-
# rendering. This includes the bounds, the cursor position, and the font settings.
|
1098
|
+
# rendering. This includes the bounds, the cursor position, and the font settings. This method
|
1099
|
+
# assumes that the content area remains constant when content flows from one page to the next.
|
1116
1100
|
#
|
1117
1101
|
# From this point, the number of attempts the method makes is determined by the value of the
|
1118
1102
|
# keep_together keyword parameter. If the value is true (or the parent document is inhibiting
|
@@ -7,6 +7,7 @@ module Prawn
|
|
7
7
|
include ::Asciidoctor::Logging
|
8
8
|
|
9
9
|
attr_accessor :align
|
10
|
+
attr_accessor :root_font_size
|
10
11
|
attr_accessor :valign
|
11
12
|
|
12
13
|
def initialize pdf, opts = {}
|
@@ -91,7 +92,9 @@ module Prawn
|
|
91
92
|
# TODO: apply horizontal alignment; currently it is necessary to specify alignment on content blocks
|
92
93
|
apply_font_properties { pdf.traverse content }
|
93
94
|
if (extra_pages = pdf.page_number - start_page) > 0
|
94
|
-
|
95
|
+
unless extra_pages == 1 && pdf.page.empty?
|
96
|
+
logger.error message_with_context %(the table cell on page #{start_page} has been truncated; Asciidoctor PDF does not support table cell content that exceeds the height of a single page), source_location: @source_location
|
97
|
+
end
|
95
98
|
extra_pages.times { pdf.delete_current_page }
|
96
99
|
end
|
97
100
|
nil
|
@@ -107,7 +110,7 @@ module Prawn
|
|
107
110
|
prev_font_color, pdf.font_color = pdf.font_color, font_color if font_color
|
108
111
|
font_family ||= font_info[:family]
|
109
112
|
if font_size
|
110
|
-
prev_font_scale, pdf.font_scale = pdf.font_scale, (font_size.to_f / @
|
113
|
+
prev_font_scale, pdf.font_scale = pdf.font_scale, (font_size.to_f / @root_font_size)
|
111
114
|
else
|
112
115
|
font_size = font_info[:size]
|
113
116
|
end
|
@@ -16,7 +16,9 @@ class Prawn::Table::Cell::Text
|
|
16
16
|
height: spanned_content_height + FPTolerance,
|
17
17
|
at: [0, @pdf.cursor]).render
|
18
18
|
end
|
19
|
-
|
19
|
+
unless remaining_text.empty? || @pdf.scratch?
|
20
|
+
logger.error message_with_context %(the table cell on page #{@pdf.page_number} has been truncated; Asciidoctor PDF does not support table cell content that exceeds the height of a single page), source_location: @source_location
|
21
|
+
end
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
@@ -4,6 +4,8 @@ module Asciidoctor
|
|
4
4
|
module PDF
|
5
5
|
module FormattedText
|
6
6
|
class Transform
|
7
|
+
include TextTransformer
|
8
|
+
|
7
9
|
LF = ?\n
|
8
10
|
ZeroWidthSpace = ?\u200b
|
9
11
|
CharEntityTable = { amp: '&', apos: ?', gt: '>', lt: '<', nbsp: ?\u00a0, quot: '"' }
|
@@ -21,8 +23,8 @@ module Asciidoctor
|
|
21
23
|
'font_size' => :size,
|
22
24
|
'text_decoration_color' => :text_decoration_color,
|
23
25
|
'text_decoration_width' => :text_decoration_width,
|
26
|
+
'text_transform' => :text_transform,
|
24
27
|
}
|
25
|
-
#DummyText = ?\u0000
|
26
28
|
|
27
29
|
def initialize options = {}
|
28
30
|
@merge_adjacent_text_nodes = options[:merge_adjacent_text_nodes]
|
@@ -172,6 +174,11 @@ module Asciidoctor
|
|
172
174
|
previous_fragment_is_text && ((previous_fragment_text = fragments[-1][:text]).end_with? ' ')
|
173
175
|
fragments[-1][:text] = previous_fragment_text.chop
|
174
176
|
end
|
177
|
+
if (text_transform = fragment.delete :text_transform)
|
178
|
+
text = (text_chunks = extract_text pcdata).join
|
179
|
+
text_io = StringIO.new transform_text text, text_transform
|
180
|
+
restore_text pcdata, text_chunks.each_with_object([]) {|chunk, accum| accum << (text_io.read chunk.length) }
|
181
|
+
end
|
175
182
|
# NOTE: decorate child fragments with inherited properties from this element
|
176
183
|
apply pcdata, fragments, fragment
|
177
184
|
previous_fragment_is_text = false
|
@@ -251,6 +258,8 @@ module Asciidoctor
|
|
251
258
|
fragments
|
252
259
|
end
|
253
260
|
|
261
|
+
private
|
262
|
+
|
254
263
|
def build_fragment fragment, tag_name, attrs
|
255
264
|
styles = (fragment[:styles] ||= ::Set.new)
|
256
265
|
case tag_name
|
@@ -324,7 +333,6 @@ module Asciidoctor
|
|
324
333
|
# NOTE: spaces in style value are superfluous for our purpose; split drops record after trailing ;
|
325
334
|
attrs[:style].tr(' ', '').split(';').each do |style|
|
326
335
|
pname, pvalue = style.split ':', 2
|
327
|
-
# TODO: text-transform
|
328
336
|
case pname
|
329
337
|
when 'color' # color needed to support syntax highlighters
|
330
338
|
fragment[:color] = pvalue.length == 7 ? (pvalue.slice 1, 6) : (pvalue.slice 1, 3).each_char.map {|c| c * 2 }.join if (pvalue.start_with? '#') && (HexColorRx.match? pvalue)
|
@@ -409,6 +417,29 @@ module Asciidoctor
|
|
409
417
|
end
|
410
418
|
end
|
411
419
|
end
|
420
|
+
|
421
|
+
def extract_text pcdata
|
422
|
+
pcdata.reduce [] do |accum, it|
|
423
|
+
case it[:type]
|
424
|
+
when :text
|
425
|
+
accum << it[:value]
|
426
|
+
when :element
|
427
|
+
accum += (extract_text it[:pcdata]) if it.key? :pcdata
|
428
|
+
end
|
429
|
+
accum
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
433
|
+
def restore_text pcdata, text_chunks
|
434
|
+
pcdata.each do |it|
|
435
|
+
case it[:type]
|
436
|
+
when :text
|
437
|
+
it[:value] = text_chunks.shift
|
438
|
+
when :element
|
439
|
+
restore_text it[:pcdata], text_chunks if it.key? :pcdata
|
440
|
+
end
|
441
|
+
end
|
442
|
+
end
|
412
443
|
end
|
413
444
|
end
|
414
445
|
end
|
@@ -64,6 +64,29 @@ module Asciidoctor
|
|
64
64
|
string.tr LowerAlphaChars, SmallCapsChars
|
65
65
|
end
|
66
66
|
end
|
67
|
+
|
68
|
+
# Apply the text transform to the specified text.
|
69
|
+
#
|
70
|
+
# Supported transform values are "uppercase", "lowercase", or "none" (passed
|
71
|
+
# as either a String or a Symbol). When the uppercase transform is applied to
|
72
|
+
# the text, it correctly uppercases visible text while leaving markup and
|
73
|
+
# named character entities unchanged. The none transform returns the text
|
74
|
+
# unmodified.
|
75
|
+
#
|
76
|
+
def transform_text text, transform
|
77
|
+
case transform
|
78
|
+
when :uppercase, 'uppercase'
|
79
|
+
uppercase_pcdata text
|
80
|
+
when :lowercase, 'lowercase'
|
81
|
+
lowercase_pcdata text
|
82
|
+
when :capitalize, 'capitalize'
|
83
|
+
capitalize_words_pcdata text
|
84
|
+
when :smallcaps, 'smallcaps'
|
85
|
+
smallcaps_pcdata text
|
86
|
+
else
|
87
|
+
text
|
88
|
+
end
|
89
|
+
end
|
67
90
|
end
|
68
91
|
end
|
69
92
|
end
|
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: 2.1.
|
4
|
+
version: 2.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dan Allen
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2022-
|
12
|
+
date: 2022-07-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: asciidoctor
|