asciidoctor 2.0.17 → 2.0.19

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.
@@ -120,8 +120,14 @@ module Helpers
120
120
  # str - the String to check
121
121
  #
122
122
  # returns true if the String is a URI, false if it is not
123
- def uriish? str
124
- (str.include? ':') && (UriSniffRx.match? str)
123
+ if ::RUBY_ENGINE == 'jruby'
124
+ def uriish? str
125
+ (str.include? ':') && !(str.start_with? 'uri:classloader:') && (UriSniffRx.match? str)
126
+ end
127
+ else
128
+ def uriish? str
129
+ (str.include? ':') && (UriSniffRx.match? str)
130
+ end
125
131
  end
126
132
 
127
133
  # Internal: Encode a URI component String for safe inclusion in a URI.
@@ -398,18 +398,22 @@ class Parser
398
398
  # REVIEW this may be doing too much
399
399
  if part
400
400
  if !section.blocks?
401
- # if this block wasn't marked as [partintro], emulate behavior as if it had
401
+ # if this not a [partintro] open block, enclose it in a [partintro] open block
402
402
  if new_block.style != 'partintro'
403
- # emulate [partintro] paragraph
404
- if new_block.context == :paragraph
405
- new_block.context = :open
403
+ # if this is already a normal open block, simply add the partintro style
404
+ if new_block.style == 'open' && new_block.context == :open
406
405
  new_block.style = 'partintro'
407
- # emulate [partintro] open block
408
406
  else
409
407
  new_block.parent = (intro = Block.new section, :open, content_model: :compound)
410
408
  intro.style = 'partintro'
411
409
  section.blocks << intro
412
410
  end
411
+ # if this is a [partintro] paragraph, convert it to a [partintro] open block w/ single paragraph
412
+ elsif new_block.content_model == :simple
413
+ new_block.content_model = :compound
414
+ new_block << (Block.new new_block, :paragraph, source: new_block.lines, subs: new_block.subs)
415
+ new_block.lines.clear
416
+ new_block.subs.clear
413
417
  end
414
418
  elsif section.blocks.size == 1
415
419
  first_block = section.blocks[0]
@@ -419,12 +423,11 @@ class Parser
419
423
  # rebuild [partintro] paragraph as an open block
420
424
  elsif first_block.content_model != :compound
421
425
  new_block.parent = (intro = Block.new section, :open, content_model: :compound)
422
- intro.style = 'partintro'
423
- section.blocks.shift
424
- if first_block.style == 'partintro'
426
+ if first_block.style == (intro.style = 'partintro')
425
427
  first_block.context = :paragraph
426
428
  first_block.style = nil
427
429
  end
430
+ section.blocks.shift
428
431
  intro << first_block
429
432
  section.blocks << intro
430
433
  end
@@ -1052,9 +1055,9 @@ class Parser
1052
1055
  attributes.delete('style')
1053
1056
  if (block = extension.process_method[parent, block_reader || (Reader.new lines), attributes.merge]) && block != parent
1054
1057
  attributes.replace block.attributes
1055
- # FIXME if the content model is set to compound, but we only have simple in this context, then
1056
- # forcefully set the content_model to simple to prevent parsing blocks from children
1057
- # TODO document this behavior!!
1058
+ # NOTE an extension can change the content model from :simple to :compound. It's up to the extension
1059
+ # to decide which one to use. The extension can consult the cloaked-context attribute to determine
1060
+ # if the input is a paragraph or delimited block.
1058
1061
  if block.content_model == :compound && Block === block && !(lines = block.lines).empty?
1059
1062
  content_model = :compound
1060
1063
  block_reader = Reader.new lines
@@ -1168,8 +1171,8 @@ class Parser
1168
1171
  if reftext.include? ']'
1169
1172
  reftext = reftext.gsub '\]', ']'
1170
1173
  reftext = document.sub_attributes reftext if reftext.include? ATTR_REF_HEAD
1171
- elsif (reftext.include? ATTR_REF_HEAD) && (reftext = document.sub_attributes reftext).empty?
1172
- next
1174
+ elsif reftext.include? ATTR_REF_HEAD
1175
+ reftext = nil if (reftext = document.sub_attributes reftext).empty?
1173
1176
  end
1174
1177
  end
1175
1178
  end
@@ -1439,21 +1442,33 @@ class Parser
1439
1442
 
1440
1443
  # a delimited block immediately breaks the list unless preceded
1441
1444
  # by a list continuation (they are harsh like that ;0)
1442
- if (match = is_delimited_block?(this_line, true))
1443
- if continuation == :active
1444
- buffer << this_line
1445
- # grab all the lines in the block, leaving the delimiters in place
1446
- # we're being more strict here about the terminator, but I think that's a good thing
1447
- buffer.concat reader.read_lines_until(terminator: match.terminator, read_last_line: true, context: nil)
1448
- continuation = :inactive
1449
- else
1445
+ if (match = is_delimited_block? this_line, true)
1446
+ break unless continuation == :active
1447
+ buffer << this_line
1448
+ # grab all the lines in the block, leaving the delimiters in place
1449
+ # we're being more strict here about the terminator, but I think that's a good thing
1450
+ buffer.concat reader.read_lines_until terminator: match.terminator, read_last_line: true, context: nil
1451
+ continuation = :inactive
1452
+ # BlockAttributeLineRx only breaks dlist if ensuing line is not a list item
1453
+ elsif dlist && continuation != :active && (this_line.start_with? '[') && (BlockAttributeLineRx.match? this_line)
1454
+ block_attribute_lines = [this_line]
1455
+ while (next_line = reader.peek_line)
1456
+ if is_delimited_block? next_line
1457
+ interrupt = true
1458
+ elsif next_line.empty? || ((next_line.start_with? '[') && (BlockAttributeLineRx.match? next_line))
1459
+ block_attribute_lines << reader.read_line
1460
+ next
1461
+ elsif (AnyListRx.match? next_line) && !(is_sibling_list_item? next_line, list_type, sibling_trait)
1462
+ buffer.concat block_attribute_lines
1463
+ else # rubocop:disable Lint/DuplicateBranch
1464
+ interrupt = true
1465
+ end
1466
+ break
1467
+ end
1468
+ if interrupt
1469
+ reader.unshift_lines block_attribute_lines
1450
1470
  break
1451
1471
  end
1452
- # technically BlockAttributeLineRx only breaks if ensuing line is not a list item
1453
- # which really means BlockAttributeLineRx only breaks if it's acting as a block delimiter
1454
- # FIXME to be AsciiDoc compliant, we shouldn't break if style in attribute line is "literal" (i.e., [literal])
1455
- elsif dlist && continuation != :active && (BlockAttributeLineRx.match? this_line)
1456
- break
1457
1472
  elsif continuation == :active && !this_line.empty?
1458
1473
  # literal paragraphs have special considerations (and this is one of
1459
1474
  # two entry points into one)
@@ -1470,7 +1485,8 @@ class Parser
1470
1485
  end
1471
1486
  continuation = :inactive
1472
1487
  # let block metadata play out until we find the block
1473
- elsif (BlockTitleRx.match? this_line) || (BlockAttributeLineRx.match? this_line) || (AttributeEntryRx.match? this_line)
1488
+ elsif ((ch0 = this_line.chr) == '.' && (BlockTitleRx.match? this_line)) ||
1489
+ (ch0 == '[' && (BlockAttributeLineRx.match? this_line)) || (ch0 == ':' && (AttributeEntryRx.match? this_line))
1474
1490
  buffer << this_line
1475
1491
  else
1476
1492
  if (nested_list_type = (within_nested_list ? [:dlist] : NESTABLE_LIST_CONTEXTS).find {|ctx| ListRxMap[ctx].match? this_line })
@@ -109,6 +109,7 @@ class PathResolver
109
109
  SLASH = '/'
110
110
  BACKSLASH = '\\'
111
111
  DOUBLE_SLASH = '//'
112
+ URI_CLASSLOADER = 'uri:classloader:'
112
113
  WindowsRootRx = %r(^(?:[a-zA-Z]:)?[\\/])
113
114
 
114
115
  attr_accessor :file_separator
@@ -148,8 +149,9 @@ class PathResolver
148
149
  # Public: Check if the specified path is an absolute root path (or, in the
149
150
  # browser environment, an absolute URI as well)
150
151
  #
151
- # This operation considers both posix paths and Windows paths. If the JavaScript IO
152
- # module is xmlhttprequest, this operation also considers absolute URIs.
152
+ # This operation considers both POSIX and Windows paths. If the JavaScript IO module
153
+ # is xmlhttprequest, this operation also considers absolute URIs. If running on JRuby,
154
+ # this operation also considers classloader URIs (starts with uri:classloader:).
153
155
  #
154
156
  # Unix absolute paths and UNC paths start with slash. Windows roots can
155
157
  # start with a drive letter. When the IO module is xmlhttprequest (Opal
@@ -164,6 +166,10 @@ class PathResolver
164
166
  def root? path
165
167
  (absolute_path? path) || (path.start_with? 'file://', 'http://', 'https://')
166
168
  end
169
+ elsif ::RUBY_ENGINE == 'jruby'
170
+ def root? path
171
+ (absolute_path? path) || (path.start_with? URI_CLASSLOADER)
172
+ end
167
173
  else
168
174
  alias root? absolute_path?
169
175
  end
@@ -299,6 +305,9 @@ class PathResolver
299
305
  # ex. /sample/path
300
306
  elsif posix_path.start_with? SLASH
301
307
  root = SLASH
308
+ # ex. uri:classloader:sample/path (or uri:classloader:/sample/path)
309
+ elsif posix_path.start_with? URI_CLASSLOADER
310
+ root = posix_path.slice 0, URI_CLASSLOADER.length
302
311
  # ex. C:/sample/path (or file:///sample/path in browser environment)
303
312
  else
304
313
  root = posix_path.slice 0, (posix_path.index SLASH) + 1
@@ -125,16 +125,21 @@ class Reader
125
125
  # Returns the next line of the source data as a String if there are lines remaining.
126
126
  # Returns nothing if there is no more data.
127
127
  def peek_line direct = false
128
- if direct || @look_ahead > 0
129
- @unescape_next_line ? ((line = @lines[-1]).slice 1, line.length) : @lines[-1]
130
- elsif @lines.empty?
131
- @look_ahead = 0
132
- nil
133
- else
134
- # FIXME the problem with this approach is that we aren't
135
- # retaining the modified line (hence the @unescape_next_line tweak)
136
- # perhaps we need a stack of proxied lines
137
- (process_line @lines[-1]) || peek_line
128
+ while true
129
+ next_line = @lines[-1]
130
+ if direct || @look_ahead > 0
131
+ return @unescape_next_line ? (next_line.slice 1, next_line.length) : next_line
132
+ elsif next_line
133
+ # FIXME the problem with this approach is that we aren't
134
+ # retaining the modified line (hence the @unescape_next_line tweak)
135
+ # perhaps we need a stack of proxied lines
136
+ if (line = process_line next_line)
137
+ return line
138
+ end
139
+ else
140
+ @look_ahead = 0
141
+ return
142
+ end
138
143
  end
139
144
  end
140
145
 
@@ -690,7 +695,7 @@ class PreprocessorReader < Reader
690
695
  # only process lines in AsciiDoc files
691
696
  if (@process_lines = file.end_with?(*ASCIIDOC_EXTENSIONS.keys))
692
697
  # NOTE registering the include with a nil value tracks it while not making it visible to interdocument xrefs
693
- @includes[path.slice 0, (path.rindex '.')] = attributes['partial-option'] ? nil : true
698
+ @includes[path.slice 0, (path.rindex '.')] ||= attributes['partial-option'] ? nil : true
694
699
  end
695
700
  else
696
701
  @dir = '.'
@@ -698,7 +703,7 @@ class PreprocessorReader < Reader
698
703
  @process_lines = true
699
704
  if (@path = path)
700
705
  # NOTE registering the include with a nil value tracks it while not making it visible to interdocument xrefs
701
- @includes[Helpers.rootname path] = attributes['partial-option'] ? nil : true
706
+ @includes[Helpers.rootname path] ||= attributes['partial-option'] ? nil : true
702
707
  else
703
708
  @path = '<stdin>'
704
709
  end
@@ -1035,7 +1040,7 @@ class PreprocessorReader < Reader
1035
1040
  # however, be friendly and at least make it a link to the source document
1036
1041
  elsif doc.safe >= SafeMode::SECURE
1037
1042
  # FIXME we don't want to use a link macro if we are in a verbatim context
1038
- replace_next_line %(link:#{expanded_target}[])
1043
+ replace_next_line %(link:#{expanded_target}[role=include])
1039
1044
  elsif @maxdepth
1040
1045
  if @include_stack.size >= @maxdepth[:curr]
1041
1046
  logger.error message_with_context %(maximum include depth of #{@maxdepth[:rel]} exceeded), source_location: cursor
@@ -1197,15 +1202,16 @@ class PreprocessorReader < Reader
1197
1202
  push_include inc_lines, inc_path, relpath, inc_offset, parsed_attrs
1198
1203
  end
1199
1204
  else
1205
+ inc_content = nil
1200
1206
  begin
1201
1207
  # NOTE read content before shift so cursor is only advanced if IO operation succeeds
1202
1208
  inc_content = reader.call(inc_path, read_mode) {|f| f.read }
1203
1209
  shift
1204
- push_include inc_content, inc_path, relpath, 1, parsed_attrs
1205
1210
  rescue
1206
1211
  logger.error message_with_context %(include #{target_type} not readable: #{inc_path}), source_location: cursor
1207
1212
  return replace_next_line %(Unresolved directive in #{@path} - include::#{expanded_target}[#{attrlist}])
1208
1213
  end
1214
+ push_include inc_content, inc_path, relpath, 1, parsed_attrs
1209
1215
  end
1210
1216
  true
1211
1217
  end
@@ -1232,7 +1238,7 @@ class PreprocessorReader < Reader
1232
1238
  def resolve_include_path target, attrlist, attributes
1233
1239
  doc = @document
1234
1240
  if (Helpers.uriish? target) || (::String === @dir ? nil : (target = %(#{@dir}/#{target})))
1235
- return replace_next_line %(link:#{target}[#{attrlist}]) unless doc.attr? 'allow-uri-read'
1241
+ return replace_next_line %(link:#{target}[role=include]) unless doc.attr? 'allow-uri-read'
1236
1242
  if doc.attr? 'cache-uri'
1237
1243
  # caching requires the open-uri-cached gem to be installed
1238
1244
  # processing will be automatically aborted if these libraries can't be opened
@@ -1280,27 +1286,22 @@ class PreprocessorReader < Reader
1280
1286
 
1281
1287
  # Private: Ignore front-matter, commonly used in static site generators
1282
1288
  def skip_front_matter! data, increment_linenos = true
1283
- front_matter = nil
1284
- if data[0] == '---'
1285
- original_data = data.drop 0
1286
- data.shift
1287
- front_matter = []
1289
+ return unless (delim = data[0]) == '---'
1290
+ original_data = data.drop 0
1291
+ data.shift
1292
+ front_matter = []
1293
+ @lineno += 1 if increment_linenos
1294
+ until (eof = data.empty?) || data[0] == delim
1295
+ front_matter << data.shift
1288
1296
  @lineno += 1 if increment_linenos
1289
- while !data.empty? && data[0] != '---'
1290
- front_matter << data.shift
1291
- @lineno += 1 if increment_linenos
1292
- end
1293
-
1294
- if data.empty?
1295
- data.unshift(*original_data)
1296
- @lineno = 0 if increment_linenos
1297
- front_matter = nil
1298
- else
1299
- data.shift
1300
- @lineno += 1 if increment_linenos
1301
- end
1302
1297
  end
1303
-
1298
+ if eof
1299
+ data.unshift(*original_data)
1300
+ @lineno -= original_data.size if increment_linenos
1301
+ return
1302
+ end
1303
+ data.shift
1304
+ @lineno += 1 if increment_linenos
1304
1305
  front_matter
1305
1306
  end
1306
1307
 
@@ -89,7 +89,7 @@ module Asciidoctor
89
89
  # include::chapter1.ad[]
90
90
  # include::example.txt[lines=1;2;5..10]
91
91
  #
92
- IncludeDirectiveRx = /^(\\)?include::([^\[][^\[]*)\[(#{CC_ANY}+)?\]$/
92
+ IncludeDirectiveRx = /^(\\)?include::([^\s\[](?:[^\[]*[^\s\[])?)\[(#{CC_ANY}+)?\]$/
93
93
 
94
94
  # Matches a trailing tag directive in an include file.
95
95
  #
@@ -516,9 +516,9 @@ module Asciidoctor
516
516
  # <https://github.com>
517
517
  # link:https://github.com[]
518
518
  # "https://github.com[]"
519
+ # (https://github.com) <= parenthesis not included in autolink
519
520
  #
520
- # FIXME revisit! the main issue is we need different rules for implicit vs explicit
521
- InlineLinkRx = %r((^|link:|#{CG_BLANK}|&lt;|[>\(\)\[\];"'])(\\?(?:https?|file|ftp|irc)://[^\s\[\]<]*([^\s.,\[\]<]))(?:\[(|#{CC_ALL}*?[^\\])\])?)m
521
+ InlineLinkRx = %r((^|link:|#{CG_BLANK}|&lt;|[>\(\)\[\];"'])(\\?(?:https?|file|ftp|irc)://)(?:([^\s\[\]]+)\[(|#{CC_ALL}*?[^\\])\]|([^\s\[\]<]*([^\s,.?!\[\]<\)]))))m
522
522
 
523
523
  # Match a link or e-mail inline macro.
524
524
  #
@@ -568,23 +568,17 @@ module Asciidoctor
568
568
  # Examples
569
569
  #
570
570
  # +text+
571
- # `text` (compat)
571
+ # [x-]+text+
572
+ # [x-]`text`
573
+ # `text` (compat only)
574
+ # [role]`text` (compat only)
572
575
  #
573
576
  # NOTE we always capture the attributes so we know when to use compatible (i.e., legacy) behavior
574
577
  InlinePassRx = {
575
- false => ['+', '`', /(^|[^#{CC_WORD};:])(?:\[([^\]]+)\])?(\\?(\+|`)(\S|\S#{CC_ALL}*?\S)\4)(?!#{CG_WORD})/m],
576
- true => ['`', nil, /(^|[^`#{CC_WORD}])(?:\[([^\]]+)\])?(\\?(`)([^`\s]|[^`\s]#{CC_ALL}*?\S)\4)(?![`#{CC_WORD}])/m]
578
+ false => ['+', '-]', /((?:^|[^#{CC_WORD};:\\])(?=(\[)|\+)|\\(?=\[)|(?=\\\+))(?:\2(x-|[^\]]+ x-)\]|(?:\[([^\]]+)\])?(?=(\\)?\+))(\5?(\+|`)(\S|\S#{CC_ALL}*?\S)\7)(?!#{CG_WORD})/m],
579
+ true => ['`', nil, /(^|[^`#{CC_WORD}])(?:(\Z)()|\[([^\]]+)\](?=(\\))?)?(\5?(`)([^`\s]|[^`\s]#{CC_ALL}*?\S)\7)(?![`#{CC_WORD}])/m],
577
580
  }
578
581
 
579
- # Matches an inline plus passthrough spanning multiple lines, but only when it occurs directly
580
- # inside constrained monospaced formatting in non-compat mode.
581
- #
582
- # Examples
583
- #
584
- # +text+
585
- #
586
- SinglePlusInlinePassRx = /^(\\)?\+(\S|\S#{CC_ALL}*?\S)\+$/m
587
-
588
582
  # Matches several variants of the passthrough inline macro, which may span multiple lines.
589
583
  #
590
584
  # Examples
@@ -716,7 +710,11 @@ module Asciidoctor
716
710
  #
717
711
  # not c:/sample.adoc or c:\sample.adoc
718
712
  #
719
- UriSniffRx = %r(^#{CG_ALPHA}[#{CC_ALNUM}.+-]+:/{0,2})
713
+ if RUBY_ENGINE == 'opal'
714
+ UriSniffRx = %r(^#{CG_ALPHA}[#{CC_ALNUM}.+-]+:/{0,2})
715
+ else
716
+ UriSniffRx = %r(\A#{CG_ALPHA}[#{CC_ALNUM}.+-]+:/{0,2})
717
+ end
720
718
 
721
719
  # Detects XML tags
722
720
  XmlSanitizeRx = /<[^>]+>/
@@ -526,9 +526,9 @@ module Substitutors
526
526
  if found_colon && (text.include? '://')
527
527
  # inline urls, target[text] (optionally prefixed with link: and optionally surrounded by <>)
528
528
  text = text.gsub InlineLinkRx do
529
- if (target = $2).start_with? RS
529
+ if (target = $2 + ($3 || $5)).start_with? RS
530
530
  # honor the escape
531
- next %(#{$1}#{target.slice 1, target.length}#{$4})
531
+ next ($&.slice 0, (rs_idx = $1.length)) + ($&.slice rs_idx + 1, $&.length)
532
532
  end
533
533
 
534
534
  prefix, suffix = $1, ''
@@ -543,15 +543,7 @@ module Substitutors
543
543
  when 'link:', ?", ?'
544
544
  next $&
545
545
  end
546
- case $3
547
- when ')', '?', '!'
548
- target = target.chop
549
- if (suffix = $3) == ')' && (target.end_with? '.', '?', '!')
550
- suffix = target[-1] + suffix
551
- target = target.chop
552
- end
553
- # NOTE handle case when modified target is a URI scheme (e.g., http://)
554
- next $& if target.end_with? '://'
546
+ case $6
555
547
  when ';'
556
548
  if (prefix.start_with? '&lt;') && (target.end_with? '&gt;')
557
549
  # move surrounding <> out of URL
@@ -755,7 +747,7 @@ module Substitutors
755
747
 
756
748
  if doc.compat_mode
757
749
  fragment = refid
758
- elsif (hash_idx = refid.index '#')
750
+ elsif (hash_idx = refid.index '#') && refid[hash_idx - 1] != '&'
759
751
  if hash_idx > 0
760
752
  if (fragment_len = refid.length - 1 - hash_idx) > 0
761
753
  path, fragment = (refid.slice 0, hash_idx), (refid.slice hash_idx + 1, fragment_len)
@@ -1027,11 +1019,17 @@ module Substitutors
1027
1019
  next %(#{$1}[#{attrlist}]#{RS * (escape_count - 1)}#{boundary}#{$5}#{boundary})
1028
1020
  elsif $1 == RS
1029
1021
  preceding = %([#{attrlist}])
1030
- else
1031
- if boundary == '++' && (attrlist.end_with? 'x-')
1022
+ elsif boundary == '++'
1023
+ if attrlist == 'x-'
1024
+ old_behavior = true
1025
+ attributes = {}
1026
+ elsif attrlist.end_with? ' x-'
1032
1027
  old_behavior = true
1033
- attrlist = attrlist.slice 0, attrlist.length - 2
1028
+ attributes = parse_quoted_text_attributes attrlist.slice 0, attrlist.length - 3
1029
+ else
1030
+ attributes = parse_quoted_text_attributes attrlist
1034
1031
  end
1032
+ else
1035
1033
  attributes = parse_quoted_text_attributes attrlist
1036
1034
  end
1037
1035
  elsif (escape_count = $3.length) > 0
@@ -1066,41 +1064,43 @@ module Substitutors
1066
1064
  pass_inline_char1, pass_inline_char2, pass_inline_rx = InlinePassRx[compat_mode]
1067
1065
  text = text.gsub pass_inline_rx do
1068
1066
  preceding = $1
1069
- attrlist = $2
1070
- escape_mark = RS if (quoted_text = $3).start_with? RS
1071
- format_mark = $4
1072
- content = $5
1067
+ attrlist = $4 || $3
1068
+ escaped = true if $5
1069
+ quoted_text = $6
1070
+ format_mark = $7
1071
+ content = $8
1073
1072
 
1074
1073
  if compat_mode
1075
1074
  old_behavior = true
1076
- elsif (old_behavior = attrlist && (attrlist.end_with? 'x-'))
1077
- attrlist = attrlist.slice 0, attrlist.length - 2
1075
+ elsif attrlist && (attrlist == 'x-' || (attrlist.end_with? ' x-'))
1076
+ old_behavior = old_behavior_forced = true
1078
1077
  end
1079
1078
 
1080
1079
  if attrlist
1081
- if format_mark == '`' && !old_behavior
1082
- next extract_inner_passthrough content, %(#{preceding}[#{attrlist}]#{escape_mark})
1083
- elsif escape_mark
1080
+ if escaped
1084
1081
  # honor the escape of the formatting mark
1085
1082
  next %(#{preceding}[#{attrlist}]#{quoted_text.slice 1, quoted_text.length})
1086
1083
  elsif preceding == RS
1087
1084
  # honor the escape of the attributes
1085
+ next %(#{preceding}[#{attrlist}]#{quoted_text}) if old_behavior_forced && format_mark == '`'
1088
1086
  preceding = %([#{attrlist}])
1087
+ elsif old_behavior_forced
1088
+ attributes = attrlist == 'x-' ? {} : (parse_quoted_text_attributes attrlist.slice 0, attrlist.length - 3)
1089
1089
  else
1090
1090
  attributes = parse_quoted_text_attributes attrlist
1091
1091
  end
1092
- elsif format_mark == '`' && !old_behavior
1093
- next extract_inner_passthrough content, %(#{preceding}#{escape_mark})
1094
- elsif escape_mark
1092
+ elsif escaped
1095
1093
  # honor the escape of the formatting mark
1096
1094
  next %(#{preceding}#{quoted_text.slice 1, quoted_text.length})
1095
+ elsif compat_mode && preceding == RS
1096
+ next quoted_text
1097
1097
  end
1098
1098
 
1099
1099
  if compat_mode
1100
1100
  passthrus[passthru_key = passthrus.size] = { text: content, subs: BASIC_SUBS, attributes: attributes, type: :monospaced }
1101
1101
  elsif attributes
1102
1102
  if old_behavior
1103
- subs = (format_mark == '`' ? BASIC_SUBS : NORMAL_SUBS)
1103
+ subs = format_mark == '`' ? BASIC_SUBS : NORMAL_SUBS
1104
1104
  passthrus[passthru_key = passthrus.size] = { text: content, subs: subs, attributes: attributes, type: :monospaced }
1105
1105
  else
1106
1106
  passthrus[passthru_key = passthrus.size] = { text: content, subs: BASIC_SUBS, attributes: attributes, type: :unquoted }
@@ -1399,20 +1399,6 @@ module Substitutors
1399
1399
  end.join LF)
1400
1400
  end
1401
1401
 
1402
- # Internal: Extract nested single-plus passthrough; otherwise return unprocessed
1403
- def extract_inner_passthrough text, pre
1404
- if (text.end_with? '+') && (text.start_with? '+', '\+') && SinglePlusInlinePassRx =~ text
1405
- if $1
1406
- %(#{pre}`+#{$2}+`)
1407
- else
1408
- @passthroughs[passthru_key = @passthroughs.size] = { text: $2, subs: BASIC_SUBS }
1409
- %(#{pre}`#{PASS_START}#{passthru_key}#{PASS_END}`)
1410
- end
1411
- else
1412
- %(#{pre}`#{text}`)
1413
- end
1414
- end
1415
-
1416
1402
  # Internal: Convert a quoted text region
1417
1403
  #
1418
1404
  # match - The MatchData for the quoted text region
@@ -25,7 +25,7 @@ class SyntaxHighlighter::HighlightJsAdapter < SyntaxHighlighter::Base
25
25
  #{(doc.attr? 'highlightjs-languages') ? ((doc.attr 'highlightjs-languages').split ',').map {|lang| %[<script src="#{base_url}/languages/#{lang.lstrip}.min.js"></script>\n] }.join : ''}<script>
26
26
  if (!hljs.initHighlighting.called) {
27
27
  hljs.initHighlighting.called = true
28
- ;[].slice.call(document.querySelectorAll('pre.highlight > code')).forEach(function (el) { hljs.highlightBlock(el) })
28
+ ;[].slice.call(document.querySelectorAll('pre.highlight > code[data-lang]')).forEach(function (el) { hljs.highlightBlock(el) })
29
29
  }
30
30
  </script>)
31
31
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Asciidoctor
3
- VERSION = '2.0.17'
3
+ VERSION = '2.0.19'
4
4
  end
data/man/asciidoctor.1 CHANGED
@@ -252,15 +252,15 @@ Jason Porter wrote the first implementation of the CLI interface provided by thi
252
252
  \fBProject documentation:\fP \c
253
253
  .URL "https://docs.asciidoctor.org" "" ""
254
254
  .sp
255
+ \fBCommunity chat:\fP \c
256
+ .URL "https://chat.asciidoctor.org" "" ""
257
+ .sp
255
258
  \fBSource repository:\fP \c
256
259
  .URL "https://github.com/asciidoctor/asciidoctor" "" ""
257
260
  .sp
258
- \fBCommunity chat:\fP \c
259
- .URL "https://asciidoctor.zulipchat.com" "" ""
260
- .sp
261
- \fBDiscussion list:\fP \c
261
+ \fBMailing list archive:\fP \c
262
262
  .URL "https://discuss.asciidoctor.org" "" ""
263
263
  .SH "COPYING"
264
264
  .sp
265
265
  Copyright (C) 2012\-present Dan Allen, Sarah White, Ryan Waldron, and the individual contributors to Asciidoctor.
266
- Use of this software is granted under the terms of the MIT License.
266
+ Use of this software is granted under the terms of the MIT License.
data/man/asciidoctor.adoc CHANGED
@@ -46,10 +46,11 @@ If _FILE_ is _-_ then the AsciiDoc source is read from standard input.
46
46
  *-a, --attribute*=_ATTRIBUTE_::
47
47
  Define, override, or unset a document attribute.
48
48
  Command-line attributes take precedence over attributes defined in the source file unless either the name or value ends in _@_.
49
+ No substitutions are applied to the value.
49
50
  +
50
51
  _ATTRIBUTE_ is normally formatted as a key-value pair, in the form _NAME=VALUE_.
51
52
  Alternate forms are _NAME_ (where the _VALUE_ defaults to an empty string), _NAME!_ (unsets the _NAME_ attribute), and _NAME=VALUE@_ (or _NAME@=VALUE_) (where _VALUE_ does not override the _NAME_ attribute if it's already defined in the source document).
52
- Values containing spaces should be enclosed in quotes.
53
+ A value containing spaces must be enclosed in quotes, in the form _NAME="VALUE WITH SPACES"_.
53
54
  +
54
55
  This option may be specified more than once.
55
56
 
@@ -190,11 +191,11 @@ Jason Porter wrote the first implementation of the CLI interface provided by thi
190
191
 
191
192
  *Project documentation:* https://docs.asciidoctor.org
192
193
 
193
- *Source repository:* https://github.com/asciidoctor/asciidoctor
194
+ *Community chat:* https://chat.asciidoctor.org
194
195
 
195
- *Community chat:* https://asciidoctor.zulipchat.com
196
+ *Source repository:* https://github.com/asciidoctor/asciidoctor
196
197
 
197
- *Discussion list:* https://discuss.asciidoctor.org
198
+ *Mailing list archive:* https://discuss.asciidoctor.org
198
199
 
199
200
  == Copying
200
201
 
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.17
4
+ version: 2.0.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Allen
@@ -13,7 +13,7 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2022-01-06 00:00:00.000000000 Z
16
+ date: 2018-03-20 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: concurrent-ruby
@@ -63,14 +63,14 @@ dependencies:
63
63
  requirements:
64
64
  - - "~>"
65
65
  - !ruby/object:Gem::Version
66
- version: 5.2.0
66
+ version: 6.1.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: 5.2.0
73
+ version: 6.1.0
74
74
  - !ruby/object:Gem::Dependency
75
75
  name: minitest
76
76
  requirement: !ruby/object:Gem::Requirement
@@ -91,14 +91,14 @@ dependencies:
91
91
  requirements:
92
92
  - - "~>"
93
93
  - !ruby/object:Gem::Version
94
- version: 1.10.0
94
+ version: 1.13.0
95
95
  type: :development
96
96
  prerelease: false
97
97
  version_requirements: !ruby/object:Gem::Requirement
98
98
  requirements:
99
99
  - - "~>"
100
100
  - !ruby/object:Gem::Version
101
- version: 1.10.0
101
+ version: 1.13.0
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: rake
104
104
  requirement: !ruby/object:Gem::Requirement
@@ -188,6 +188,7 @@ files:
188
188
  - data/locale/attributes-sr.adoc
189
189
  - data/locale/attributes-sr_Latn.adoc
190
190
  - data/locale/attributes-sv.adoc
191
+ - data/locale/attributes-sw.adoc
191
192
  - data/locale/attributes-th.adoc
192
193
  - data/locale/attributes-tr.adoc
193
194
  - data/locale/attributes-uk.adoc
@@ -254,7 +255,7 @@ licenses:
254
255
  metadata:
255
256
  bug_tracker_uri: https://github.com/asciidoctor/asciidoctor/issues
256
257
  changelog_uri: https://github.com/asciidoctor/asciidoctor/blob/HEAD/CHANGELOG.adoc
257
- mailing_list_uri: http://discuss.asciidoctor.org
258
+ mailing_list_uri: https://chat.asciidoctor.org
258
259
  source_code_uri: https://github.com/asciidoctor/asciidoctor
259
260
  post_install_message:
260
261
  rdoc_options: []
@@ -271,7 +272,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
271
272
  - !ruby/object:Gem::Version
272
273
  version: '0'
273
274
  requirements: []
274
- rubygems_version: 3.2.32
275
+ rubygems_version: 3.4.10
275
276
  signing_key:
276
277
  specification_version: 4
277
278
  summary: An implementation of the AsciiDoc text processor and publishing toolchain