current_line = line
current_block = root
while current_line != null do
- current_line.kind(self).process(self)
+ line_kind(current_line.as(not null)).process(self)
end
self.in_list = old_mode
self.current_block = old_root
# Is the current recursion in list mode?
# Used when visiting blocks with `recurse`
private var in_list = false
+
+ # The type of line.
+ # see: `md_line_*`
+ fun line_kind(md: MDLine): Line do
+ var value = md.value
+ var leading = md.leading
+ var trailing = md.trailing
+ if md.is_empty then return new LineEmpty
+ if md.leading > 3 then return new LineCode
+ if value[leading] == '#' then return new LineHeadline
+ if value[leading] == '>' then return new LineBlockquote
+
+ if value.length - leading - trailing > 2 then
+ if value[leading] == '`' and md.count_chars_start('`') >= 3 then
+ return new LineFence
+ end
+ if value[leading] == '~' and md.count_chars_start('~') >= 3 then
+ return new LineFence
+ end
+ end
+
+ if value.length - leading - trailing > 2 and
+ (value[leading] == '*' or value[leading] == '-' or value[leading] == '_') then
+ if md.count_chars(value[leading]) >= 3 then
+ return new LineHR
+ end
+ end
+
+ if value.length - leading >= 2 and value[leading + 1] == ' ' then
+ var c = value[leading]
+ if c == '*' or c == '-' or c == '+' then return new LineUList
+ end
+
+ if value.length - leading >= 3 and value[leading].is_digit then
+ var i = leading + 1
+ while i < value.length and value[i].is_digit do i += 1
+ if i + 1 < value.length and value[i] == '.' and value[i + 1] == ' ' then
+ return new LineOList
+ end
+ end
+
+ if value[leading] == '<' and md.check_html then return new LineXML
+
+ var next = md.next
+ if next != null and not next.is_empty then
+ if next.count_chars('=') > 0 then
+ return new LineHeadline1
+ end
+ if next.count_chars('-') > 0 then
+ return new LineHeadline2
+ end
+ end
+ return new LineOther
+ end
+
end
# Emit output corresponding to blocks content.
var line = first_line
while line != null do
if not line.is_empty then
- var kind = line.kind(v)
+ var kind = v.line_kind(line)
if kind isa LineList then
line.value = kind.extract_value(line)
else
var line = block.first_line
line = line.next
while line != null do
- var t = line.kind(v)
+ var t = v.line_kind(line)
if t isa LineList or
(not line.is_empty and (line.prev_empty and line.leading == 0 and
not (t isa LineList))) then
if next != null then next.prev_empty = true
end
- # The type of line.
- # see `md_line_*`
- fun kind(v: MarkdownProcessor): Line do
- var value = self.value
- if is_empty then return new LineEmpty
- if leading > 3 then return new LineCode
- if value[leading] == '#' then return new LineHeadline
- if value[leading] == '>' then return new LineBlockquote
-
- if value.length - leading - trailing > 2 then
- if value[leading] == '`' and count_chars_start('`') >= 3 then
- return new LineFence
- end
- if value[leading] == '~' and count_chars_start('~') >= 3 then
- return new LineFence
- end
- end
-
- if value.length - leading - trailing > 2 and
- (value[leading] == '*' or value[leading] == '-' or value[leading] == '_') then
- if count_chars(value[leading]) >= 3 then
- return new LineHR
- end
- end
-
- if value.length - leading >= 2 and value[leading + 1] == ' ' then
- var c = value[leading]
- if c == '*' or c == '-' or c == '+' then return new LineUList
- end
-
- if value.length - leading >= 3 and value[leading].is_digit then
- var i = leading + 1
- while i < value.length and value[i].is_digit do i += 1
- if i + 1 < value.length and value[i] == '.' and value[i + 1] == ' ' then
- return new LineOList
- end
- end
-
- if value[leading] == '<' and check_html then return new LineXML
-
- if next != null and not next.is_empty then
- if next.count_chars('=') > 0 then
- return new LineHeadline1
- end
- if next.count_chars('-') > 0 then
- return new LineHeadline2
- end
- end
- return new LineOther
- end
-
# Number or leading spaces on this line.
var leading: Int = 0 is writable
# go to block end
var was_empty = line.prev_empty
while line != null and not line.is_empty do
- var t = line.kind(v)
+ var t = v.line_kind(line)
if v.in_list and t isa LineList then
break
end
redef fun process(v) do
var line = v.current_line
# lookup block end
- while line != null and (line.is_empty or line.kind(v) isa LineCode) do
+ while line != null and (line.is_empty or v.line_kind(line) isa LineCode) do
line = line.next
end
# split at block end line
while line != null do
if not line.is_empty and (line.prev_empty and
line.leading == 0 and
- not line.kind(v) isa LineBlockquote) then break
+ not v.line_kind(line) isa LineBlockquote) then break
line = line.next
end
# build sub block
# go to fence end
var line = v.current_line.next
while line != null do
- if line.kind(v) isa LineFence then break
+ if v.line_kind(line) isa LineFence then break
line = line.next
end
if line != null then
end
block.kind = new BlockFence(block)
block.first_line.clear
- if block.last_line.kind(v) isa LineFence then
+ var last = block.last_line
+ if last != null and v.line_kind(last) isa LineFence then
block.last_line.clear
end
block.remove_surrounding_empty_lines
var line = v.current_line
# go to list end
while line != null do
- var t = line.kind(v)
+ var t = v.line_kind(line)
if not line.is_empty and (line.prev_empty and line.leading == 0 and
not t isa LineList) then break
line = line.next
fun test_line_type do
var v = new MarkdownProcessor
subject = new MDLine("")
- assert subject.kind(v) isa LineEmpty
+ assert v.line_kind(subject) isa LineEmpty
subject = new MDLine(" ")
- assert subject.kind(v) isa LineEmpty
+ assert v.line_kind(subject) isa LineEmpty
subject = new MDLine("text ")
- assert subject.kind(v) isa LineOther
+ assert v.line_kind(subject) isa LineOther
subject = new MDLine(" # Title")
- assert subject.kind(v) isa LineHeadline
+ assert v.line_kind(subject) isa LineHeadline
subject = new MDLine(" ### Title")
- assert subject.kind(v) isa LineHeadline
+ assert v.line_kind(subject) isa LineHeadline
subject = new MDLine(" code")
- assert subject.kind(v) isa LineCode
+ assert v.line_kind(subject) isa LineCode
subject = new MDLine(" ~~~")
- assert subject.kind(v) isa LineFence
+ assert v.line_kind(subject) isa LineFence
subject = new MDLine(" ```")
- assert subject.kind(v) isa LineFence
+ assert v.line_kind(subject) isa LineFence
subject = new MDLine(" Title ")
subject.next = new MDLine("== ")
- assert subject.kind(v) isa LineHeadline1
+ assert v.line_kind(subject) isa LineHeadline1
subject = new MDLine(" Title ")
subject.next = new MDLine("-- ")
- assert subject.kind(v) isa LineHeadline2
+ assert v.line_kind(subject) isa LineHeadline2
subject = new MDLine(" * * * ")
- assert subject.kind(v) isa LineHR
+ assert v.line_kind(subject) isa LineHR
subject = new MDLine(" *** ")
- assert subject.kind(v) isa LineHR
+ assert v.line_kind(subject) isa LineHR
subject = new MDLine("- -- ")
- assert subject.kind(v) isa LineHR
+ assert v.line_kind(subject) isa LineHR
subject = new MDLine("--------- ")
- assert subject.kind(v) isa LineHR
+ assert v.line_kind(subject) isa LineHR
subject = new MDLine(" >")
- assert subject.kind(v) isa LineBlockquote
+ assert v.line_kind(subject) isa LineBlockquote
subject = new MDLine("<p></p>")
- assert subject.kind(v) isa LineXML
+ assert v.line_kind(subject) isa LineXML
subject = new MDLine("<p>")
- assert subject.kind(v) isa LineOther
+ assert v.line_kind(subject) isa LineOther
subject = new MDLine(" * foo")
- assert subject.kind(v) isa LineUList
+ assert v.line_kind(subject) isa LineUList
subject = new MDLine("- foo")
- assert subject.kind(v) isa LineUList
+ assert v.line_kind(subject) isa LineUList
subject = new MDLine("+ foo")
- assert subject.kind(v) isa LineUList
+ assert v.line_kind(subject) isa LineUList
subject = new MDLine("1. foo")
- assert subject.kind(v) isa LineOList
+ assert v.line_kind(subject) isa LineOList
subject = new MDLine(" 11111. foo")
- assert subject.kind(v) isa LineOList
+ assert v.line_kind(subject) isa LineOList
end
fun test_count_chars do