asciidoctor-pdf 2.0.0 → 2.0.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 027a0c91049b52843552b50087dc100ecaf0143bf2d342c2d3e5a8d37bd8fcda
4
- data.tar.gz: 1723e9c0ab2eab7f2f25dd31e6085e31103724c27eff2e3b9a1fe818d64161af
3
+ metadata.gz: 0d912c0aa04b380a6b2a69420f01a3c4795bb897dd3b1fbc22316ec38f333905
4
+ data.tar.gz: 6a717bfc06aa32799bc4bfb24c0e67b621709eac500efb1e78c1cf9f42d06afc
5
5
  SHA512:
6
- metadata.gz: d563c7b4def055b2732563910f0abc318d09e566423592a008535730480363a52f36f0d3bd27ed431490d3cf80bc855c8e98dc271556b8b27ea63ebd1a7b284d
7
- data.tar.gz: 82834fe8af002bc265e09880d8ef11e25e6e9943c1bf6fb4359f655364a15b49e8b71134adbe0fb3db567759944915faabe1cf5720a558751c3fcb53266c1c3f
6
+ metadata.gz: 69b76de214031c839abed9c1de5a0df55925ff638e4f9eab327e8970b66e78b499a1e9966bf7df436767a71728f6e6396608ad821feebf7a995de0585ca00861
7
+ data.tar.gz: 5f86394d598bdd7aa2c574912f95213cefa0620f375a34c35ff15d00369c0ca36b2dcec836ac95c460f9222f5ca24fa2b7573dd85448a5b5677cba5c1d2dd164
data/CHANGELOG.adoc CHANGED
@@ -5,6 +5,18 @@
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.0.1 (2022-05-21) - @mojavelinux
9
+
10
+ Bug Fixes::
11
+
12
+ * scale inline image to fit within available height of page, accounting for the top padding of the line and the bottom gutter (#2193)
13
+ * short-circuit formatted_text routine and log error if fragments in first line cannot fit on a new page
14
+ * break and wrap long contiguous text in source block when linenums are enabled (#2198)
15
+
16
+ === Details
17
+
18
+ {url-repo}/releases/tag/v2.0.1[git tag] | {url-repo}/compare/v2.0.0\...v2.0.1[full diff]
19
+
8
20
  == 2.0.0 (2022-05-18) - @mojavelinux
9
21
 
10
22
  Improvements::
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.0.0, 2022-05-18
3
+ v2.0.1, 2022-05-21
4
4
  // Settings:
5
5
  :experimental:
6
6
  :idprefix:
@@ -24,7 +24,7 @@ endif::[]
24
24
  :project-handle: asciidoctor-pdf
25
25
  // Variables:
26
26
  :release-line: 2.0.x
27
- :release-version: 2.0.0
27
+ :release-version: 2.0.1
28
28
  // URLs:
29
29
  :url-gem: https://rubygems.org/gems/asciidoctor-pdf
30
30
  :url-project: https://github.com/asciidoctor/asciidoctor-pdf
@@ -717,7 +717,7 @@ module Asciidoctor
717
717
  when 'page'
718
718
  pagenums = term.dests.uniq {|dest| dest[:page] }.map {|dest| %(<a anchor="#{dest[:anchor]}">#{dest[:page]}</a>) }
719
719
  when 'range'
720
- first_anchor_per_page = term.dests.each_with_object({}) {|dest, accum| accum[dest[:page]] ||= dest[:anchor] }
720
+ first_anchor_per_page = {}.tap {|accum| term.dests.each {|dest| accum[dest[:page]] ||= dest[:anchor] } }
721
721
  pagenums = (consolidate_ranges first_anchor_per_page.keys).map do |range|
722
722
  anchor = first_anchor_per_page[(range.include? '-') ? (range.partition '-')[0] : range]
723
723
  %(<a anchor="#{anchor}">#{range}</a>)
@@ -814,7 +814,7 @@ module Asciidoctor
814
814
  if (text_align = resolve_text_align_from_role (roles = node.roles), query_theme: true, remove_predefined: true)
815
815
  prose_opts[:align] = text_align
816
816
  end
817
- role_keys = roles.map {|role| %(role_#{role}).to_sym } unless roles.empty?
817
+ role_keys = roles.map {|role| %(role_#{role}) } unless roles.empty?
818
818
  if (text_indent = @theme.prose_text_indent) > 0 ||
819
819
  ((text_indent = @theme.prose_text_indent_inner) > 0 && node.previous_sibling&.context == :paragraph)
820
820
  prose_opts[:indent_paragraphs] = text_indent
@@ -1081,7 +1081,7 @@ module Asciidoctor
1081
1081
  highlight_lines = nil
1082
1082
  else
1083
1083
  pg_highlight_bg_color = pg_block_styles[:highlight_background_color]
1084
- highlight_lines = highlight_lines.map {|linenum| [linenum, pg_highlight_bg_color] }.to_h
1084
+ highlight_lines = {}.tap {|accum| highlight_lines.each {|linenum| accum[linenum] = pg_highlight_bg_color } }
1085
1085
  end
1086
1086
  end
1087
1087
  if (node.option? 'linenums') || (node.attr? 'linenums')
@@ -1120,7 +1120,7 @@ module Asciidoctor
1120
1120
  lexer ||= ::Rouge::Lexers::PlainText
1121
1121
  source_string, conum_mapping = extract_conums source_string if callouts_enabled
1122
1122
  if (node.attr? 'highlight') && !(hl_lines = (node.resolve_lines_to_highlight source_string, (node.attr 'highlight'))).empty?
1123
- formatter_opts[:highlight_lines] = hl_lines.map {|linenum| [linenum, true] }.to_h
1123
+ formatter_opts[:highlight_lines] = {}.tap {|accum| hl_lines.each {|linenum| accum[linenum] = true } }
1124
1124
  end
1125
1125
  fragments = formatter.format (lexer.lex source_string), formatter_opts rescue [text: source_string]
1126
1126
  source_chunks = conum_mapping ? (restore_conums fragments, conum_mapping) : fragments
@@ -1396,7 +1396,7 @@ module Asciidoctor
1396
1396
  end
1397
1397
  theme_margin :prose, :bottom, (next_enclosed_block actual_node) #unless actual_node.nested?
1398
1398
  when 'qanda'
1399
- @list_numerals << '1'
1399
+ @list_numerals << 1
1400
1400
  convert_list node
1401
1401
  @list_numerals.pop
1402
1402
  else
@@ -3261,64 +3261,70 @@ module Asciidoctor
3261
3261
  end
3262
3262
  end
3263
3263
 
3264
- colspec_dict = PageSides.each_with_object({}) do |side, acc|
3265
- side_trim_content_width = trim_content_width[side]
3266
- if (custom_colspecs = @theme[%(#{periphery}_#{side}_columns)] || @theme[%(#{periphery}_columns)])
3267
- case (colspecs = (custom_colspecs.to_s.tr ',', ' ').split).size
3268
- when 0, 1
3269
- colspecs = { left: '0', center: colspecs[0] || '100', right: '0' }
3270
- when 2
3271
- colspecs = { left: colspecs[0], center: '0', right: colspecs[1] }
3272
- else # 3
3273
- colspecs = { left: colspecs[0], center: colspecs[1], right: colspecs[2] }
3274
- end
3275
- tot_width = 0
3276
- side_colspecs = colspecs.map do |col, spec|
3277
- if (alignment_char = spec.chr).to_i.to_s == alignment_char
3278
- alignment = :left
3279
- rel_width = spec.to_f
3280
- else
3281
- alignment = AlignmentTable[alignment_char]
3282
- rel_width = (spec.slice 1, spec.length).to_f
3264
+ colspec_dict = {}.tap do |acc|
3265
+ PageSides.each do |side|
3266
+ side_trim_content_width = trim_content_width[side]
3267
+ if (custom_colspecs = @theme[%(#{periphery}_#{side}_columns)] || @theme[%(#{periphery}_columns)])
3268
+ case (colspecs = (custom_colspecs.to_s.tr ',', ' ').split).size
3269
+ when 0, 1
3270
+ colspecs = { left: '0', center: colspecs[0] || '100', right: '0' }
3271
+ when 2
3272
+ colspecs = { left: colspecs[0], center: '0', right: colspecs[1] }
3273
+ else # 3
3274
+ colspecs = { left: colspecs[0], center: colspecs[1], right: colspecs[2] }
3283
3275
  end
3284
- tot_width += rel_width
3285
- [col, align: alignment, width: rel_width, x: 0]
3286
- end.to_h
3287
- # QUESTION: should we allow the columns to overlap (capping width at 100%)?
3288
- side_colspecs.each {|_, colspec| colspec[:width] = (colspec[:width] / tot_width) * side_trim_content_width }
3289
- side_colspecs[:right][:x] = (side_colspecs[:center][:x] = side_colspecs[:left][:width]) + side_colspecs[:center][:width]
3290
- acc[side] = side_colspecs
3291
- else
3292
- acc[side] = {
3293
- left: { align: :left, width: side_trim_content_width, x: 0 },
3294
- center: { align: :center, width: side_trim_content_width, x: 0 },
3295
- right: { align: :right, width: side_trim_content_width, x: 0 },
3296
- }
3276
+ tot_width = 0
3277
+ side_colspecs = {}.tap do |accum|
3278
+ colspecs.each do |col, spec|
3279
+ if (alignment_char = spec.chr).to_i.to_s == alignment_char
3280
+ alignment = :left
3281
+ rel_width = spec.to_f
3282
+ else
3283
+ alignment = AlignmentTable[alignment_char]
3284
+ rel_width = (spec.slice 1, spec.length).to_f
3285
+ end
3286
+ tot_width += rel_width
3287
+ accum[col] = { align: alignment, width: rel_width, x: 0 }
3288
+ end
3289
+ end
3290
+ # QUESTION: should we allow the columns to overlap (capping width at 100%)?
3291
+ side_colspecs.each {|_, colspec| colspec[:width] = (colspec[:width] / tot_width) * side_trim_content_width }
3292
+ side_colspecs[:right][:x] = (side_colspecs[:center][:x] = side_colspecs[:left][:width]) + side_colspecs[:center][:width]
3293
+ acc[side] = side_colspecs
3294
+ else
3295
+ acc[side] = {
3296
+ left: { align: :left, width: side_trim_content_width, x: 0 },
3297
+ center: { align: :center, width: side_trim_content_width, x: 0 },
3298
+ right: { align: :right, width: side_trim_content_width, x: 0 },
3299
+ }
3300
+ end
3297
3301
  end
3298
3302
  end
3299
3303
 
3300
- content_dict = PageSides.each_with_object({}) do |side, acc|
3301
- side_content = {}
3302
- ColumnPositions.each do |position|
3303
- next if (val = @theme[%(#{periphery}_#{side}_#{position}_content)]).nil_or_empty?
3304
- val = val.to_s unless ::String === val
3305
- if (val.include? ':') && val =~ ImageAttributeValueRx
3306
- attrlist = $2
3307
- image_attrs = (AttributeList.new attrlist).parse %w(alt width)
3308
- image_path, image_format = ::Asciidoctor::Image.target_and_format $1, image_attrs
3309
- if (image_path = resolve_image_path doc, image_path, image_format, @themesdir) && (::File.readable? image_path)
3310
- image_opts = resolve_image_options image_path, image_format, image_attrs, container_size: [colspec_dict[side][position][:width], trim_content_height[side]]
3311
- side_content[position] = [image_path, image_opts, image_attrs['link']]
3304
+ content_dict = {}.tap do |acc|
3305
+ PageSides.each do |side|
3306
+ side_content = {}
3307
+ ColumnPositions.each do |position|
3308
+ next if (val = @theme[%(#{periphery}_#{side}_#{position}_content)]).nil_or_empty?
3309
+ val = val.to_s unless ::String === val
3310
+ if (val.include? ':') && val =~ ImageAttributeValueRx
3311
+ attrlist = $2
3312
+ image_attrs = (AttributeList.new attrlist).parse %w(alt width)
3313
+ image_path, image_format = ::Asciidoctor::Image.target_and_format $1, image_attrs
3314
+ if (image_path = resolve_image_path doc, image_path, image_format, @themesdir) && (::File.readable? image_path)
3315
+ image_opts = resolve_image_options image_path, image_format, image_attrs, container_size: [colspec_dict[side][position][:width], trim_content_height[side]]
3316
+ side_content[position] = [image_path, image_opts, image_attrs['link']]
3317
+ else
3318
+ # NOTE: allows inline image handler to report invalid reference and replace with alt text
3319
+ side_content[position] = %(image:#{image_path}[#{attrlist}])
3320
+ end
3312
3321
  else
3313
- # NOTE: allows inline image handler to report invalid reference and replace with alt text
3314
- side_content[position] = %(image:#{image_path}[#{attrlist}])
3322
+ side_content[position] = val
3315
3323
  end
3316
- else
3317
- side_content[position] = val
3318
3324
  end
3319
- end
3320
3325
 
3321
- acc[side] = side_content
3326
+ acc[side] = side_content
3327
+ end
3322
3328
  end
3323
3329
 
3324
3330
  if (trim_bg_color = trim_styles[:bg_color]) || trim_bg_image || trim_border_width > 0
@@ -3866,18 +3872,17 @@ module Asciidoctor
3866
3872
 
3867
3873
  def register_fonts font_catalog, fonts_dir
3868
3874
  return unless font_catalog
3869
- dirs = (fonts_dir.split ValueSeparatorRx, -1).map do |dir|
3870
- dir == 'GEM_FONTS_DIR' || dir.empty? ? ThemeLoader::FontsDir : dir
3871
- end
3875
+ dirs = (fonts_dir.split ValueSeparatorRx, -1).map {|dir| dir == 'GEM_FONTS_DIR' || dir.empty? ? ThemeLoader::FontsDir : dir }
3872
3876
  font_catalog.each do |key, styles|
3873
- styles = styles.each_with_object({}) do |(style, path), accum|
3874
- found = dirs.any? do |dir|
3875
- resolved_font_path = font_path path, dir
3876
- accum[style.to_sym] = resolved_font_path if ::File.readable? resolved_font_path
3877
+ register_font key => ({}.tap do |accum|
3878
+ styles.each do |style, path|
3879
+ found = dirs.any? do |dir|
3880
+ resolved_font_path = font_path path, dir
3881
+ accum[style.to_sym] = resolved_font_path if ::File.readable? resolved_font_path
3882
+ end
3883
+ raise ::Errno::ENOENT, ((File.absolute_path? path) ? %(#{path} not found) : %(#{path} not found in #{fonts_dir.gsub ValueSeparatorRx, ' or '})) unless found
3877
3884
  end
3878
- raise ::Errno::ENOENT, ((File.absolute_path? path) ? %(#{path} not found) : %(#{path} not found in #{fonts_dir.gsub ValueSeparatorRx, ' or '})) unless found
3879
- end
3880
- register_font key => styles
3885
+ end)
3881
3886
  end
3882
3887
  end
3883
3888
 
@@ -4578,14 +4583,16 @@ module Asciidoctor
4578
4583
  def consolidate_ranges nums
4579
4584
  if nums.size > 1
4580
4585
  prev = nil
4581
- nums.each_with_object [] do |num, accum|
4586
+ accum = []
4587
+ nums.each do |num|
4582
4588
  if prev && (prev.to_i + 1) == num.to_i
4583
4589
  accum[-1][1] = num
4584
4590
  else
4585
4591
  accum << [num]
4586
4592
  end
4587
4593
  prev = num
4588
- end.map {|range| range.join '-' }
4594
+ end
4595
+ accum.map {|range| range.join '-' }
4589
4596
  else
4590
4597
  nums
4591
4598
  end
@@ -4930,14 +4937,16 @@ module Asciidoctor
4930
4937
  result = yield
4931
4938
  else
4932
4939
  email = nil
4933
- original_attrs = AuthorAttributeNames.each_with_object({}) do |(prop_name, attr_name), accum|
4934
- accum[attr_name] = doc.attr attr_name
4935
- if (val = author[prop_name])
4936
- doc.set_attr attr_name, val
4937
- # NOTE: email attribute could be a url
4938
- email = val if prop_name == :email
4939
- else
4940
- doc.remove_attr attr_name
4940
+ original_attrs = {}.tap do |accum|
4941
+ AuthorAttributeNames.each do |prop_name, attr_name|
4942
+ accum[attr_name] = doc.attr attr_name
4943
+ if (val = author[prop_name])
4944
+ doc.set_attr attr_name, val
4945
+ # NOTE: email attribute could be a url
4946
+ email = val if prop_name == :email
4947
+ else
4948
+ doc.remove_attr attr_name
4949
+ end
4941
4950
  end
4942
4951
  end
4943
4952
  doc.set_attr 'url', ((email.include? '@') ? %(mailto:#{email}) : email) if email
@@ -4,7 +4,7 @@ Prawn::Font::AFM.instance_variable_set :@hide_m17n_warning, true
4
4
 
5
5
  require 'prawn/icon'
6
6
 
7
- Prawn::Icon::Compatibility.send :prepend, (::Module.new { def warning *_args; end })
7
+ Prawn::Icon::Compatibility.prepend (::Module.new { def warning *_args; end })
8
8
 
9
9
  module Asciidoctor
10
10
  module Prawn
@@ -431,15 +431,19 @@ module Asciidoctor
431
431
 
432
432
  # NOTE: override built-in fill_formatted_text_box to insert leading before second line when :first_line is true
433
433
  def fill_formatted_text_box text, options
434
- if (initial_gap = options[:initial_gap]) && (first_text = text[0]) && first_text[:from_page] != page_number
434
+ if (initial_gap = options[:initial_gap]) && !text.empty? && text[0][:from_page] != page_number
435
435
  self.y -= initial_gap
436
436
  end
437
437
  merge_text_box_positioning_options options
438
438
  box = ::Prawn::Text::Formatted::Box.new text, options
439
- remaining_text = box.render
439
+ remaining_fragments = box.render
440
440
  @no_text_printed = box.nothing_printed?
441
441
  @all_text_printed = box.everything_printed?
442
- remaining_text[0][:from_page] = page_number unless remaining_text.empty?
442
+ unless remaining_fragments.empty? || (remaining_fragments[0][:from_page] ||= page_number) == page_number
443
+ log :error, %(cannot fit formatted text on page: #{remaining_fragments.map {|it| it[:image_path] || it[:text] }.join})
444
+ page.tare_content_stream
445
+ remaining_fragments = {}
446
+ end
443
447
 
444
448
  if @final_gap || (options[:first_line] && !(@no_text_printed || @all_text_printed))
445
449
  self.y -= box.height + box.line_gap + box.leading
@@ -447,7 +451,7 @@ module Asciidoctor
447
451
  self.y -= box.height
448
452
  end
449
453
 
450
- remaining_text
454
+ remaining_fragments
451
455
  end
452
456
 
453
457
  # NOTE: override built-in draw_indented_formatted_line to set first_line flag
@@ -483,7 +487,13 @@ module Asciidoctor
483
487
  else
484
488
  remaining_fragments = box.render dry_run: true
485
489
  end
486
- remaining_fragments.empty? ? (remaining_fragments = nil) : (remaining_fragments[0][:from_page] = page_number)
490
+ if remaining_fragments.empty?
491
+ remaining_fragments = nil
492
+ elsif (remaining_fragments[0][:from_page] ||= page_number) != page_number
493
+ log :error, %(cannot fit formatted text on page: #{remaining_fragments.map {|it| it[:image_path] || it[:text] }.join})
494
+ page.tare_content_stream
495
+ remaining_fragments = nil
496
+ end
487
497
  if first_line_text_transform
488
498
  # NOTE: applying text transform here could alter the wrapping, so isolate first line and shrink it to fit
489
499
  first_line_text = (box.instance_variable_get :@printed_lines)[0]
@@ -2,12 +2,15 @@
2
2
 
3
3
  module Prawn::Text::Formatted::ProtectBottomGutter
4
4
  def enough_height_for_this_line?
5
- return super unless @arranger.finished?
6
- begin
7
- @height -= @bottom_gutter
5
+ if @arranger.finished? && @arranger.fragments.none? {|it| it.format_state[:full_height] }
6
+ begin
7
+ @height -= @bottom_gutter
8
+ super
9
+ ensure
10
+ @height += @bottom_gutter
11
+ end
12
+ else
8
13
  super
9
- ensure
10
- @height += @bottom_gutter
11
14
  end
12
15
  end
13
16
  end
@@ -38,7 +38,7 @@ module Asciidoctor::PDF::FormattedText
38
38
  return if (raw_image_fragments = fragments.select {|f| (f.key? :image_path) && !(f.key? :image_obj) }).empty?
39
39
  scratch = doc.scratch?
40
40
  available_w = available_width
41
- available_h = doc.page.empty? ? doc.cursor : doc.bounds.height
41
+ available_h = doc.bounds.height
42
42
  last_fragment = {}
43
43
  raw_image_fragments.each do |fragment|
44
44
  if fragment[:object_id] == last_fragment[:object_id]
@@ -96,6 +96,10 @@ module Asciidoctor::PDF::FormattedText
96
96
  if (f_height = image_h) > (line_font = doc.font).height * 1.5
97
97
  # align with descender (equivalent to vertical-align: bottom in CSS)
98
98
  fragment[:ascender] = f_height - (fragment[:descender] = line_font.descender)
99
+ if f_height == available_h
100
+ fragment[:ascender] -= (doc.calc_line_metrics (doc.instance_variable_get :@base_line_height), line_font, doc.font_size).padding_top
101
+ fragment[:full_height] = true
102
+ end
99
103
  doc.font_size (fragment[:size] = f_height * (doc.font_size / line_font.height))
100
104
  # align with baseline (roughly equivalent to vertical-align: baseline in CSS)
101
105
  #fragment[:ascender] = f_height
@@ -11,15 +11,15 @@ module Asciidoctor
11
11
  def wrap array
12
12
  return super unless array[0][:linenum] # sanity check
13
13
  initialize_wrap array
14
+ @line_wrap.extend SourceLineWrap
14
15
  highlight_line = stop = nil
15
16
  unconsumed = @arranger.unconsumed
16
17
  until stop
17
18
  if (first_fragment = unconsumed[0])[:linenum]
18
19
  linenum_text = first_fragment[:text]
19
- linenum_spacer ||= { text: (NoBreakSpace.encode linenum_text.encoding) + (' ' * (linenum_text.length - 1)) }
20
+ linenum_spacer ||= { text: (NoBreakSpace.encode linenum_text.encoding) + (' ' * (linenum_text.length - 1)), linenum: :spacer }
20
21
  highlight_line = (second_fragment = unconsumed[1])[:highlight] ? second_fragment.dup : nil
21
- else
22
- # NOTE: a wrapped line
22
+ else # wrapped line
23
23
  first_fragment[:text] = first_fragment[:text].lstrip
24
24
  @arranger.unconsumed.unshift highlight_line if highlight_line
25
25
  @arranger.unconsumed.unshift linenum_spacer.dup
@@ -43,6 +43,12 @@ module Asciidoctor
43
43
  @arranger.unconsumed
44
44
  end
45
45
  end
46
+
47
+ module SourceLineWrap
48
+ def update_line_status_based_on_last_output
49
+ @arranger.current_format_state[:linenum] ? nil : super
50
+ end
51
+ end
46
52
  end
47
53
  end
48
54
  end
@@ -95,22 +95,24 @@ module Asciidoctor
95
95
  styles: (to_styles theme.menu_font_style),
96
96
  }.compact,
97
97
  }
98
- revise_roles = [].to_set
99
- theme.each_pair.each_with_object @theme_settings do |(key, val), accum|
100
- next unless (key = key.to_s).start_with? 'role_'
101
- role, key = (key.slice 5, key.length).split '_', 2
102
- if (prop = ThemeKeyToFragmentProperty[key])
103
- (accum[role] ||= {})[prop] = val
104
- #elsif key == 'font_kerning'
105
- # unless (resolved_val = val == 'none' ? false : (val == 'normal' ? true : nil)).nil?
106
- # (accum[role] ||= {})[:kerning] = resolved_val
107
- # end
108
- elsif key == 'font_style' || key == 'text_decoration'
109
- revise_roles << role
98
+ @theme_settings.tap do |accum|
99
+ revise_roles = [].to_set
100
+ theme.each_pair do |key, val|
101
+ next unless (key = key.to_s).start_with? 'role_'
102
+ role, key = (key.slice 5, key.length).split '_', 2
103
+ if (prop = ThemeKeyToFragmentProperty[key])
104
+ (accum[role] ||= {})[prop] = val
105
+ #elsif key == 'font_kerning'
106
+ # unless (resolved_val = val == 'none' ? false : (val == 'normal' ? true : nil)).nil?
107
+ # (accum[role] ||= {})[:kerning] = resolved_val
108
+ # end
109
+ elsif key == 'font_style' || key == 'text_decoration'
110
+ revise_roles << role
111
+ end
112
+ end
113
+ revise_roles.each do |role|
114
+ (accum[role] ||= {})[:styles] = to_styles theme[%(role_#{role}_font_style)], theme[%(role_#{role}_text_decoration)]
110
115
  end
111
- end
112
- revise_roles.each_with_object @theme_settings do |role, accum|
113
- (accum[role] ||= {})[:styles] = to_styles theme[%(role_#{role}_font_style)], theme[%(role_#{role}_text_decoration)]
114
116
  end
115
117
  @theme_settings['line-through'] = { styles: [:strikethrough].to_set } unless @theme_settings.key? 'line-through'
116
118
  @theme_settings['underline'] = { styles: [:underline].to_set } unless @theme_settings.key? 'underline'
@@ -276,8 +278,10 @@ module Asciidoctor
276
278
  when '#' # hex string (e.g., #FF0000)
277
279
  fragment[:color] = value.length == 7 ? (value.slice 1, 6) : (value.slice 1, 3).each_char.map {|c| c * 2 }.join if HexColorRx.match? value
278
280
  when '[' # CMYK array (e.g., [50, 100, 0, 0])
279
- fragment[:color] = ((((value.slice 1, value.length).chomp ']').split ', ', 4).each_with_object ::Array.new 4, 0).with_index do |(it, accum), idx|
280
- accum[idx] = (ival = it.to_i) == (fval = it.to_f) ? ival : fval
281
+ fragment[:color] = [0, 0, 0, 0].tap do |accum|
282
+ (((value.slice 1, value.length).chomp ']').split ', ', 4).each_with_index do |it, idx|
283
+ accum[idx] = (ival = it.to_i) == (fval = it.to_f) ? ival : fval
284
+ end
281
285
  end
282
286
  else # assume a 6-character hex color (internal only)
283
287
  fragment[:color] = value
@@ -15,9 +15,7 @@ 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
18
+ DeprecatedKeys = { 'table_caption_side' => 'table_caption_end' }.tap {|accum| %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 {|prefix| accum[%(#{prefix}_align)] = %(#{prefix}_text_align) } }
21
19
  PaddingBottomHackKeys = %w(example_padding quote_padding sidebar_padding verse_padding)
22
20
 
23
21
  VariableRx = /\$([a-z0-9_-]+)/
@@ -159,10 +157,12 @@ module Asciidoctor
159
157
  elsif key == 'font_fallbacks'
160
158
  data[key] = ::Array === val ? val.map {|name| expand_vars name.to_s, data } : []
161
159
  elsif key.start_with? 'admonition_icon_'
162
- data[key] = val.map do |(key2, val2)|
163
- key2 = key2.tr '-', '_' if key2.include? '-'
164
- [key2.to_sym, (key2.end_with? '_color') ? (to_color evaluate val2, data) : (evaluate val2, data)]
165
- end.to_h if val
160
+ data[key] = {}.tap do |accum|
161
+ val.each do |key2, val2|
162
+ key2 = key2.tr '-', '_' if key2.include? '-'
163
+ accum[key2.to_sym] = (key2.end_with? '_color') ? (to_color evaluate val2, data) : (evaluate val2, data)
164
+ end
165
+ end if val
166
166
  elsif ::Hash === val
167
167
  if (rekey = DeprecatedCategoryKeys[key])
168
168
  logger.warn %(the #{key.tr '_', '-'} theme category is deprecated; use the #{rekey.tr '_', '-'} category instead)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Asciidoctor
4
4
  module PDF
5
- VERSION = '2.0.0'
5
+ VERSION = '2.0.1'
6
6
  end
7
7
  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.0.0
4
+ version: 2.0.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-05-18 00:00:00.000000000 Z
12
+ date: 2022-05-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: asciidoctor