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 }