chore: implement list html render

This commit is contained in:
Steven 2023-12-16 09:01:19 +08:00
parent b00443c222
commit 6421fbc68a
5 changed files with 49 additions and 1 deletions

View file

@ -43,6 +43,10 @@ func (p *OrderedListParser) Parse(tokens []*tokenizer.Token) (ast.Node, error) {
}
contentTokens := tokens[3:size]
lastToken := contentTokens[len(contentTokens)-1]
if lastToken.Type == tokenizer.Newline {
contentTokens = contentTokens[:len(contentTokens)-1]
}
children, err := ParseInline(contentTokens)
if err != nil {
return nil, err

View file

@ -30,6 +30,8 @@ var defaultBlockParsers = []BlockParser{
NewHorizontalRuleParser(),
NewHeadingParser(),
NewBlockquoteParser(),
NewUnorderedListParser(),
NewOrderedListParser(),
NewParagraphParser(),
NewLineBreakParser(),
}

View file

@ -24,10 +24,10 @@ func (*UnorderedListParser) Match(tokens []*tokenizer.Token) (int, bool) {
contentTokens := []*tokenizer.Token{}
for _, token := range tokens[2:] {
contentTokens = append(contentTokens, token)
if token.Type == tokenizer.Newline {
break
}
contentTokens = append(contentTokens, token)
}
if len(contentTokens) == 0 {
return 0, false
@ -44,6 +44,10 @@ func (p *UnorderedListParser) Parse(tokens []*tokenizer.Token) (ast.Node, error)
symbolToken := tokens[0]
contentTokens := tokens[2:size]
lastToken := contentTokens[len(contentTokens)-1]
if lastToken.Type == tokenizer.Newline {
contentTokens = contentTokens[:len(contentTokens)-1]
}
children, err := ParseInline(contentTokens)
if err != nil {
return nil, err

View file

@ -39,6 +39,10 @@ func (r *HTMLRender) RenderNode(node ast.Node) {
r.renderHorizontalRule(n)
case *ast.Blockquote:
r.renderBlockquote(n)
case *ast.UnorderedList:
r.renderUnorderedList(n)
case *ast.OrderedList:
r.renderOrderedList(n)
case *ast.Bold:
r.renderBold(n)
case *ast.Italic:
@ -113,6 +117,32 @@ func (r *HTMLRender) renderBlockquote(node *ast.Blockquote) {
}
}
func (r *HTMLRender) renderUnorderedList(node *ast.UnorderedList) {
prevSibling, nextSibling := node.PrevSibling(), node.NextSibling()
if prevSibling == nil || prevSibling.Type() != ast.UnorderedListNode {
r.output.WriteString("<ul>")
}
r.output.WriteString("<li>")
r.RenderNodes(node.Children)
r.output.WriteString("</li>")
if nextSibling == nil || nextSibling.Type() != ast.UnorderedListNode {
r.output.WriteString("</ul>")
}
}
func (r *HTMLRender) renderOrderedList(node *ast.OrderedList) {
prevSibling, nextSibling := node.PrevSibling(), node.NextSibling()
if prevSibling == nil || prevSibling.Type() != ast.OrderedListNode {
r.output.WriteString("<ol>")
}
r.output.WriteString("<li>")
r.RenderNodes(node.Children)
r.output.WriteString("</li>")
if nextSibling == nil || nextSibling.Type() != ast.OrderedListNode {
r.output.WriteString("</ol>")
}
}
func (r *HTMLRender) renderText(node *ast.Text) {
r.output.WriteString(node.Content)
}

View file

@ -34,6 +34,14 @@ func TestHTMLRender(t *testing.T) {
text: "#article #memo",
expected: `<p><span>#article</span> <span>#memo</span></p>`,
},
{
text: "* Hello\n* world!",
expected: `<ul><li>Hello</li><li>world!</li></ul>`,
},
{
text: "1. Hello\n2. world\n* !",
expected: `<ol><li>Hello</li><li>world</li></ol><ul><li>!</li></ul>`,
},
}
for _, test := range tests {