aboutsummaryrefslogtreecommitdiff
path: root/markdown/ast_list.go
blob: b07f0134bee280aa0213a8903abe8cd758d701f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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
}