asciidoctor-pdf 2.0.0.alpha.1 → 2.0.0.alpha.2
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 +38 -1
- data/README.adoc +3 -3
- data/data/themes/base-theme.yml +3 -2
- data/data/themes/default-theme.yml +6 -5
- data/docs/theming-guide.adoc +3 -3
- data/lib/asciidoctor/pdf/converter.rb +282 -208
- data/lib/asciidoctor/pdf/ext/asciidoctor/document.rb +4 -0
- data/lib/asciidoctor/pdf/ext/prawn/extensions.rb +57 -3
- data/lib/asciidoctor/pdf/ext/prawn/formatted_text/box.rb +5 -0
- data/lib/asciidoctor/pdf/ext/prawn/formatted_text/protect_bottom_gutter.rb +13 -0
- data/lib/asciidoctor/pdf/ext/prawn/images.rb +6 -2
- data/lib/asciidoctor/pdf/ext/prawn.rb +1 -0
- data/lib/asciidoctor/pdf/formatted_text/transform.rb +7 -2
- data/lib/asciidoctor/pdf/nogmagick.rb +6 -0
- data/lib/asciidoctor/pdf/theme_loader.rb +13 -3
- data/lib/asciidoctor/pdf/version.rb +1 -1
- metadata +4 -2
@@ -11,6 +11,10 @@ class Asciidoctor::Document
|
|
11
11
|
preface.sectname = 'preface'
|
12
12
|
preface.title = blk0.instance_variable_get :@title
|
13
13
|
preface.id = preface.generate_id
|
14
|
+
if (first_child = blk0.blocks[0])&.option? 'notitle'
|
15
|
+
preface.set_option 'notitle'
|
16
|
+
first_child.role = 'lead' if first_child.context == :paragraph && !first_child.role?
|
17
|
+
end
|
14
18
|
preface.blocks.replace (blk0.blocks.map do |b|
|
15
19
|
b.parent = preface
|
16
20
|
b
|
@@ -545,18 +545,24 @@ module Asciidoctor
|
|
545
545
|
# text 'An indented paragraph inside a box with equal padding on all sides.'
|
546
546
|
# end
|
547
547
|
#
|
548
|
-
def pad_box padding
|
548
|
+
def pad_box padding, node = nil
|
549
549
|
if padding
|
550
550
|
# TODO: implement shorthand combinations like in CSS
|
551
551
|
p_top, p_right, p_bottom, p_left = ::Array === padding ? padding : (::Array.new 4, padding)
|
552
|
+
# logic is intentionally inlined
|
552
553
|
begin
|
553
|
-
|
554
|
+
if node && ((last_block = node).content_model != :compound || (last_block = node.blocks[-1])&.context == :paragraph)
|
555
|
+
@bottom_gutters << { last_block => p_bottom }
|
556
|
+
else
|
557
|
+
@bottom_gutters << {}
|
558
|
+
end
|
554
559
|
move_down p_top
|
555
560
|
bounds.add_left_padding p_left
|
556
561
|
bounds.add_right_padding p_right
|
557
562
|
yield
|
558
563
|
cursor > p_bottom ? (move_down p_bottom) : reference_bounds.move_past_bottom unless at_page_top?
|
559
564
|
ensure
|
565
|
+
@bottom_gutters.pop
|
560
566
|
bounds.subtract_left_padding p_left
|
561
567
|
bounds.subtract_right_padding p_right
|
562
568
|
end
|
@@ -594,6 +600,50 @@ module Asciidoctor
|
|
594
600
|
|
595
601
|
alias expand_margin_value expand_padding_value
|
596
602
|
|
603
|
+
def expand_grid_values shorthand, default = nil
|
604
|
+
if ::Array === shorthand
|
605
|
+
case shorthand.size
|
606
|
+
when 1
|
607
|
+
[(value0 = shorthand[0] || default), value0]
|
608
|
+
when 2
|
609
|
+
shorthand.map {|it| it || default }
|
610
|
+
when 4
|
611
|
+
if Asciidoctor::PDF::ThemeLoader::CMYKColorValue === shorthand
|
612
|
+
[shorthand, shorthand]
|
613
|
+
else
|
614
|
+
(shorthand.slice 0, 2).map {|it| it || default }
|
615
|
+
end
|
616
|
+
else
|
617
|
+
(shorthand.slice 0, 2).map {|it| it || default }
|
618
|
+
end
|
619
|
+
else
|
620
|
+
[(value0 = shorthand || default), value0]
|
621
|
+
end
|
622
|
+
end
|
623
|
+
|
624
|
+
def expand_rect_values shorthand, default = nil
|
625
|
+
if ::Array === shorthand
|
626
|
+
case shorthand.size
|
627
|
+
when 1
|
628
|
+
[(value0 = shorthand[0] || default), value0, value0, value0]
|
629
|
+
when 2
|
630
|
+
[(value0 = shorthand[0] || default), (value1 = shorthand[1] || default), value0, value1]
|
631
|
+
when 3
|
632
|
+
[shorthand[0] || default, (value1 = shorthand[1] || default), shorthand[2] || default, value1]
|
633
|
+
when 4
|
634
|
+
if Asciidoctor::PDF::ThemeLoader::CMYKColorValue === shorthand
|
635
|
+
[shorthand, shorthand, shorthand, shorthand]
|
636
|
+
else
|
637
|
+
shorthand.map {|it| it || default }
|
638
|
+
end
|
639
|
+
else
|
640
|
+
(shorthand.slice 0, 4).map {|it| it || default }
|
641
|
+
end
|
642
|
+
else
|
643
|
+
[(value0 = shorthand || default), value0, value0, value0]
|
644
|
+
end
|
645
|
+
end
|
646
|
+
|
597
647
|
# Stretch the current bounds to the left and right edges of the current page
|
598
648
|
# while yielding the specified block if the verdict argument is true.
|
599
649
|
# Otherwise, simply yield the specified block.
|
@@ -768,6 +818,11 @@ module Asciidoctor
|
|
768
818
|
pg = page_number
|
769
819
|
pdf_store = state.store
|
770
820
|
content_id = page.content.identifier
|
821
|
+
page_ref = page.dictionary
|
822
|
+
(prune_dests = proc do |node|
|
823
|
+
node.children.delete_if {|it| ::PDF::Core::NameTree::Node === it ? prune_dests[it] : it.value.data[0] == page_ref }
|
824
|
+
false
|
825
|
+
end)[dests.data]
|
771
826
|
# NOTE: cannot delete objects and IDs, otherwise references get corrupted; so just reset the value
|
772
827
|
(pdf_store.instance_variable_get :@objects)[content_id] = ::PDF::Core::Reference.new content_id, {}
|
773
828
|
pdf_store.pages.data[:Kids].pop
|
@@ -866,7 +921,6 @@ module Asciidoctor
|
|
866
921
|
def scratch?
|
867
922
|
@label == :scratch
|
868
923
|
end
|
869
|
-
alias is_scratch? scratch?
|
870
924
|
|
871
925
|
def with_dry_run &block
|
872
926
|
yield dry_run(&block).position_onto self, cursor
|
@@ -6,6 +6,11 @@ Prawn::Text::Formatted::Box.prepend (Module.new do
|
|
6
6
|
def initialize formatted_text, options = {}
|
7
7
|
super
|
8
8
|
formatted_text[0][:normalize_line_height] = true if options[:normalize_line_height] && !formatted_text.empty?
|
9
|
+
options[:extensions]&.each {|extension| extend extension }
|
10
|
+
if (bottom_gutter = options[:bottom_gutter]) && bottom_gutter > 0
|
11
|
+
@bottom_gutter = bottom_gutter
|
12
|
+
extend Prawn::Text::Formatted::ProtectBottomGutter
|
13
|
+
end
|
9
14
|
end
|
10
15
|
|
11
16
|
def draw_fragment_overlay_styles fragment
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Prawn::Text::Formatted::ProtectBottomGutter
|
4
|
+
def enough_height_for_this_line?
|
5
|
+
return super unless @arranger.finished?
|
6
|
+
begin
|
7
|
+
@height -= @bottom_gutter
|
8
|
+
super
|
9
|
+
ensure
|
10
|
+
@height += @bottom_gutter
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -13,14 +13,18 @@ module Asciidoctor
|
|
13
13
|
#opts[:cache_images] = cache_uri if !(opts.key? :cache_images) && (respond_to? :cache_uri)
|
14
14
|
#opts[:fallback_font_name] = fallback_svg_font_name if !(opts.key? :fallback_font_name) && (respond_to? :fallback_svg_font_name)
|
15
15
|
if (fit = opts.delete :fit) && !(opts[:width] || opts[:height])
|
16
|
-
svg (::File.read file, mode: 'r:UTF-8'), opts do |svg_doc|
|
16
|
+
image_info = svg (::File.read file, mode: 'r:UTF-8'), opts do |svg_doc|
|
17
17
|
# NOTE: fit to specified width, then reduce size if height exceeds bounds
|
18
18
|
svg_doc.calculate_sizing requested_width: fit[0] if svg_doc.sizing.output_width != fit[0]
|
19
19
|
svg_doc.calculate_sizing requested_height: fit[1] if svg_doc.sizing.output_height > fit[1]
|
20
20
|
end
|
21
21
|
else
|
22
|
-
svg (::File.read file, mode: 'r:UTF-8'), opts
|
22
|
+
image_info = svg (::File.read file, mode: 'r:UTF-8'), opts
|
23
23
|
end
|
24
|
+
if ::Asciidoctor::Logging === self && !scratch? && !(warnings = image_info[:warnings]).empty?
|
25
|
+
warnings.each {|warning| log :warn, %(problem encountered in image: #{file}; #{warning}) }
|
26
|
+
end
|
27
|
+
image_info
|
24
28
|
else
|
25
29
|
::File.open(file, 'rb') {|fd| super fd, opts }
|
26
30
|
end
|
@@ -7,4 +7,5 @@ require_relative 'prawn/images'
|
|
7
7
|
require_relative 'prawn/formatted_text/arranger'
|
8
8
|
require_relative 'prawn/formatted_text/box'
|
9
9
|
require_relative 'prawn/formatted_text/fragment'
|
10
|
+
require_relative 'prawn/formatted_text/protect_bottom_gutter'
|
10
11
|
require_relative 'prawn/extensions'
|
@@ -156,14 +156,19 @@ module Asciidoctor
|
|
156
156
|
if (pcdata = node[:pcdata]).empty?
|
157
157
|
# QUESTION: should this be handled by the formatter after the transform is complete?
|
158
158
|
if previous_fragment_is_text && ((previous_fragment_text = fragments[-1][:text]).end_with? ' ')
|
159
|
-
fragments[-1][:text] = previous_fragment_text.
|
159
|
+
fragments[-1][:text] = previous_fragment_text.chop
|
160
160
|
end
|
161
161
|
else
|
162
162
|
tag_name = node[:name]
|
163
163
|
attributes = node[:attributes]
|
164
164
|
parent = clone_fragment inherited
|
165
|
+
fragment = build_fragment parent, tag_name, attributes
|
166
|
+
if tag_name == :a && fragment[:type] == :indexterm && !attributes[:visible] &&
|
167
|
+
previous_fragment_is_text && ((previous_fragment_text = fragments[-1][:text]).end_with? ' ')
|
168
|
+
fragments[-1][:text] = previous_fragment_text.chop
|
169
|
+
end
|
165
170
|
# NOTE: decorate child fragments with inherited properties from this element
|
166
|
-
apply pcdata, fragments,
|
171
|
+
apply pcdata, fragments, fragment
|
167
172
|
previous_fragment_is_text = false
|
168
173
|
end
|
169
174
|
# case 2: void element
|
@@ -15,6 +15,9 @@ module Asciidoctor
|
|
15
15
|
BaseThemePath = ::File.join ThemesDir, 'base-theme.yml'
|
16
16
|
BundledThemeNames = (::Dir.children ThemesDir).map {|it| it.slice 0, it.length - 10 }
|
17
17
|
DeprecatedCategoryKeys = { 'blockquote' => 'quote', 'key' => 'kbd', 'literal' => 'codespan', 'outline_list' => 'list' }
|
18
|
+
AmbiguousAlignKeys = %w(base heading heading_h1 heading_h2 heading_h3 heading_h4 heading_h5 heading_h6 title_page abstract abstract_title admonition_label sidebar_title toc_title).each_with_object({}) do |prefix, accum|
|
19
|
+
accum[%(#{prefix}_align)] = %(#{prefix}_text_align)
|
20
|
+
end
|
18
21
|
|
19
22
|
VariableRx = /\$([a-z0-9_-]+)/
|
20
23
|
LoneVariableRx = /^\$([a-z0-9_-]+)$/
|
@@ -22,6 +25,7 @@ module Asciidoctor
|
|
22
25
|
MultiplyDivideOpRx = %r((-?\d+(?:\.\d+)?) +([*/^]) +(-?\d+(?:\.\d+)?))
|
23
26
|
AddSubtractOpRx = /(-?\d+(?:\.\d+)?) +([+\-]) +(-?\d+(?:\.\d+)?)/
|
24
27
|
PrecisionFuncRx = /^(round|floor|ceil)\(/
|
28
|
+
RoleAlignKeyRx = /(?:_text)?_align$/
|
25
29
|
|
26
30
|
module ColorValue; end
|
27
31
|
|
@@ -77,7 +81,7 @@ module Asciidoctor
|
|
77
81
|
else
|
78
82
|
theme_data = load_file theme_path, nil, theme_dir
|
79
83
|
unless (::File.dirname theme_path) == ThemesDir
|
80
|
-
theme_data.
|
84
|
+
theme_data.base_text_align ||= 'left'
|
81
85
|
theme_data.base_line_height ||= 1
|
82
86
|
theme_data.base_font_color ||= '000000'
|
83
87
|
theme_data.code_font_family ||= (theme_data.codespan_font_family || 'Courier')
|
@@ -166,9 +170,14 @@ module Asciidoctor
|
|
166
170
|
val.each do |subkey, subval|
|
167
171
|
process_entry %(#{key}_#{key == 'role' || !(subkey.include? '-') ? subkey : (subkey.tr '-', '_')}), subval, data
|
168
172
|
end
|
173
|
+
elsif (rekey = AmbiguousAlignKeys[key]) ||
|
174
|
+
((key.start_with? 'role_') && (key.end_with? '_align') && (rekey = key.sub RoleAlignKeyRx, '_text_align'))
|
175
|
+
data[rekey] = evaluate val, data
|
169
176
|
# QUESTION: do we really need to evaluate_math in this case?
|
170
177
|
elsif key.end_with? '_color'
|
171
|
-
if key == '
|
178
|
+
if key == 'table_border_color'
|
179
|
+
data[key] = ::Array === val ? val.map {|it| to_color evaluate it, data } : (to_color evaluate val, data)
|
180
|
+
elsif key == 'table_grid_color' && ::Array === val && val.size == 2
|
172
181
|
data[key] = val.map {|it| to_color evaluate it, data }
|
173
182
|
else
|
174
183
|
data[key] = to_color evaluate val, data
|
@@ -206,7 +215,8 @@ module Asciidoctor
|
|
206
215
|
def resolve_var vars, ref, var
|
207
216
|
var = var.tr '-', '_' if var.include? '-'
|
208
217
|
if (vars.respond_to? var) ||
|
209
|
-
DeprecatedCategoryKeys.any? {|old, new| (var.start_with? old + '_') && (vars.respond_to? (replace = new + (var.slice old.length, var.length))) && (var = replace) }
|
218
|
+
DeprecatedCategoryKeys.any? {|old, new| (var.start_with? old + '_') && (vars.respond_to? (replace = new + (var.slice old.length, var.length))) && (var = replace) } ||
|
219
|
+
((replace = AmbiguousAlignKeys[var]) && (vars.respond_to? replace) && (var = replace))
|
210
220
|
vars[var]
|
211
221
|
else
|
212
222
|
logger.warn %(unknown variable reference in PDF theme: #{ref})
|
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.0.0.alpha.
|
4
|
+
version: 2.0.0.alpha.2
|
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-04-
|
12
|
+
date: 2022-04-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: asciidoctor
|
@@ -270,6 +270,7 @@ files:
|
|
270
270
|
- lib/asciidoctor/pdf/ext/prawn/formatted_text/arranger.rb
|
271
271
|
- lib/asciidoctor/pdf/ext/prawn/formatted_text/box.rb
|
272
272
|
- lib/asciidoctor/pdf/ext/prawn/formatted_text/fragment.rb
|
273
|
+
- lib/asciidoctor/pdf/ext/prawn/formatted_text/protect_bottom_gutter.rb
|
273
274
|
- lib/asciidoctor/pdf/ext/prawn/images.rb
|
274
275
|
- lib/asciidoctor/pdf/ext/pygments.rb
|
275
276
|
- lib/asciidoctor/pdf/ext/rouge.rb
|
@@ -289,6 +290,7 @@ files:
|
|
289
290
|
- lib/asciidoctor/pdf/formatted_text/transform.rb
|
290
291
|
- lib/asciidoctor/pdf/index_catalog.rb
|
291
292
|
- lib/asciidoctor/pdf/measurements.rb
|
293
|
+
- lib/asciidoctor/pdf/nogmagick.rb
|
292
294
|
- lib/asciidoctor/pdf/optimizer.rb
|
293
295
|
- lib/asciidoctor/pdf/pdfmark.rb
|
294
296
|
- lib/asciidoctor/pdf/roman_numeral.rb
|