package markdown
import (
"fmt"
"html/template"
"regexp"
)
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) {
var content template.HTML
for _, c := range a.content {
ct, err := c.Eval(opt)
if err != nil {
return "", err
}
content += template.HTML(fmt.Sprintf("
%s", trimSpace(ct)))
}
return template.HTML(fmt.Sprintf("<%s>%s%s>", a.tag, content, a.tag)), 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
}