asciidoctor 2.0.22 → 2.0.24

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: 5c8bf90148c22e9396333d1062352368ea297bd1a63d03c0166e0dde81677989
4
- data.tar.gz: a9c48ed8d9827acb0b9919b1f6909c1752cd62115b3e6e7e9b552d8a6d7930c6
3
+ metadata.gz: 1b219565eafae2806084f9fee67def534a864eaaebc7891dced5d5f4cd238abb
4
+ data.tar.gz: 51137dfb8f450991351e82b0da3d15ad923209dad72606ab2a5b868a78c6e1a0
5
5
  SHA512:
6
- metadata.gz: 84f45230cbd9b25b810ef9a369b2c2e769833517fda4197f55f52129b86c6c30b9c4f06d20df20e6abd552a3b12679c123641de35c8d29e6dd3d0d3b511b8185
7
- data.tar.gz: 0cf0028a60356d0966ff1637e130b285b73d769f7bcf426a31397f9eab8bbe91118d78fa27c303684f0e624dd062980ec5602c931e65272382d079b086ea076f
6
+ metadata.gz: 141b60fe34a662b4924f873985be200c1e5f9b574e44aa7336ec7febed0d3a4fbe8b8e8619441da2f7fdca51a17a0689155634cbde1fc63478c9dae6fd41d382
7
+ data.tar.gz: 814788310c10bf2cdda6e7cde44a43fcd83702aea854aa48d9e51b3af77e9ec13c0966dbf73f298eb8d39ff84fe8aa5d01881283016ea49c3609c3bf065a663c
data/CHANGELOG.adoc CHANGED
@@ -16,6 +16,66 @@ 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.24 (2025-10-13) - @mojavelinux
20
+
21
+ Compliance::
22
+
23
+ * Support link attribute on inline image macro when converting to DocBook (#4385)
24
+ * Add magic comment `backticks_javascript: true` to achieve compatibility with Opal 2.0 (#4775) (*@janbiedermann*)
25
+ * Extract the require logic of the OpenURI library for Asciidoctor.js compatibility (#4244) (*@ggrossetie*)
26
+
27
+ Improvements::
28
+
29
+ * Suppress warning about loading logger from stdlib when using Ruby 3.4 (#4769)
30
+ * Log error if unterminated preprocessor conditional directive is detected (#3545)
31
+ * Coerce names passed to the `positional_attrs` directive on an extension to strings (#4674)
32
+ * Ignore `SOURCE_DATE_EPOCH` environment variable if value is empty instead of exiting with non-zero exit code (#4631)
33
+ * Change Brazilian Portuguese translation for toc-title (#4653) (*@giflw*)
34
+
35
+ Bug Fixes::
36
+
37
+ * Consider `convert_` prefix when looking for missing convert method in converter (#4669) (*@eugoka*)
38
+ * Don't push conditional onto stack if conditional preprocessor directive is invalid when skipping lines (#4603)
39
+ * Only style code tag as block element when inside pre in listing block; not inside verse block (#4610)
40
+ * Pass kwargs to Logger superclass and only assign defaults when kwarg is not specified (#4773)
41
+ * Don't add role=include to link macro that replaces include directive when running in compat mode (#4608)
42
+
43
+ Documentation::
44
+
45
+ * Rewrite documentation for how to create a custom converter from scratch and make examples more thorough (#4699)
46
+
47
+ Build / Infrastructure::
48
+
49
+ * Fix classification of several substitution tests (#4691) (*@scouten*)
50
+
51
+ === Details
52
+
53
+ {url-repo}/releases/tag/v2.0.24[git tag] | {url-repo}/compare/v2.0.23\...v2.0.24[full diff]
54
+ // end::compact[]
55
+
56
+ == 2.0.23 (2024-05-17) - @mojavelinux
57
+
58
+ Compliance::
59
+
60
+ * Encode spaces in mailto links as %20, in accordance with RFC 3986, instead of + (#4576)
61
+
62
+ Improvements::
63
+
64
+ * Log error when an incomplete row is detected at the end of a table (#4573)
65
+
66
+ Bug Fixes::
67
+
68
+ * Don't leave behind empty line inside skipped preprocessor conditional (#4580)
69
+ * Don't duplicate block attribute line above detached block that breaks a dlist; fixes duplicate role on detached block (#4565)
70
+ * Don't crash when parsing xref shorthand if target starts with URL protocol and text is offset by space (#4570)
71
+ * Only drop current row if colspan of last cell exceeds specified number of columns (#4587)
72
+ * Drop last row if colspan of last cell in table exceeds specified number of columns (#4587)
73
+ * Preserve repeating spaces in verbatim content in manpage output (#3583)
74
+
75
+ === Details
76
+
77
+ {url-repo}/releases/tag/v2.0.23[git tag] | {url-repo}/compare/v2.0.22\...v2.0.23[full diff]
78
+
19
79
  == 2.0.22 (2024-03-08) - @mojavelinux
20
80
 
21
81
  Improvements::
@@ -29,7 +89,6 @@ Compliance::
29
89
  === Details
30
90
 
31
91
  {url-repo}/releases/tag/v2.0.22[git tag] | {url-repo}/compare/v2.0.21\...v2.0.22[full diff]
32
- // end::compact[]
33
92
 
34
93
  == 2.0.21 (2024-02-20) - @mojavelinux
35
94
 
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.22, 2024-03-08
3
+ v2.0.24, 2025-10-13
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.22
19
+ :release-version: 2.0.24
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.22, 2024-03-08
3
+ v2.0.24, 2025-10-13
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.22
19
+ :release-version: 2.0.24
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.22, 2024-03-08
3
+ v2.0.24, 2025-10-13
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.22
19
+ :release-version: 2.0.24
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.22, 2024-03-08
3
+ v2.0.24, 2025-10-13
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.22
20
+ :release-version: 2.0.24
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.22, 2024-03-08
3
+ v2.0.24, 2025-10-13
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.22
19
+ :release-version: 2.0.24
20
20
  // URLs:
21
21
  :url-org: https://github.com/asciidoctor
22
22
  :url-repo: {url-org}/asciidoctor
@@ -130,7 +130,7 @@ If you're using AsciiDoc.py, see {url-docs}/asciidoctor/latest/migrate/asciidoc-
130
130
 
131
131
  Asciidoctor works on Linux, macOS and Windows and requires one of the following implementations of {url-ruby}[Ruby]:
132
132
 
133
- * CRuby (aka MRI) 2.3 - 3.2
133
+ * CRuby (aka MRI) 2.3 - 3.3
134
134
  * JRuby 9.1 - 9.4
135
135
  * TruffleRuby (GraalVM)
136
136
 
data/asciidoctor.gemspec CHANGED
@@ -19,7 +19,8 @@ Gem::Specification.new do |s|
19
19
  'bug_tracker_uri' => 'https://github.com/asciidoctor/asciidoctor/issues',
20
20
  'changelog_uri' => 'https://github.com/asciidoctor/asciidoctor/blob/HEAD/CHANGELOG.adoc',
21
21
  'mailing_list_uri' => 'https://chat.asciidoctor.org',
22
- 'source_code_uri' => 'https://github.com/asciidoctor/asciidoctor'
22
+ 'source_code_uri' => 'https://github.com/asciidoctor/asciidoctor',
23
+ 'funding_uri' => 'https://opencollective.com/asciidoctor'
23
24
  }
24
25
 
25
26
  # NOTE the logic to build the list of files is designed to produce a usable package even when the git command is not available
@@ -38,7 +39,7 @@ Gem::Specification.new do |s|
38
39
  s.add_development_dependency 'cucumber', '~> 3.1.0'
39
40
  # erubi is needed for testing alternate eRuby impls
40
41
  s.add_development_dependency 'erubi', '~> 1.10.0'
41
- s.add_development_dependency 'haml', '~> 6.1.0'
42
+ s.add_development_dependency 'haml', '~> 6.3.0'
42
43
  s.add_development_dependency 'minitest', '~> 5.22.0'
43
44
  s.add_development_dependency 'nokogiri', '~> 1.13.0'
44
45
  s.add_development_dependency 'rake', '~> 12.3.0'
@@ -17,7 +17,7 @@ ifdef::preface-title[:preface-title: Prefácio]
17
17
  :section-refsig: Seção
18
18
  :table-caption: Tabela
19
19
  :tip-caption: Dica
20
- :toc-title: Índice
20
+ :toc-title: Sumário
21
21
  :untitled-label: Sem título
22
22
  :version-label: Versão
23
23
  :warning-caption: Aviso
@@ -106,7 +106,6 @@ h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title str
106
106
  :not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
107
107
  pre{color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;line-height:1.45;text-rendering:optimizeSpeed}
108
108
  pre code,pre pre{color:inherit;font-size:inherit;line-height:inherit}
109
- pre>code{display:block}
110
109
  pre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal}
111
110
  em em{font-style:normal}
112
111
  strong strong{font-weight:400}
@@ -209,6 +208,7 @@ table.tableblock.fit-content>caption.title{white-space:nowrap;width:0}
209
208
  .literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class=highlight],.listingblock>.content>pre[class^="highlight "]{background:#f7f7f8}
210
209
  .literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)}
211
210
  .listingblock>.content{position:relative}
211
+ .listingblock pre>code{display:block}
212
212
  .listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5}
213
213
  .listingblock:hover code[data-lang]::before{display:block}
214
214
  .listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5}
@@ -399,15 +399,7 @@ class AbstractNode
399
399
  # Returns A data URI string built from Base64 encoded data read from the URI
400
400
  # and the mime type specified in the Content Type header.
401
401
  def generate_data_uri_from_uri image_uri, cache_uri = false
402
- if cache_uri
403
- # caching requires the open-uri-cached gem to be installed
404
- # processing will be automatically aborted if these libraries can't be opened
405
- Helpers.require_library 'open-uri/cached', 'open-uri-cached'
406
- elsif !RUBY_ENGINE_OPAL
407
- # autoload open-uri
408
- ::OpenURI
409
- end
410
-
402
+ Helpers.require_open_uri cache_uri
411
403
  begin
412
404
  mimetype, bindata = ::OpenURI.open_uri(image_uri, URI_READ_MODE) {|f| [f.content_type, f.read] }
413
405
  # NOTE pack 'm0' is equivalent to Base64.strict_encode64
@@ -59,7 +59,7 @@ class Callouts
59
59
  #
60
60
  # Returns A space-separated String of callout ids associated with the specified list item
61
61
  def callout_ids li_ordinal
62
- current_list.map {|it| it[:ordinal] == li_ordinal ? %(#{it[:id]} ) : '' }.join.chop
62
+ current_list.map {|item| item[:ordinal] == li_ordinal ? %(#{item[:id]} ) : '' }.join.chop
63
63
  end
64
64
 
65
65
  # Public: The current list for which callouts are being collected
@@ -94,7 +94,7 @@ module Asciidoctor
94
94
  self[:attributes][name] = val
95
95
  end
96
96
  opts.on('-T', '--template-dir DIR', 'a directory containing custom converter templates that override the built-in converter (requires tilt gem)',
97
- 'may be specified multiple times') do |template_dir|
97
+ 'may be specified more than once') do |template_dir|
98
98
  if self[:template_dirs].nil?
99
99
  self[:template_dirs] = [template_dir]
100
100
  elsif ::Array === self[:template_dirs]
@@ -535,12 +535,15 @@ class Converter::DocBook5Converter < Converter::Base
535
535
  end
536
536
 
537
537
  def convert_inline_image node
538
- %(<inlinemediaobject#{common_attributes nil, node.role}>
538
+ img = %(<inlinemediaobject#{common_attributes nil, node.role}>
539
539
  <imageobject>
540
- <imagedata fileref="#{node.type == 'icon' ? (node.icon_uri node.target) : (node.image_uri node.target)}"#{image_size_attributes node.attributes}/>
540
+ <imagedata fileref="#{node.type == 'icon' ? (node.icon_uri node.target) : (fileref = node.image_uri node.target)}"#{image_size_attributes node.attributes}/>
541
541
  </imageobject>
542
542
  <textobject><phrase>#{node.alt}</phrase></textobject>
543
543
  </inlinemediaobject>)
544
+ fileref && (node.attr? 'link') && (link_href = node.attr 'link') ?
545
+ %(<link xl:href="#{link_href}">#{img}</link>) :
546
+ img
544
547
  end
545
548
 
546
549
  def convert_inline_indexterm node
@@ -699,7 +699,7 @@ allbox tab(:);'
699
699
  def manify str, opts = {}
700
700
  case opts.fetch :whitespace, :collapse
701
701
  when :preserve
702
- str = str.gsub TAB, ET
702
+ str = (str.gsub TAB, ET).gsub(/(^)? +/) { $1 ? $& : %(#{ESC_BS}&#{$&}) }
703
703
  when :normalize
704
704
  str = str.gsub WrappedIndentRx, LF
705
705
  else
@@ -390,8 +390,8 @@ module Converter
390
390
  def convert node, transform = node.node_name, opts = nil
391
391
  opts ? (send 'convert_' + transform, node, opts) : (send 'convert_' + transform, node)
392
392
  rescue
393
- raise unless ::NoMethodError === (ex = $!) && ex.receiver == self && ex.name.to_s == transform
394
- logger.warn %(missing convert handler for #{ex.name} node in #{@backend} backend (#{self.class}))
393
+ raise unless ::NoMethodError === (ex = $!) && ex.receiver == self && ex.name.to_s == 'convert_' + transform
394
+ logger.warn %(missing convert handler for #{transform} node in #{@backend} backend (#{self.class}))
395
395
  nil
396
396
  end
397
397
 
@@ -1038,7 +1038,7 @@ class Document < AbstractBlock
1038
1038
  docinfo = docinfo ? ['private'] : nil
1039
1039
  end
1040
1040
  else
1041
- docinfo = docinfo.split(',').map {|it| it.strip }
1041
+ docinfo = docinfo.split(',').map {|keyword| keyword.strip }
1042
1042
  end
1043
1043
 
1044
1044
  if docinfo
@@ -1256,7 +1256,7 @@ class Document < AbstractBlock
1256
1256
  # localdatetime, docdate, docyear, doctime, and docdatetime. Honor the SOURCE_DATE_EPOCH environment variable, if set.
1257
1257
  def fill_datetime_attributes attrs, input_mtime
1258
1258
  # See https://reproducible-builds.org/specs/source-date-epoch/
1259
- now = (::ENV.key? 'SOURCE_DATE_EPOCH') ? (source_date_epoch = (::Time.at Integer ::ENV['SOURCE_DATE_EPOCH']).utc) : ::Time.now
1259
+ now = ::ENV['SOURCE_DATE_EPOCH'].nil_or_empty? ? ::Time.now : (source_date_epoch = (::Time.at Integer ::ENV['SOURCE_DATE_EPOCH']).utc)
1260
1260
  if (localdate = attrs['localdate'])
1261
1261
  attrs['localyear'] ||= (localdate.index '-') == 4 ? (localdate.slice 0, 4) : nil
1262
1262
  else
@@ -309,7 +309,7 @@ module Extensions
309
309
  alias parse_content_as content_model
310
310
 
311
311
  def positional_attributes *value
312
- option :positional_attrs, value.flatten
312
+ option :positional_attrs, (value.flatten.map {|name| name.to_s })
313
313
  end
314
314
  alias name_positional_attributes positional_attributes
315
315
  # NOTE positional_attrs alias is deprecated
@@ -485,7 +485,7 @@ module Extensions
485
485
  # to add content to the header.
486
486
  class DocinfoProcessor < Processor
487
487
  def initialize config = {}
488
- super config
488
+ super
489
489
  @config[:location] ||= :head
490
490
  end
491
491
 
@@ -1359,7 +1359,7 @@ module Extensions
1359
1359
 
1360
1360
  def add_document_processor kind, args, &block
1361
1361
  kind_name = kind.to_s.tr '_', ' '
1362
- kind_class_symbol = kind_name.split.map {|it| it.capitalize }.join.to_sym
1362
+ kind_class_symbol = kind_name.split.map {|segment| segment.capitalize }.join.to_sym
1363
1363
  kind_class = Extensions.const_get kind_class_symbol, false
1364
1364
  kind_java_class = (defined? ::AsciidoctorJ) ? (::AsciidoctorJ::Extensions.const_get kind_class_symbol, false) : nil
1365
1365
  kind_store = instance_variable_get(%(@#{kind}_extensions).to_sym) || instance_variable_set(%(@#{kind}_extensions).to_sym, [])
@@ -1403,7 +1403,7 @@ module Extensions
1403
1403
 
1404
1404
  def add_syntax_processor kind, args, &block
1405
1405
  kind_name = kind.to_s.tr '_', ' '
1406
- kind_class_symbol = (kind_name.split.map {|it| it.capitalize } << 'Processor').join.to_sym
1406
+ kind_class_symbol = (kind_name.split.map {|segment| segment.capitalize } << 'Processor').join.to_sym
1407
1407
  kind_class = Extensions.const_get kind_class_symbol, false
1408
1408
  kind_java_class = (defined? ::AsciidoctorJ) ? (::AsciidoctorJ::Extensions.const_get kind_class_symbol, false) : nil
1409
1409
  kind_store = instance_variable_get(%(@#{kind}_extensions).to_sym) || instance_variable_set(%(@#{kind}_extensions).to_sym, {})
@@ -1,3 +1,4 @@
1
+ # backtick_javascript: true
1
2
  # frozen_string_literal: true
2
3
  module Asciidoctor
3
4
  # Internal: Except where noted, a module that contains internal helper functions.
@@ -48,6 +49,25 @@ module Helpers
48
49
  nil
49
50
  end
50
51
 
52
+ # Internal: Require the OpenURI library.
53
+ #
54
+ # Attempts to load `open-uri-cached` if the cache argument is true otherwise autoload `open-uri`.
55
+ #
56
+ # cache - A Boolean flag indicating whether to activate content cache URI
57
+ #
58
+ # Returns nothing
59
+ def require_open_uri cache = false
60
+ if cache
61
+ # caching requires the open-uri-cached gem to be installed
62
+ # processing will be automatically aborted if these libraries can't be opened
63
+ require_library 'open-uri/cached', 'open-uri-cached' unless defined? ::OpenURI::Cache
64
+ else
65
+ # autoload open-uri
66
+ ::OpenURI
67
+ end
68
+ nil
69
+ end
70
+
51
71
  # Internal: Prepare the source data Array for parsing.
52
72
  #
53
73
  # Encodes the data to UTF-8, if necessary, and removes any trailing
@@ -145,10 +165,13 @@ module Helpers
145
165
  })
146
166
  )
147
167
  end
168
+ elsif (CGI = ::CGI).respond_to? :escapeURIComponent
169
+ def encode_uri_component str
170
+ CGI.escapeURIComponent str
171
+ end
148
172
  else
149
- CGI = ::CGI
150
173
  def encode_uri_component str
151
- CGI.escape str
174
+ (CGI.escape str).gsub '+', '%20'
152
175
  end
153
176
  end
154
177
 
@@ -1,15 +1,26 @@
1
1
  # frozen_string_literal: true
2
- require 'logger'
2
+
3
+ proc do
4
+ old_verbose, $VERBOSE = $VERBOSE, nil
5
+ require 'logger' # suppress warning in Ruby 3.4 about loading logger from stdlib
6
+ $VERBOSE = old_verbose
7
+ end.call
3
8
 
4
9
  module Asciidoctor
5
10
  class Logger < ::Logger
6
11
  attr_reader :max_severity
7
12
 
8
- def initialize *args
13
+ def initialize *args, **opts
14
+ opts[:progname] = 'asciidoctor'
15
+ opts[:formatter] = BasicFormatter.new unless opts.key? :formatter
16
+ opts[:level] = WARN unless opts.key? :level
17
+ args = [$stderr] if args.empty?
9
18
  super
10
- self.progname = 'asciidoctor'
11
- self.formatter = BasicFormatter.new
12
- self.level = WARN
19
+ if @progname.nil? && (method __method__).super_method.parameters.size == 3
20
+ @progname = opts[:progname]
21
+ @formatter = opts[:formatter]
22
+ @level = opts[:level]
23
+ end
13
24
  end
14
25
 
15
26
  def add severity, message = nil, progname = nil
@@ -1476,6 +1476,7 @@ class Parser
1476
1476
  break
1477
1477
  end
1478
1478
  if interrupt
1479
+ this_line = nil
1479
1480
  reader.unshift_lines block_attribute_lines
1480
1481
  break
1481
1482
  end
@@ -1897,7 +1898,7 @@ class Parser
1897
1898
  implicit_author_metadata[%(firstname_#{name_idx = idx + 1})],
1898
1899
  implicit_author_metadata[%(middlename_#{name_idx})],
1899
1900
  implicit_author_metadata[%(lastname_#{name_idx})]
1900
- ].compact.map {|it| it.tr ' ', '_' }.join ' '
1901
+ ].compact.map {|name| name.tr ' ', '_' }.join ' '
1901
1902
  end if sparse
1902
1903
  # process as names only
1903
1904
  author_metadata = process_authors authors, true, false
@@ -2413,6 +2414,7 @@ class Parser
2413
2414
  end
2414
2415
  end
2415
2416
 
2417
+ parser_ctx.close_table
2416
2418
  table.assign_column_widths unless (table.attributes['colcount'] ||= table.columns.size) == 0 || explicit_colspecs
2417
2419
  table.has_header_option = true if implicit_header
2418
2420
  table.partition_header_footer attributes
@@ -467,7 +467,7 @@ class Reader
467
467
  if lines_to_restore.respond_to? :reverse
468
468
  @lines.push(*lines_to_restore.reverse)
469
469
  else
470
- lines_to_restore.reverse_each {|it| @lines.push it }
470
+ lines_to_restore.reverse_each {|l| @lines.push l }
471
471
  end
472
472
  nil
473
473
  end
@@ -619,7 +619,7 @@ class PreprocessorReader < Reader
619
619
 
620
620
  # Public: Initialize the PreprocessorReader object
621
621
  def initialize document, data = nil, cursor = nil, opts = {}
622
- @document = document
622
+ @sourcemap = (@document = document).sourcemap
623
623
  super data, cursor, opts
624
624
  if (default_include_depth = (document.attributes['max-include-depth'] || 64).to_i) > 0
625
625
  # track absolute max depth, current max depth for comparing to include stack size, and relative max depth for reporting
@@ -657,6 +657,11 @@ class PreprocessorReader < Reader
657
657
  if (line = super)
658
658
  line
659
659
  elsif @include_stack.empty?
660
+ end_cursor = nil
661
+ @conditional_stack.delete_if do |conditional|
662
+ logger.error message_with_context %(detected unterminated preprocessor conditional directive: #{conditional[:name]}::#{conditional[:target] || ''}[#{conditional[:expr] || ''}]), source_location: conditional[:source_location] || (end_cursor ||= cursor_at_prev_line)
663
+ true
664
+ end
660
665
  nil
661
666
  else
662
667
  pop_include
@@ -820,6 +825,10 @@ class PreprocessorReader < Reader
820
825
  return line unless @process_lines
821
826
 
822
827
  if line.empty?
828
+ if @skipping
829
+ shift
830
+ return
831
+ end
823
832
  @look_ahead += 1
824
833
  return line
825
834
  end
@@ -886,7 +895,7 @@ class PreprocessorReader < Reader
886
895
  # preprocessing recursively until the next line of available content is
887
896
  # found.
888
897
  #
889
- # keyword - The conditional inclusion directive (ifdef, ifndef, ifeval, endif)
898
+ # name - The name of the conditional inclusion directive (ifdef, ifndef, ifeval, endif)
890
899
  # target - The target, which is the name of one or more attributes that are
891
900
  # used in the condition (blank in the case of the ifeval directive)
892
901
  # delimiter - The conditional delimiter for multiple attributes ('+' means all
@@ -897,27 +906,32 @@ class PreprocessorReader < Reader
897
906
  # ifndef directives, and for the conditional expression for the ifeval directive.
898
907
  #
899
908
  # Returns a Boolean indicating whether the cursor should be advanced
900
- def preprocess_conditional_directive keyword, target, delimiter, text
909
+ def preprocess_conditional_directive name, target, delimiter, text
901
910
  # attributes are case insensitive
902
911
  target = target.downcase unless (no_target = target.empty?)
903
912
 
904
- if keyword == 'endif'
913
+ if name == 'endif'
905
914
  if text
906
915
  logger.error message_with_context %(malformed preprocessor directive - text not permitted: endif::#{target}[#{text}]), source_location: cursor
907
916
  elsif @conditional_stack.empty?
908
917
  logger.error message_with_context %(unmatched preprocessor directive: endif::#{target}[]), source_location: cursor
909
- elsif no_target || target == (pair = @conditional_stack[-1])[:target]
918
+ elsif no_target || target == @conditional_stack[-1][:target]
910
919
  @conditional_stack.pop
911
920
  @skipping = @conditional_stack.empty? ? false : @conditional_stack[-1][:skipping]
912
921
  else
913
- logger.error message_with_context %(mismatched preprocessor directive: endif::#{target}[], expected endif::#{pair[:target]}[]), source_location: cursor
922
+ logger.error message_with_context %(mismatched preprocessor directive: endif::#{target}[], expected endif::#{@conditional_stack[-1][:target] || ''}[]), source_location: cursor
914
923
  end
915
924
  return true
916
925
  elsif @skipping
926
+ if name === 'ifeval'
927
+ return true unless no_target && text && (EvalExpressionRx.match? text.strip)
928
+ elsif no_target
929
+ return true
930
+ end
917
931
  skip = false
918
932
  else
919
933
  # QUESTION any way to wrap ifdef & ifndef logic up together?
920
- case keyword
934
+ case name
921
935
  when 'ifdef'
922
936
  if no_target
923
937
  logger.error message_with_context %(malformed preprocessor directive - missing target: ifdef::[#{text}]), source_location: cursor
@@ -926,10 +940,10 @@ class PreprocessorReader < Reader
926
940
  case delimiter
927
941
  when ','
928
942
  # skip if no attribute is defined
929
- skip = target.split(',', -1).none? {|name| @document.attributes.key? name }
943
+ skip = target.split(',', -1).none? {|attr_name| @document.attributes.key? attr_name }
930
944
  when '+'
931
945
  # skip if any attribute is undefined
932
- skip = target.split('+', -1).any? {|name| !@document.attributes.key? name }
946
+ skip = target.split('+', -1).any? {|attr_name| !@document.attributes.key? attr_name }
933
947
  else
934
948
  # if the attribute is undefined, then skip
935
949
  skip = !@document.attributes.key?(target)
@@ -942,10 +956,10 @@ class PreprocessorReader < Reader
942
956
  case delimiter
943
957
  when ','
944
958
  # skip if any attribute is defined
945
- skip = target.split(',', -1).any? {|name| @document.attributes.key? name }
959
+ skip = target.split(',', -1).any? {|attr_name| @document.attributes.key? attr_name }
946
960
  when '+'
947
961
  # skip if all attributes are defined
948
- skip = target.split('+', -1).all? {|name| @document.attributes.key? name }
962
+ skip = target.split('+', -1).all? {|attr_name| @document.attributes.key? attr_name }
949
963
  else
950
964
  # if the attribute is defined, then skip
951
965
  skip = @document.attributes.key?(target)
@@ -972,11 +986,11 @@ class PreprocessorReader < Reader
972
986
  end
973
987
 
974
988
  # conditional inclusion block
975
- if keyword == 'ifeval' || !text
989
+ if name == 'ifeval'
976
990
  @skipping = true if skip
977
- @conditional_stack << { target: target, skip: skip, skipping: @skipping }
991
+ @conditional_stack << { name: name, expr: text, skip: skip, skipping: @skipping, source_location: @sourcemap ? cursor : nil }
978
992
  # single line conditional inclusion
979
- else
993
+ elsif text
980
994
  unless @skipping || skip
981
995
  replace_next_line text.rstrip
982
996
  # HACK push dummy line to stand in for the opening conditional directive that's subsequently dropped
@@ -985,6 +999,10 @@ class PreprocessorReader < Reader
985
999
  # QUESTION should we just call preprocess_include_directive here?
986
1000
  @look_ahead -= 1 if text.start_with? 'include::'
987
1001
  end
1002
+ # conditional inclusion block
1003
+ else
1004
+ @skipping = true if skip
1005
+ @conditional_stack << { name: name, target: target, skip: skip, skipping: @skipping, source_location: @sourcemap ? cursor : nil }
988
1006
  end
989
1007
 
990
1008
  true
@@ -1039,9 +1057,9 @@ class PreprocessorReader < Reader
1039
1057
  # if running in SafeMode::SECURE or greater, don't process this directive
1040
1058
  # however, be friendly and at least make it a link to the source document
1041
1059
  elsif doc.safe >= SafeMode::SECURE
1060
+ # FIXME we don't want to use a passthrough or link macro if we're in a verbatim context
1042
1061
  expanded_target = %(pass:c[#{expanded_target}]) if expanded_target.include? ' '
1043
- # FIXME we don't want to use a link macro if we are in a verbatim context
1044
- replace_next_line %(link:#{expanded_target}[role=include])
1062
+ replace_next_line %(link:#{expanded_target}[#{(doc.attr? 'compat-mode') ? '' : 'role=include'}])
1045
1063
  elsif @maxdepth
1046
1064
  if @include_stack.size >= @maxdepth[:curr]
1047
1065
  logger.error message_with_context %(maximum include depth of #{@maxdepth[:rel]} exceeded), source_location: cursor
@@ -1240,17 +1258,11 @@ class PreprocessorReader < Reader
1240
1258
  doc = @document
1241
1259
  if (Helpers.uriish? target) || (::String === @dir ? nil : (target = %(#{@dir}/#{target})))
1242
1260
  unless doc.attr? 'allow-uri-read'
1261
+ # FIXME we don't want to use a passthrough or link macro if we're in a verbatim context
1243
1262
  target = %(pass:c[#{target}]) if target.include? ' '
1244
- return replace_next_line %(link:#{target}[role=include])
1245
- end
1246
- if doc.attr? 'cache-uri'
1247
- # caching requires the open-uri-cached gem to be installed
1248
- # processing will be automatically aborted if these libraries can't be opened
1249
- Helpers.require_library 'open-uri/cached', 'open-uri-cached' unless defined? ::OpenURI::Cache
1250
- elsif !RUBY_ENGINE_OPAL
1251
- # autoload open-uri
1252
- ::OpenURI
1263
+ return replace_next_line %(link:#{target}[#{(doc.attr? 'compat-mode') ? '' : 'role=include'}])
1253
1264
  end
1265
+ Helpers.require_open_uri doc.attr? 'cache-uri'
1254
1266
  [(::URI.parse target), :uri, target]
1255
1267
  else
1256
1268
  # include file is resolved relative to dir of current include, or base_dir if within original docfile
@@ -519,7 +519,12 @@ module Asciidoctor
519
519
  # "https://github.com[]"
520
520
  # (https://github.com) <= parenthesis not included in autolink
521
521
  #
522
- InlineLinkRx = %r((^|link:|#{CG_BLANK}|\\?&lt;()|[>\(\)\[\];"'])(\\?(?:https?|file|ftp|irc)://)(?:([^\s\[\]]+)\[(|#{CC_ALL}*?[^\\])\]|\2([^\s]*?)&gt;|([^\s\[\]<]*([^\s,.?!\[\]<\)]))))m
522
+ if RUBY_ENGINE == 'opal'
523
+ # NOTE In JavaScript, a back reference succeeds if not set; invert the logic to give it a match to refute
524
+ InlineLinkRx = %r((^|link:|#{CG_BLANK}|\\?&lt;(?=\\?(?:https?|file|ftp|irc)(:))|[>\(\)\[\];"'])(\\?(?:https?|file|ftp|irc)://)(?:([^\s\[\]]+)\[(|#{CC_ALL}*?[^\\])\]|(?!\2)([^\s]+?)&gt;|([^\s\[\]<]*([^\s,.?!\[\]<\)]))))
525
+ else
526
+ InlineLinkRx = %r((^|link:|#{CG_BLANK}|\\?&lt;()|[>\(\)\[\];"'])(\\?(?:https?|file|ftp|irc)://)(?:([^\s\[\]]+)\[(|#{CC_ALL}*?[^\\])\]|\2([^\s]+?)&gt;|([^\s\[\]<]*([^\s,.?!\[\]<\)]))))m
527
+ end
523
528
 
524
529
  # Match a link or e-mail inline macro.
525
530
  #
@@ -384,7 +384,7 @@ module Substitutors
384
384
  if (items = $2)
385
385
  items = items.gsub ESC_R_SB, R_SB if items.include? R_SB
386
386
  if (delim = items.include?('&gt;') ? '&gt;' : (items.include?(',') ? ',' : nil))
387
- submenus = items.split(delim).map {|it| it.strip }
387
+ submenus = items.split(delim).map {|item| item.strip }
388
388
  menuitem = submenus.pop
389
389
  else
390
390
  submenus, menuitem = [], items.rstrip
@@ -402,7 +402,7 @@ module Substitutors
402
402
  # honor the escape
403
403
  next $&.slice 1, $&.length if $&.start_with? RS
404
404
 
405
- menu, *submenus = $1.split('&gt;').map {|it| it.strip }
405
+ menu, *submenus = $1.split('&gt;').map {|item| item.strip }
406
406
  menuitem = submenus.pop
407
407
  Inline.new(self, :menu, nil, attributes: { 'menu' => menu, 'submenus' => submenus, 'menuitem' => menuitem }).convert
408
408
  end
@@ -454,7 +454,7 @@ module Substitutors
454
454
  end
455
455
  attrs['terms'] = terms
456
456
  if (see_also = attrs['see-also'])
457
- attrs['see-also'] = (see_also.include? ',') ? (see_also.split ',').map {|it| it.lstrip } : [see_also]
457
+ attrs['see-also'] = (see_also.include? ',') ? (see_also.split ',').map {|item| item.lstrip } : [see_also]
458
458
  end
459
459
  else
460
460
  attrs = { 'terms' => attrlist }
@@ -471,7 +471,7 @@ module Substitutors
471
471
  if (term = normalize_text $2, true, true).include? '='
472
472
  term = (attrs = (AttributeList.new term, self).parse)[1] || (attrs = nil) || term
473
473
  if attrs && (see_also = attrs['see-also'])
474
- attrs['see-also'] = (see_also.include? ',') ? (see_also.split ',').map {|it| it.lstrip } : [see_also]
474
+ attrs['see-also'] = (see_also.include? ',') ? (see_also.split ',').map {|item| item.lstrip } : [see_also]
475
475
  end
476
476
  end
477
477
  (Inline.new self, :indexterm, term, attributes: attrs, type: :visible).convert
@@ -537,9 +537,8 @@ module Substitutors
537
537
  # honor the escapes
538
538
  next $&.slice 1, $&.length if $1.start_with? RS
539
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
540
+ next $& unless $6
541
+ doc.register :links, (target = $3 + $6)
543
542
  link_text = (doc_attrs.key? 'hide-uri-scheme') ? (target.sub UriSniffRx, '') : target
544
543
  (Inline.new self, :anchor, link_text, type: :link, target: target, attributes: { 'role' => 'bare' }).convert
545
544
  else
@@ -1006,7 +1005,7 @@ module Substitutors
1006
1005
  end
1007
1006
  # If the start attribute is defined, then the lines to highlight specified by the provided spec should be relative to the start value.
1008
1007
  unless (shift = start ? start - 1 : 0) == 0
1009
- lines = lines.map {|it| it - shift }
1008
+ lines = lines.map {|n| n - shift }
1010
1009
  end
1011
1010
  lines.sort
1012
1011
  end
@@ -1542,7 +1541,7 @@ module Substitutors
1542
1541
  end
1543
1542
  values << accum.strip
1544
1543
  else
1545
- str.split(',').map {|it| it.strip }
1544
+ str.split(',').map {|item| item.strip }
1546
1545
  end
1547
1546
  end
1548
1547
  end
@@ -16,14 +16,15 @@ class SyntaxHighlighter::CodeRayAdapter < SyntaxHighlighter::Base
16
16
  def highlight node, source, lang, opts
17
17
  @requires_stylesheet = true if (css_mode = opts[:css_mode]) == :class
18
18
  lang = lang ? (::CodeRay::Scanners[lang = lang.to_sym] && lang rescue :text) : :text
19
- highlighted = ::CodeRay::Duo[lang, :html,
19
+ highlighter_opts = {
20
20
  css: css_mode,
21
21
  line_numbers: (line_numbers = opts[:number_lines]),
22
22
  line_number_start: opts[:start_line_number],
23
23
  line_number_anchors: false,
24
24
  highlight_lines: opts[:highlight_lines],
25
25
  bold_every: false,
26
- ].highlight source
26
+ }
27
+ highlighted = ::CodeRay::Duo[lang, :html, highlighter_opts].highlight source
27
28
  if line_numbers == :table && opts[:callouts]
28
29
  [highlighted, (idx = highlighted.index CodeCellStartTagCs) ? idx + CodeCellStartTagCs.length : nil]
29
30
  else
@@ -300,7 +300,7 @@ class Table::Cell < AbstractBlock
300
300
  # QUESTION is is faster to check for :: before splitting?
301
301
  inner_document_lines = cell_text.split LF, -1
302
302
  if (unprocessed_line1 = inner_document_lines[0]).include? '::'
303
- preprocessed_lines = (PreprocessorReader.new @document, [unprocessed_line1]).readlines
303
+ preprocessed_lines = (PreprocessorReader.new @document, [unprocessed_line1], inner_document_cursor).readlines
304
304
  unless unprocessed_line1 == preprocessed_lines[0] && preprocessed_lines.size < 2
305
305
  inner_document_lines.shift
306
306
  inner_document_lines.unshift(*preprocessed_lines) unless preprocessed_lines.empty?
@@ -659,36 +659,43 @@ class Table::ParserContext
659
659
  end
660
660
  end
661
661
  else
662
- # QUESTION is this right for cells that span columns?
663
- unless (column = @table.columns[@current_row.size])
664
- logger.error message_with_context 'dropping cell because it exceeds specified number of columns', source_location: @reader.cursor_before_mark
665
- return nil
666
- end
662
+ column = @table.columns[@current_row.size]
667
663
  end
668
664
 
669
- cell = Table::Cell.new(column, cell_text, cellspec, cursor: @reader.cursor_before_mark)
665
+ cell = Table::Cell.new column, cell_text, cellspec, cursor: (cursor_before_mark = @reader.cursor_before_mark)
670
666
  @reader.mark
671
667
  unless !cell.rowspan || cell.rowspan == 1
672
668
  activate_rowspan(cell.rowspan, (cell.colspan || 1))
673
669
  end
674
670
  @column_visits += (cell.colspan || 1)
675
671
  @current_row << cell
676
- # don't close the row if we're on the first line and the column count has not been set explicitly
677
- # TODO perhaps the colcount/linenum logic should be in end_of_row? (or a should_end_row? method)
678
- close_row if end_of_row? && (@colcount != -1 || @linenum > 0 || (eol && i == repeat))
672
+ if (row_status = end_of_row?) > -1 && (@colcount != -1 || @linenum > 0 || (eol && i == repeat))
673
+ if row_status > 0
674
+ logger.error message_with_context 'dropping cell because it exceeds specified number of columns', source_location: cursor_before_mark
675
+ close_row true
676
+ else
677
+ close_row
678
+ end
679
+ end
679
680
  end
680
681
  @cell_open = false
681
682
  nil
682
683
  end
683
684
 
685
+ def close_table
686
+ return if @column_visits == 0
687
+ logger.error message_with_context 'dropping cells from incomplete row detected end of table', source_location: @reader.cursor_before_mark
688
+ nil
689
+ end
690
+
684
691
  private
685
692
 
686
693
  # Internal: Close the row by adding it to the Table and resetting the row
687
694
  # Array and counter variables.
688
695
  #
689
696
  # returns nothing
690
- def close_row
691
- @table.rows.body << @current_row
697
+ def close_row drop = false
698
+ @table.rows.body << @current_row unless drop
692
699
  # don't have to account for active rowspans here
693
700
  # since we know this is first row
694
701
  @colcount = @column_visits if @colcount == -1
@@ -709,8 +716,10 @@ class Table::ParserContext
709
716
  end
710
717
 
711
718
  # Internal: Check whether we've met the number of effective columns for the current row.
719
+ #
720
+ # returns -1 if not at end of row, 0 if exactly at end of row, and 1 if overruns end of row
712
721
  def end_of_row?
713
- @colcount == -1 || effective_column_visits == @colcount
722
+ @colcount == -1 ? 0 : effective_column_visits <=> @colcount
714
723
  end
715
724
 
716
725
  # Internal: Calculate the effective column visits, which consists of the number of
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Asciidoctor
3
- VERSION = '2.0.22'
3
+ VERSION = '2.0.24'
4
4
  end
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.21
4
+ .\" Generator: Asciidoctor 2.0.23
5
5
  .\" Date: 2018-03-20
6
6
  .\" Manual: Asciidoctor Manual
7
- .\" Source: Asciidoctor 2.0.22
7
+ .\" Source: Asciidoctor 2.0.24
8
8
  .\" Language: English
9
9
  .\"
10
- .TH "ASCIIDOCTOR" "1" "2018-03-20" "Asciidoctor 2.0.22" "Asciidoctor Manual"
10
+ .TH "ASCIIDOCTOR" "1" "2018-03-20" "Asciidoctor 2.0.24" "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.22
4
+ :release-version: 2.0.24
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.22
4
+ version: 2.0.24
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Allen
@@ -10,7 +10,7 @@ authors:
10
10
  - Jason Porter
11
11
  - Nick Hengeveld
12
12
  - Jeremy McAnally
13
- autorequire:
13
+ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
  date: 2018-03-20 00:00:00.000000000 Z
@@ -63,14 +63,14 @@ dependencies:
63
63
  requirements:
64
64
  - - "~>"
65
65
  - !ruby/object:Gem::Version
66
- version: 6.1.0
66
+ version: 6.3.0
67
67
  type: :development
68
68
  prerelease: false
69
69
  version_requirements: !ruby/object:Gem::Requirement
70
70
  requirements:
71
71
  - - "~>"
72
72
  - !ruby/object:Gem::Version
73
- version: 6.1.0
73
+ version: 6.3.0
74
74
  - !ruby/object:Gem::Dependency
75
75
  name: minitest
76
76
  requirement: !ruby/object:Gem::Requirement
@@ -257,7 +257,8 @@ metadata:
257
257
  changelog_uri: https://github.com/asciidoctor/asciidoctor/blob/HEAD/CHANGELOG.adoc
258
258
  mailing_list_uri: https://chat.asciidoctor.org
259
259
  source_code_uri: https://github.com/asciidoctor/asciidoctor
260
- post_install_message:
260
+ funding_uri: https://opencollective.com/asciidoctor
261
+ post_install_message:
261
262
  rdoc_options: []
262
263
  require_paths:
263
264
  - lib
@@ -272,8 +273,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
272
273
  - !ruby/object:Gem::Version
273
274
  version: '0'
274
275
  requirements: []
275
- rubygems_version: 3.5.3
276
- signing_key:
276
+ rubygems_version: 3.5.22
277
+ signing_key:
277
278
  specification_version: 4
278
279
  summary: An implementation of the AsciiDoc text processor and publishing toolchain
279
280
  test_files: []