From 6421fbc68a84313c649e00ee848fbca2bb4ca0c4 Mon Sep 17 00:00:00 2001 From: Steven Date: Sat, 16 Dec 2023 09:01:19 +0800 Subject: [PATCH] chore: implement list html render --- plugin/gomark/parser/ordered_list.go | 4 ++++ plugin/gomark/parser/parser.go | 2 ++ plugin/gomark/parser/unordered_list.go | 6 +++++- plugin/gomark/render/html/html.go | 30 ++++++++++++++++++++++++++ plugin/gomark/render/html/html_test.go | 8 +++++++ 5 files changed, 49 insertions(+), 1 deletion(-) diff --git a/plugin/gomark/parser/ordered_list.go b/plugin/gomark/parser/ordered_list.go index 4e01b476..b4c2f151 100644 --- a/plugin/gomark/parser/ordered_list.go +++ b/plugin/gomark/parser/ordered_list.go @@ -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 diff --git a/plugin/gomark/parser/parser.go b/plugin/gomark/parser/parser.go index 3f97ef0d..9be62f5a 100644 --- a/plugin/gomark/parser/parser.go +++ b/plugin/gomark/parser/parser.go @@ -30,6 +30,8 @@ var defaultBlockParsers = []BlockParser{ NewHorizontalRuleParser(), NewHeadingParser(), NewBlockquoteParser(), + NewUnorderedListParser(), + NewOrderedListParser(), NewParagraphParser(), NewLineBreakParser(), } diff --git a/plugin/gomark/parser/unordered_list.go b/plugin/gomark/parser/unordered_list.go index c64daeb1..b98ca9c6 100644 --- a/plugin/gomark/parser/unordered_list.go +++ b/plugin/gomark/parser/unordered_list.go @@ -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 diff --git a/plugin/gomark/render/html/html.go b/plugin/gomark/render/html/html.go index 46f90bc6..ca67a52e 100644 --- a/plugin/gomark/render/html/html.go +++ b/plugin/gomark/render/html/html.go @@ -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("") + } +} + +func (r *HTMLRender) renderOrderedList(node *ast.OrderedList) { + prevSibling, nextSibling := node.PrevSibling(), node.NextSibling() + if prevSibling == nil || prevSibling.Type() != ast.OrderedListNode { + r.output.WriteString("
    ") + } + r.output.WriteString("
  1. ") + r.RenderNodes(node.Children) + r.output.WriteString("
  2. ") + if nextSibling == nil || nextSibling.Type() != ast.OrderedListNode { + r.output.WriteString("
") + } +} + func (r *HTMLRender) renderText(node *ast.Text) { r.output.WriteString(node.Content) } diff --git a/plugin/gomark/render/html/html_test.go b/plugin/gomark/render/html/html_test.go index 25164254..f497af45 100644 --- a/plugin/gomark/render/html/html_test.go +++ b/plugin/gomark/render/html/html_test.go @@ -34,6 +34,14 @@ func TestHTMLRender(t *testing.T) { text: "#article #memo", expected: `

#article #memo

`, }, + { + text: "* Hello\n* world!", + expected: ``, + }, + { + text: "1. Hello\n2. world\n* !", + expected: `
  1. Hello
  2. world
`, + }, } for _, test := range tests {