65 lines
1.3 KiB
V
65 lines
1.3 KiB
V
module markdownparser2
|
|
|
|
// Parse a heading element
|
|
fn (mut p Parser) parse_heading() ?&MarkdownElement {
|
|
start_pos := p.pos
|
|
start_line := p.line
|
|
start_column := p.column
|
|
|
|
// Count the number of # characters
|
|
mut level := 0
|
|
for p.pos < p.text.len && p.text[p.pos] == `#` && level < 6 {
|
|
level++
|
|
p.pos++
|
|
p.column++
|
|
}
|
|
|
|
// Must be followed by a space
|
|
if p.pos >= p.text.len || (p.text[p.pos] != ` ` && p.text[p.pos] != `\t`) {
|
|
p.pos = start_pos
|
|
p.line = start_line
|
|
p.column = start_column
|
|
return p.parse_paragraph()
|
|
}
|
|
|
|
// Skip whitespace after #
|
|
p.skip_whitespace()
|
|
|
|
// Read the heading text until end of line
|
|
mut content := ''
|
|
for p.pos < p.text.len && p.text[p.pos] != `\n` {
|
|
content += p.text[p.pos].ascii_str()
|
|
p.pos++
|
|
p.column++
|
|
}
|
|
|
|
// Skip the newline
|
|
if p.pos < p.text.len && p.text[p.pos] == `\n` {
|
|
p.pos++
|
|
p.line++
|
|
p.column = 1
|
|
}
|
|
|
|
// Trim trailing whitespace and optional closing #s
|
|
content = content.trim_right(' \t')
|
|
for content.ends_with('#') {
|
|
content = content.trim_right('#').trim_right(' \t')
|
|
}
|
|
|
|
// Create the heading element
|
|
mut heading := &MarkdownElement{
|
|
typ: .heading
|
|
content: content
|
|
line_number: start_line
|
|
column: start_column
|
|
attributes: {
|
|
'level': level.str()
|
|
}
|
|
}
|
|
|
|
// Parse inline elements within the heading
|
|
heading.children = p.parse_inline(content)
|
|
|
|
return heading
|
|
}
|