From 40b1f53362105a495c6a486f3488e83d79eb582a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?William=20Herg=C3=A8s?= Date: Fri, 3 Oct 2025 22:22:40 +0200 Subject: feat(markdown): eval option to setup custom image source func --- markdown/ast.go | 6 +++--- markdown/ast_code.go | 2 +- markdown/ast_external.go | 15 ++++++++------- markdown/ast_external_test.go | 6 +++--- markdown/ast_header.go | 4 ++-- markdown/ast_list.go | 4 ++-- markdown/ast_list_test.go | 2 +- markdown/ast_modifier.go | 4 ++-- markdown/ast_modifier_test.go | 2 +- markdown/ast_paragraph.go | 6 +++--- markdown/ast_paragraph_test.go | 2 +- markdown/ast_quote.go | 6 +++--- markdown/ast_quote_test.go | 2 +- markdown/ast_test.go | 2 +- markdown/error_test.go | 6 +++--- markdown/eval.go | 18 ++++++++++++++---- 16 files changed, 49 insertions(+), 38 deletions(-) (limited to 'markdown') diff --git a/markdown/ast.go b/markdown/ast.go index c45eb1e..b19fd07 100644 --- a/markdown/ast.go +++ b/markdown/ast.go @@ -11,17 +11,17 @@ import ( var ErrUnkownLexType = errors.New("unkown lex type") type block interface { - Eval() (template.HTML, *ParseError) + Eval(*Option) (template.HTML, *ParseError) } type tree struct { blocks []block } -func (t *tree) Eval() (template.HTML, *ParseError) { +func (t *tree) Eval(opt *Option) (template.HTML, *ParseError) { var content template.HTML for _, c := range t.blocks { - ct, err := c.Eval() + ct, err := c.Eval(opt) if err != nil { return "", err } diff --git a/markdown/ast_code.go b/markdown/ast_code.go index 85a3668..6980f32 100644 --- a/markdown/ast_code.go +++ b/markdown/ast_code.go @@ -25,7 +25,7 @@ type astCode struct { codeType codeType } -func (a *astCode) Eval() (template.HTML, *ParseError) { +func (a *astCode) Eval(_ *Option) (template.HTML, *ParseError) { switch a.codeType { case codeOneLine: return template.HTML(fmt.Sprintf("%s", template.HTMLEscapeString(a.content))), nil diff --git a/markdown/ast_external.go b/markdown/ast_external.go index ea78450..f37a685 100644 --- a/markdown/ast_external.go +++ b/markdown/ast_external.go @@ -10,12 +10,12 @@ type astLink struct { href block } -func (a *astLink) Eval() (template.HTML, *ParseError) { - content, err := a.content.Eval() +func (a *astLink) Eval(opt *Option) (template.HTML, *ParseError) { + content, err := a.content.Eval(opt) if err != nil { return "", err } - href, err := a.href.Eval() + href, err := a.href.Eval(opt) if err != nil { return "", err } @@ -28,21 +28,22 @@ type astImage struct { source []*astParagraph } -func (a *astImage) Eval() (template.HTML, *ParseError) { - alt, err := a.alt.Eval() +func (a *astImage) Eval(opt *Option) (template.HTML, *ParseError) { + alt, err := a.alt.Eval(opt) if err != nil { return "", err } - src, err := a.src.Eval() + src, err := a.src.Eval(opt) if err != nil { return "", err } + src = template.HTML(opt.ImageSource(string(src))) if a.source == nil { return template.HTML(fmt.Sprintf(`
%s
`, alt, src)), nil } var s template.HTML for _, c := range a.source { - ct, err := c.Eval() + ct, err := c.Eval(opt) if err != nil { return "", err } diff --git a/markdown/ast_external_test.go b/markdown/ast_external_test.go index 306b9d0..19abf29 100644 --- a/markdown/ast_external_test.go +++ b/markdown/ast_external_test.go @@ -8,7 +8,7 @@ func TestExternal(t *testing.T) { if err != nil { t.Fatal(err) } - got, err := tree.Eval() + got, err := tree.Eval(nil) if err != nil { t.Fatal(err) } @@ -21,7 +21,7 @@ func TestExternal(t *testing.T) { if err != nil { t.Fatal(err) } - got, err = tree.Eval() + got, err = tree.Eval(nil) if err != nil { t.Fatal(err) } @@ -40,7 +40,7 @@ Hors de la source if err != nil { t.Fatal(err) } - got, err = tree.Eval() + got, err = tree.Eval(nil) if err != nil { t.Fatal(err) } diff --git a/markdown/ast_header.go b/markdown/ast_header.go index d51b046..716a4a6 100644 --- a/markdown/ast_header.go +++ b/markdown/ast_header.go @@ -13,12 +13,12 @@ type astHeader struct { content *astParagraph } -func (a *astHeader) Eval() (template.HTML, *ParseError) { +func (a *astHeader) Eval(opt *Option) (template.HTML, *ParseError) { if a.level > 6 { return "", &ParseError{lxs: lexers{}, internal: ErrInvalidCodeFormat} } var content template.HTML - content, err := a.content.Eval() + content, err := a.content.Eval(opt) if err != nil { return "", err } diff --git a/markdown/ast_list.go b/markdown/ast_list.go index 9aa36e7..b82df67 100644 --- a/markdown/ast_list.go +++ b/markdown/ast_list.go @@ -20,10 +20,10 @@ type astList struct { content []*astParagraph } -func (a *astList) Eval() (template.HTML, *ParseError) { +func (a *astList) Eval(opt *Option) (template.HTML, *ParseError) { var content template.HTML for _, c := range a.content { - ct, err := c.Eval() + ct, err := c.Eval(opt) if err != nil { return "", err } diff --git a/markdown/ast_list_test.go b/markdown/ast_list_test.go index 2819814..f33a229 100644 --- a/markdown/ast_list_test.go +++ b/markdown/ast_list_test.go @@ -32,7 +32,7 @@ func TestList(t *testing.T) { if err != nil { t.Fatal(err) } - got, err := tree.Eval() + got, err := tree.Eval(nil) if err != nil { t.Fatal(err) } diff --git a/markdown/ast_modifier.go b/markdown/ast_modifier.go index 205786a..909d25e 100644 --- a/markdown/ast_modifier.go +++ b/markdown/ast_modifier.go @@ -26,10 +26,10 @@ type astModifier struct { super bool } -func (a *astModifier) Eval() (template.HTML, *ParseError) { +func (a *astModifier) Eval(opt *Option) (template.HTML, *ParseError) { var content template.HTML for _, c := range a.content { - ct, err := c.Eval() + ct, err := c.Eval(opt) if err != nil { return "", &ParseError{lxs: lexers{}, internal: err} } diff --git a/markdown/ast_modifier_test.go b/markdown/ast_modifier_test.go index 3cdb955..8ccc860 100644 --- a/markdown/ast_modifier_test.go +++ b/markdown/ast_modifier_test.go @@ -11,7 +11,7 @@ func TestModifier(t *testing.T) { if err != nil { t.Fatal(err) } - c, err := tree.Eval() + c, err := tree.Eval(nil) if err != nil { t.Fatal(err) } diff --git a/markdown/ast_paragraph.go b/markdown/ast_paragraph.go index 8590c3e..ae1f657 100644 --- a/markdown/ast_paragraph.go +++ b/markdown/ast_paragraph.go @@ -15,10 +15,10 @@ type astParagraph struct { oneLine bool } -func (a *astParagraph) Eval() (template.HTML, *ParseError) { +func (a *astParagraph) Eval(opt *Option) (template.HTML, *ParseError) { var content template.HTML for _, c := range a.content { - ct, err := c.Eval() + ct, err := c.Eval(opt) if err != nil { return "", err } @@ -95,6 +95,6 @@ func paragraph(lxs *lexers, oneLine bool) (*astParagraph, *ParseError) { type astLiteral string -func (a astLiteral) Eval() (template.HTML, *ParseError) { +func (a astLiteral) Eval(_ *Option) (template.HTML, *ParseError) { return template.HTML(template.HTMLEscapeString(string(a))), nil } diff --git a/markdown/ast_paragraph_test.go b/markdown/ast_paragraph_test.go index 4479cbc..9155a9b 100644 --- a/markdown/ast_paragraph_test.go +++ b/markdown/ast_paragraph_test.go @@ -9,7 +9,7 @@ func TestParagraph(t *testing.T) { if err != nil { t.Fatal(err) } - c, err := tree.Eval() + c, err := tree.Eval(nil) if err != nil { t.Fatal(err) } diff --git a/markdown/ast_quote.go b/markdown/ast_quote.go index 3040636..ebd0527 100644 --- a/markdown/ast_quote.go +++ b/markdown/ast_quote.go @@ -11,10 +11,10 @@ type astQuote struct { source []*astParagraph } -func (a *astQuote) Eval() (template.HTML, *ParseError) { +func (a *astQuote) Eval(opt *Option) (template.HTML, *ParseError) { var quote template.HTML for _, c := range a.quote { - ct, err := c.Eval() + ct, err := c.Eval(opt) if err != nil { return "", err } @@ -23,7 +23,7 @@ func (a *astQuote) Eval() (template.HTML, *ParseError) { quote = template.HTML(fmt.Sprintf("
%s
", trimSpace(quote))) var source template.HTML for _, c := range a.source { - ct, err := c.Eval() + ct, err := c.Eval(opt) if err != nil { return "", err } diff --git a/markdown/ast_quote_test.go b/markdown/ast_quote_test.go index e9a3202..3346174 100644 --- a/markdown/ast_quote_test.go +++ b/markdown/ast_quote_test.go @@ -12,7 +12,7 @@ avec une source if err != nil { t.Fatal(err) } - c, err := tree.Eval() + c, err := tree.Eval(nil) if err != nil { t.Fatal(err) } diff --git a/markdown/ast_test.go b/markdown/ast_test.go index acd6aa7..a75840c 100644 --- a/markdown/ast_test.go +++ b/markdown/ast_test.go @@ -50,7 +50,7 @@ func TestAst(t *testing.T) { if err != nil { t.Fatal(err) } - res, err := tree.Eval() + res, err := tree.Eval(nil) if err != nil { t.Fatal(err) } diff --git a/markdown/error_test.go b/markdown/error_test.go index 6f1ba01..1bd766a 100644 --- a/markdown/error_test.go +++ b/markdown/error_test.go @@ -3,21 +3,21 @@ package markdown import "testing" func TestError(t *testing.T) { - v, err := Parse("**bonsoir") + v, err := Parse("**bonsoir", nil) if err == nil { t.Errorf("expected error, got %s", v) } else { t.Log(err.Pretty()) } - v, err = Parse("bo*nso**ir") + v, err = Parse("bo*nso**ir", nil) if err == nil { t.Errorf("expected error, got %s", v) } else { t.Log(err.Pretty()) } - v, err = Parse("test ``` hehe") + v, err = Parse("test ``` hehe", nil) if err == nil { t.Errorf("expected error, got %s", v) } else { diff --git a/markdown/eval.go b/markdown/eval.go index db9d150..56bb989 100644 --- a/markdown/eval.go +++ b/markdown/eval.go @@ -2,15 +2,25 @@ package markdown import "html/template" -func Parse(s string) (template.HTML, *ParseError) { +type Option struct { + ImageSource func(string) string +} + +func Parse(s string, opt *Option) (template.HTML, *ParseError) { lxs := lex(s) tree, err := ast(lxs) if err != nil { return "", err } - return tree.Eval() + if opt == nil { + opt = new(Option) + } + if opt.ImageSource == nil { + opt.ImageSource = func(s string) string { return s } + } + return tree.Eval(opt) } -func ParseBytes(b []byte) (template.HTML, *ParseError) { - return Parse(string(b)) +func ParseBytes(b []byte, opt *Option) (template.HTML, *ParseError) { + return Parse(string(b), opt) } -- cgit v1.2.3