asciidoctor 2.0.20 → 2.0.22

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: 95bddd5f820dc0441d3accb7dd49864b1fb9f1807823887d0075e595a2d55094
4
- data.tar.gz: 1dd21111bda88dde555fe981b30e89684bd0ac0bbe8e329721bbdc7b18ab806d
3
+ metadata.gz: 5c8bf90148c22e9396333d1062352368ea297bd1a63d03c0166e0dde81677989
4
+ data.tar.gz: a9c48ed8d9827acb0b9919b1f6909c1752cd62115b3e6e7e9b552d8a6d7930c6
5
5
  SHA512:
6
- metadata.gz: a03b03f8a1bda4d71235f975603353c9653c1ad98ff26a42b5d2d844dab6954c41d75c45d598a8b976bba3b4b35aa05f7e2791c1dc6c1da75714bced767f6f8f
7
- data.tar.gz: c463c0c23a75ddadf2c1eff1cc3afdf574b07a2551693b7330a1cebcef8a9e789ffa5f9bec005843a327837d33f42298f30684f6d16a8c0271d1379ac080485e
6
+ metadata.gz: 84f45230cbd9b25b810ef9a369b2c2e769833517fda4197f55f52129b86c6c30b9c4f06d20df20e6abd552a3b12679c123641de35c8d29e6dd3d0d3b511b8185
7
+ data.tar.gz: 0cf0028a60356d0966ff1637e130b285b73d769f7bcf426a31397f9eab8bbe91118d78fa27c303684f0e624dd062980ec5602c931e65272382d079b086ea076f
data/CHANGELOG.adoc CHANGED
@@ -16,6 +16,52 @@ For an even more detailed look at what has changed, refer to the {url-repo}/comm
16
16
  This project utilizes semantic versioning.
17
17
 
18
18
  // tag::compact[]
19
+ == 2.0.22 (2024-03-08) - @mojavelinux
20
+
21
+ Improvements::
22
+
23
+ * Set `cloaked-context` attribute on source block when context is not `:listing` (#4556)
24
+
25
+ Compliance::
26
+
27
+ * Remove use of base64 library to prevent warning in Ruby >= 3.3 (#4561)
28
+
29
+ === Details
30
+
31
+ {url-repo}/releases/tag/v2.0.22[git tag] | {url-repo}/compare/v2.0.21\...v2.0.22[full diff]
32
+ // end::compact[]
33
+
34
+ == 2.0.21 (2024-02-20) - @mojavelinux
35
+
36
+ Compliance::
37
+
38
+ * Turn off system-dependent newline conversion when writing files; don't convert line feeds to system-dependent newline (#4550)
39
+ * Support logger in Ruby 3.3 by instantiating super class (#4493) (*@mtasaka*)
40
+ * Add support for `scaledwidth` and `scale` attributes on inline image macro in DocBook output (#4552)
41
+ * Update latest Ruby to 3.3 in CI workflows
42
+
43
+ Improvements::
44
+
45
+ * Change title to doctitle in warning message about use of abstract to make subject more clear
46
+ * Modify default stylesheet to add text decoration to active footnote number link in footnotes list (#4530) (@Larhzu)
47
+
48
+ Bug Fixes::
49
+
50
+ * Nested dlist attached using list continuation should not consume detached paragraph (#3535)
51
+ * Don't break nested dlist with attached block if offset from parent list by empty line (#3693)
52
+ * Preserve paragraph breaks in normal table cell in manpage output (#4481)
53
+ * Style cells in head row as bold in manpage output (#4490)
54
+ * Escape spaces in include target (using inline passthrough) when generating link from include directive (#4461)
55
+ * Move abstract inside info tag in DocBook output (#3602)
56
+ * Honor secondary and tertiary terms on `indexterm` macro when primary term is quoted and contains an equals sign (#3652)
57
+ * Remove extra border below doctitle when sidebar toc is collapsed into main content area (#4523)
58
+ * Treat bare URL enclosed in angle brackets as unconstrained syntax; only match until closing angled bracket (#4468)
59
+ * Allow URL enclosed in angled brackets syntax to be escaped using backslash (#4468)
60
+
61
+ === Details
62
+
63
+ {url-repo}/releases/tag/v2.0.21[git tag] | {url-repo}/compare/v2.0.20\...v2.0.21[full diff]
64
+
19
65
  == 2.0.20 (2023-05-18) - @mojavelinux
20
66
 
21
67
  Bug Fixes::
@@ -26,7 +72,6 @@ Bug Fixes::
26
72
  === Details
27
73
 
28
74
  {url-repo}/releases/tag/v2.0.20[git tag] | {url-repo}/compare/v2.0.19\...v2.0.20[full diff]
29
- // end::compact[]
30
75
 
31
76
  == 2.0.19 (2023-05-17) - @mojavelinux
32
77
 
data/README-de.adoc CHANGED
@@ -1,6 +1,6 @@
1
1
  = Asciidoctor
2
2
  Dan Allen <https://github.com/mojavelinux[@mojavelinux]>; Sarah White <https://github.com/graphitefriction[@graphitefriction]>
3
- v2.0.20, 2023-05-18
3
+ v2.0.22, 2024-03-08
4
4
  // settings:
5
5
  :idprefix:
6
6
  :idseparator: -
@@ -16,7 +16,7 @@ ifdef::env-github[]
16
16
  :warning-caption: :warning:
17
17
  endif::[]
18
18
  // Variables:
19
- :release-version: 2.0.20
19
+ :release-version: 2.0.22
20
20
  // URIs:
21
21
  :uri-org: https://github.com/asciidoctor
22
22
  :uri-repo: {uri-org}/asciidoctor
data/README-fr.adoc CHANGED
@@ -1,6 +1,6 @@
1
1
  = Asciidoctor
2
2
  Dan Allen <https://github.com/mojavelinux[@mojavelinux]>; Sarah White <https://github.com/graphitefriction[@graphitefriction]>
3
- v2.0.20, 2023-05-18
3
+ v2.0.22, 2024-03-08
4
4
  // settings:
5
5
  :idprefix:
6
6
  :idseparator: -
@@ -16,7 +16,7 @@ ifdef::env-github[]
16
16
  :warning-caption: :warning:
17
17
  endif::[]
18
18
  // Variables:
19
- :release-version: 2.0.20
19
+ :release-version: 2.0.22
20
20
  // URIs:
21
21
  :uri-org: https://github.com/asciidoctor
22
22
  :uri-repo: {uri-org}/asciidoctor
data/README-jp.adoc CHANGED
@@ -1,6 +1,6 @@
1
1
  = Asciidoctor
2
2
  Dan Allen <https://github.com/mojavelinux[@mojavelinux]>; Sarah White <https://github.com/graphitefriction[@graphitefriction]>
3
- v2.0.20, 2023-05-18
3
+ v2.0.22, 2024-03-08
4
4
  // settings:
5
5
  :idprefix:
6
6
  :idseparator: -
@@ -16,7 +16,7 @@ ifdef::env-github[]
16
16
  :warning-caption: :warning:
17
17
  endif::[]
18
18
  // Variables:
19
- :release-version: 2.0.20
19
+ :release-version: 2.0.22
20
20
  // URIs:
21
21
  :uri-org: https://github.com/asciidoctor
22
22
  :uri-repo: {uri-org}/asciidoctor
data/README-zh_CN.adoc CHANGED
@@ -1,6 +1,6 @@
1
1
  = Asciidoctor
2
2
  Dan Allen <https://github.com/mojavelinux[@mojavelinux]>; Sarah White <https://github.com/graphitefriction[@graphitefriction]>
3
- v2.0.20, 2023-05-18
3
+ v2.0.22, 2024-03-08
4
4
  // settings:
5
5
  :page-layout: base
6
6
  :idprefix:
@@ -17,7 +17,7 @@ ifdef::env-github[]
17
17
  :warning-caption: :warning:
18
18
  endif::[]
19
19
  // Variables:
20
- :release-version: 2.0.20
20
+ :release-version: 2.0.22
21
21
  // URIs:
22
22
  :uri-org: https://github.com/asciidoctor
23
23
  :uri-repo: {uri-org}/asciidoctor
data/README.adoc CHANGED
@@ -1,6 +1,6 @@
1
1
  = Asciidoctor
2
2
  Dan Allen <https://github.com/mojavelinux[@mojavelinux]>; Sarah White <https://github.com/graphitefriction[@graphitefriction]>
3
- v2.0.20, 2023-05-18
3
+ v2.0.22, 2024-03-08
4
4
  // settings:
5
5
  :idprefix:
6
6
  :idseparator: -
@@ -16,7 +16,7 @@ ifdef::env-github[]
16
16
  :warning-caption: :warning:
17
17
  endif::[]
18
18
  // Variables:
19
- :release-version: 2.0.20
19
+ :release-version: 2.0.22
20
20
  // URLs:
21
21
  :url-org: https://github.com/asciidoctor
22
22
  :url-repo: {url-org}/asciidoctor
data/asciidoctor.gemspec CHANGED
@@ -39,7 +39,7 @@ Gem::Specification.new do |s|
39
39
  # erubi is needed for testing alternate eRuby impls
40
40
  s.add_development_dependency 'erubi', '~> 1.10.0'
41
41
  s.add_development_dependency 'haml', '~> 6.1.0'
42
- s.add_development_dependency 'minitest', '~> 5.14.0'
42
+ s.add_development_dependency 'minitest', '~> 5.22.0'
43
43
  s.add_development_dependency 'nokogiri', '~> 1.13.0'
44
44
  s.add_development_dependency 'rake', '~> 12.3.0'
45
45
  s.add_development_dependency 'slim', '~> 4.1.0'
@@ -112,7 +112,7 @@ Attach a block or paragraph to a list item using a list continuation (which you
112
112
 
113
113
  .Some Authors
114
114
  [circle]
115
- - Edgar Allen Poe
115
+ - Edgar Allan Poe
116
116
  - Sheri S. Tepper
117
117
  - Bill Bryson
118
118
 
@@ -130,7 +130,7 @@ p a>code:hover{color:rgba(0,0,0,.9)}
130
130
  #content::before{content:none}
131
131
  #header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
132
132
  #header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
133
- #header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
133
+ #header>h1:only-child{border-bottom:1px solid #dddddf;padding-bottom:8px}
134
134
  #header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:flex;flex-flow:row wrap}
135
135
  #header .details span:first-child{margin-left:-.125em}
136
136
  #header .details span.email a{color:rgba(0,0,0,.85)}
@@ -152,6 +152,7 @@ p a>code:hover{color:rgba(0,0,0,.9)}
152
152
  #toctitle{color:#7a2518;font-size:1.2em}
153
153
  @media screen and (min-width:768px){#toctitle{font-size:1.375em}
154
154
  body.toc2{padding-left:15em;padding-right:0}
155
+ body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
155
156
  #toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
156
157
  #toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
157
158
  #toc.toc2>ul{font-size:.9em;margin-bottom:0}
@@ -317,7 +318,7 @@ a.image{text-decoration:none;display:inline-block}
317
318
  a.image object{pointer-events:none}
318
319
  sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
319
320
  sup.footnote a,sup.footnoteref a{text-decoration:none}
320
- sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
321
+ sup.footnote a:active,sup.footnoteref a:active,#footnotes .footnote a:first-of-type:active{text-decoration:underline}
321
322
  #footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
322
323
  #footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
323
324
  #footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
@@ -354,8 +354,8 @@ class AbstractNode
354
354
  #
355
355
  # First, and foremost, the target image path is cleaned if the document safe mode level
356
356
  # is set to at least SafeMode::SAFE (a condition which is true by default) to prevent access
357
- # to ancestor paths in the filesystem. The image data is then read and converted to
358
- # Base64. Finally, a data URI is built which can be used in an image tag.
357
+ # to ancestor paths in the filesystem. The image data is then read and converted to base64.
358
+ # Finally, a data URI is built which can be used in an image tag.
359
359
  #
360
360
  # target_image - A String path to the target image
361
361
  # asset_dir_key - The String attribute key used to lookup the directory where
@@ -376,8 +376,8 @@ class AbstractNode
376
376
  end
377
377
 
378
378
  if ::File.readable? image_path
379
- # NOTE base64 is autoloaded by reference to ::Base64
380
- %(data:#{mimetype};base64,#{::Base64.strict_encode64 ::File.binread image_path})
379
+ # NOTE pack 'm0' is equivalent to Base64.strict_encode64
380
+ %(data:#{mimetype};base64,#{[(::File.binread image_path)].pack 'm0'})
381
381
  else
382
382
  logger.warn %(image to embed not found or not readable: #{image_path})
383
383
  %(data:#{mimetype};base64,)
@@ -410,8 +410,8 @@ class AbstractNode
410
410
 
411
411
  begin
412
412
  mimetype, bindata = ::OpenURI.open_uri(image_uri, URI_READ_MODE) {|f| [f.content_type, f.read] }
413
- # NOTE base64 is autoloaded by reference to ::Base64
414
- %(data:#{mimetype};base64,#{::Base64.strict_encode64 bindata})
413
+ # NOTE pack 'm0' is equivalent to Base64.strict_encode64
414
+ %(data:#{mimetype};base64,#{[bindata].pack 'm0'})
415
415
  rescue
416
416
  logger.warn %(could not retrieve image data from URI: #{image_uri})
417
417
  image_uri
@@ -44,7 +44,8 @@ class Converter::DocBook5Converter < Converter::Base
44
44
  end
45
45
  root_tag_idx = result.size
46
46
  id = node.id
47
- result << (document_info_tag node) unless node.noheader
47
+ abstract = find_root_abstract node
48
+ result << (document_info_tag node, abstract) unless node.noheader
48
49
  if manpage
49
50
  result << '<refentry>'
50
51
  result << '<refmeta>'
@@ -61,7 +62,9 @@ class Converter::DocBook5Converter < Converter::Base
61
62
  unless (docinfo_content = node.docinfo :header).empty?
62
63
  result << docinfo_content
63
64
  end
64
- result << node.content if node.blocks?
65
+ abstract = extract_abstract node, abstract if abstract
66
+ result << (node.blocks.map {|block| block.convert }.compact.join LF) if node.blocks?
67
+ restore_abstract abstract if abstract
65
68
  unless (docinfo_content = node.docinfo :footer).empty?
66
69
  result << docinfo_content
67
70
  end
@@ -73,7 +76,15 @@ class Converter::DocBook5Converter < Converter::Base
73
76
  result.join LF
74
77
  end
75
78
 
76
- alias convert_embedded content_only
79
+ def convert_embedded node
80
+ # NOTE in DocBook 5, the root abstract must be in the info tag and is thus not part of the body
81
+ if @backend == 'docbook5' && (abstract = find_root_abstract node)
82
+ abstract = extract_abstract node, abstract
83
+ end
84
+ result = node.blocks.map {|block| block.convert }.compact.join LF
85
+ restore_abstract abstract if abstract
86
+ result
87
+ end
77
88
 
78
89
  def convert_section node
79
90
  if node.document.doctype == 'manpage'
@@ -183,27 +194,11 @@ class Converter::DocBook5Converter < Converter::Base
183
194
  end
184
195
 
185
196
  def convert_image node
186
- # NOTE according to the DocBook spec, content area, scaling, and scaling to fit are mutually exclusive
187
- # See http://tdg.docbook.org/tdg/4.5/imagedata-x.html#d0e79635
188
- if node.attr? 'scaledwidth'
189
- width_attribute = %( width="#{node.attr 'scaledwidth'}")
190
- depth_attribute = ''
191
- scale_attribute = ''
192
- elsif node.attr? 'scale'
193
- # QUESTION should we set the viewport using width and depth? (the scaled image would be contained within this box)
194
- #width_attribute = (node.attr? 'width') ? %( width="#{node.attr 'width'}") : ''
195
- #depth_attribute = (node.attr? 'height') ? %( depth="#{node.attr 'height'}") : ''
196
- scale_attribute = %( scale="#{node.attr 'scale'}")
197
- else
198
- width_attribute = (node.attr? 'width') ? %( contentwidth="#{node.attr 'width'}") : ''
199
- depth_attribute = (node.attr? 'height') ? %( contentdepth="#{node.attr 'height'}") : ''
200
- scale_attribute = ''
201
- end
202
197
  align_attribute = (node.attr? 'align') ? %( align="#{node.attr 'align'}") : ''
203
198
 
204
199
  mediaobject = %(<mediaobject>
205
200
  <imageobject>
206
- <imagedata fileref="#{node.image_uri(node.attr 'target')}"#{width_attribute}#{depth_attribute}#{scale_attribute}#{align_attribute}/>
201
+ <imagedata fileref="#{node.image_uri node.attr 'target'}"#{image_size_attributes node.attributes}#{align_attribute}/>
207
202
  </imageobject>
208
203
  <textobject><phrase>#{node.alt}</phrase></textobject>
209
204
  </mediaobject>)
@@ -308,13 +303,17 @@ class Converter::DocBook5Converter < Converter::Base
308
303
  def convert_open node
309
304
  case node.style
310
305
  when 'abstract'
311
- if node.parent == node.document && node.document.doctype == 'book'
312
- logger.warn 'abstract block cannot be used in a document without a title when doctype is book. Excluding block content.'
306
+ if (parent = node.parent) == node.document && node.document.doctype == 'book'
307
+ logger.warn 'abstract block cannot be used in a document without a doctitle when doctype is book. Excluding block content.'
313
308
  ''
314
309
  else
315
- %(<abstract>
310
+ result = %(<abstract>
316
311
  #{title_tag node}#{enclose_content node}
317
312
  </abstract>)
313
+ if @backend == 'docbook5' && !(node.option? 'root') && (parent.context == :open ? parent.style == 'partintro' : parent.context == :section && parent.sectname == 'partintro') && node == parent.blocks[0]
314
+ result = %(<info>\n#{result}\n</info>)
315
+ end
316
+ result
318
317
  end
319
318
  when 'partintro'
320
319
  if node.level == 0 && node.parent.context == :section && node.document.doctype == 'book'
@@ -536,11 +535,9 @@ class Converter::DocBook5Converter < Converter::Base
536
535
  end
537
536
 
538
537
  def convert_inline_image node
539
- width_attribute = (node.attr? 'width') ? %( contentwidth="#{node.attr 'width'}") : ''
540
- depth_attribute = (node.attr? 'height') ? %( contentdepth="#{node.attr 'height'}") : ''
541
538
  %(<inlinemediaobject#{common_attributes nil, node.role}>
542
539
  <imageobject>
543
- <imagedata fileref="#{node.type == 'icon' ? (node.icon_uri node.target) : (node.image_uri node.target)}"#{width_attribute}#{depth_attribute}/>
540
+ <imagedata fileref="#{node.type == 'icon' ? (node.icon_uri node.target) : (node.image_uri node.target)}"#{image_size_attributes node.attributes}/>
544
541
  </imageobject>
545
542
  <textobject><phrase>#{node.alt}</phrase></textobject>
546
543
  </inlinemediaobject>)
@@ -648,6 +645,23 @@ class Converter::DocBook5Converter < Converter::Base
648
645
  end
649
646
  end
650
647
 
648
+ def image_size_attributes attributes
649
+ # NOTE according to the DocBook spec, content area, scaling, and scaling to fit are mutually exclusive
650
+ # See http://tdg.docbook.org/tdg/4.5/imagedata-x.html#d0e79635
651
+ if attributes.key? 'scaledwidth'
652
+ %( width="#{attributes['scaledwidth']}")
653
+ elsif attributes.key? 'scale'
654
+ # QUESTION should we set the viewport using width and depth? (the scaled image would be contained within this box)
655
+ #width_attribute = (attributes.key? 'width') ? %( width="#{attributes['width']}") : ''
656
+ #depth_attribute = (attributes.key? 'height') ? %( depth="#{attributes['height']}") : ''
657
+ %( scale="#{attributes['scale']}")
658
+ else
659
+ width_attribute = (attributes.key? 'width') ? %( contentwidth="#{attributes['width']}") : ''
660
+ depth_attribute = (attributes.key? 'height') ? %( contentdepth="#{attributes['height']}") : ''
661
+ %(#{width_attribute}#{depth_attribute})
662
+ end
663
+ end
664
+
651
665
  def author_tag doc, author
652
666
  result = []
653
667
  result << '<author>'
@@ -661,7 +675,7 @@ class Converter::DocBook5Converter < Converter::Base
661
675
  result.join LF
662
676
  end
663
677
 
664
- def document_info_tag doc
678
+ def document_info_tag doc, abstract
665
679
  result = ['<info>']
666
680
  unless doc.notitle
667
681
  if (title = doc.doctitle partition: true, use_fallback: true).subtitle?
@@ -715,11 +729,37 @@ class Converter::DocBook5Converter < Converter::Base
715
729
  result << docinfo_content
716
730
  end
717
731
  end
732
+ if abstract
733
+ abstract.set_option 'root'
734
+ result << (convert abstract, abstract.node_name)
735
+ abstract.remove_attr 'root-option'
736
+ end
718
737
  result << '</info>'
719
738
 
720
739
  result.join LF
721
740
  end
722
741
 
742
+ def find_root_abstract doc
743
+ return unless doc.blocks?
744
+ if (first_block = doc.blocks[0]).context == :preamble
745
+ return unless (first_block = first_block.blocks[0])
746
+ elsif first_block.context == :section
747
+ return first_block if first_block.sectname == 'abstract'
748
+ return unless first_block.sectname == 'preface' && (first_block = first_block.blocks[0])
749
+ end
750
+ return first_block if first_block.style == 'abstract' && first_block.context == :open
751
+ end
752
+
753
+ def extract_abstract document, abstract
754
+ parent = abstract.parent
755
+ parent = parent.parent while parent != document && parent.blocks.length == 1
756
+ parent.blocks.delete_at 0
757
+ end
758
+
759
+ def restore_abstract abstract
760
+ abstract.parent.blocks.insert 0, abstract
761
+ end
762
+
723
763
  def get_root_document node
724
764
  while (node = node.document).nested?
725
765
  node = node.parent_document
@@ -742,26 +782,18 @@ class Converter::DocBook5Converter < Converter::Base
742
782
 
743
783
  def cover_tag doc, face, use_placeholder = false
744
784
  if (cover_image = doc.attr %(#{face}-cover-image))
745
- width_attr = ''
746
- depth_attr = ''
747
785
  if (cover_image.include? ':') && ImageMacroRx =~ cover_image
748
- attrlist = $2
749
- cover_image = doc.image_uri $1
750
- if attrlist
751
- attrs = (AttributeList.new attrlist).parse ['alt', 'width', 'height']
752
- if attrs.key? 'scaledwidth'
753
- # NOTE scalefit="1" is the default in this case
754
- width_attr = %( width="#{attrs['scaledwidth']}")
755
- else
756
- width_attr = %( contentwidth="#{attrs['width']}") if attrs.key? 'width'
757
- depth_attr = %( contentdepth="#{attrs['height']}") if attrs.key? 'height'
758
- end
759
- end
786
+ target, attrlist = $1, $2
787
+ cover_image = doc.image_uri target
788
+ # NOTE scalefit="1" is the default for a cover image
789
+ size_attrs = image_size_attributes (AttributeList.new attrlist).parse %w(alt width height) if attrlist
790
+ else
791
+ size_attrs = ''
760
792
  end
761
793
  %(<cover role="#{face}">
762
794
  <mediaobject>
763
795
  <imageobject>
764
- <imagedata fileref="#{cover_image}"#{width_attr}#{depth_attr}/>
796
+ <imagedata fileref="#{cover_image}"#{size_attrs}/>
765
797
  </imageobject>
766
798
  </mediaobject>
767
799
  </cover>)
@@ -748,7 +748,7 @@ Your browser does not support the audio tag.
748
748
  def convert_open node
749
749
  if (style = node.style) == 'abstract'
750
750
  if node.parent == node.document && node.document.doctype == 'book'
751
- logger.warn 'abstract block cannot be used in a document without a title when doctype is book. Excluding block content.'
751
+ logger.warn 'abstract block cannot be used in a document without a doctitle when doctype is book. Excluding block content.'
752
752
  ''
753
753
  else
754
754
  id_attr = node.id ? %( id="#{node.id}") : ''
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module Asciidoctor
3
- # A built-in {Converter} implementation that generates the man page (troff) format.
3
+ # A built-in {Converter} implementation that generates the man page (groff) format.
4
4
  #
5
5
  # The output of this converter adheres to the man definition as defined by
6
6
  # groff and uses the manpage output of the DocBook toolchain as a foundation.
@@ -432,7 +432,7 @@ allbox tab(:);'
432
432
  when :literal
433
433
  cell_content = %(.nf#{LF}#{manify cell.text, whitespace: :preserve}#{LF}.fi)
434
434
  else
435
- cell_content = manify cell.content.join, whitespace: :normalize
435
+ cell_content = cell.content.map {|p| manify p, whitespace: :normalize }.join %(#{LF}.sp#{LF})
436
436
  end
437
437
  row_text[row_index] << %(#{cell_content}#{LF})
438
438
  else # tsec == :head || tsec == :foot
@@ -476,21 +476,14 @@ allbox tab(:);'
476
476
  end unless rows.empty?
477
477
  end
478
478
 
479
- #row_header.each do |row|
480
- # result << LF
481
- # row.each_with_index do |cell, i|
482
- # result << (cell.join ' ')
483
- # result << ' ' if row.size > i + 1
484
- # end
485
- #end
486
- # FIXME temporary fix to get basic table to display
487
- result << LF
488
- result << ('lt ' * row_header[0].size).chop
489
-
490
- result << %(.#{LF})
491
- row_text.each do |row|
492
- result << row.join
479
+ if node.has_header_option && (header_row_text = row_text[0])
480
+ result << %(#{LF}#{row_header[0].join ' '}.)
481
+ result << %(#{LF}#{header_row_text.join})
482
+ result << '.T&'
483
+ row_text = row_text.slice 1, row_text.length
493
484
  end
485
+ result << %(#{LF}#{row_header[0].map { 'lt' }.join ' '}.#{LF})
486
+ row_text.each {|row| result << row.join }
494
487
  result << %(.TE#{LF}.sp)
495
488
  result.join
496
489
  end
@@ -712,40 +705,38 @@ allbox tab(:);'
712
705
  else
713
706
  str = str.tr_s WHITESPACE, ' '
714
707
  end
715
- str = str
716
- .gsub(LiteralBackslashRx) { $1 ? $& : '\\(rs' } # literal backslash (not a troff escape sequence)
717
- .gsub(EllipsisCharRefRx, '...') # horizontal ellipsis
718
- .gsub(LeadingPeriodRx, '\\\&.') # leading . is used in troff for macro call or other formatting; replace with \&.
719
- .gsub(EscapedMacroRx) do # drop orphaned \c escape lines, unescape troff macro, quote adjacent character, isolate macro line
720
- (rest = $3.lstrip).empty? ? %(.#{$1}"#{$2}") : %(.#{$1}"#{$2.rstrip}"#{LF}#{rest})
721
- end
722
- .gsub('-', '\-')
723
- .gsub('&lt;', '<')
724
- .gsub('&gt;', '>')
725
- .gsub('&#43;', '+') # plus sign; alternately could use \c(pl
726
- .gsub('&#160;', '\~') # non-breaking space
727
- .gsub('&#169;', '\(co') # copyright sign
728
- .gsub('&#174;', '\(rg') # registered sign
729
- .gsub('&#8482;', '\(tm') # trademark sign
730
- .gsub('&#176;', '\(de') # degree sign
731
- .gsub('&#8201;', ' ') # thin space
732
- .gsub('&#8211;', '\(en') # en dash
733
- .gsub(EmDashCharRefRx, '\(em') # em dash
734
- .gsub('&#8216;', '\(oq') # left single quotation mark
735
- .gsub('&#8217;', '\(cq') # right single quotation mark
736
- .gsub('&#8220;', '\(lq') # left double quotation mark
737
- .gsub('&#8221;', '\(rq') # right double quotation mark
738
- .gsub('&#8592;', '\(<-') # leftwards arrow
739
- .gsub('&#8594;', '\(->') # rightwards arrow
740
- .gsub('&#8656;', '\(lA') # leftwards double arrow
741
- .gsub('&#8658;', '\(rA') # rightwards double arrow
742
- .gsub('&#8203;', '\:') # zero width space
743
- .gsub('&amp;', '&') # literal ampersand (NOTE must take place after any other replacement that includes &)
744
- .gsub('\'', '\*(Aq') # apostrophe / neutral single quote
745
- .gsub(MockMacroRx, '\1') # mock boundary
746
- .gsub(ESC_BS, '\\') # unescape troff backslash (NOTE update if more escapes are added)
747
- .gsub(ESC_FS, '.') # unescape full stop in troff commands (NOTE must take place after gsub(LeadingPeriodRx))
748
- .rstrip # strip trailing space
708
+ str = str.
709
+ gsub(LiteralBackslashRx) { $1 ? $& : '\\(rs' }. # literal backslash (not a troff escape sequence)
710
+ gsub(EllipsisCharRefRx, '...'). # horizontal ellipsis
711
+ gsub(LeadingPeriodRx, '\\\&.'). # leading . is used in troff for macro call or other formatting; replace with \&.
712
+ gsub(EscapedMacroRx) { (rest = $3.lstrip).empty? ? %(.#{$1}"#{$2}") : %(.#{$1}"#{$2.rstrip}"#{LF}#{rest}) }. # drop orphaned \c escape lines, unescape troff macro, quote adjacent character, isolate macro line
713
+ gsub('-', '\-').
714
+ gsub('&lt;', '<').
715
+ gsub('&gt;', '>').
716
+ gsub('&#43;', '+'). # plus sign; alternately could use \c(pl
717
+ gsub('&#160;', '\~'). # non-breaking space
718
+ gsub('&#169;', '\(co'). # copyright sign
719
+ gsub('&#174;', '\(rg'). # registered sign
720
+ gsub('&#8482;', '\(tm'). # trademark sign
721
+ gsub('&#176;', '\(de'). # degree sign
722
+ gsub('&#8201;', ' '). # thin space
723
+ gsub('&#8211;', '\(en'). # en dash
724
+ gsub(EmDashCharRefRx, '\(em'). # em dash
725
+ gsub('&#8216;', '\(oq'). # left single quotation mark
726
+ gsub('&#8217;', '\(cq'). # right single quotation mark
727
+ gsub('&#8220;', '\(lq'). # left double quotation mark
728
+ gsub('&#8221;', '\(rq'). # right double quotation mark
729
+ gsub('&#8592;', '\(<-'). # leftwards arrow
730
+ gsub('&#8594;', '\(->'). # rightwards arrow
731
+ gsub('&#8656;', '\(lA'). # leftwards double arrow
732
+ gsub('&#8658;', '\(rA'). # rightwards double arrow
733
+ gsub('&#8203;', '\:'). # zero width space
734
+ gsub('&amp;', '&'). # literal ampersand (NOTE must take place after any other replacement that includes &)
735
+ gsub('\'', '\*(Aq'). # apostrophe / neutral single quote
736
+ gsub(MockMacroRx, '\1'). # mock boundary
737
+ gsub(ESC_BS, '\\'). # unescape troff backslash (NOTE update if more escapes are added)
738
+ gsub(ESC_FS, '.'). # unescape full stop in troff commands (NOTE must take place after gsub(LeadingPeriodRx))
739
+ rstrip # strip trailing space
749
740
  opts[:append_newline] ? %(#{str}#{LF}) : str
750
741
  end
751
742
 
@@ -40,6 +40,7 @@ class MemoryLogger < ::Logger
40
40
  attr_reader :messages
41
41
 
42
42
  def initialize
43
+ super nil
43
44
  self.level = WARN
44
45
  @messages = []
45
46
  end
@@ -67,6 +68,7 @@ class NullLogger < ::Logger
67
68
  attr_reader :max_severity
68
69
 
69
70
  def initialize
71
+ super nil
70
72
  self.level = WARN
71
73
  end
72
74
 
@@ -43,6 +43,12 @@ class Parser
43
43
 
44
44
  AuthorKeys = ['author', 'authorinitials', 'firstname', 'middlename', 'lastname', 'email']
45
45
 
46
+ ListContinuationMarker = ::Module.new
47
+
48
+ ListContinuationPlaceholder = ::String.new.extend ListContinuationMarker
49
+
50
+ ListContinuationString = (::String.new LIST_CONTINUATION).extend ListContinuationMarker
51
+
46
52
  # Internal: A Hash mapping horizontal alignment abbreviations to alignments
47
53
  # that can be applied to a table cell (or to all cells in a column)
48
54
  TableCellHorzAlignments = {
@@ -555,6 +561,7 @@ class Parser
555
561
  # process lines verbatim
556
562
  if style && Compliance.strict_verbatim_paragraphs && (VERBATIM_STYLES.include? style)
557
563
  block_context = style.to_sym
564
+ cloaked_context = :paragraph
558
565
  reader.unshift_line this_line
559
566
  # advance to block parsing =>
560
567
  break
@@ -812,16 +819,17 @@ class Parser
812
819
  unless block
813
820
  case block_context
814
821
  when :listing, :source
815
- if block_context == :source || (!attributes[1] && (language = attributes[2] || doc_attrs['source-language']))
816
- if language
822
+ if block_context == :source || (language = attributes[1] ? nil : attributes[2] || doc_attrs['source-language'])
823
+ if language # :listing
817
824
  attributes['style'] = 'source'
818
825
  attributes['language'] = language
819
826
  AttributeList.rekey attributes, [nil, nil, 'linenums']
820
- else
827
+ else # :source
821
828
  AttributeList.rekey attributes, [nil, 'language', 'linenums']
822
829
  if doc_attrs.key? 'source-language'
823
830
  attributes['language'] = doc_attrs['source-language']
824
831
  end unless attributes.key? 'language'
832
+ attributes['cloaked-context'] = cloaked_context unless cloaked_context == :listing
825
833
  end
826
834
  if attributes['linenums-option'] || doc_attrs['source-linenums-option']
827
835
  attributes['linenums'] = ''
@@ -850,6 +858,7 @@ class Parser
850
858
  else
851
859
  attributes['language'] = language
852
860
  end
861
+ attributes['cloaked-context'] = cloaked_context
853
862
  if attributes['linenums-option'] || doc_attrs['source-linenums-option']
854
863
  attributes['linenums'] = ''
855
864
  end unless attributes.key? 'linenums'
@@ -1420,17 +1429,18 @@ class Parser
1420
1429
  # the termination of the list
1421
1430
  break if is_sibling_list_item?(this_line, list_type, sibling_trait)
1422
1431
 
1432
+ this_line = ListContinuationString if this_line == LIST_CONTINUATION
1423
1433
  prev_line = buffer.empty? ? nil : buffer[-1]
1424
1434
 
1425
- if prev_line == LIST_CONTINUATION
1435
+ if ListContinuationMarker === prev_line
1426
1436
  if continuation == :inactive
1427
1437
  continuation = :active
1428
1438
  has_text = true
1429
- buffer[-1] = '' unless within_nested_list
1439
+ buffer[-1] = ListContinuationPlaceholder unless within_nested_list
1430
1440
  end
1431
1441
 
1432
1442
  # dealing with adjacent list continuations (which is really a syntax error)
1433
- if this_line == LIST_CONTINUATION
1443
+ if ListContinuationMarker === this_line
1434
1444
  if continuation != :frozen
1435
1445
  continuation = :frozen
1436
1446
  buffer << this_line
@@ -1489,7 +1499,7 @@ class Parser
1489
1499
  (ch0 == '[' && (BlockAttributeLineRx.match? this_line)) || (ch0 == ':' && (AttributeEntryRx.match? this_line))
1490
1500
  buffer << this_line
1491
1501
  else
1492
- if (nested_list_type = (within_nested_list ? [:dlist] : NESTABLE_LIST_CONTEXTS).find {|ctx| ListRxMap[ctx].match? this_line })
1502
+ if (nested_list_type = (within_nested_list ? [:dlist] : NESTABLE_LIST_CONTEXTS).find {|ctx| ListRxMap[ctx] =~ this_line })
1493
1503
  within_nested_list = true
1494
1504
  if nested_list_type == :dlist && $3.nil_or_empty?
1495
1505
  # get greedy again
@@ -1510,7 +1520,7 @@ class Parser
1510
1520
 
1511
1521
  if this_line == LIST_CONTINUATION
1512
1522
  detached_continuation = buffer.size
1513
- buffer << this_line
1523
+ buffer << ListContinuationString
1514
1524
  elsif has_text # has_text only relevant for dlist, which is more greedy until it has text for an item; has_text is always true for all other lists
1515
1525
  # in this block, we have to see whether we stay in the list
1516
1526
  # TODO any way to combine this with the check after skipping blank lines?
@@ -1543,6 +1553,9 @@ class Parser
1543
1553
  buffer << this_line
1544
1554
  has_text = true
1545
1555
  end
1556
+ elsif ListContinuationMarker === this_line
1557
+ has_text = true
1558
+ buffer << this_line
1546
1559
  else
1547
1560
  has_text = true unless this_line.empty?
1548
1561
  if (nested_list_type = (within_nested_list ? [:dlist] : NESTABLE_LIST_CONTEXTS).find {|ctx| ListRxMap[ctx] =~ this_line })
@@ -1559,16 +1572,17 @@ class Parser
1559
1572
 
1560
1573
  reader.unshift_line this_line if this_line
1561
1574
 
1562
- buffer[detached_continuation] = '' if detached_continuation
1575
+ buffer[detached_continuation] = ListContinuationPlaceholder if detached_continuation
1563
1576
 
1564
1577
  until buffer.empty?
1578
+ # drop optional trailing continuation
1579
+ if ListContinuationMarker === (last_line = buffer[-1])
1580
+ buffer.pop
1581
+ break
1565
1582
  # strip trailing blank lines to prevent empty blocks
1566
- if (last_line = buffer[-1]).empty?
1583
+ elsif last_line.empty?
1567
1584
  buffer.pop
1568
1585
  else
1569
- # drop optional trailing continuation
1570
- # (a blank line would have served the same purpose in the document)
1571
- buffer.pop if last_line == LIST_CONTINUATION
1572
1586
  break
1573
1587
  end
1574
1588
  end
@@ -1039,6 +1039,7 @@ class PreprocessorReader < Reader
1039
1039
  # if running in SafeMode::SECURE or greater, don't process this directive
1040
1040
  # however, be friendly and at least make it a link to the source document
1041
1041
  elsif doc.safe >= SafeMode::SECURE
1042
+ expanded_target = %(pass:c[#{expanded_target}]) if expanded_target.include? ' '
1042
1043
  # FIXME we don't want to use a link macro if we are in a verbatim context
1043
1044
  replace_next_line %(link:#{expanded_target}[role=include])
1044
1045
  elsif @maxdepth
@@ -1238,7 +1239,10 @@ class PreprocessorReader < Reader
1238
1239
  def resolve_include_path target, attrlist, attributes
1239
1240
  doc = @document
1240
1241
  if (Helpers.uriish? target) || (::String === @dir ? nil : (target = %(#{@dir}/#{target})))
1241
- return replace_next_line %(link:#{target}[role=include]) unless doc.attr? 'allow-uri-read'
1242
+ unless doc.attr? 'allow-uri-read'
1243
+ target = %(pass:c[#{target}]) if target.include? ' '
1244
+ return replace_next_line %(link:#{target}[role=include])
1245
+ end
1242
1246
  if doc.attr? 'cache-uri'
1243
1247
  # caching requires the open-uri-cached gem to be installed
1244
1248
  # processing will be automatically aborted if these libraries can't be opened
@@ -103,6 +103,7 @@ module Asciidoctor
103
103
  # }
104
104
  # // end::try-catch[]
105
105
  # NOTE m flag is required for Asciidoctor.js
106
+ # NOTE the regex checks for \r to account of include files that use Windows newlines
106
107
  TagDirectiveRx = /\b(?:tag|(e)nd)::(\S+?)\[\](?=$|[ \r])/m
107
108
 
108
109
  ## Attribute entries and references
@@ -513,12 +514,12 @@ module Asciidoctor
513
514
  #
514
515
  # https://github.com
515
516
  # https://github.com[GitHub]
516
- # <https://github.com>
517
+ # <https://github.com> <= angle brackets not included in autolink
517
518
  # link:https://github.com[]
518
519
  # "https://github.com[]"
519
520
  # (https://github.com) <= parenthesis not included in autolink
520
521
  #
521
- InlineLinkRx = %r((^|link:|#{CG_BLANK}|&lt;|[>\(\)\[\];"'])(\\?(?:https?|file|ftp|irc)://)(?:([^\s\[\]]+)\[(|#{CC_ALL}*?[^\\])\]|([^\s\[\]<]*([^\s,.?!\[\]<\)]))))m
522
+ InlineLinkRx = %r((^|link:|#{CG_BLANK}|\\?&lt;()|[>\(\)\[\];"'])(\\?(?:https?|file|ftp|irc)://)(?:([^\s\[\]]+)\[(|#{CC_ALL}*?[^\\])\]|\2([^\s]*?)&gt;|([^\s\[\]<]*([^\s,.?!\[\]<\)]))))m
522
523
 
523
524
  # Match a link or e-mail inline macro.
524
525
  #
@@ -445,7 +445,14 @@ module Substitutors
445
445
  # indexterm:[Tigers,Big cats]
446
446
  if (attrlist = normalize_text $2, true, true).include? '='
447
447
  if (primary = (attrs = (AttributeList.new attrlist, self).parse)[1])
448
- attrs['terms'] = [primary]
448
+ terms = [primary]
449
+ if (secondary = attrs[2])
450
+ terms << secondary
451
+ if (tertiary = attrs[3])
452
+ terms << tertiary
453
+ end
454
+ end
455
+ attrs['terms'] = terms
449
456
  if (see_also = attrs['see-also'])
450
457
  attrs['see-also'] = (see_also.include? ',') ? (see_also.split ',').map {|it| it.lstrip } : [see_also]
451
458
  end
@@ -524,97 +531,101 @@ module Substitutors
524
531
  end
525
532
 
526
533
  if found_colon && (text.include? '://')
527
- # inline urls, target[text] (optionally prefixed with link: and optionally surrounded by <>)
534
+ # inline urls, target[text] (optionally prefixed with link: or enclosed in <>)
528
535
  text = text.gsub InlineLinkRx do
529
- if (target = $2 + ($3 || $5)).start_with? RS
530
- # honor the escape
531
- next ($&.slice 0, (rs_idx = $1.length)) + ($&.slice rs_idx + 1, $&.length)
532
- end
533
-
534
- prefix, suffix = $1, ''
535
- # NOTE if $4 is set, we're looking at a formal macro (e.g., https://example.org[])
536
- if $4
537
- prefix = '' if prefix == 'link:'
538
- link_text = nil if (link_text = $4).empty?
536
+ if $2 && !$5
537
+ # honor the escapes
538
+ next $&.slice 1, $&.length if $1.start_with? RS
539
+ next %(#{$1}#{$&.slice $1.length + 1, $&.length}) if $3.start_with? RS
540
+ target = $3 + $6
541
+ next $& if target == $3
542
+ doc.register :links, target
543
+ link_text = (doc_attrs.key? 'hide-uri-scheme') ? (target.sub UriSniffRx, '') : target
544
+ (Inline.new self, :anchor, link_text, type: :link, target: target, attributes: { 'role' => 'bare' }).convert
539
545
  else
540
- # invalid macro syntax (link: prefix w/o trailing square brackets or enclosed in double quotes)
541
- # FIXME we probably shouldn't even get here when the link: prefix is present; the regex is doing too much
542
- case prefix
543
- when 'link:', ?", ?'
544
- next $&
545
- end
546
- case $6
547
- when ';'
548
- if (prefix.start_with? '&lt;') && (target.end_with? '&gt;')
549
- # move surrounding <> out of URL
550
- prefix = prefix.slice 4, prefix.length
551
- target = target.slice 0, target.length - 4
552
- elsif (target = target.chop).end_with? ')'
553
- # move trailing ); out of URL
554
- target = target.chop
555
- suffix = ');'
556
- else
557
- # move trailing ; out of URL
558
- suffix = ';'
546
+ # honor the escape
547
+ next %(#{$1}#{$&.slice $1.length + 1, $&.length}) if $3.start_with? RS
548
+ prefix, target, suffix = $1, $3 + ($4 || $7), ''
549
+ # NOTE if $5 is set (the attrlist), we're looking at a formal macro (e.g., https://example.org[])
550
+ if $5
551
+ prefix = '' if prefix == 'link:'
552
+ link_text = nil if (link_text = $5).empty?
553
+ else
554
+ case prefix
555
+ # invalid macro syntax (link: prefix w/o trailing square brackets or URL enclosed in quotes)
556
+ # FIXME we probably shouldn't even get here when the link: prefix is present; the regex is doing too much
557
+ when 'link:', ?", ?'
558
+ next $&
559
559
  end
560
- # NOTE handle case when modified target is a URI scheme (e.g., http://)
561
- next $& if target.end_with? '://'
562
- when ':'
563
- if (target = target.chop).end_with? ')'
564
- # move trailing ): out of URL
565
- target = target.chop
566
- suffix = '):'
567
- else
568
- # move trailing : out of URL
569
- suffix = ':'
560
+ case $8
561
+ when ';'
562
+ if (target = target.chop).end_with? ')'
563
+ # move trailing ); out of URL
564
+ target = target.chop
565
+ suffix = ');'
566
+ else
567
+ # move trailing ; out of URL
568
+ suffix = ';'
569
+ end
570
+ # NOTE handle case when modified target is a bare URI scheme (e.g., http://)
571
+ next $& if target == $3
572
+ when ':'
573
+ if (target = target.chop).end_with? ')'
574
+ # move trailing ): out of URL
575
+ target = target.chop
576
+ suffix = '):'
577
+ else
578
+ # move trailing : out of URL
579
+ suffix = ':'
580
+ end
581
+ # NOTE handle case when modified target is a bare URI scheme (e.g., http://)
582
+ next $& if target == $3
570
583
  end
571
- # NOTE handle case when modified target is a URI scheme (e.g., http://)
572
- next $& if target.end_with? '://'
573
584
  end
574
- end
575
585
 
576
- attrs, link_opts = nil, { type: :link }
586
+ link_opts = { type: :link }
577
587
 
578
- if link_text
579
- new_link_text = link_text = link_text.gsub ESC_R_SB, R_SB if link_text.include? R_SB
580
- if !doc.compat_mode && (link_text.include? '=')
581
- # NOTE if an equals sign (=) is present, extract attributes from link text
582
- link_text, attrs = extract_attributes_from_text link_text, ''
583
- new_link_text = link_text
584
- link_opts[:id] = attrs['id']
585
- end
588
+ if link_text
589
+ new_link_text = link_text = link_text.gsub ESC_R_SB, R_SB if link_text.include? R_SB
590
+ if !doc.compat_mode && (link_text.include? '=')
591
+ # NOTE if an equals sign (=) is present, extract attributes from link text
592
+ link_text, attrs = extract_attributes_from_text link_text, ''
593
+ new_link_text = link_text
594
+ link_opts[:id] = attrs['id']
595
+ end
586
596
 
587
- if link_text.end_with? '^'
588
- new_link_text = link_text = link_text.chop
589
- if attrs
590
- attrs['window'] ||= '_blank'
591
- else
592
- attrs = { 'window' => '_blank' }
597
+ if link_text.end_with? '^'
598
+ new_link_text = link_text = link_text.chop
599
+ if attrs
600
+ attrs['window'] ||= '_blank'
601
+ else
602
+ attrs = { 'window' => '_blank' }
603
+ end
593
604
  end
594
- end
595
605
 
596
- if new_link_text && new_link_text.empty?
597
- # NOTE it's not possible for the URI scheme to be bare in this case
606
+ if new_link_text && new_link_text.empty?
607
+ # NOTE the modified target will not be a bare URI scheme (e.g., http://) in this case
608
+ link_text = (doc_attrs.key? 'hide-uri-scheme') ? (target.sub UriSniffRx, '') : target
609
+ bare = true
610
+ end
611
+ else
612
+ # NOTE the modified target will not be a bare URI scheme (e.g., http://) in this case
598
613
  link_text = (doc_attrs.key? 'hide-uri-scheme') ? (target.sub UriSniffRx, '') : target
599
614
  bare = true
600
615
  end
601
- else
602
- # NOTE it's not possible for the URI scheme to be bare in this case
603
- link_text = (doc_attrs.key? 'hide-uri-scheme') ? (target.sub UriSniffRx, '') : target
604
- bare = true
605
- end
606
616
 
607
- if bare
608
- if attrs
609
- attrs['role'] = (attrs.key? 'role') ? %(bare #{attrs['role']}) : 'bare'
610
- else
611
- attrs = { 'role' => 'bare' }
617
+ if bare
618
+ if attrs
619
+ attrs['role'] = (attrs.key? 'role') ? %(bare #{attrs['role']}) : 'bare'
620
+ else
621
+ attrs = { 'role' => 'bare' }
622
+ end
612
623
  end
613
- end
614
624
 
615
- doc.register :links, (link_opts[:target] = target)
616
- link_opts[:attributes] = attrs if attrs
617
- %(#{prefix}#{(Inline.new self, :anchor, link_text, link_opts).convert}#{suffix})
625
+ doc.register :links, (link_opts[:target] = target)
626
+ link_opts[:attributes] = attrs if attrs
627
+ %(#{prefix}#{(Inline.new self, :anchor, link_text, link_opts).convert}#{suffix})
628
+ end
618
629
  end
619
630
  end
620
631
 
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Asciidoctor
3
- VERSION = '2.0.20'
3
+ VERSION = '2.0.22'
4
4
  end
data/lib/asciidoctor.rb CHANGED
@@ -6,7 +6,6 @@ if RUBY_ENGINE == 'opal'
6
6
  # this require is satisfied by the Asciidoctor.js build; it augments the Ruby environment for Asciidoctor.js
7
7
  require 'asciidoctor/js'
8
8
  else
9
- autoload :Base64, 'base64'
10
9
  require 'cgi/util'
11
10
  autoload :OpenURI, 'open-uri'
12
11
  autoload :Pathname, 'pathname'
@@ -209,13 +208,13 @@ module Asciidoctor
209
208
  BOM_BYTES_UTF_16BE = [0xfe, 0xff]
210
209
 
211
210
  # The mode to use when opening a file for reading
212
- FILE_READ_MODE = RUBY_ENGINE_OPAL ? 'r' : 'rb:utf-8:utf-8'
211
+ FILE_READ_MODE = RUBY_ENGINE_OPAL ? 'r' : 'rb:UTF-8:UTF-8'
213
212
 
214
213
  # The mode to use when opening a URI for reading
215
214
  URI_READ_MODE = FILE_READ_MODE
216
215
 
217
216
  # The mode to use when opening a file for writing
218
- FILE_WRITE_MODE = RUBY_ENGINE_OPAL ? 'w' : 'w:utf-8'
217
+ FILE_WRITE_MODE = RUBY_ENGINE_OPAL ? 'w' : 'wb:UTF-8'
219
218
 
220
219
  # The default document type
221
220
  # Can influence markup generated by the converters
data/man/asciidoctor.1 CHANGED
@@ -1,13 +1,13 @@
1
1
  '\" t
2
2
  .\" Title: asciidoctor
3
3
  .\" Author: Dan Allen, Sarah White
4
- .\" Generator: Asciidoctor 2.0.19
4
+ .\" Generator: Asciidoctor 2.0.21
5
5
  .\" Date: 2018-03-20
6
6
  .\" Manual: Asciidoctor Manual
7
- .\" Source: Asciidoctor 2.0.20
7
+ .\" Source: Asciidoctor 2.0.22
8
8
  .\" Language: English
9
9
  .\"
10
- .TH "ASCIIDOCTOR" "1" "2018-03-20" "Asciidoctor 2.0.20" "Asciidoctor Manual"
10
+ .TH "ASCIIDOCTOR" "1" "2018-03-20" "Asciidoctor 2.0.22" "Asciidoctor Manual"
11
11
  .ie \n(.g .ds Aq \(aq
12
12
  .el .ds Aq '
13
13
  .ss \n[.ss] 0
data/man/asciidoctor.adoc CHANGED
@@ -1,7 +1,7 @@
1
1
  = asciidoctor(1)
2
2
  Dan Allen; Sarah White
3
3
  :doctype: manpage
4
- :release-version: 2.0.20
4
+ :release-version: 2.0.22
5
5
  :man manual: Asciidoctor Manual
6
6
  :man source: Asciidoctor {release-version}
7
7
  ifdef::backend-manpage[:!author:]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asciidoctor
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.20
4
+ version: 2.0.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Allen
@@ -77,14 +77,14 @@ dependencies:
77
77
  requirements:
78
78
  - - "~>"
79
79
  - !ruby/object:Gem::Version
80
- version: 5.14.0
80
+ version: 5.22.0
81
81
  type: :development
82
82
  prerelease: false
83
83
  version_requirements: !ruby/object:Gem::Requirement
84
84
  requirements:
85
85
  - - "~>"
86
86
  - !ruby/object:Gem::Version
87
- version: 5.14.0
87
+ version: 5.22.0
88
88
  - !ruby/object:Gem::Dependency
89
89
  name: nokogiri
90
90
  requirement: !ruby/object:Gem::Requirement
@@ -272,7 +272,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
272
272
  - !ruby/object:Gem::Version
273
273
  version: '0'
274
274
  requirements: []
275
- rubygems_version: 3.4.10
275
+ rubygems_version: 3.5.3
276
276
  signing_key:
277
277
  specification_version: 4
278
278
  summary: An implementation of the AsciiDoc text processor and publishing toolchain