Files
herolib/lib/data/markdownparser2/parser_list.v
2025-03-07 21:03:55 +01:00

97 lines
1.7 KiB
V

module markdownparser2
// Parse a list element
fn (mut p Parser) parse_list() ?&MarkdownElement {
start_pos := p.pos
start_line := p.line
start_column := p.column
// Determine list type (ordered or unordered)
mut is_ordered := false
mut start_number := 1
mut marker := ''
if p.text[p.pos].is_digit() {
// Ordered list
is_ordered = true
// Parse start number
mut num_str := ''
for p.pos < p.text.len && p.text[p.pos].is_digit() {
num_str += p.text[p.pos].ascii_str()
p.pos++
p.column++
}
start_number = num_str.int()
// Must be followed by a period
if p.pos >= p.text.len || p.text[p.pos] != `.` {
p.pos = start_pos
p.line = start_line
p.column = start_column
return p.parse_paragraph()
}
marker = '.'
p.pos++
p.column++
} else {
// Unordered list
marker = p.text[p.pos].ascii_str()
p.pos++
p.column++
}
// Must be followed by whitespace
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()
}
// Create the list element
mut list := &MarkdownElement{
typ: .list
content: ''
line_number: start_line
column: start_column
attributes: {
'ordered': is_ordered.str()
'start': start_number.str()
'marker': marker
}
}
// Parse list items
for {
// Parse list item
if item := p.parse_list_item(is_ordered, marker) {
list.children << item
} else {
break
}
// Check if we're at the end of the list
p.skip_whitespace()
if p.pos >= p.text.len {
break
}
// Check for next list item
if is_ordered {
if !p.text[p.pos].is_digit() {
break
}
} else {
if p.text[p.pos] != marker[0] {
break
}
}
}
return list
}