From 72eed1cfa1f5067a7ca581c53bb40e9e0fb047cc Mon Sep 17 00:00:00 2001 From: Anhgelus Morhtuuzh Date: Thu, 2 Oct 2025 13:21:37 +0200 Subject: fix(markdown): bad list parsing --- mardown/ast_external.go | 76 +++++++++++++++++++++++++++++++++----------- mardown/ast_external_test.go | 18 +++++++++++ mardown/ast_list.go | 4 ++- mardown/ast_paragraph.go | 3 +- mardown/ast_quote.go | 2 +- mardown/ast_test.go | 8 +++++ 6 files changed, 89 insertions(+), 22 deletions(-) (limited to 'mardown') diff --git a/mardown/ast_external.go b/mardown/ast_external.go index 87fb880..78f12c8 100644 --- a/mardown/ast_external.go +++ b/mardown/ast_external.go @@ -25,7 +25,7 @@ func (a *astLink) Eval() (template.HTML, error) { type astImage struct { alt block src block - source *astParagraph + source []*astParagraph } func (a *astImage) Eval() (template.HTML, error) { @@ -40,11 +40,16 @@ func (a *astImage) Eval() (template.HTML, error) { if a.source == nil { return template.HTML(fmt.Sprintf(`
%s
`, alt, src)), nil } - source, err := a.source.Eval() - if err != nil { - return "", err + var s template.HTML + for _, c := range a.source { + ct, err := c.Eval() + if err != nil { + return "", err + } + s += ct + " " } - return template.HTML(fmt.Sprintf(`
%s
%s
`, alt, src, source)), nil + s = s[:len(s)-1] + return template.HTML(fmt.Sprintf(`
%s
%s
`, alt, src, s)), nil } func external(lxs *lexers) (block, error) { @@ -69,7 +74,7 @@ func external(lxs *lexers) (block, error) { func link(lxs *lexers) (block, error) { lk := new(astLink) start := lxs.current - content, href, _, ok := parseExternal(lxs, 1) + content, href, _, ok := parseExternal(lxs, false) if !ok { return reset(lxs, start), nil } @@ -81,34 +86,60 @@ func link(lxs *lexers) (block, error) { func image(lxs *lexers) (block, error) { img := new(astImage) start := lxs.current - alt, src, _, ok := parseExternal(lxs, 2) + alt, src, source, ok := parseExternal(lxs, true) if !ok { return reset(lxs, start), nil } img.alt = astLiteral(alt) img.src = astLiteral(src) - //img.source = astLiteral(source) + img.source = source return img, nil } -func parseExternal(lxs *lexers, maxBreak int) (string, string, string, bool) { +func parseExternal(lxs *lexers, withSource bool) (string, string, []*astParagraph, bool) { next := false var s string var first string var end string + var ps []*astParagraph n := 0 - for lxs.Next() && n < maxBreak { + fn := func() bool { + p, err := paragraph(lxs, true) + if err != nil { + return false + } + ps = append(ps, p) + n = 0 + return true + } + for lxs.Next() && n < 2 { switch lxs.Current().Type { case lexerBreak: - n++ + if !withSource { + return "", "", nil, false + } + n += len(lxs.Current().Value) + if first != "" && end != "" { + if !lxs.Next() { + return first, end, ps, true + } + ok := fn() + if !ok { + return "", "", nil, false + } + lxs.Before() // because we must parse lexerBreak + } case lexerExternal: + if first != "" && end != "" { + return "", "", nil, false + } if n > 0 && (first == "" || end == "") { - return "", "", "", false + return "", "", nil, false } n = 0 if !next { if lxs.Current().Value != "](" || !lxs.Next() { - return "", "", "", false + return "", "", nil, false } lxs.Before() // because we called Next first = s @@ -116,23 +147,30 @@ func parseExternal(lxs *lexers, maxBreak int) (string, string, string, bool) { next = true } else { if lxs.Current().Value != ")" { - return "", "", "", false + return "", "", nil, false } - if maxBreak == 1 { - return first, s, "", true + if !withSource { + return first, s, nil, true } end = s s = "" + if lxs.Next() && lxs.Current().Type != lexerBreak { + return "", "", nil, false + } + lxs.Before() // because we called Next } default: + if ps != nil { + return "", "", nil, false + } n = 0 s += lxs.Current().Value } } - if maxBreak == 1 { - return "", "", "", false + if !withSource { + return "", "", nil, false } - return first, end, s, true + return first, end, ps, true } func reset(lxs *lexers, start int) block { diff --git a/mardown/ast_external_test.go b/mardown/ast_external_test.go index fc0597d..afae085 100644 --- a/mardown/ast_external_test.go +++ b/mardown/ast_external_test.go @@ -28,4 +28,22 @@ func TestExternal(t *testing.T) { if string(got) != `
image alt
` { t.Errorf("invalid value, got %s", got) } + + lxs = lex(` +![image alt](image src) +source 1 +source 2 +`) + tree, err = ast(lxs) + if err != nil { + t.Fatal(err) + } + got, err = tree.Eval() + if err != nil { + t.Fatal(err) + } + if string(got) != `
image alt
source 1 source 2
` { + t.Errorf("invalid value, got %s", got) + } + } diff --git a/mardown/ast_list.go b/mardown/ast_list.go index 8eb451a..f95324b 100644 --- a/mardown/ast_list.go +++ b/mardown/ast_list.go @@ -42,7 +42,7 @@ func list(lxs *lexers) (block, error) { for lxs.Next() && n < 2 { switch lxs.Current().Type { case lexerBreak: - n++ + n += len(lxs.Current().Value) case lexerList: n = 0 tp := detectListType(lxs.Current().Value) @@ -56,9 +56,11 @@ func list(lxs *lexers) (block, error) { 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 } diff --git a/mardown/ast_paragraph.go b/mardown/ast_paragraph.go index 44b5dd9..23d526e 100644 --- a/mardown/ast_paragraph.go +++ b/mardown/ast_paragraph.go @@ -40,9 +40,10 @@ func paragraph(lxs *lexers, oneLine bool) (*astParagraph, error) { n := 0 lxs.current-- // because we do not use it before the next for lxs.Next() && n < maxBreak { + //println("p", strings.ReplaceAll(lxs.Current().Value, "\n", "/n")) switch lxs.Current().Type { case lexerBreak: - n = len(lxs.Current().Value) + n += len(lxs.Current().Value) case lexerQuote, lexerList: if n > 0 { lxs.Before() // because we did not use it diff --git a/mardown/ast_quote.go b/mardown/ast_quote.go index d673f61..f046445 100644 --- a/mardown/ast_quote.go +++ b/mardown/ast_quote.go @@ -44,7 +44,7 @@ func quote(lxs *lexers) (*astQuote, error) { for lxs.Next() && n < 2 { switch lxs.Current().Type { case lexerBreak: - n = len(lxs.Current().Value) + n += len(lxs.Current().Value) quoteContinue = false case lexerQuote: n = 0 diff --git a/mardown/ast_test.go b/mardown/ast_test.go index 573349e..3b2a77a 100644 --- a/mardown/ast_test.go +++ b/mardown/ast_test.go @@ -23,6 +23,10 @@ avec une source 1. et maintenant 2. elle l'est - hehe + +![Ceci est ma pfp :3](https://cdn.anhgelus.world/pfp.jpg) +Ma pfp hehe :D +Elle est **magnifique**, n'est-ce pas ? ` var parsed = ` @@ -34,6 +38,10 @@ var parsed = `
  1. et maintenant
  2. elle l'est
+
+Ceci est ma pfp :3 +
Ma pfp hehe :D Elle est magnifique, n'est-ce pas ?
+
` func TestAst(t *testing.T) { -- cgit v1.2.3