asciidoctor-pdf 2.1.3 → 2.1.4

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: f7753392586bac4a044601fefa9ecb58745e02fc37434dd5a26e020692890e65
4
- data.tar.gz: 301fe3fef546588aacba4ca8d9c5afd91d4a19a816f07a8fcc66121c8f58f626
3
+ metadata.gz: eb8baebe850d75fcfc95460fbbdf89978867adb076acf572abaff0f51e18fb04
4
+ data.tar.gz: d4dbbaab4981db0666488ae108aee0f5851feb706e3846b13cd5cf46c341b5bc
5
5
  SHA512:
6
- metadata.gz: b26fe1f74b22bd73eba166190d21afebafdc1630dba5fee8174aa946b463d81b7e620cb8f400e803507f050c6dd48a1d732a1273a78fc1cd0e958da69a0a3c9c
7
- data.tar.gz: 15cd75342088585a51f19cb342a8023fbc2aa6d0cd89fff72385370172059ac10c98fa51b8126845ce40436fcd89dc0c1f47aa763df14dad24ba2bcd95f92205
6
+ metadata.gz: 26b1c9830deeb0a39494e9cdb85fa5c2e2295efe8b3d527525b27c6dcf420a8ab94e06eeaca3431425e9cf547150d372bab49813af946cdd5ea0e155d6aad1f0
7
+ data.tar.gz: d584830d1eb1f76a005b48cf6a20030311d40184254d4ddfbd752f99a66c27feab85292c79012af0c9c4b7272a1727f402828f1c6d992228660ccbf78be44d2a
data/CHANGELOG.adoc CHANGED
@@ -5,6 +5,22 @@
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.4 (2022-06-26) - @mojavelinux
9
+
10
+ Improvements::
11
+
12
+ * include source location in warning message for truncated table cell if sourcemap is enabled (#2261)
13
+
14
+ Bug Fixes::
15
+
16
+ * allow alt text for block image, video, and audio to wrap to next line on same page (#2258)
17
+ * apply text-tranform from custom role on phrase after attributes have been resolved (#2263)
18
+ * make URL check more strict so image target containing a colon is not mistaken as a URL
19
+
20
+ === Details
21
+
22
+ {url-repo}/releases/tag/v2.1.4[git tag] | {url-repo}/compare/v2.1.3\...v2.1.4[full diff]
23
+
8
24
  == 2.1.3 (2022-06-23) - @mojavelinux
9
25
 
10
26
  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.3, 2022-06-23
3
+ v2.1.4, 2022-06-26
4
4
  // Settings:
5
5
  :experimental:
6
6
  :idprefix:
@@ -114,6 +114,7 @@ module Asciidoctor
114
114
  UriBreakCharsRx = %r((?:/|\?|&amp;|#)(?!$))
115
115
  UriBreakCharRepl = %(\\&#{ZeroWidthSpace})
116
116
  UriSchemeBoundaryRx = %r((?<=://))
117
+ UrlSniffRx = %r(^\p{Alpha}[\p{Alnum}+.-]*://)
117
118
  LineScanRx = /\n|.+/
118
119
  BlankLineRx = /\n{2,}/
119
120
  CjkLineBreakRx = /(?=[\u3000\u30a0-\u30ff\u3040-\u309f\p{Han}\uff00-\uffef])/
@@ -1886,7 +1887,7 @@ module Asciidoctor
1886
1887
  add_dest_for_block node if node.id
1887
1888
  audio_path = node.media_uri node.attr 'target'
1888
1889
  play_symbol = (node.document.attr? 'icons', 'font') ? %(<font name="fas">#{(icon_font_data 'fas').unicode 'play'}</font>) : RightPointer
1889
- ink_prose %(#{play_symbol}#{NoBreakSpace}<a href="#{audio_path}">#{audio_path}</a> <em>(audio)</em>), normalize: false, margin: 0, single_line: true
1890
+ ink_prose %(#{play_symbol}#{NoBreakSpace}<a href="#{audio_path}">#{audio_path}</a> <em>(audio)</em>), normalize: false, margin: 0
1890
1891
  ink_caption node, labeled: false, end: :bottom if node.title?
1891
1892
  theme_margin :block, :bottom, (next_enclosed_block node)
1892
1893
  end
@@ -1914,7 +1915,7 @@ module Asciidoctor
1914
1915
  if poster.nil_or_empty?
1915
1916
  add_dest_for_block node if node.id
1916
1917
  play_symbol = (node.document.attr? 'icons', 'font') ? %(<font name="fas">#{(icon_font_data 'fas').unicode 'play'}</font>) : RightPointer
1917
- ink_prose %(#{play_symbol}#{NoBreakSpace}<a href="#{video_path}">#{video_path}</a> <em>(#{type})</em>), normalize: false, margin: 0, single_line: true
1918
+ ink_prose %(#{play_symbol}#{NoBreakSpace}<a href="#{video_path}">#{video_path}</a> <em>(#{type})</em>), normalize: false, margin: 0
1918
1919
  ink_caption node, labeled: false, end: :bottom if node.title?
1919
1920
  theme_margin :block, :bottom, (next_enclosed_block node)
1920
1921
  else
@@ -2053,7 +2054,8 @@ module Asciidoctor
2053
2054
  content: cell_text,
2054
2055
  colspan: cell.colspan || 1,
2055
2056
  align: (cell.attr 'halign').to_sym,
2056
- valign: (val = cell.attr 'valign') == 'middle' ? :center : val.to_sym
2057
+ valign: (val = cell.attr 'valign') == 'middle' ? :center : val.to_sym,
2058
+ source_location: cell.source_location
2057
2059
  end)
2058
2060
  end
2059
2061
  end unless head_rows.empty?
@@ -2072,7 +2074,8 @@ module Asciidoctor
2072
2074
  colspan: cell.colspan || 1,
2073
2075
  rowspan: cell.rowspan || 1,
2074
2076
  align: (cell.attr 'halign').to_sym,
2075
- valign: (val = cell.attr 'valign') == 'middle' ? :center : val.to_sym
2077
+ valign: (val = cell.attr 'valign') == 'middle' ? :center : val.to_sym,
2078
+ source_location: cell.source_location
2076
2079
  cell_line_metrics = body_cell_line_metrics
2077
2080
  case cell.style
2078
2081
  when :emphasis
@@ -2133,7 +2136,7 @@ module Asciidoctor
2133
2136
  # NOTE: line metrics get applied when AsciiDoc content is converted
2134
2137
  cell_line_metrics = nil
2135
2138
  asciidoc_cell = ::Prawn::Table::Cell::AsciiDoc.new self, (cell_data.merge content: cell.inner_document, padding: body_cell_padding)
2136
- cell_data = { content: asciidoc_cell }
2139
+ cell_data = { content: asciidoc_cell, source_location: cell.source_location }
2137
2140
  end
2138
2141
  if cell_line_metrics
2139
2142
  cell_padding = body_cell_padding.dup
@@ -2685,13 +2688,7 @@ module Asciidoctor
2685
2688
  end
2686
2689
 
2687
2690
  if (roles = node.role)
2688
- theme = load_theme node.document
2689
- roles.split.each do |role|
2690
- if (text_transform = theme[%(role_#{role}_text_transform)])
2691
- inner_text = transform_text inner_text, text_transform
2692
- end
2693
- inner_text = inner_text.gsub DoubleSpaceRx, ' ' + ZeroWidthSpace if role == 'pre-wrap' && (inner_text.include? DoubleSpace)
2694
- end
2691
+ inner_text = inner_text.gsub DoubleSpaceRx, ' ' + ZeroWidthSpace if (node.has_role? 'pre-wrap') && (inner_text.include? DoubleSpace)
2695
2692
  quoted_text = is_tag ? %(#{open.chop} class="#{roles}">#{inner_text}#{close}) : %(<span class="#{roles}">#{open}#{inner_text}#{close}</span>)
2696
2693
  else
2697
2694
  quoted_text = %(#{open}#{inner_text}#{close})
@@ -3241,7 +3238,8 @@ module Asciidoctor
3241
3238
  end
3242
3239
  end
3243
3240
 
3244
- # NOTE: inline_format is true by default
3241
+ # NOTE: inline_format option is true by default
3242
+ # NOTE: single_line option is not compatible with this method
3245
3243
  def ink_prose string, opts = {}
3246
3244
  top_margin = (margin = (opts.delete :margin)) || (opts.delete :margin_top) || 0
3247
3245
  bot_margin = margin || (opts.delete :margin_bottom) || @theme.prose_margin_bottom
@@ -4255,10 +4253,10 @@ module Asciidoctor
4255
4253
  # NOTE: this will catch a classloader resource path on JRuby (e.g., uri:classloader:/path/to/image)
4256
4254
  elsif ::File.absolute_path? image_path
4257
4255
  ::File.absolute_path image_path
4258
- elsif !(is_uri = node.is_uri? image_path) && imagesdir && (::File.absolute_path? imagesdir)
4256
+ elsif !(is_url = url? image_path) && imagesdir && (::File.absolute_path? imagesdir)
4259
4257
  ::File.absolute_path image_path, imagesdir
4260
4258
  # handle case when image is a URI
4261
- elsif is_uri || (imagesdir && (node.is_uri? imagesdir) && (image_path = node.normalize_web_path image_path, imagesdir, false))
4259
+ elsif is_url || (imagesdir && (url? imagesdir) && (image_path = node.normalize_web_path image_path, imagesdir, false))
4262
4260
  if !allow_uri_read
4263
4261
  log :warn, %(cannot embed remote image: #{image_path} (allow-uri-read attribute not enabled))
4264
4262
  return
@@ -4496,6 +4494,7 @@ module Asciidoctor
4496
4494
  end
4497
4495
 
4498
4496
  # TODO: document me, esp the first line formatting functionality
4497
+ # NOTE: single_line option should only be used if height option is specified
4499
4498
  def typeset_text string, line_metrics, opts = {}
4500
4499
  opts = { leading: line_metrics.leading, final_gap: line_metrics.final_gap }.merge opts
4501
4500
  string = string.gsub CjkLineBreakRx, ZeroWidthSpace if @cjk_line_breaks
@@ -4950,7 +4949,7 @@ module Asciidoctor
4950
4949
  alt_text_vars[:'/link'] = ''
4951
4950
  end
4952
4951
  theme_font :image_alt do
4953
- ink_prose alt_text_template % alt_text_vars, align: opts[:align], margin: 0, normalize: false, single_line: true
4952
+ ink_prose alt_text_template % alt_text_vars, align: opts[:align], margin: 0, normalize: false
4954
4953
  end
4955
4954
  ink_caption node, category: :image, end: :bottom if node.title?
4956
4955
  theme_margin :block, :bottom, (next_enclosed_block node) unless opts[:pinned]
@@ -5045,6 +5044,10 @@ module Asciidoctor
5045
5044
  false
5046
5045
  end
5047
5046
 
5047
+ def url? str
5048
+ (str.include? ':/') && (UrlSniffRx.match? str)
5049
+ end
5050
+
5048
5051
  # Calculate the width that is needed to print all the
5049
5052
  # fragments without wrapping any lines.
5050
5053
  #
@@ -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
@@ -91,7 +91,9 @@ module Prawn
91
91
  # TODO: apply horizontal alignment; currently it is necessary to specify alignment on content blocks
92
92
  apply_font_properties { pdf.traverse content }
93
93
  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?
94
+ unless extra_pages == 1 && pdf.page.empty?
95
+ 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
96
+ end
95
97
  extra_pages.times { pdf.delete_current_page }
96
98
  end
97
99
  nil
@@ -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.3'
5
+ VERSION = '2.1.4'
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.3
4
+ version: 2.1.4
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-23 00:00:00.000000000 Z
12
+ date: 2022-06-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: asciidoctor