asciidoctor-pdf 2.1.5 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +71 -8
- data/README.adoc +1 -1
- data/bin/asciidoctor-pdf +26 -7
- data/bin/asciidoctor-pdf-optimize +1 -2
- data/data/themes/base-theme.yml +2 -2
- data/data/themes/default-theme.yml +7 -30
- data/lib/asciidoctor/pdf/converter.rb +232 -154
- data/lib/asciidoctor/pdf/ext/asciidoctor/document.rb +5 -0
- data/lib/asciidoctor/pdf/ext/prawn/document/column_box.rb +4 -0
- data/lib/asciidoctor/pdf/ext/prawn/extensions.rb +10 -4
- data/lib/asciidoctor/pdf/ext/prawn/formatted_text/arranger.rb +11 -0
- data/lib/asciidoctor/pdf/ext/prawn/formatted_text/line_wrap.rb +42 -0
- data/lib/asciidoctor/pdf/ext/prawn.rb +1 -0
- data/lib/asciidoctor/pdf/formatted_text/transform.rb +5 -2
- data/lib/asciidoctor/pdf/sanitizer.rb +7 -3
- data/lib/asciidoctor/pdf/theme_loader.rb +10 -14
- data/lib/asciidoctor/pdf/version.rb +1 -1
- metadata +3 -2
@@ -371,14 +371,16 @@ module Asciidoctor
|
|
371
371
|
else
|
372
372
|
super points.to_f
|
373
373
|
end
|
374
|
-
# NOTE: assume em value (since a font size of 1 is extremely unlikely)
|
375
|
-
elsif points <= 1
|
376
|
-
super @font_size * points
|
377
374
|
else
|
378
375
|
super points
|
379
376
|
end
|
380
377
|
end
|
381
378
|
|
379
|
+
def set_font font, size = nil
|
380
|
+
@font = font
|
381
|
+
font_size size if size
|
382
|
+
end
|
383
|
+
|
382
384
|
def resolve_font_style styles
|
383
385
|
if styles.include? :bold
|
384
386
|
(styles.include? :italic) ? :bold_italic : :bold
|
@@ -1121,6 +1123,10 @@ module Asciidoctor
|
|
1121
1123
|
# Note that if the block has content that itself requires a dry run, that nested dry run will
|
1122
1124
|
# be performed in a separate scratch document.
|
1123
1125
|
#
|
1126
|
+
# The block passed to dry run should take steps to avoid leaving the document state modified.
|
1127
|
+
# This can be done by calling `push_scratch doc` at the start of the block and `pop_scratch`
|
1128
|
+
# in the ensure clause of the block.
|
1129
|
+
#
|
1124
1130
|
# options - A Hash of options that configure the dry run computation:
|
1125
1131
|
# :keep_together - A Boolean indicating whether an attempt should be made to keep
|
1126
1132
|
# the content on the same page (optional, default: false).
|
@@ -1133,7 +1139,7 @@ module Asciidoctor
|
|
1133
1139
|
#
|
1134
1140
|
# Returns an Extent or ScratchExtent object that describes the bounds of the content block.
|
1135
1141
|
def dry_run keep_together: nil, pages_advanced: 0, single_page: nil, onto: nil, &block
|
1136
|
-
(scratch_pdf = scratch).start_new_page layout: page.layout
|
1142
|
+
(scratch_pdf = scratch).start_new_page layout: page.layout, margin: page_margin
|
1137
1143
|
saved_bounds = scratch_pdf.bounds
|
1138
1144
|
scratch_pdf.bounds = bounds.dup.tap do |bounds_copy|
|
1139
1145
|
bounds_copy.instance_variable_set :@document, scratch_pdf
|
@@ -26,6 +26,17 @@ Prawn::Text::Formatted::Arranger.prepend (Module.new do
|
|
26
26
|
(string = super) == @dummy_text ? (string.extend Prawn::Text::NoopLstripBang) : string
|
27
27
|
end
|
28
28
|
|
29
|
+
def preview_joined_string
|
30
|
+
if (next_unconsumed = @unconsumed[0] || {})[:wj] && !(@consumed[-1] || [])[:wj]
|
31
|
+
idx = 0
|
32
|
+
str = '' if (str = next_unconsumed[:text]) == @dummy_text
|
33
|
+
while (next_unconsumed = @unconsumed[idx += 1] || {})[:wj] && (next_string = next_unconsumed[:text])
|
34
|
+
str += next_string unless next_string == @dummy_text
|
35
|
+
end
|
36
|
+
str unless str == ''
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
29
40
|
def apply_font_size size, styles
|
30
41
|
if (subscript? styles) || (superscript? styles)
|
31
42
|
size ||= @document.font_size
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Prawn::Text::Formatted::LineWrap.prepend (Module.new do
|
4
|
+
def add_fragment_to_line fragment
|
5
|
+
case fragment
|
6
|
+
when ''
|
7
|
+
true
|
8
|
+
when ?\n
|
9
|
+
@newline_encountered = true
|
10
|
+
false
|
11
|
+
else
|
12
|
+
if (joined_string = @arranger.preview_joined_string)
|
13
|
+
joined_string_width = @document.width_of (tokenize joined_string)[0], kerning: @kerning
|
14
|
+
else
|
15
|
+
joined_string_width = 0
|
16
|
+
end
|
17
|
+
last_idx = (segments = tokenize fragment).length - 1
|
18
|
+
segments.each_with_index do |segment, idx|
|
19
|
+
if segment == (zero_width_space segment.encoding)
|
20
|
+
segment_width = effective_segment_width = 0
|
21
|
+
else
|
22
|
+
segment_width = effective_segment_width = @document.width_of segment, kerning: @kerning
|
23
|
+
effective_segment_width += joined_string_width if idx === last_idx
|
24
|
+
end
|
25
|
+
if @accumulated_width + effective_segment_width <= @width
|
26
|
+
@accumulated_width += segment_width
|
27
|
+
if segment[-1] == (shy = soft_hyphen segment.encoding)
|
28
|
+
@accumulated_width -= (@document.width_of shy, kerning: @kerning)
|
29
|
+
end
|
30
|
+
@fragment_output += segment
|
31
|
+
else
|
32
|
+
@line_contains_more_than_one_word = false if @accumulated_width == 0 && @line_contains_more_than_one_word
|
33
|
+
end_of_the_line_reached segment
|
34
|
+
fragment_finished fragment
|
35
|
+
return false
|
36
|
+
end
|
37
|
+
end
|
38
|
+
fragment_finished fragment
|
39
|
+
true
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end)
|
@@ -13,5 +13,6 @@ require_relative 'prawn/formatted_text/arranger'
|
|
13
13
|
require_relative 'prawn/formatted_text/box'
|
14
14
|
require_relative 'prawn/formatted_text/fragment'
|
15
15
|
require_relative 'prawn/formatted_text/indented_paragraph_wrap'
|
16
|
+
require_relative 'prawn/formatted_text/line_wrap'
|
16
17
|
require_relative 'prawn/formatted_text/protect_bottom_gutter'
|
17
18
|
require_relative 'prawn/extensions'
|
@@ -315,10 +315,12 @@ module Asciidoctor
|
|
315
315
|
end) : value
|
316
316
|
elsif (value = attrs[:id])
|
317
317
|
# NOTE: text is null character, which is used as placeholder text so Prawn doesn't drop fragment
|
318
|
-
|
318
|
+
new_fragment = { name: value, callback: [InlineDestinationMarker] }
|
319
|
+
new_fragment[:wj] = true if fragment[:wj]
|
319
320
|
if (type = attrs[:type])
|
320
|
-
|
321
|
+
new_fragment[:type] = type.to_sym
|
321
322
|
end
|
323
|
+
fragment = new_fragment
|
322
324
|
visible = nil
|
323
325
|
end
|
324
326
|
end
|
@@ -357,6 +359,7 @@ module Asciidoctor
|
|
357
359
|
end
|
358
360
|
# TODO: we could limit to select tags, but doesn't seem to really affect performance
|
359
361
|
attrs[:class].split.each do |class_name|
|
362
|
+
fragment[:wj] = true if class_name == 'wj'
|
360
363
|
next unless @theme_settings.key? class_name
|
361
364
|
update_fragment fragment, @theme_settings[class_name]
|
362
365
|
# NOTE: defer assignment of callback since we must look at combined styles of element and role
|
@@ -8,7 +8,7 @@ module Asciidoctor
|
|
8
8
|
'>' => '>',
|
9
9
|
'&' => '&',
|
10
10
|
}
|
11
|
-
XMLSpecialCharsRx =
|
11
|
+
XMLSpecialCharsRx = /&(?:[lg]t|amp);/
|
12
12
|
InverseXMLSpecialChars = XMLSpecialChars.invert
|
13
13
|
InverseXMLSpecialCharsRx = /[#{InverseXMLSpecialChars.keys.join}]/
|
14
14
|
(BuiltInNamedEntities = {
|
@@ -28,16 +28,20 @@ module Asciidoctor
|
|
28
28
|
#
|
29
29
|
# FIXME: move to a module so we can mix it in elsewhere
|
30
30
|
# FIXME: add option to control escaping entities, or a filter mechanism in general
|
31
|
-
def sanitize string
|
31
|
+
def sanitize string, compact: true
|
32
32
|
string = string.gsub SanitizeXMLRx, '' if string.include? '<'
|
33
33
|
string = string.gsub(CharRefRx) { $1 ? BuiltInNamedEntities[$1] : ([$2 ? $2.to_i : ($3.to_i 16)].pack 'U1') } if string.include? '&'
|
34
|
-
string.strip.tr_s ' ', ' '
|
34
|
+
compact ? (string.strip.tr_s ' ', ' ') : string
|
35
35
|
end
|
36
36
|
|
37
37
|
def escape_xml string
|
38
38
|
string.gsub InverseXMLSpecialCharsRx, InverseXMLSpecialChars
|
39
39
|
end
|
40
40
|
|
41
|
+
def unescape_xml string
|
42
|
+
string.gsub XMLSpecialCharsRx, XMLSpecialChars
|
43
|
+
end
|
44
|
+
|
41
45
|
def escape_amp string
|
42
46
|
string.gsub UnescapedAmpersandRx, '&'
|
43
47
|
end
|
@@ -160,7 +160,7 @@ module Asciidoctor
|
|
160
160
|
data[key] = {}.tap do |accum|
|
161
161
|
val.each do |key2, val2|
|
162
162
|
key2 = key2.tr '-', '_' if key2.include? '-'
|
163
|
-
accum[key2.to_sym] = (key2.end_with? '_color') ? (to_color evaluate val2, data) : (evaluate val2, data)
|
163
|
+
accum[key2.to_sym] = (key2.end_with? '_color') ? (to_color evaluate val2, data, math: false) : (evaluate val2, data)
|
164
164
|
end
|
165
165
|
end if val
|
166
166
|
elsif ::Hash === val
|
@@ -173,20 +173,18 @@ module Asciidoctor
|
|
173
173
|
end
|
174
174
|
elsif (rekey = DeprecatedKeys[key]) ||
|
175
175
|
((key.start_with? 'role_') && (key.end_with? '_align') && (rekey = key.sub RoleAlignKeyRx, '_text_align'))
|
176
|
-
data[rekey] = evaluate val, data
|
176
|
+
data[rekey] = evaluate val, data, math: false
|
177
177
|
elsif PaddingBottomHackKeys.include? key
|
178
178
|
val = evaluate val, data
|
179
179
|
# normalize padding hacks for themes designed before the converter had smart margins
|
180
180
|
val[2] = val[0] if ::Array === val && val[0].to_f >= 0 && val[2].to_f <= 0
|
181
181
|
data[key] = val
|
182
|
-
# QUESTION: do we really need to evaluate_math in this case?
|
183
182
|
elsif key.end_with? '_color'
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
data[key] = val.map {|it| to_color evaluate it, data }
|
183
|
+
# assume table_grid_color is a single color unless the value is a 2-element array for backwards compatibility
|
184
|
+
if key == 'table_border_color' ? ::Array === val : (key == 'table_grid_color' && ::Array === val && val.size == 2)
|
185
|
+
data[key] = val.map {|it| to_color evaluate it, data, math: false }
|
188
186
|
else
|
189
|
-
data[key] = to_color evaluate val, data
|
187
|
+
data[key] = to_color evaluate val, data, math: false
|
190
188
|
end
|
191
189
|
elsif key.end_with? '_content'
|
192
190
|
data[key] = (expand_vars val.to_s, data).to_s
|
@@ -196,12 +194,12 @@ module Asciidoctor
|
|
196
194
|
data
|
197
195
|
end
|
198
196
|
|
199
|
-
def evaluate expr, vars
|
197
|
+
def evaluate expr, vars, math: true
|
200
198
|
case expr
|
201
199
|
when ::String
|
202
|
-
evaluate_math expand_vars expr, vars
|
200
|
+
math ? (evaluate_math expand_vars expr, vars) : (expand_vars expr, vars)
|
203
201
|
when ::Array
|
204
|
-
expr.map {|e| evaluate e, vars }
|
202
|
+
expr.map {|e| evaluate e, vars, math: math }
|
205
203
|
else
|
206
204
|
expr
|
207
205
|
end
|
@@ -233,7 +231,6 @@ module Asciidoctor
|
|
233
231
|
def evaluate_math expr
|
234
232
|
return expr if !(::String === expr) || ColorValue === expr
|
235
233
|
# resolve measurement values (e.g., 0.5in => 36)
|
236
|
-
# QUESTION: should we round the value? perhaps leave that to the precision functions
|
237
234
|
# NOTE: leave % as a string; handled by converter for now
|
238
235
|
original, expr = expr, (resolve_measurement_values expr)
|
239
236
|
while true
|
@@ -257,8 +254,7 @@ module Asciidoctor
|
|
257
254
|
end
|
258
255
|
end
|
259
256
|
if (expr.end_with? ')') && expr =~ PrecisionFuncRx
|
260
|
-
op = $1
|
261
|
-
offset = op.length + 1
|
257
|
+
offset = (op = $1).length + 1
|
262
258
|
expr = expr[offset...-1].to_f.send op.to_sym
|
263
259
|
end
|
264
260
|
if expr == original
|
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.
|
4
|
+
version: 2.3.0
|
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-08-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: asciidoctor
|
@@ -280,6 +280,7 @@ files:
|
|
280
280
|
- lib/asciidoctor/pdf/ext/prawn/formatted_text/box.rb
|
281
281
|
- lib/asciidoctor/pdf/ext/prawn/formatted_text/fragment.rb
|
282
282
|
- lib/asciidoctor/pdf/ext/prawn/formatted_text/indented_paragraph_wrap.rb
|
283
|
+
- lib/asciidoctor/pdf/ext/prawn/formatted_text/line_wrap.rb
|
283
284
|
- lib/asciidoctor/pdf/ext/prawn/formatted_text/protect_bottom_gutter.rb
|
284
285
|
- lib/asciidoctor/pdf/ext/prawn/images.rb
|
285
286
|
- lib/asciidoctor/pdf/ext/pygments.rb
|