asciidoctor 2.0.17 → 2.0.19

Sign up to get free protection for your applications and to get access to all the features.
@@ -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