asciidoctor-pdf 2.0.0.alpha.1 → 2.0.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +94 -1
- data/README.adoc +32 -14
- data/data/fonts/ABOUT-mplus1p-subset +1 -0
- data/data/fonts/ABOUT-notosans-subset +1 -0
- data/data/fonts/ABOUT-notoserif-subset +1 -0
- data/data/fonts/mplus1mn-bold-subset.ttf +0 -0
- data/data/fonts/mplus1mn-bold_italic-subset.ttf +0 -0
- data/data/fonts/mplus1mn-italic-subset.ttf +0 -0
- data/data/fonts/mplus1mn-regular-subset.ttf +0 -0
- data/data/fonts/mplus1p-regular-fallback.ttf +0 -0
- data/data/fonts/notosans-bold-subset.ttf +0 -0
- data/data/fonts/notosans-bold_italic-subset.ttf +0 -0
- data/data/fonts/notosans-italic-subset.ttf +0 -0
- data/data/fonts/notosans-regular-subset.ttf +0 -0
- data/data/fonts/notoserif-bold-subset.ttf +0 -0
- data/data/fonts/notoserif-bold_italic-subset.ttf +0 -0
- data/data/fonts/notoserif-italic-subset.ttf +0 -0
- data/data/fonts/notoserif-regular-subset.ttf +0 -0
- data/data/themes/base-theme.yml +11 -20
- data/data/themes/default-theme.yml +8 -7
- data/docs/theming-guide.adoc +11 -10
- data/lib/asciidoctor/pdf/converter.rb +445 -305
- data/lib/asciidoctor/pdf/ext/asciidoctor/document.rb +4 -0
- data/lib/asciidoctor/pdf/ext/pdf-core/page.rb +8 -0
- data/lib/asciidoctor/pdf/ext/prawn/extensions.rb +117 -38
- 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-table/cell/asciidoc.rb +1 -1
- 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/nopngmagick.rb +3 -0
- data/lib/asciidoctor/pdf/optimizer.rb +12 -5
- data/lib/asciidoctor/pdf/text_transformer.rb +14 -0
- data/lib/asciidoctor/pdf/theme_loader.rb +19 -3
- data/lib/asciidoctor/pdf/version.rb +1 -1
- metadata +5 -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
|
@@ -14,6 +14,14 @@ class PDF::Core::Page
|
|
14
14
|
content.stream.filtered_stream == (@tare_content_stream ||= InitialPageContent) && document.page_number > 0
|
15
15
|
end
|
16
16
|
|
17
|
+
# Flags this page as imported.
|
18
|
+
#
|
19
|
+
def imported
|
20
|
+
@imported_page = true
|
21
|
+
end
|
22
|
+
|
23
|
+
alias imported_page imported
|
24
|
+
|
17
25
|
# Reset the content of the page.
|
18
26
|
# Note that this method may leave behind an orphaned background image.
|
19
27
|
def reset_content
|
@@ -103,7 +103,7 @@ module Asciidoctor
|
|
103
103
|
NewPageRequiredError = ::Class.new ::StopIteration
|
104
104
|
|
105
105
|
InhibitNewPageProc = proc do |pdf|
|
106
|
-
pdf.
|
106
|
+
pdf.delete_current_page
|
107
107
|
raise NewPageRequiredError
|
108
108
|
end
|
109
109
|
|
@@ -111,7 +111,7 @@ module Asciidoctor
|
|
111
111
|
|
112
112
|
DetectEmptyFirstPageProc = proc do |delegate, pdf|
|
113
113
|
if pdf.state.pages[pdf.page_number - 2].empty?
|
114
|
-
pdf.
|
114
|
+
pdf.delete_current_page
|
115
115
|
raise NewPageRequiredError
|
116
116
|
end
|
117
117
|
delegate.call pdf if (pdf.state.on_page_create_callback = delegate)
|
@@ -269,6 +269,20 @@ module Asciidoctor
|
|
269
269
|
dest_xyz 0, page_height, nil, (page_num ? state.pages[page_num - 1] : page)
|
270
270
|
end
|
271
271
|
|
272
|
+
# Gets the destination registered for the specified name. The return value
|
273
|
+
# matches that which was passed to the add_dest method.
|
274
|
+
#
|
275
|
+
def get_dest name, node = dests.data
|
276
|
+
node.children.each do |child|
|
277
|
+
if ::PDF::Core::NameTree::Value === child
|
278
|
+
return child.value.data if child.name == name
|
279
|
+
elsif (found = get_dest name, child)
|
280
|
+
return found
|
281
|
+
end
|
282
|
+
end
|
283
|
+
nil
|
284
|
+
end
|
285
|
+
|
272
286
|
# Fonts
|
273
287
|
|
274
288
|
# Registers a new custom font described in the data parameter
|
@@ -495,6 +509,8 @@ module Asciidoctor
|
|
495
509
|
lowercase_pcdata text
|
496
510
|
when :capitalize, 'capitalize'
|
497
511
|
capitalize_words_pcdata text
|
512
|
+
when :smallcaps, 'smallcaps'
|
513
|
+
smallcaps_pcdata text
|
498
514
|
else
|
499
515
|
text
|
500
516
|
end
|
@@ -538,25 +554,34 @@ module Asciidoctor
|
|
538
554
|
# Example:
|
539
555
|
#
|
540
556
|
# pad_box 20 do
|
541
|
-
# text 'A paragraph inside a blox with even padding
|
557
|
+
# text 'A paragraph inside a blox with even padding from all edges.'
|
558
|
+
# end
|
559
|
+
#
|
560
|
+
# pad_box [10, 5] do
|
561
|
+
# text 'A paragraph inside a box with different padding from ends and sides.'
|
542
562
|
# end
|
543
563
|
#
|
544
|
-
# pad_box [
|
545
|
-
# text '
|
564
|
+
# pad_box [5, 10, 15, 20] do
|
565
|
+
# text 'A paragraph inside a box with different padding from each edge.'
|
546
566
|
# end
|
547
567
|
#
|
548
|
-
def pad_box padding
|
568
|
+
def pad_box padding, node = nil
|
549
569
|
if padding
|
550
|
-
|
551
|
-
|
570
|
+
p_top, p_right, p_bottom, p_left = expand_padding_value padding
|
571
|
+
# logic is intentionally inlined
|
552
572
|
begin
|
553
|
-
|
573
|
+
if node && ((last_block = node).content_model != :compound || (last_block = node.blocks[-1])&.context == :paragraph)
|
574
|
+
@bottom_gutters << { last_block => p_bottom }
|
575
|
+
else
|
576
|
+
@bottom_gutters << {}
|
577
|
+
end
|
554
578
|
move_down p_top
|
555
579
|
bounds.add_left_padding p_left
|
556
580
|
bounds.add_right_padding p_right
|
557
581
|
yield
|
558
|
-
cursor > p_bottom ? (move_down p_bottom) : reference_bounds.move_past_bottom unless at_page_top?
|
559
582
|
ensure
|
583
|
+
cursor > p_bottom ? (move_down p_bottom) : reference_bounds.move_past_bottom unless at_page_top?
|
584
|
+
@bottom_gutters.pop
|
560
585
|
bounds.subtract_left_padding p_left
|
561
586
|
bounds.subtract_right_padding p_right
|
562
587
|
end
|
@@ -570,30 +595,73 @@ module Asciidoctor
|
|
570
595
|
end
|
571
596
|
|
572
597
|
def expand_padding_value shorthand
|
573
|
-
|
574
|
-
if ::Array ===
|
575
|
-
case
|
598
|
+
(@edge_shorthand_cache ||= ::Hash.new do |store, key|
|
599
|
+
if ::Array === key
|
600
|
+
case key.size
|
576
601
|
when 1
|
577
|
-
|
602
|
+
value = [(value0 = key[0] || 0), value0, value0, value0]
|
578
603
|
when 2
|
579
|
-
|
604
|
+
value = [(value0 = key[0] || 0), (value1 = key[1] || 0), value0, value1]
|
580
605
|
when 3
|
581
|
-
|
606
|
+
value = [key[0] || 0, (value1 = key[1] || 0), key[2] || 0, value1]
|
582
607
|
when 4
|
583
|
-
|
608
|
+
value = key.map {|it| it || 0 }
|
584
609
|
else
|
585
|
-
|
610
|
+
value = (key.slice 0, 4).map {|it| it || 0 }
|
586
611
|
end
|
587
612
|
else
|
588
|
-
|
613
|
+
value = [(value0 = key || 0), value0, value0, value0]
|
589
614
|
end
|
590
|
-
|
591
|
-
end
|
592
|
-
padding.dup
|
615
|
+
store[key] = value
|
616
|
+
end)[shorthand]
|
593
617
|
end
|
594
618
|
|
595
619
|
alias expand_margin_value expand_padding_value
|
596
620
|
|
621
|
+
def expand_grid_values shorthand, default = nil
|
622
|
+
if ::Array === shorthand
|
623
|
+
case shorthand.size
|
624
|
+
when 1
|
625
|
+
[(value0 = shorthand[0] || default), value0]
|
626
|
+
when 2
|
627
|
+
shorthand.map {|it| it || default }
|
628
|
+
when 4
|
629
|
+
if Asciidoctor::PDF::ThemeLoader::CMYKColorValue === shorthand
|
630
|
+
[shorthand, shorthand]
|
631
|
+
else
|
632
|
+
(shorthand.slice 0, 2).map {|it| it || default }
|
633
|
+
end
|
634
|
+
else
|
635
|
+
(shorthand.slice 0, 2).map {|it| it || default }
|
636
|
+
end
|
637
|
+
else
|
638
|
+
[(value0 = shorthand || default), value0]
|
639
|
+
end
|
640
|
+
end
|
641
|
+
|
642
|
+
def expand_rect_values shorthand, default = nil
|
643
|
+
if ::Array === shorthand
|
644
|
+
case shorthand.size
|
645
|
+
when 1
|
646
|
+
[(value0 = shorthand[0] || default), value0, value0, value0]
|
647
|
+
when 2
|
648
|
+
[(value0 = shorthand[0] || default), (value1 = shorthand[1] || default), value0, value1]
|
649
|
+
when 3
|
650
|
+
[shorthand[0] || default, (value1 = shorthand[1] || default), shorthand[2] || default, value1]
|
651
|
+
when 4
|
652
|
+
if Asciidoctor::PDF::ThemeLoader::CMYKColorValue === shorthand
|
653
|
+
[shorthand, shorthand, shorthand, shorthand]
|
654
|
+
else
|
655
|
+
shorthand.map {|it| it || default }
|
656
|
+
end
|
657
|
+
else
|
658
|
+
(shorthand.slice 0, 4).map {|it| it || default }
|
659
|
+
end
|
660
|
+
else
|
661
|
+
[(value0 = shorthand || default), value0, value0, value0]
|
662
|
+
end
|
663
|
+
end
|
664
|
+
|
597
665
|
# Stretch the current bounds to the left and right edges of the current page
|
598
666
|
# while yielding the specified block if the verdict argument is true.
|
599
667
|
# Otherwise, simply yield the specified block.
|
@@ -650,7 +718,8 @@ module Asciidoctor
|
|
650
718
|
def fill_and_stroke_bounds f_color = fill_color, s_color = stroke_color, options = {}
|
651
719
|
no_fill = !f_color || f_color == 'transparent'
|
652
720
|
if ::Array === (s_width = options[:line_width] || 0)
|
653
|
-
|
721
|
+
s_width = [s_width[0], s_width[1], s_width[0], s_width[1]] if s_width.size == 2
|
722
|
+
s_width_max = (s_width = s_width.map {|it| it || 0 }).max
|
654
723
|
radius = 0
|
655
724
|
else
|
656
725
|
radius = options[:radius] || 0
|
@@ -668,13 +737,19 @@ module Asciidoctor
|
|
668
737
|
|
669
738
|
# stroke
|
670
739
|
if s_width_max
|
671
|
-
|
672
|
-
|
673
|
-
|
740
|
+
s_width_top, s_width_right, s_width_bottom, s_width_left = s_width
|
741
|
+
projection_top, projection_right, projection_bottom, projection_left = s_width.map {|it| it * 0.5 }
|
742
|
+
if s_width_top > 0
|
743
|
+
stroke_horizontal_rule s_color, line_width: s_width_top, line_style: options[:line_style], left_projection: projection_left, right_projection: projection_right
|
744
|
+
end
|
745
|
+
if s_width_right > 0
|
746
|
+
stroke_vertical_rule s_color, line_width: s_width_right, line_style: options[:line_style], at: bounds.width, top_projection: projection_top, bottom_projection: projection_bottom
|
747
|
+
end
|
748
|
+
if s_width_bottom > 0
|
749
|
+
stroke_horizontal_rule s_color, line_width: s_width_bottom, line_style: options[:line_style], at: bounds.height, left_projection: projection_left, right_projection: projection_right
|
674
750
|
end
|
675
|
-
if
|
676
|
-
stroke_vertical_rule s_color, line_width:
|
677
|
-
stroke_vertical_rule s_color, line_width: s_width_side, line_style: options[:line_style], at: bounds.width
|
751
|
+
if s_width_left > 0
|
752
|
+
stroke_vertical_rule s_color, line_width: s_width_left, line_style: options[:line_style], top_projection: projection_top, bottom_projection: projection_bottom
|
678
753
|
end
|
679
754
|
else
|
680
755
|
stroke_color s_color
|
@@ -709,8 +784,8 @@ module Asciidoctor
|
|
709
784
|
rule_y = cursor - (options[:at] || 0)
|
710
785
|
rule_style = options[:line_style]
|
711
786
|
rule_width = options[:line_width] || 0.5
|
712
|
-
rule_x_start = bounds.left
|
713
|
-
rule_x_end = bounds.right
|
787
|
+
rule_x_start = bounds.left - (options[:left_projection] || 0)
|
788
|
+
rule_x_end = bounds.right - (options[:right_projection] || 0)
|
714
789
|
save_graphics_state do
|
715
790
|
stroke_color rule_color
|
716
791
|
case rule_style
|
@@ -740,8 +815,8 @@ module Asciidoctor
|
|
740
815
|
#
|
741
816
|
def stroke_vertical_rule rule_color = stroke_color, options = {}
|
742
817
|
rule_x = options[:at] || 0
|
743
|
-
rule_y_from = bounds.top
|
744
|
-
rule_y_to = bounds.bottom
|
818
|
+
rule_y_from = bounds.top + (options[:top_projection] || 0)
|
819
|
+
rule_y_to = bounds.bottom - (options[:bottom_projection] || 0)
|
745
820
|
rule_style = options[:line_style]
|
746
821
|
rule_width = options[:line_width] || 0.5
|
747
822
|
save_graphics_state do
|
@@ -764,10 +839,15 @@ module Asciidoctor
|
|
764
839
|
|
765
840
|
# Deletes the current page and move the cursor
|
766
841
|
# to the previous page.
|
767
|
-
def
|
842
|
+
def delete_current_page
|
768
843
|
pg = page_number
|
769
844
|
pdf_store = state.store
|
770
845
|
content_id = page.content.identifier
|
846
|
+
page_ref = page.dictionary
|
847
|
+
(prune_dests = proc do |node|
|
848
|
+
node.children.delete_if {|it| ::PDF::Core::NameTree::Node === it ? prune_dests[it] : it.value.data[0] == page_ref }
|
849
|
+
false
|
850
|
+
end)[dests.data]
|
771
851
|
# NOTE: cannot delete objects and IDs, otherwise references get corrupted; so just reset the value
|
772
852
|
(pdf_store.instance_variable_get :@objects)[content_id] = ::PDF::Core::Reference.new content_id, {}
|
773
853
|
pdf_store.pages.data[:Kids].pop
|
@@ -793,7 +873,7 @@ module Asciidoctor
|
|
793
873
|
prev_page_size = page.size
|
794
874
|
state.compress = false if state.compress # can't use compression if using template
|
795
875
|
prev_text_rendering_mode = (defined? @text_rendering_mode) ? @text_rendering_mode : nil
|
796
|
-
|
876
|
+
delete_current_page if options[:replace]
|
797
877
|
# NOTE: use functionality provided by prawn-templates
|
798
878
|
start_new_page_discretely template: file, template_page: options[:page]
|
799
879
|
# prawn-templates sets text_rendering_mode to :unknown, which breaks running content; revert
|
@@ -805,11 +885,11 @@ module Asciidoctor
|
|
805
885
|
# way atm to prevent the size & layout of the imported page from affecting subsequent pages
|
806
886
|
advance_page size: prev_page_size, layout: prev_page_layout if options.fetch :advance, true
|
807
887
|
elsif options.fetch :advance_if_missing, true
|
808
|
-
|
888
|
+
delete_current_page
|
809
889
|
# NOTE: see previous comment
|
810
890
|
advance_page size: prev_page_size, layout: prev_page_layout
|
811
891
|
else
|
812
|
-
|
892
|
+
delete_current_page
|
813
893
|
end
|
814
894
|
nil
|
815
895
|
end
|
@@ -866,7 +946,6 @@ module Asciidoctor
|
|
866
946
|
def scratch?
|
867
947
|
@label == :scratch
|
868
948
|
end
|
869
|
-
alias is_scratch? scratch?
|
870
949
|
|
871
950
|
def with_dry_run &block
|
872
951
|
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
|
@@ -99,7 +99,7 @@ module Prawn
|
|
99
99
|
apply_font_properties { pdf.traverse content }
|
100
100
|
if (extra_pages = pdf.page_number - start_page) > 0
|
101
101
|
logger.error %(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) unless extra_pages == 1 && pdf.page.empty?
|
102
|
-
extra_pages.times { pdf.
|
102
|
+
extra_pages.times { pdf.delete_current_page }
|
103
103
|
end
|
104
104
|
nil
|
105
105
|
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
|
@@ -40,9 +40,10 @@ module Asciidoctor
|
|
40
40
|
attr_reader :quality
|
41
41
|
attr_reader :compatibility_level
|
42
42
|
|
43
|
-
def initialize quality = 'default', compatibility_level = '1.4'
|
43
|
+
def initialize quality = 'default', compatibility_level = '1.4', compliance = 'PDF'
|
44
44
|
@quality = QUALITY_NAMES[quality]
|
45
45
|
@compatibility_level = compatibility_level
|
46
|
+
@compliance = compliance
|
46
47
|
if (gs_path = ::ENV['GS'])
|
47
48
|
::RGhost::Config::GS[:path] = gs_path
|
48
49
|
end
|
@@ -57,10 +58,16 @@ module Asciidoctor
|
|
57
58
|
else
|
58
59
|
inputs = target
|
59
60
|
end
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
d:
|
61
|
+
d = { Printed: false, CannotEmbedFontPolicy: '/Warning', CompatibilityLevel: @compatibility_level }
|
62
|
+
case @compliance
|
63
|
+
when 'PDF/A', 'PDF/A-1', 'PDF/A-2', 'PDF/A-3'
|
64
|
+
d[:PDFA] = ((@compliance.split '-', 2)[1] || 1).to_i
|
65
|
+
d[:ShowAnnots] = false
|
66
|
+
when 'PDF/X', 'PDF/X-1', 'PDF/X-3'
|
67
|
+
d[:PDFX] = true
|
68
|
+
d[:ShowAnnots] = false
|
69
|
+
end
|
70
|
+
(::RGhost::Convert.new inputs).to :pdf, filename: filename_tmp.to_s, quality: @quality, d: d
|
64
71
|
filename_o.binwrite filename_tmp.binread
|
65
72
|
end
|
66
73
|
nil
|
@@ -10,6 +10,12 @@ module Asciidoctor
|
|
10
10
|
WordRx = /\p{Word}+/
|
11
11
|
Hyphen = '-'
|
12
12
|
SoftHyphen = ?\u00ad
|
13
|
+
LowerAlphaChars = 'a-z'
|
14
|
+
# NOTE: use more widely-supported ғ instead of ꜰ as replacement for F
|
15
|
+
# NOTE: use more widely-supported ǫ instead of ꞯ as replacement for Q
|
16
|
+
# NOTE: use more widely-supported s (lowercase latin "s") instead of ꜱ as replacement for S
|
17
|
+
# NOTE: in small caps, x (lowercase latin "x") remains unchanged
|
18
|
+
SmallCapsChars = 'ᴀʙᴄᴅᴇғɢʜɪᴊᴋʟᴍɴoᴘǫʀsᴛᴜᴠᴡxʏᴢ'
|
13
19
|
|
14
20
|
def capitalize_words_pcdata string
|
15
21
|
if XMLMarkupRx.match? string
|
@@ -50,6 +56,14 @@ module Asciidoctor
|
|
50
56
|
string.upcase
|
51
57
|
end
|
52
58
|
end
|
59
|
+
|
60
|
+
def smallcaps_pcdata string
|
61
|
+
if XMLMarkupRx.match? string
|
62
|
+
string.gsub(PCDATAFilterRx) { $2 ? ($2.tr LowerAlphaChars, SmallCapsChars) : $1 }
|
63
|
+
else
|
64
|
+
string.tr LowerAlphaChars, SmallCapsChars
|
65
|
+
end
|
66
|
+
end
|
53
67
|
end
|
54
68
|
end
|
55
69
|
end
|
@@ -15,6 +15,10 @@ 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
|
+
DeprecatedKeys = %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({ 'table_caption_side' => 'table_caption_end' }) do |prefix, accum|
|
19
|
+
accum[%(#{prefix}_align)] = %(#{prefix}_text_align)
|
20
|
+
end
|
21
|
+
PaddingBottomHackKeys = %w(example_padding quote_padding sidebar_padding verse_padding)
|
18
22
|
|
19
23
|
VariableRx = /\$([a-z0-9_-]+)/
|
20
24
|
LoneVariableRx = /^\$([a-z0-9_-]+)$/
|
@@ -22,6 +26,7 @@ module Asciidoctor
|
|
22
26
|
MultiplyDivideOpRx = %r((-?\d+(?:\.\d+)?) +([*/^]) +(-?\d+(?:\.\d+)?))
|
23
27
|
AddSubtractOpRx = /(-?\d+(?:\.\d+)?) +([+\-]) +(-?\d+(?:\.\d+)?)/
|
24
28
|
PrecisionFuncRx = /^(round|floor|ceil)\(/
|
29
|
+
RoleAlignKeyRx = /(?:_text)?_align$/
|
25
30
|
|
26
31
|
module ColorValue; end
|
27
32
|
|
@@ -77,7 +82,7 @@ module Asciidoctor
|
|
77
82
|
else
|
78
83
|
theme_data = load_file theme_path, nil, theme_dir
|
79
84
|
unless (::File.dirname theme_path) == ThemesDir
|
80
|
-
theme_data.
|
85
|
+
theme_data.base_text_align ||= 'left'
|
81
86
|
theme_data.base_line_height ||= 1
|
82
87
|
theme_data.base_font_color ||= '000000'
|
83
88
|
theme_data.code_font_family ||= (theme_data.codespan_font_family || 'Courier')
|
@@ -166,9 +171,19 @@ module Asciidoctor
|
|
166
171
|
val.each do |subkey, subval|
|
167
172
|
process_entry %(#{key}_#{key == 'role' || !(subkey.include? '-') ? subkey : (subkey.tr '-', '_')}), subval, data
|
168
173
|
end
|
174
|
+
elsif (rekey = DeprecatedKeys[key]) ||
|
175
|
+
((key.start_with? 'role_') && (key.end_with? '_align') && (rekey = key.sub RoleAlignKeyRx, '_text_align'))
|
176
|
+
data[rekey] = evaluate val, data
|
177
|
+
elsif PaddingBottomHackKeys.include? key
|
178
|
+
val = evaluate val, data
|
179
|
+
# normalize padding hacks for themes designed before the converter had smart margins
|
180
|
+
val[2] = val[0] if ::Array === val && val[0].to_f >= 0 && val[2].to_f <= 0
|
181
|
+
data[key] = val
|
169
182
|
# QUESTION: do we really need to evaluate_math in this case?
|
170
183
|
elsif key.end_with? '_color'
|
171
|
-
if key == '
|
184
|
+
if key == 'table_border_color'
|
185
|
+
data[key] = ::Array === val ? val.map {|it| to_color evaluate it, data } : (to_color evaluate val, data)
|
186
|
+
elsif key == 'table_grid_color' && ::Array === val && val.size == 2
|
172
187
|
data[key] = val.map {|it| to_color evaluate it, data }
|
173
188
|
else
|
174
189
|
data[key] = to_color evaluate val, data
|
@@ -206,7 +221,8 @@ module Asciidoctor
|
|
206
221
|
def resolve_var vars, ref, var
|
207
222
|
var = var.tr '-', '_' if var.include? '-'
|
208
223
|
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) }
|
224
|
+
DeprecatedCategoryKeys.any? {|old, new| (var.start_with? old + '_') && (vars.respond_to? (replace = new + (var.slice old.length, var.length))) && (var = replace) } ||
|
225
|
+
((replace = DeprecatedKeys[var]) && (vars.respond_to? replace) && (var = replace))
|
210
226
|
vars[var]
|
211
227
|
else
|
212
228
|
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.
|
4
|
+
version: 2.0.0.beta.1
|
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-05-04 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,8 @@ 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
|
294
|
+
- lib/asciidoctor/pdf/nopngmagick.rb
|
292
295
|
- lib/asciidoctor/pdf/optimizer.rb
|
293
296
|
- lib/asciidoctor/pdf/pdfmark.rb
|
294
297
|
- lib/asciidoctor/pdf/roman_numeral.rb
|