From 5ff5db6770a4cd7f506121287070fb342de62e79 Mon Sep 17 00:00:00 2001 From: Anhgelus Morhtuuzh Date: Sun, 21 Dec 2025 14:16:03 +0100 Subject: feat(markdown): option to render poem --- markdown/ast_external.go | 6 +++++- markdown/ast_paragraph.go | 13 +++++++++++-- markdown/ast_paragraph_test.go | 14 +++++++++++--- markdown/ast_test.go | 18 +++++++++++++++++- markdown/eval.go | 1 + 5 files changed, 45 insertions(+), 7 deletions(-) diff --git a/markdown/ast_external.go b/markdown/ast_external.go index 7223a9b..be63131 100644 --- a/markdown/ast_external.go +++ b/markdown/ast_external.go @@ -26,7 +26,11 @@ func (a *astLink) Eval(opt *Option) (template.HTML, *ParseError) { } rr := opt.RenderLink(string(content), string(href)) if a.addSpace { - return " " + rr, nil + s, err := astBreak{}.Eval(opt) + if err != nil { + return "", err + } + return s + rr, nil } return rr, nil } diff --git a/markdown/ast_paragraph.go b/markdown/ast_paragraph.go index 70d3414..30fd4a1 100644 --- a/markdown/ast_paragraph.go +++ b/markdown/ast_paragraph.go @@ -34,6 +34,15 @@ func (a *astParagraph) Eval(opt *Option) (template.HTML, *ParseError) { ).Render(), nil } +type astBreak struct{} + +func (a astBreak) Eval(opt *Option) (template.HTML, *ParseError) { + if opt.Poem { + return dom.NewVoidElement("br").Render(), nil + } + return " ", nil +} + func paragraph(lxs *lexers, oneLine bool) (*astParagraph, *ParseError) { tree := new(astParagraph) tree.oneLine = oneLine @@ -46,11 +55,11 @@ func paragraph(lxs *lexers, oneLine bool) (*astParagraph, *ParseError) { s := lxs.Current().Value // replace line break by space if n > 0 && len(tree.content) != 0 { - s = " " + s + tree.content = append(tree.content, astBreak{}) } tree.content = append(tree.content, conv(s)) } - lxs.current-- // because we do not use it before the next + lxs.Before() // because we do not use it before the next for lxs.Next() && n < maxBreak { switch lxs.Current().Type { case lexerBreak: diff --git a/markdown/ast_paragraph_test.go b/markdown/ast_paragraph_test.go index ab3ab6c..c18dfc7 100644 --- a/markdown/ast_paragraph_test.go +++ b/markdown/ast_paragraph_test.go @@ -7,10 +7,18 @@ func TestParagraph(t *testing.T) { t.Run("simple", test("bonsoir", `

bonsoir

`)) }) t.Run("replacer", func(t *testing.T) { - opt := &Option{ - Replaces: map[rune]string{'~': " "}, - } + opt := &Option{Replaces: map[rune]string{'~': " "}} t.Run("empty", testWithOptions(opt, "bonsoir", `

bonsoir

`)) t.Run("simple", testWithOptions(opt, "bonsoir~!", `

bonsoir !

`)) }) + t.Run("poem", func(t *testing.T) { + opt := &Option{Poem: true} + t.Run("simple", testWithOptions(opt, "bonsoir", `

bonsoir

`)) + t.Run("one_break", testWithOptions(opt, `bonsoir +world`, `

bonsoir
world

`)) + t.Run("mult_break", testWithOptions(opt, `bonsoir +world + +new line`, `

bonsoir
world

new line

`)) + }) } diff --git a/markdown/ast_test.go b/markdown/ast_test.go index ed2ef87..c0c7fb3 100644 --- a/markdown/ast_test.go +++ b/markdown/ast_test.go @@ -41,7 +41,22 @@ var parsed = `
Ceci est ma pfp :3 -
Ma pfp hehe :D Elle est magnifique, n'est-ce pas ?
+
Ma pfp hehe :D Elle est magnifique, n'est-ce pas ?
+
+` + +var parsedPoem = ` +

Je suis un titre

+

Avec une description classique,
sur plusieurs lignes !

+

Et je peux mettre du texte en gras,
en italique et les deux en même temps !

+
Je suis une magnifique citation sur plusieurs lignes

avec une source

+
qui recommence après !

qui a elle aussi une source :D

+ +
  1. et maintenant
  2. elle l'est
+ +
+Ceci est ma pfp :3 +
Ma pfp hehe :D Elle est magnifique, n'est-ce pas ?
` @@ -65,5 +80,6 @@ func testWithOptions(opt *Option, input, expected string) func(*testing.T) { func TestAst(t *testing.T) { t.Run("ast", func(t *testing.T) { t.Run("complete", test(raw, strings.ReplaceAll(parsed, "\n", ""))) + t.Run("poem", testWithOptions(&Option{Poem: true}, raw, strings.ReplaceAll(parsedPoem, "\n", ""))) }) } diff --git a/markdown/eval.go b/markdown/eval.go index ae4bafc..9b0e099 100644 --- a/markdown/eval.go +++ b/markdown/eval.go @@ -8,6 +8,7 @@ type Option struct { ImageSource func(source string) string RenderLink func(content, href string) template.HTML Replaces map[rune]string + Poem bool } func Parse(s string, opt *Option) (template.HTML, *ParseError) { -- cgit v1.2.3