asciidoctor-pdf 2.1.3 → 2.1.4
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 +16 -0
- data/README.adoc +1 -1
- data/lib/asciidoctor/pdf/converter.rb +19 -16
- data/lib/asciidoctor/pdf/ext/prawn/extensions.rb +0 -23
- data/lib/asciidoctor/pdf/ext/prawn-table/cell/asciidoc.rb +3 -1
- 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: eb8baebe850d75fcfc95460fbbdf89978867adb076acf572abaff0f51e18fb04
|
4
|
+
data.tar.gz: d4dbbaab4981db0666488ae108aee0f5851feb706e3846b13cd5cf46c341b5bc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 26b1c9830deeb0a39494e9cdb85fa5c2e2295efe8b3d527525b27c6dcf420a8ab94e06eeaca3431425e9cf547150d372bab49813af946cdd5ea0e155d6aad1f0
|
7
|
+
data.tar.gz: d584830d1eb1f76a005b48cf6a20030311d40184254d4ddfbd752f99a66c27feab85292c79012af0c9c4b7272a1727f402828f1c6d992228660ccbf78be44d2a
|
data/CHANGELOG.adoc
CHANGED
@@ -5,6 +5,22 @@
|
|
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.4 (2022-06-26) - @mojavelinux
|
9
|
+
|
10
|
+
Improvements::
|
11
|
+
|
12
|
+
* include source location in warning message for truncated table cell if sourcemap is enabled (#2261)
|
13
|
+
|
14
|
+
Bug Fixes::
|
15
|
+
|
16
|
+
* allow alt text for block image, video, and audio to wrap to next line on same page (#2258)
|
17
|
+
* apply text-tranform from custom role on phrase after attributes have been resolved (#2263)
|
18
|
+
* make URL check more strict so image target containing a colon is not mistaken as a URL
|
19
|
+
|
20
|
+
=== Details
|
21
|
+
|
22
|
+
{url-repo}/releases/tag/v2.1.4[git tag] | {url-repo}/compare/v2.1.3\...v2.1.4[full diff]
|
23
|
+
|
8
24
|
== 2.1.3 (2022-06-23) - @mojavelinux
|
9
25
|
|
10
26
|
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.4, 2022-06-26
|
4
4
|
// Settings:
|
5
5
|
:experimental:
|
6
6
|
:idprefix:
|
@@ -114,6 +114,7 @@ module Asciidoctor
|
|
114
114
|
UriBreakCharsRx = %r((?:/|\?|&|#)(?!$))
|
115
115
|
UriBreakCharRepl = %(\\&#{ZeroWidthSpace})
|
116
116
|
UriSchemeBoundaryRx = %r((?<=://))
|
117
|
+
UrlSniffRx = %r(^\p{Alpha}[\p{Alnum}+.-]*://)
|
117
118
|
LineScanRx = /\n|.+/
|
118
119
|
BlankLineRx = /\n{2,}/
|
119
120
|
CjkLineBreakRx = /(?=[\u3000\u30a0-\u30ff\u3040-\u309f\p{Han}\uff00-\uffef])/
|
@@ -1886,7 +1887,7 @@ module Asciidoctor
|
|
1886
1887
|
add_dest_for_block node if node.id
|
1887
1888
|
audio_path = node.media_uri node.attr 'target'
|
1888
1889
|
play_symbol = (node.document.attr? 'icons', 'font') ? %(<font name="fas">#{(icon_font_data 'fas').unicode 'play'}</font>) : RightPointer
|
1889
|
-
ink_prose %(#{play_symbol}#{NoBreakSpace}<a href="#{audio_path}">#{audio_path}</a> <em>(audio)</em>), normalize: false, margin: 0
|
1890
|
+
ink_prose %(#{play_symbol}#{NoBreakSpace}<a href="#{audio_path}">#{audio_path}</a> <em>(audio)</em>), normalize: false, margin: 0
|
1890
1891
|
ink_caption node, labeled: false, end: :bottom if node.title?
|
1891
1892
|
theme_margin :block, :bottom, (next_enclosed_block node)
|
1892
1893
|
end
|
@@ -1914,7 +1915,7 @@ module Asciidoctor
|
|
1914
1915
|
if poster.nil_or_empty?
|
1915
1916
|
add_dest_for_block node if node.id
|
1916
1917
|
play_symbol = (node.document.attr? 'icons', 'font') ? %(<font name="fas">#{(icon_font_data 'fas').unicode 'play'}</font>) : RightPointer
|
1917
|
-
ink_prose %(#{play_symbol}#{NoBreakSpace}<a href="#{video_path}">#{video_path}</a> <em>(#{type})</em>), normalize: false, margin: 0
|
1918
|
+
ink_prose %(#{play_symbol}#{NoBreakSpace}<a href="#{video_path}">#{video_path}</a> <em>(#{type})</em>), normalize: false, margin: 0
|
1918
1919
|
ink_caption node, labeled: false, end: :bottom if node.title?
|
1919
1920
|
theme_margin :block, :bottom, (next_enclosed_block node)
|
1920
1921
|
else
|
@@ -2053,7 +2054,8 @@ module Asciidoctor
|
|
2053
2054
|
content: cell_text,
|
2054
2055
|
colspan: cell.colspan || 1,
|
2055
2056
|
align: (cell.attr 'halign').to_sym,
|
2056
|
-
valign: (val = cell.attr 'valign') == 'middle' ? :center : val.to_sym
|
2057
|
+
valign: (val = cell.attr 'valign') == 'middle' ? :center : val.to_sym,
|
2058
|
+
source_location: cell.source_location
|
2057
2059
|
end)
|
2058
2060
|
end
|
2059
2061
|
end unless head_rows.empty?
|
@@ -2072,7 +2074,8 @@ module Asciidoctor
|
|
2072
2074
|
colspan: cell.colspan || 1,
|
2073
2075
|
rowspan: cell.rowspan || 1,
|
2074
2076
|
align: (cell.attr 'halign').to_sym,
|
2075
|
-
valign: (val = cell.attr 'valign') == 'middle' ? :center : val.to_sym
|
2077
|
+
valign: (val = cell.attr 'valign') == 'middle' ? :center : val.to_sym,
|
2078
|
+
source_location: cell.source_location
|
2076
2079
|
cell_line_metrics = body_cell_line_metrics
|
2077
2080
|
case cell.style
|
2078
2081
|
when :emphasis
|
@@ -2133,7 +2136,7 @@ module Asciidoctor
|
|
2133
2136
|
# NOTE: line metrics get applied when AsciiDoc content is converted
|
2134
2137
|
cell_line_metrics = nil
|
2135
2138
|
asciidoc_cell = ::Prawn::Table::Cell::AsciiDoc.new self, (cell_data.merge content: cell.inner_document, padding: body_cell_padding)
|
2136
|
-
cell_data = { content: asciidoc_cell }
|
2139
|
+
cell_data = { content: asciidoc_cell, source_location: cell.source_location }
|
2137
2140
|
end
|
2138
2141
|
if cell_line_metrics
|
2139
2142
|
cell_padding = body_cell_padding.dup
|
@@ -2685,13 +2688,7 @@ module Asciidoctor
|
|
2685
2688
|
end
|
2686
2689
|
|
2687
2690
|
if (roles = node.role)
|
2688
|
-
|
2689
|
-
roles.split.each do |role|
|
2690
|
-
if (text_transform = theme[%(role_#{role}_text_transform)])
|
2691
|
-
inner_text = transform_text inner_text, text_transform
|
2692
|
-
end
|
2693
|
-
inner_text = inner_text.gsub DoubleSpaceRx, ' ' + ZeroWidthSpace if role == 'pre-wrap' && (inner_text.include? DoubleSpace)
|
2694
|
-
end
|
2691
|
+
inner_text = inner_text.gsub DoubleSpaceRx, ' ' + ZeroWidthSpace if (node.has_role? 'pre-wrap') && (inner_text.include? DoubleSpace)
|
2695
2692
|
quoted_text = is_tag ? %(#{open.chop} class="#{roles}">#{inner_text}#{close}) : %(<span class="#{roles}">#{open}#{inner_text}#{close}</span>)
|
2696
2693
|
else
|
2697
2694
|
quoted_text = %(#{open}#{inner_text}#{close})
|
@@ -3241,7 +3238,8 @@ module Asciidoctor
|
|
3241
3238
|
end
|
3242
3239
|
end
|
3243
3240
|
|
3244
|
-
# NOTE: inline_format is true by default
|
3241
|
+
# NOTE: inline_format option is true by default
|
3242
|
+
# NOTE: single_line option is not compatible with this method
|
3245
3243
|
def ink_prose string, opts = {}
|
3246
3244
|
top_margin = (margin = (opts.delete :margin)) || (opts.delete :margin_top) || 0
|
3247
3245
|
bot_margin = margin || (opts.delete :margin_bottom) || @theme.prose_margin_bottom
|
@@ -4255,10 +4253,10 @@ module Asciidoctor
|
|
4255
4253
|
# NOTE: this will catch a classloader resource path on JRuby (e.g., uri:classloader:/path/to/image)
|
4256
4254
|
elsif ::File.absolute_path? image_path
|
4257
4255
|
::File.absolute_path image_path
|
4258
|
-
elsif !(
|
4256
|
+
elsif !(is_url = url? image_path) && imagesdir && (::File.absolute_path? imagesdir)
|
4259
4257
|
::File.absolute_path image_path, imagesdir
|
4260
4258
|
# handle case when image is a URI
|
4261
|
-
elsif
|
4259
|
+
elsif is_url || (imagesdir && (url? imagesdir) && (image_path = node.normalize_web_path image_path, imagesdir, false))
|
4262
4260
|
if !allow_uri_read
|
4263
4261
|
log :warn, %(cannot embed remote image: #{image_path} (allow-uri-read attribute not enabled))
|
4264
4262
|
return
|
@@ -4496,6 +4494,7 @@ module Asciidoctor
|
|
4496
4494
|
end
|
4497
4495
|
|
4498
4496
|
# TODO: document me, esp the first line formatting functionality
|
4497
|
+
# NOTE: single_line option should only be used if height option is specified
|
4499
4498
|
def typeset_text string, line_metrics, opts = {}
|
4500
4499
|
opts = { leading: line_metrics.leading, final_gap: line_metrics.final_gap }.merge opts
|
4501
4500
|
string = string.gsub CjkLineBreakRx, ZeroWidthSpace if @cjk_line_breaks
|
@@ -4950,7 +4949,7 @@ module Asciidoctor
|
|
4950
4949
|
alt_text_vars[:'/link'] = ''
|
4951
4950
|
end
|
4952
4951
|
theme_font :image_alt do
|
4953
|
-
ink_prose alt_text_template % alt_text_vars, align: opts[:align], margin: 0, normalize: false
|
4952
|
+
ink_prose alt_text_template % alt_text_vars, align: opts[:align], margin: 0, normalize: false
|
4954
4953
|
end
|
4955
4954
|
ink_caption node, category: :image, end: :bottom if node.title?
|
4956
4955
|
theme_margin :block, :bottom, (next_enclosed_block node) unless opts[:pinned]
|
@@ -5045,6 +5044,10 @@ module Asciidoctor
|
|
5045
5044
|
false
|
5046
5045
|
end
|
5047
5046
|
|
5047
|
+
def url? str
|
5048
|
+
(str.include? ':/') && (UrlSniffRx.match? str)
|
5049
|
+
end
|
5050
|
+
|
5048
5051
|
# Calculate the width that is needed to print all the
|
5049
5052
|
# fragments without wrapping any lines.
|
5050
5053
|
#
|
@@ -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
|
@@ -91,7 +91,9 @@ module Prawn
|
|
91
91
|
# TODO: apply horizontal alignment; currently it is necessary to specify alignment on content blocks
|
92
92
|
apply_font_properties { pdf.traverse content }
|
93
93
|
if (extra_pages = pdf.page_number - start_page) > 0
|
94
|
-
|
94
|
+
unless extra_pages == 1 && pdf.page.empty?
|
95
|
+
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
|
96
|
+
end
|
95
97
|
extra_pages.times { pdf.delete_current_page }
|
96
98
|
end
|
97
99
|
nil
|
@@ -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.4
|
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-06-
|
12
|
+
date: 2022-06-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: asciidoctor
|