asciidoctor-pdf 2.1.3 → 2.1.4

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: 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