# Process the stack of delimiters
private fun process_delimiters(stack_bottom: nullable MdDelimiter) do
var openers_bottom = new HashMap[Char, nullable MdDelimiter]
# find first closer above stack bottom
var closer = last_delimiter
while closer != null and closer.prev != stack_bottom do
closer = closer.prev
end
# move forward, looking for closers, and handling each
while closer != null do
var delimiter_char = closer.delimiter_char
if not closer.can_close then
closer = closer.next
continue
end
if not delimiter_processors_map.has_key(delimiter_char) then
closer = closer.next
continue
end
var delimiter_processor = delimiter_processors_map[delimiter_char]
var opening_delimiter_char = delimiter_processor.opening_delimiter
# Found delimiter closer. Now look back for first matching opener
var use_delims = 0
var opener_found = false
var potential_opener_found = false
var opener = closer.prev
while opener != null and opener != stack_bottom and (not openers_bottom.has_key(delimiter_char) or opener != openers_bottom[delimiter_char]) do
if opener.can_open and opener.delimiter_char == opening_delimiter_char then
potential_opener_found = true
use_delims = delimiter_processor.delimiter_use(opener, closer)
if use_delims > 0 then
opener_found = true
break
end
end
opener = opener.prev
end
if not opener_found then
if not potential_opener_found then
# Set lower bound for future searches for openers.
# Only do this when we didn't even have a potential opener
# (one that matches the character and can open).
# If an opener was rejected because of the number of delimiters
# (e.g. because of the "multiple of 3" rule),
# we want to consider it next time because the number of delimiter
# can change as we continue processing.
openers_bottom[delimiter_char] = closer.prev
if not closer.can_open then
# We can remove a closer that can't be an opener,
# once we've seen there's no matching opener.
remove_delimiters_keep_node(closer)
end
end
closer = closer.next
continue
end
var opener_node = opener.as(not null).node
var closer_node = closer.node
# Remove number of used delimieters from stack and inline nodes
opener.as(not null).length -= use_delims
closer.length -= use_delims
opener_node.literal = opener_node.literal.substring(0,
opener_node.literal.length - use_delims)
closer_node.literal = closer_node.literal.substring(0,
closer_node.literal.length - use_delims)
remove_delimiters_between(opener, closer)
# The delimieter processor can re-parent the nodes between opener and closer,
# so make sure they're contiguous already.
# Exclusive because we want to keep opener/closer themselves.
merge_text_nodes_between_exclusive(opener_node, closer_node)
delimiter_processor.process(opener_node, closer_node, use_delims)
# Node delimieter characters left to process, so we can remove
# delimieter and the now empty node
if opener.as(not null).length == 0 then
remove_delimiters_and_node(opener)
end
if closer.length == 0 then
var next = closer.next
remove_delimiters_and_node(closer)
closer = next
end
end
# Remove all delimiters
while last_delimiter != null and last_delimiter != stack_bottom do
remove_delimiters_keep_node(last_delimiter)
end
end
lib/markdown2/markdown_inline_parsing.nit:914,2--1014,4