lib/asciidoctor/parser.rb in asciidoctor-2.0.20 vs lib/asciidoctor/parser.rb in asciidoctor-2.0.21

- old
+ new

@@ -41,10 +41,16 @@ NoOp = nil AuthorKeys = ['author', 'authorinitials', 'firstname', 'middlename', 'lastname', 'email'] + ListContinuationMarker = ::Module.new + + ListContinuationPlaceholder = ::String.new.extend ListContinuationMarker + + ListContinuationString = (::String.new LIST_CONTINUATION).extend ListContinuationMarker + # Internal: A Hash mapping horizontal alignment abbreviations to alignments # that can be applied to a table cell (or to all cells in a column) TableCellHorzAlignments = { '<' => 'left', '>' => 'right', @@ -1418,21 +1424,22 @@ # the complete list item and can begin processing it # the remainder of the method determines whether we've reached # the termination of the list break if is_sibling_list_item?(this_line, list_type, sibling_trait) + this_line = ListContinuationString if this_line == LIST_CONTINUATION prev_line = buffer.empty? ? nil : buffer[-1] - if prev_line == LIST_CONTINUATION + if ListContinuationMarker === prev_line if continuation == :inactive continuation = :active has_text = true - buffer[-1] = '' unless within_nested_list + buffer[-1] = ListContinuationPlaceholder unless within_nested_list end # dealing with adjacent list continuations (which is really a syntax error) - if this_line == LIST_CONTINUATION + if ListContinuationMarker === this_line if continuation != :frozen continuation = :frozen buffer << this_line end this_line = nil @@ -1487,11 +1494,11 @@ # let block metadata play out until we find the block elsif ((ch0 = this_line.chr) == '.' && (BlockTitleRx.match? this_line)) || (ch0 == '[' && (BlockAttributeLineRx.match? this_line)) || (ch0 == ':' && (AttributeEntryRx.match? this_line)) buffer << this_line else - if (nested_list_type = (within_nested_list ? [:dlist] : NESTABLE_LIST_CONTEXTS).find {|ctx| ListRxMap[ctx].match? this_line }) + if (nested_list_type = (within_nested_list ? [:dlist] : NESTABLE_LIST_CONTEXTS).find {|ctx| ListRxMap[ctx] =~ this_line }) within_nested_list = true if nested_list_type == :dlist && $3.nil_or_empty? # get greedy again has_text = false end @@ -1508,11 +1515,11 @@ break if is_sibling_list_item? this_line, list_type, sibling_trait end if this_line == LIST_CONTINUATION detached_continuation = buffer.size - buffer << this_line + buffer << ListContinuationString elsif has_text # has_text only relevant for dlist, which is more greedy until it has text for an item; has_text is always true for all other lists # in this block, we have to see whether we stay in the list # TODO any way to combine this with the check after skipping blank lines? if is_sibling_list_item?(this_line, list_type, sibling_trait) break @@ -1541,10 +1548,13 @@ # pop the blank line so it's not interpreted as a list continuation buffer.pop unless within_nested_list buffer << this_line has_text = true end + elsif ListContinuationMarker === this_line + has_text = true + buffer << this_line else has_text = true unless this_line.empty? if (nested_list_type = (within_nested_list ? [:dlist] : NESTABLE_LIST_CONTEXTS).find {|ctx| ListRxMap[ctx] =~ this_line }) within_nested_list = true if nested_list_type == :dlist && $3.nil_or_empty? @@ -1557,19 +1567,20 @@ this_line = nil end reader.unshift_line this_line if this_line - buffer[detached_continuation] = '' if detached_continuation + buffer[detached_continuation] = ListContinuationPlaceholder if detached_continuation until buffer.empty? + # drop optional trailing continuation + if ListContinuationMarker === (last_line = buffer[-1]) + buffer.pop + break # strip trailing blank lines to prevent empty blocks - if (last_line = buffer[-1]).empty? + elsif last_line.empty? buffer.pop else - # drop optional trailing continuation - # (a blank line would have served the same purpose in the document) - buffer.pop if last_line == LIST_CONTINUATION break end end buffer