chore: update inline parser

This commit is contained in:
Steven
2023-12-16 10:09:20 +08:00
parent 7b0ceee57b
commit 47af632c79
19 changed files with 73 additions and 222 deletions

View File

@@ -18,8 +18,8 @@ type Bold struct {
BaseInline
// Symbol is "*" or "_".
Symbol string
Content string
Symbol string
Children []Node
}
func (*Bold) Type() NodeType {

View File

@@ -53,8 +53,12 @@ func (p *BoldParser) Parse(tokens []*tokenizer.Token) (ast.Node, error) {
prefixTokenType := tokens[0].Type
contentTokens := tokens[2 : size-2]
children, err := ParseInlineWithParsers(contentTokens, []InlineParser{NewLinkParser(), NewTextParser()})
if err != nil {
return nil, err
}
return &ast.Bold{
Symbol: prefixTokenType,
Content: tokenizer.Stringify(contentTokens),
Symbol: prefixTokenType,
Children: children,
}, nil
}

View File

@@ -21,15 +21,23 @@ func TestBoldParser(t *testing.T) {
{
text: "**Hello**",
bold: &ast.Bold{
Symbol: "*",
Content: "Hello",
Symbol: "*",
Children: []ast.Node{
&ast.Text{
Content: "Hello",
},
},
},
},
{
text: "** Hello **",
bold: &ast.Bold{
Symbol: "*",
Content: " Hello ",
Symbol: "*",
Children: []ast.Node{
&ast.Text{
Content: " Hello ",
},
},
},
},
{

View File

@@ -63,8 +63,12 @@ Hello World`,
Level: 3,
Children: []ast.Node{
&ast.Bold{
Symbol: "*",
Content: "Hello",
Symbol: "*",
Children: []ast.Node{
&ast.Text{
Content: "Hello",
},
},
},
&ast.Text{
Content: " World",

View File

@@ -29,6 +29,13 @@ func TestLinkParser(t *testing.T) {
text: "[alte]( htt ps :/ /example.com)",
link: nil,
},
{
text: "[your/slash](https://example.com)",
link: &ast.Link{
Text: "your/slash",
URL: "https://example.com",
},
},
{
text: "[hello world](https://example.com)",
link: &ast.Link{

View File

@@ -76,10 +76,14 @@ var defaultInlineParsers = []InlineParser{
}
func ParseInline(tokens []*tokenizer.Token) ([]ast.Node, error) {
return ParseInlineWithParsers(tokens, defaultInlineParsers)
}
func ParseInlineWithParsers(tokens []*tokenizer.Token, inlineParsers []InlineParser) ([]ast.Node, error) {
nodes := []ast.Node{}
var prevNode ast.Node
for len(tokens) > 0 {
for _, inlineParser := range defaultInlineParsers {
for _, inlineParser := range inlineParsers {
size, matched := inlineParser.Match(tokens)
if matched {
node, err := inlineParser.Parse(tokens)

View File

@@ -32,8 +32,12 @@ func TestParser(t *testing.T) {
&ast.Paragraph{
Children: []ast.Node{
&ast.Bold{
Symbol: "*",
Content: "Hello",
Symbol: "*",
Children: []ast.Node{
&ast.Text{
Content: "Hello",
},
},
},
&ast.Text{
Content: " world!",
@@ -51,8 +55,12 @@ func TestParser(t *testing.T) {
Content: "Hello ",
},
&ast.Bold{
Symbol: "*",
Content: "world",
Symbol: "*",
Children: []ast.Node{
&ast.Text{
Content: "world",
},
},
},
&ast.Text{
Content: "!",
@@ -78,8 +86,12 @@ func TestParser(t *testing.T) {
Content: "Hello ",
},
&ast.Bold{
Symbol: "*",
Content: "world",
Symbol: "*",
Children: []ast.Node{
&ast.Text{
Content: "world",
},
},
},
&ast.Text{
Content: "!",
@@ -150,7 +162,7 @@ func StringifyNode(node ast.Node) string {
case *ast.Text:
return "Text(" + n.Content + ")"
case *ast.Bold:
return "Bold(" + n.Symbol + n.Content + n.Symbol + ")"
return "Bold(" + n.Symbol + StringifyNodes(n.Children) + n.Symbol + ")"
case *ast.Italic:
return "Italic(" + n.Symbol + n.Content + n.Symbol + ")"
case *ast.BoldItalic:

View File

@@ -35,8 +35,12 @@ func TestUnorderedListParser(t *testing.T) {
Symbol: tokenizer.Asterisk,
Children: []ast.Node{
&ast.Bold{
Symbol: "*",
Content: "Hello",
Symbol: "*",
Children: []ast.Node{
&ast.Text{
Content: "Hello",
},
},
},
},
},

View File

@@ -149,7 +149,7 @@ func (r *HTMLRender) renderText(node *ast.Text) {
func (r *HTMLRender) renderBold(node *ast.Bold) {
r.output.WriteString("<strong>")
r.output.WriteString(node.Content)
r.RenderNodes(node.Children)
r.output.WriteString("</strong>")
}

View File

@@ -134,7 +134,7 @@ func (r *StringRender) renderText(node *ast.Text) {
}
func (r *StringRender) renderBold(node *ast.Bold) {
r.output.WriteString(node.Content)
r.RenderNodes(node.Children)
}
func (r *StringRender) renderItalic(node *ast.Italic) {
@@ -151,12 +151,12 @@ func (r *StringRender) renderCode(node *ast.Code) {
r.output.WriteString("`")
}
func (*StringRender) renderImage(*ast.Image) {
// Do nothing.
func (r *StringRender) renderImage(node *ast.Image) {
r.output.WriteString(node.AltText)
}
func (*StringRender) renderLink(*ast.Link) {
// Do nothing.
func (r *StringRender) renderLink(node *ast.Link) {
r.output.WriteString(node.Text)
}
func (r *StringRender) renderTag(node *ast.Tag) {

View File

@@ -22,6 +22,10 @@ func TestStringRender(t *testing.T) {
text: "**Hello** world!",
expected: `Hello world!`,
},
{
text: "**[your/slash](https://example.com)** world!",
expected: `your/slash world!`,
},
}
for _, test := range tests {