asciidoctor-pdf 2.1.2 → 2.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|