package markdown
import (
"html/template"
"regexp"
"strings"
"git.anhgelus.world/anhgelus/small-web/dom"
)
var regexOrdered = regexp.MustCompile(`\d+\.`)
type listType string
const (
listUnordered listType = "ul"
listOrdered listType = "ol"
)
type astList struct {
tag listType
content []*astParagraph
}
func (a *astList) Eval(opt *Option) (template.HTML, *ParseError) {
list := dom.NewContentElement(string(a.tag), make([]dom.Element, 0))
for _, c := range a.content {
ct, err := c.Eval(opt)
if err != nil {
return "", err
}
list.Contents = append(list.Contents, dom.NewLiteralContentElement(
"li",
template.HTML(strings.TrimSpace(string(ct))),
))
}
return list.Render(), nil
}
func list(lxs *lexers) (block, *ParseError) {
tree := new(astList)
tree.tag = detectListType(lxs.Current().Value)
if len(tree.tag) == 0 {
return paragraph(lxs, false)
}
n := 0
for lxs.Next() && n < 2 {
switch lxs.Current().Type {
case lexerBreak:
n += len(lxs.Current().Value)
case lexerList:
n = 0
tp := detectListType(lxs.Current().Value)
if tp != tree.tag {
lxs.Before() // because we dit not use it
return tree, nil
}
default:
n = 0
c, err := paragraph(lxs, true)
if err != nil {
return nil, err
}
lxs.Before() // because we must parse the last char
tree.content = append(tree.content, c)
}
}
lxs.Before() // because we did not use it
return tree, nil
}
func detectListType(val string) listType {
first := []rune(val)[0]
if first == '-' || first == '*' {
if len(val) > 1 {
return ""
}
return listUnordered
}
if !regexOrdered.MatchString(val) {
return ""
}
return listOrdered
}