asciidoctor-pdf 2.1.2 → 2.1.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2109e7ec140c759820252d4c7f0f155c2d7bf4adfcad9d34fddb8cf4bc81a260
4
- data.tar.gz: c18e3fb15231f968d907fc05693f6c4d7f9fbedfd29e368b0dc355f44d2e4254
3
+ metadata.gz: 0cacde45fb257acbe2644ae3da1673e0a9fe9cd42f4b97de92a3ae2d97400fdb
4
+ data.tar.gz: e4e01d9fa4e923e598277c5db822632a5dc3fe67e51ebbea26d744f8d30e7315
5
5
  SHA512:
6
- metadata.gz: 4e51a465c863440441cae24e429bbf84d9fb782e2c711958d5b72dfa585ba4b1b7c9c94b92d8155b2cea0d72eec276fac6e4669ea8a50c175ff8ed82ab91eb8d
7
- data.tar.gz: a62b653261f3194d51a738cc4b1cf46f4a78a6ba0c1687fbeb06bf5049ecc9d65a20edd7acc463a2f4b473d1248795ce39902b214b87b019cbc8485d394a32f3
6
+ metadata.gz: 2fadd03cc382136bf1387867d83d68396f58c4182a51616254562c1d6460e28e0555781e9c5c51d372cd6d3fee29f80b7c06d9fc0d6e055a2839cf63491bf92d
7
+ data.tar.gz: 6fa97a16ff15ac5b0dee3789d33aa2760595139299ae41eb4e0104b4346c8569ffb8f1377fd0844f2c98ec831a08156258754e2a54f25c9fb10972a681f0c592
data/CHANGELOG.adoc CHANGED
@@ -5,6 +5,46 @@
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.5 (2022-07-10) - @mojavelinux
9
+
10
+ Bug Fixes::
11
+
12
+ * fix position of background color on caption with outside margin (#2271)
13
+ * don't allow font scale to compound when entering nested table (#2276)
14
+
15
+ === Details
16
+
17
+ {url-repo}/releases/tag/v2.1.5[git tag] | {url-repo}/compare/v2.1.4\...v2.1.5[full diff]
18
+
19
+ == 2.1.4 (2022-06-26) - @mojavelinux
20
+
21
+ Improvements::
22
+
23
+ * include source location in warning message for truncated table cell if sourcemap is enabled (#2261)
24
+
25
+ Bug Fixes::
26
+
27
+ * allow alt text for block image, video, and audio to wrap to next line on same page (#2258)
28
+ * apply text-tranform from custom role on phrase after attributes have been resolved (#2263)
29
+ * make URL check more strict so image target containing a colon is not mistaken as a URL
30
+
31
+ === Details
32
+
33
+ {url-repo}/releases/tag/v2.1.4[git tag] | {url-repo}/compare/v2.1.3\...v2.1.4[full diff]
34
+
35
+ == 2.1.3 (2022-06-23) - @mojavelinux
36
+
37
+ Bug Fixes::
38
+
39
+ * interpret `start-at` theme keys with value `1` correctly (as `1` instead of `2`) (#2255)
40
+ * restore column layout after importing page(s) from PDF (#2253)
41
+ * fix crash when border color is transparent (`thematic-break-border-color`, `admonition-column-rule`, `quote-border-color`, `verse-border-color`)
42
+ * ensure page margin is restored after imported page
43
+
44
+ === Details
45
+
46
+ {url-repo}/releases/tag/v2.1.3[git tag] | {url-repo}/compare/v2.1.2\...v2.1.3[full diff]
47
+
8
48
  == 2.1.2 (2022-06-17) - @mojavelinux
9
49
 
10
50
  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.2, 2022-06-17
3
+ v2.1.5, 2022-07-10
4
4
  // Settings:
5
5
  :experimental:
6
6
  :idprefix:
@@ -22,8 +22,6 @@ endif::[]
22
22
  // Aliases:
23
23
  :project-name: Asciidoctor PDF
24
24
  :project-handle: asciidoctor-pdf
25
- // Variables:
26
- :release-line: 2.1.x
27
25
  // URLs:
28
26
  :url-gem: https://rubygems.org/gems/asciidoctor-pdf
29
27
  :url-project: https://github.com/asciidoctor/asciidoctor-pdf
data/bin/asciidoctor-pdf CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- if File.file?(asciidoctor_pdf = (File.expand_path '../../lib/asciidoctor/pdf.rb', __FILE__))
4
+ if File.file? (asciidoctor_pdf = File.join (File.dirname __dir__), 'lib/asciidoctor/pdf.rb')
5
5
  require asciidoctor_pdf
6
6
  else
7
7
  require 'asciidoctor/pdf'
@@ -10,14 +10,14 @@ require 'asciidoctor/cli'
10
10
 
11
11
  options = Asciidoctor::Cli::Options.new backend: 'pdf', header_footer: true
12
12
 
13
- # FIXME provide an API in Asciidoctor for sub-components to print version information
13
+ # FIXME: provide an API in Asciidoctor for sub-components to print version information
14
14
  unless ARGV != ['-v'] && (ARGV & ['-V', '--version']).empty?
15
15
  $stdout.write %(Asciidoctor PDF #{Asciidoctor::PDF::VERSION} using )
16
16
  options.print_version
17
17
  exit 0
18
18
  end
19
19
 
20
- # FIXME This is a really bizarre API. Please make me simpler.
20
+ # FIXME: This is a really bizarre API. Please make me simpler.
21
21
  case (result = options.parse! ARGV)
22
22
  when Integer
23
23
  exit result
@@ -27,8 +27,6 @@ module Asciidoctor
27
27
 
28
28
  attr_accessor :font_scale
29
29
 
30
- attr_reader :root_font_size
31
-
32
30
  attr_reader :index
33
31
 
34
32
  attr_reader :theme
@@ -114,6 +112,7 @@ module Asciidoctor
114
112
  UriBreakCharsRx = %r((?:/|\?|&amp;|#)(?!$))
115
113
  UriBreakCharRepl = %(\\&#{ZeroWidthSpace})
116
114
  UriSchemeBoundaryRx = %r((?<=://))
115
+ UrlSniffRx = %r(^\p{Alpha}[\p{Alnum}+.-]*://)
117
116
  LineScanRx = /\n|.+/
118
117
  BlankLineRx = /\n{2,}/
119
118
  CjkLineBreakRx = /(?=[\u3000\u30a0-\u30ff\u3040-\u309f\p{Han}\uff00-\uffef])/
@@ -213,7 +212,7 @@ module Asciidoctor
213
212
  first_page_offset = has_title_page ? zero_page_offset.next : zero_page_offset
214
213
  body_offset = (body_start_page_number = page_number) - 1
215
214
  if ::Integer === (running_content_start_at = @theme.running_content_start_at)
216
- running_content_body_offset = body_offset + [running_content_start_at.pred, 1].max
215
+ running_content_body_offset = body_offset + [running_content_start_at.pred, 0].max
217
216
  running_content_start_at = 'body'
218
217
  else
219
218
  running_content_body_offset = body_offset
@@ -227,7 +226,7 @@ module Asciidoctor
227
226
  end
228
227
  end
229
228
  if ::Integer === (page_numbering_start_at = @theme.page_numbering_start_at)
230
- page_numbering_body_offset = body_offset + [page_numbering_start_at.pred, 1].max
229
+ page_numbering_body_offset = body_offset + [page_numbering_start_at.pred, 0].max
231
230
  page_numbering_start_at = 'body'
232
231
  else
233
232
  page_numbering_body_offset = body_offset
@@ -263,12 +262,12 @@ module Asciidoctor
263
262
  else
264
263
  body_offset = body_start_page_number - 1
265
264
  if ::Integer === (running_content_start_at = @theme.running_content_start_at)
266
- running_content_body_offset = body_offset + [running_content_start_at.pred, 1].max
265
+ running_content_body_offset = body_offset + [running_content_start_at.pred, 0].max
267
266
  else
268
267
  running_content_body_offset = body_offset
269
268
  end
270
269
  if ::Integer === (page_numbering_start_at = @theme.page_numbering_start_at)
271
- page_numbering_body_offset = body_offset + [page_numbering_start_at.pred, 1].max
270
+ page_numbering_body_offset = body_offset + [page_numbering_start_at.pred, 0].max
272
271
  elsif page_numbering_start_at == 'cover' && has_front_cover
273
272
  page_numbering_body_offset = 0
274
273
  else
@@ -371,8 +370,6 @@ module Asciidoctor
371
370
  if (page_margin_inner = theme.page_margin_inner)
372
371
  page_margin_recto[3] = page_margin_verso[1] = page_margin_inner
373
372
  end
374
- # NOTE: prepare scratch document to use page margin from recto side (which has same width as verso side)
375
- set_page_margin page_margin_recto unless page_margin_recto == page_margin
376
373
  else
377
374
  @ppbook = nil
378
375
  end
@@ -581,6 +578,7 @@ module Asciidoctor
581
578
  end
582
579
 
583
580
  def prepare_theme theme
581
+ theme.base_border_color = nil if theme.base_border_color == 'transparent'
584
582
  theme.base_font_color ||= '000000'
585
583
  theme.base_font_size ||= 12
586
584
  theme.base_font_style = theme.base_font_style&.to_sym || :normal
@@ -943,7 +941,7 @@ module Asciidoctor
943
941
  if extent
944
942
  label_height = extent.single_page_height || cursor
945
943
  if (rule_width = @theme.admonition_column_rule_width || 0) > 0 &&
946
- (rule_color = @theme.admonition_column_rule_color || @theme.base_border_color)
944
+ (rule_color = resolve_theme_color :admonition_column_rule_color, @theme.base_border_color, nil)
947
945
  rule_style = @theme.admonition_column_rule_style&.to_sym || :solid
948
946
  float do
949
947
  extent.each_page do |first_page, last_page|
@@ -1273,7 +1271,7 @@ module Asciidoctor
1273
1271
  category = node.context == :quote ? :quote : :verse
1274
1272
  # NOTE: b_width and b_left_width are mutually exclusive
1275
1273
  if (b_left_width = @theme[%(#{category}_border_left_width)]) && b_left_width > 0
1276
- b_color = @theme[%(#{category}_border_color)] || @theme.base_border_color
1274
+ b_left_width = nil unless (b_color = resolve_theme_color %(#{category}_border_color), @theme.base_border_color, nil)
1277
1275
  else
1278
1276
  b_left_width = nil
1279
1277
  b_width = nil if (b_width = @theme[%(#{category}_border_width)]) == 0
@@ -1887,7 +1885,7 @@ module Asciidoctor
1887
1885
  add_dest_for_block node if node.id
1888
1886
  audio_path = node.media_uri node.attr 'target'
1889
1887
  play_symbol = (node.document.attr? 'icons', 'font') ? %(<font name="fas">#{(icon_font_data 'fas').unicode 'play'}</font>) : RightPointer
1890
- ink_prose %(#{play_symbol}#{NoBreakSpace}<a href="#{audio_path}">#{audio_path}</a> <em>(audio)</em>), normalize: false, margin: 0, single_line: true
1888
+ ink_prose %(#{play_symbol}#{NoBreakSpace}<a href="#{audio_path}">#{audio_path}</a> <em>(audio)</em>), normalize: false, margin: 0
1891
1889
  ink_caption node, labeled: false, end: :bottom if node.title?
1892
1890
  theme_margin :block, :bottom, (next_enclosed_block node)
1893
1891
  end
@@ -1915,7 +1913,7 @@ module Asciidoctor
1915
1913
  if poster.nil_or_empty?
1916
1914
  add_dest_for_block node if node.id
1917
1915
  play_symbol = (node.document.attr? 'icons', 'font') ? %(<font name="fas">#{(icon_font_data 'fas').unicode 'play'}</font>) : RightPointer
1918
- ink_prose %(#{play_symbol}#{NoBreakSpace}<a href="#{video_path}">#{video_path}</a> <em>(#{type})</em>), normalize: false, margin: 0, single_line: true
1916
+ ink_prose %(#{play_symbol}#{NoBreakSpace}<a href="#{video_path}">#{video_path}</a> <em>(#{type})</em>), normalize: false, margin: 0
1919
1917
  ink_caption node, labeled: false, end: :bottom if node.title?
1920
1918
  theme_margin :block, :bottom, (next_enclosed_block node)
1921
1919
  else
@@ -1996,6 +1994,7 @@ module Asciidoctor
1996
1994
  num_cols = node.columns.size
1997
1995
  table_header_size = false
1998
1996
  theme = @theme
1997
+ prev_font_scale, @font_scale = @font_scale, 1 if node.document.nested?
1999
1998
 
2000
1999
  tbl_bg_color = resolve_theme_color :table_background_color
2001
2000
  # QUESTION: should we fallback to page background color? (which is never transparent)
@@ -2054,7 +2053,8 @@ module Asciidoctor
2054
2053
  content: cell_text,
2055
2054
  colspan: cell.colspan || 1,
2056
2055
  align: (cell.attr 'halign').to_sym,
2057
- valign: (val = cell.attr 'valign') == 'middle' ? :center : val.to_sym
2056
+ valign: (val = cell.attr 'valign') == 'middle' ? :center : val.to_sym,
2057
+ source_location: cell.source_location
2058
2058
  end)
2059
2059
  end
2060
2060
  end unless head_rows.empty?
@@ -2073,7 +2073,8 @@ module Asciidoctor
2073
2073
  colspan: cell.colspan || 1,
2074
2074
  rowspan: cell.rowspan || 1,
2075
2075
  align: (cell.attr 'halign').to_sym,
2076
- valign: (val = cell.attr 'valign') == 'middle' ? :center : val.to_sym
2076
+ valign: (val = cell.attr 'valign') == 'middle' ? :center : val.to_sym,
2077
+ source_location: cell.source_location
2077
2078
  cell_line_metrics = body_cell_line_metrics
2078
2079
  case cell.style
2079
2080
  when :emphasis
@@ -2133,8 +2134,8 @@ module Asciidoctor
2133
2134
  end
2134
2135
  # NOTE: line metrics get applied when AsciiDoc content is converted
2135
2136
  cell_line_metrics = nil
2136
- asciidoc_cell = ::Prawn::Table::Cell::AsciiDoc.new self, (cell_data.merge content: cell.inner_document, padding: body_cell_padding)
2137
- cell_data = { content: asciidoc_cell }
2137
+ asciidoc_cell = ::Prawn::Table::Cell::AsciiDoc.new self, (cell_data.merge content: cell.inner_document, padding: body_cell_padding, root_font_size: @root_font_size)
2138
+ cell_data = { content: asciidoc_cell, source_location: cell.source_location }
2138
2139
  end
2139
2140
  if cell_line_metrics
2140
2141
  cell_padding = body_cell_padding.dup
@@ -2337,13 +2338,17 @@ module Asciidoctor
2337
2338
  theme_margin :block, :bottom, (next_enclosed_block node)
2338
2339
  rescue ::Prawn::Errors::CannotFit
2339
2340
  log :error, (message_with_context 'cannot fit contents of table cell into specified column width', source_location: node.source_location)
2341
+ ensure
2342
+ @font_scale = prev_font_scale if prev_font_scale
2340
2343
  end
2341
2344
 
2342
2345
  def convert_thematic_break node
2343
2346
  pad_box @theme.thematic_break_padding || [@theme.thematic_break_margin_top, 0] do
2344
- stroke_horizontal_rule @theme.thematic_break_border_color,
2345
- line_width: @theme.thematic_break_border_width,
2346
- line_style: (@theme.thematic_break_border_style&.to_sym || :solid)
2347
+ if (b_color = resolve_theme_color :thematic_break_border_color)
2348
+ stroke_horizontal_rule b_color,
2349
+ line_width: @theme.thematic_break_border_width,
2350
+ line_style: (@theme.thematic_break_border_style&.to_sym || :solid)
2351
+ end
2347
2352
  end
2348
2353
  conceal_page_top { theme_margin :block, :bottom, (next_enclosed_block node) }
2349
2354
  end
@@ -2684,13 +2689,7 @@ module Asciidoctor
2684
2689
  end
2685
2690
 
2686
2691
  if (roles = node.role)
2687
- theme = load_theme node.document
2688
- roles.split.each do |role|
2689
- if (text_transform = theme[%(role_#{role}_text_transform)])
2690
- inner_text = transform_text inner_text, text_transform
2691
- end
2692
- inner_text = inner_text.gsub DoubleSpaceRx, ' ' + ZeroWidthSpace if role == 'pre-wrap' && (inner_text.include? DoubleSpace)
2693
- end
2692
+ inner_text = inner_text.gsub DoubleSpaceRx, ' ' + ZeroWidthSpace if (node.has_role? 'pre-wrap') && (inner_text.include? DoubleSpace)
2694
2693
  quoted_text = is_tag ? %(#{open.chop} class="#{roles}">#{inner_text}#{close}) : %(<span class="#{roles}">#{open}#{inner_text}#{close}</span>)
2695
2694
  else
2696
2695
  quoted_text = %(#{open}#{inner_text}#{close})
@@ -3105,7 +3104,8 @@ module Asciidoctor
3105
3104
  end
3106
3105
  unless scratch? || !(bg_color = @theme[%(#{category_caption}_background_color)] || @theme.caption_background_color)
3107
3106
  caption_height = height_of_typeset_text string
3108
- fill_at = [bounds.left, cursor + (margin[:top] || 0)]
3107
+ fill_at = [bounds.left, cursor]
3108
+ fill_at[1] -= (margin[:top] || 0) unless at_page_top?
3109
3109
  float { bounding_box(fill_at, width: container_width, height: caption_height) { fill_bounds bg_color } }
3110
3110
  end
3111
3111
  indent(*indent_by) do
@@ -3240,7 +3240,8 @@ module Asciidoctor
3240
3240
  end
3241
3241
  end
3242
3242
 
3243
- # NOTE: inline_format is true by default
3243
+ # NOTE: inline_format option is true by default
3244
+ # NOTE: single_line option is not compatible with this method
3244
3245
  def ink_prose string, opts = {}
3245
3246
  top_margin = (margin = (opts.delete :margin)) || (opts.delete :margin_top) || 0
3246
3247
  bot_margin = margin || (opts.delete :margin_bottom) || @theme.prose_margin_bottom
@@ -4254,10 +4255,10 @@ module Asciidoctor
4254
4255
  # NOTE: this will catch a classloader resource path on JRuby (e.g., uri:classloader:/path/to/image)
4255
4256
  elsif ::File.absolute_path? image_path
4256
4257
  ::File.absolute_path image_path
4257
- elsif !(is_uri = node.is_uri? image_path) && imagesdir && (::File.absolute_path? imagesdir)
4258
+ elsif !(is_url = url? image_path) && imagesdir && (::File.absolute_path? imagesdir)
4258
4259
  ::File.absolute_path image_path, imagesdir
4259
4260
  # handle case when image is a URI
4260
- elsif is_uri || (imagesdir && (node.is_uri? imagesdir) && (image_path = node.normalize_web_path image_path, imagesdir, false))
4261
+ elsif is_url || (imagesdir && (url? imagesdir) && (image_path = node.normalize_web_path image_path, imagesdir, false))
4261
4262
  if !allow_uri_read
4262
4263
  log :warn, %(cannot embed remote image: #{image_path} (allow-uri-read attribute not enabled))
4263
4264
  return
@@ -4495,6 +4496,7 @@ module Asciidoctor
4495
4496
  end
4496
4497
 
4497
4498
  # TODO: document me, esp the first line formatting functionality
4499
+ # NOTE: single_line option should only be used if height option is specified
4498
4500
  def typeset_text string, line_metrics, opts = {}
4499
4501
  opts = { leading: line_metrics.leading, final_gap: line_metrics.final_gap }.merge opts
4500
4502
  string = string.gsub CjkLineBreakRx, ZeroWidthSpace if @cjk_line_breaks
@@ -4817,18 +4819,17 @@ module Asciidoctor
4817
4819
  end
4818
4820
 
4819
4821
  # NOTE: init_page is called within a float context; this will suppress prawn-svg messing with the cursor
4820
- # NOTE: init_page is not called for imported pages, front and back cover pages, and other image pages
4822
+ # NOTE: init_page is not called for imported pages, cover pages, image pages, and pages in the scratch document
4821
4823
  def init_page *_args
4822
4824
  next_page_side = page_side nil, @folio_placement[:inverted]
4823
4825
  if @media == 'prepress' && (next_page_margin = @page_margin_by_side[page_number == 1 ? :cover : next_page_side]) != page_margin
4824
4826
  set_page_margin next_page_margin
4825
4827
  end
4826
4828
  unless @page_bg_color == 'FFFFFF'
4827
- tare = true
4828
4829
  fill_absolute_bounds @page_bg_color
4830
+ tare = true
4829
4831
  end
4830
4832
  if (bg_image_path, bg_image_opts = @page_bg_image[next_page_side])
4831
- tare = true
4832
4833
  begin
4833
4834
  if bg_image_opts[:format] == 'pdf'
4834
4835
  # NOTE: pages that use PDF for the background do not support a background color or running content
@@ -4837,6 +4838,7 @@ module Asciidoctor
4837
4838
  else
4838
4839
  canvas { image bg_image_path, ({ position: :center, vposition: :center }.merge bg_image_opts) }
4839
4840
  end
4841
+ tare = true
4840
4842
  rescue
4841
4843
  facing_page_side = (PageSides - [next_page_side])[0]
4842
4844
  @page_bg_image[facing_page_side] = nil if @page_bg_image[facing_page_side] == @page_bg_image[next_page_side]
@@ -4949,7 +4951,7 @@ module Asciidoctor
4949
4951
  alt_text_vars[:'/link'] = ''
4950
4952
  end
4951
4953
  theme_font :image_alt do
4952
- ink_prose alt_text_template % alt_text_vars, align: opts[:align], margin: 0, normalize: false, single_line: true
4954
+ ink_prose alt_text_template % alt_text_vars, align: opts[:align], margin: 0, normalize: false
4953
4955
  end
4954
4956
  ink_caption node, category: :image, end: :bottom if node.title?
4955
4957
  theme_margin :block, :bottom, (next_enclosed_block node) unless opts[:pinned]
@@ -5031,10 +5033,8 @@ module Asciidoctor
5031
5033
  # QUESTION: should we pass a category as an argument?
5032
5034
  # QUESTION: should we make this a method on the theme ostruct? (e.g., @theme.resolve_color key, fallback)
5033
5035
  def resolve_theme_color key, fallback_color = nil, transparent_color = fallback_color
5034
- if (color = @theme[key])
5036
+ if (color = @theme[key] || fallback_color)
5035
5037
  color == 'transparent' ? transparent_color : color
5036
- else
5037
- fallback_color
5038
5038
  end
5039
5039
  end
5040
5040
 
@@ -5046,6 +5046,10 @@ module Asciidoctor
5046
5046
  false
5047
5047
  end
5048
5048
 
5049
+ def url? str
5050
+ (str.include? ':/') && (UrlSniffRx.match? str)
5051
+ end
5052
+
5049
5053
  # Calculate the width that is needed to print all the
5050
5054
  # fragments without wrapping any lines.
5051
5055
  #
@@ -5114,6 +5118,10 @@ module Asciidoctor
5114
5118
  end
5115
5119
 
5116
5120
  def init_scratch originator
5121
+ if @media == 'prepress' && page_margin != (page_margin_recto = @page_margin_by_side[:recto])
5122
+ # NOTE: prepare scratch document to use page margin from recto side (which has same width as verso side)
5123
+ set_page_margin page_margin_recto
5124
+ end
5117
5125
  @scratch_prototype = originator.instance_variable_get :@scratch_prototype
5118
5126
  @tmp_files = originator.instance_variable_get :@tmp_files
5119
5127
  text_formatter.scratch = true
@@ -6,20 +6,23 @@ Prawn::Document::ColumnBox.prepend (Module.new do
6
6
  def move_past_bottom
7
7
  (doc = @document).y = @y
8
8
  return if (@current_column = (@current_column + 1) % @columns) > 0
9
- par = @parent
10
- if (reset_y = @reflow_margins) && (reset_y == true || reset_y > doc.page_number)
11
- @y = par.absolute_top
12
- @height = par.height unless stretchy?
13
- end
9
+ parent_ = @parent
10
+ reset_top parent_ if (reflow_at = @reflow_margins) && (reflow_at == true || reflow_at > doc.page_number)
14
11
  initial_margins = doc.page.margins
15
- par.move_past_bottom
12
+ parent_.move_past_bottom
16
13
  if doc.page.margins != initial_margins
17
- doc.bounds = self.class.new doc, par, [(margin_box = doc.margin_box).absolute_left, @y],
14
+ doc.bounds = self.class.new doc, parent_, [(margin_box = doc.margin_box).absolute_left, @y],
18
15
  columns: @columns, reflow_margins: @reflow_margins, spacer: @spacer, width: margin_box.width, height: @height
19
16
  end
20
17
  nil
21
18
  end
22
19
 
20
+ def reset_top parent_ = @parent
21
+ @current_column = 0
22
+ @height = parent_.height unless stretchy?
23
+ @y = parent_.absolute_top
24
+ end
25
+
23
26
  # Rearranges the column box into a single column, where the original columns are in a single file. Used
24
27
  # for the purpose of computing the extent of content in a scratch document.
25
28
  def single_file
@@ -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
@@ -924,6 +901,8 @@ module Asciidoctor
924
901
  def import_page file, options = {}
925
902
  prev_page_layout = page.layout
926
903
  prev_page_size = page.size
904
+ prev_page_margin = page_margin
905
+ prev_bounds = bounds
927
906
  state.compress = false if state.compress # can't use compression if using template
928
907
  prev_text_rendering_mode = (defined? @text_rendering_mode) ? @text_rendering_mode : nil
929
908
  delete_current_page if options[:replace]
@@ -936,11 +915,15 @@ module Asciidoctor
936
915
  # NOTE: set page size & layout explicitly in case imported page differs
937
916
  # I'm not sure it's right to start a new page here, but unfortunately there's no other
938
917
  # way atm to prevent the size & layout of the imported page from affecting subsequent pages
939
- advance_page size: prev_page_size, layout: prev_page_layout if options.fetch :advance, true
918
+ if options.fetch :advance, true
919
+ advance_page layout: prev_page_layout, margin: prev_page_margin, size: prev_page_size
920
+ (@bounding_box = prev_bounds).reset_top if ColumnBox === prev_bounds
921
+ end
940
922
  elsif options.fetch :advance_if_missing, true
941
923
  delete_current_page
942
924
  # NOTE: see previous comment
943
- advance_page size: prev_page_size, layout: prev_page_layout
925
+ advance_page layout: prev_page_layout, margin: prev_page_margin, size: prev_page_size
926
+ @y = (@bounding_box = prev_bounds).reset_top if ColumnBox === prev_bounds
944
927
  else
945
928
  delete_current_page
946
929
  end
@@ -1112,7 +1095,8 @@ module Asciidoctor
1112
1095
  # This method performs all work in a scratch document (or documents). It begins by starting a
1113
1096
  # new page in the scratch document, first creating the scratch document if necessary. It then
1114
1097
  # applies all the settings from the main document to the scratch document that impact
1115
- # rendering. This includes the bounds, the cursor position, and the font settings.
1098
+ # rendering. This includes the bounds, the cursor position, and the font settings. This method
1099
+ # assumes that the content area remains constant when content flows from one page to the next.
1116
1100
  #
1117
1101
  # From this point, the number of attempts the method makes is determined by the value of the
1118
1102
  # keep_together keyword parameter. If the value is true (or the parent document is inhibiting
@@ -7,6 +7,7 @@ module Prawn
7
7
  include ::Asciidoctor::Logging
8
8
 
9
9
  attr_accessor :align
10
+ attr_accessor :root_font_size
10
11
  attr_accessor :valign
11
12
 
12
13
  def initialize pdf, opts = {}
@@ -91,7 +92,9 @@ module Prawn
91
92
  # TODO: apply horizontal alignment; currently it is necessary to specify alignment on content blocks
92
93
  apply_font_properties { pdf.traverse content }
93
94
  if (extra_pages = pdf.page_number - start_page) > 0
94
- 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?
95
+ unless extra_pages == 1 && pdf.page.empty?
96
+ 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
97
+ end
95
98
  extra_pages.times { pdf.delete_current_page }
96
99
  end
97
100
  nil
@@ -107,7 +110,7 @@ module Prawn
107
110
  prev_font_color, pdf.font_color = pdf.font_color, font_color if font_color
108
111
  font_family ||= font_info[:family]
109
112
  if font_size
110
- prev_font_scale, pdf.font_scale = pdf.font_scale, (font_size.to_f / @pdf.root_font_size)
113
+ prev_font_scale, pdf.font_scale = pdf.font_scale, (font_size.to_f / @root_font_size)
111
114
  else
112
115
  font_size = font_info[:size]
113
116
  end
@@ -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
- logger.error %(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) unless remaining_text.empty? || @pdf.scratch?
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
 
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  Prawn::Table::Cell.prepend (Module.new do
4
+ attr_writer :source_location
5
+
4
6
  def border_color= color
5
7
  color = [color, color] if Asciidoctor::PDF::ThemeLoader::CMYKColorValue === color
6
8
  super
@@ -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
@@ -3,7 +3,7 @@
3
3
  module Asciidoctor
4
4
  module PDF
5
5
  class IndexCatalog
6
- include ::Asciidoctor::PDF::TextTransformer
6
+ include TextTransformer
7
7
 
8
8
  LeadingAlphaRx = /^\p{Alpha}/
9
9
 
@@ -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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Asciidoctor
4
4
  module PDF
5
- VERSION = '2.1.2'
5
+ VERSION = '2.1.5'
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.1.2
4
+ version: 2.1.5
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-17 00:00:00.000000000 Z
12
+ date: 2022-07-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: asciidoctor