Files
herolib/lib/data/markdownparser2/parser_list_item.v
2025-03-24 06:44:39 +01:00

119 lines
2.8 KiB
Verilog

module markdownparser2
// Parse a list item
fn (mut p Parser) parse_list_item(is_ordered bool, marker string) ?&MarkdownElement {
// Save starting position for potential rollback
start_pos := p.pos // Unused but kept for consistency
start_line := p.line
start_column := p.column
// Skip whitespace
p.skip_whitespace()
// Check for task list item
mut is_task := false
mut is_completed := false
if p.pos + 3 < p.text.len && p.text[p.pos] == `[`
&& (p.text[p.pos + 1] == ` ` || p.text[p.pos + 1] == `x` || p.text[p.pos + 1] == `X`)
&& p.text[p.pos + 2] == `]` && (p.text[p.pos + 3] == ` ` || p.text[p.pos + 3] == `\t`) {
is_task = true
is_completed = p.text[p.pos + 1] == `x` || p.text[p.pos + 1] == `X`
p.pos += 3
p.column += 3
p.skip_whitespace()
}
// Read item content until end of line or next list item
mut content := ''
mut lines := []string{}
// Read the first line
for p.pos < p.text.len && p.text[p.pos] != `\n` {
content += p.text[p.pos].ascii_str()
p.pos++
p.column++
}
lines << content
// Skip the newline
if p.pos < p.text.len && p.text[p.pos] == `\n` {
p.pos++
p.line++
p.column = 1
}
// Read additional lines of the list item
for p.pos < p.text.len {
// Check if the line is indented (part of the current item)
if p.text[p.pos] == ` ` || p.text[p.pos] == `\t` {
// Count indentation
mut indent := 0
for p.pos < p.text.len && (p.text[p.pos] == ` ` || p.text[p.pos] == `\t`) {
indent++
p.pos++
p.column++
}
// If indented enough, it's part of the current item
if indent >= 2 {
mut line := ''
for p.pos < p.text.len && p.text[p.pos] != `\n` {
line += p.text[p.pos].ascii_str()
p.pos++
p.column++
}
lines << line
// Skip the newline
if p.pos < p.text.len && p.text[p.pos] == `\n` {
p.pos++
p.line++
p.column = 1
}
} else {
// Not indented enough, end of list item
break
}
} else if p.text[p.pos] == `\n` {
// Empty line - could be a continuation or the end of the list item
p.pos++
p.line++
p.column = 1
// Check if the next line is indented
if p.pos < p.text.len && (p.text[p.pos] == ` ` || p.text[p.pos] == `\t`) {
lines << ''
} else {
break
}
} else {
// Not an indented line, end of list item
break
}
}
// Join the lines with newlines
content = lines.join('\n')
// Create the list item element
mut item := &MarkdownElement{
typ: if is_task { .task_list_item } else { .list_item }
content: content
line_number: start_line
column: start_column
attributes: if is_task {
{
'completed': is_completed.str()
}
} else {
map[string]string{}
}
}
// Parse inline elements within the list item
item.children = p.parse_inline(content)
return item
}