Skip to content

Commit

Permalink
修复连续的图片中后续的图片渲染错误的问题
Browse files Browse the repository at this point in the history
见:<https://blog.twofei.com/902/#comment-1221>。

根因:遍历语法树的时候替换了节点导致遍历节点提前退出。
  • Loading branch information
movsb committed Apr 22, 2024
1 parent ac7e805 commit 9f0ca6f
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 33 deletions.
12 changes: 11 additions & 1 deletion service/modules/renderers/all_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,20 @@ func TestMarkdownAll(t *testing.T) {
Markdown: `[](#section)`,
Html: `<p><a href="#section"></a></p>`,
},
{
ID: 6.0,
Markdown: `
![样式1](1.jpg "样式1")
![样式2](2.jpg "样式2")
![样式3](3.jpg '样式3"><a>"')`,
Html: `<p><img src="1.jpg" alt="样式1" title="样式1" loading="lazy" />
<img src="2.jpg" alt="样式2" title="样式2" loading="lazy" />
<img src="3.jpg" alt="样式3" title="样式3&quot;&gt;&lt;a&gt;&quot;" loading="lazy" /></p>`,
},
}
for _, tc := range cases {
md := renderers.NewMarkdown(tc.Options...)
if tc.ID == 2.1 {
if tc.ID == 6.0 {
log.Println(`debug`)
}
_, html, err := md.Render(tc.Markdown)
Expand Down
47 changes: 15 additions & 32 deletions service/modules/renderers/markdown.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,6 @@ type _Markdown struct {
modifiedAnchorReference string
}

var (
imageKind ast.NodeKind
)

func init() {
imageKind = ast.NewNodeKind(`image`)
}

type Option func(me *_Markdown) error

// 解析 Markdown 中的相对链接。
Expand Down Expand Up @@ -118,6 +110,9 @@ func (me *_Markdown) Render(source string) (string, string, error) {
md := goldmark.New(
goldmark.WithRendererOptions(
html.WithUnsafe(),
renderer.WithNodeRenderers(
util.Prioritized(me, 100),
),
),
goldmark.WithExtensions(extension.GFM),
goldmark.WithExtensions(extension.DefinitionList),
Expand Down Expand Up @@ -165,13 +160,6 @@ func (me *_Markdown) Render(source string) (string, string, error) {
if err := ast.Walk(doc, func(n ast.Node, entering bool) (ast.WalkStatus, error) {
if entering {
switch n.Kind() {
case ast.KindImage:
oldImage := n.(*ast.Image)
newImage := &_Image{
image: oldImage,
}
parent := n.Parent()
parent.ReplaceChild(parent, oldImage, newImage)
case ast.KindHeading:
if me.disableHeadings {
return ast.WalkStop, status.Errorf(codes.InvalidArgument, `Markdown 不能包含标题元素。`)
Expand Down Expand Up @@ -208,38 +196,28 @@ func (me *_Markdown) Render(source string) (string, string, error) {
return ``, ``, err
}

rdr := md.Renderer()
if reg, ok := rdr.(renderer.NodeRendererFuncRegisterer); ok {
reg.Register(imageKind, me.renderImage)
}

buf := bytes.NewBuffer(nil)
err := rdr.Render(buf, []byte(source), doc)
err := md.Renderer().Render(buf, []byte(source), doc)
return title, buf.String(), err
}

type _Image struct {
ast.BaseBlock
image *ast.Image
func (me *_Markdown) RegisterFuncs(r renderer.NodeRendererFuncRegisterer) {
r.Register(ast.KindImage, me.renderImage)
}

func (n *_Image) Dump(source []byte, level int) { ast.DumpHelper(n, source, level, nil, nil) }
func (n *_Image) Type() ast.NodeType { return ast.TypeInline }
func (n *_Image) Kind() ast.NodeKind { return imageKind }

func (me *_Markdown) renderImage(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
if !entering {
return ast.WalkContinue, nil
}

n := node.(*_Image)
n := node.(*ast.Image)

// 解析可能的自定义。
// 不是很严格,可能有转义错误。
url, _ := url.Parse(string(n.image.Destination))
url, _ := url.Parse(string(n.Destination))
if url == nil {
w.WriteString(`<img />`)
log.Println(`图片地址解析失败:`, string(n.image.Destination))
log.Println(`图片地址解析失败:`, string(n.Destination))
return ast.WalkContinue, nil
}

Expand All @@ -264,8 +242,13 @@ func (me *_Markdown) renderImage(w util.BufWriter, source []byte, node ast.Node,
// TODO 不知道 escape 几次了个啥。
_, _ = w.Write(util.EscapeHTML(util.URLEscape([]byte(url.String()), true)))
_, _ = w.WriteString(`" alt="`)
_, _ = w.Write(nodeToHTMLText(n.image, source))
_, _ = w.Write(nodeToHTMLText(n, source))
_ = w.WriteByte('"')
if n.Title != nil {
_, _ = w.WriteString(` title="`)
w.Write(util.EscapeHTML(n.Title))
_ = w.WriteByte('"')
}
if n.Attributes() != nil {
html.RenderAttributes(w, n, html.ImageAttributeFilter)
}
Expand Down

0 comments on commit 9f0ca6f

Please sign in to comment.