Signed-off-by: Daniel <845765@qq.com>
This commit is contained in:
Daniel 2025-11-23 11:09:21 +08:00
parent 69c2afbd18
commit 58608d8db5
No known key found for this signature in database
GPG key ID: 86211BA83DF03017

View file

@ -78,48 +78,42 @@ func HTML2Tree(htmlStr string, luteEngine *lute.Lute) (tree *parse.Tree, withMat
return ast.WalkContinue return ast.WalkContinue
} }
if ast.NodeHTMLBlock == n.Type { switch n.Type {
if bytes.HasPrefix(n.Tokens, []byte("<pre ")) && bytes.HasSuffix(n.Tokens, []byte("</pre>")) && bytes.Contains(n.Tokens, []byte("data:image/svg+xml;base64")) { case ast.NodeHTMLBlock:
matches := regexp.MustCompile(`(?sU)<pre [^>]*>(.*)</pre>`).FindSubmatch(n.Tokens) if bytes.HasPrefix(n.Tokens, []byte("<pre ")) && bytes.HasSuffix(n.Tokens, []byte("</pre>")) {
if len(matches) >= 2 { if bytes.Contains(n.Tokens, []byte("data:image/svg+xml;base64")) {
n.Tokens = matches[1] matches := regexp.MustCompile(`(?sU)<pre [^>]*>(.*)</pre>`).FindSubmatch(n.Tokens)
} if len(matches) >= 2 {
subTree := parse.Inline("", n.Tokens, luteEngine.ParseOptions) n.Tokens = matches[1]
if nil != subTree && nil != subTree.Root && nil != subTree.Root.FirstChild {
n.Type = ast.NodeParagraph
var children []*ast.Node
for c := subTree.Root.FirstChild.FirstChild; nil != c; c = c.Next {
children = append(children, c)
} }
for _, c := range children { subTree := parse.Inline("", n.Tokens, luteEngine.ParseOptions)
n.AppendChild(c) if nil != subTree && nil != subTree.Root && nil != subTree.Root.FirstChild {
n.Type = ast.NodeParagraph
var children []*ast.Node
for c := subTree.Root.FirstChild.FirstChild; nil != c; c = c.Next {
children = append(children, c)
}
for _, c := range children {
n.AppendChild(c)
}
} }
} else if bytes.Contains(n.Tokens, []byte("<svg")) {
processHTMLBlockSvgImg(n, assetDirPath)
} }
} }
return ast.WalkContinue case ast.NodeText:
}
if ast.NodeText == n.Type {
if n.ParentIs(ast.NodeTableCell) { if n.ParentIs(ast.NodeTableCell) {
n.Tokens = bytes.ReplaceAll(n.Tokens, []byte("\\|"), []byte("|")) n.Tokens = bytes.ReplaceAll(n.Tokens, []byte("\\|"), []byte("|"))
n.Tokens = bytes.ReplaceAll(n.Tokens, []byte("|"), []byte("\\|")) n.Tokens = bytes.ReplaceAll(n.Tokens, []byte("|"), []byte("\\|"))
n.Tokens = bytes.ReplaceAll(n.Tokens, []byte("\\<br /\\>"), []byte("<br />")) n.Tokens = bytes.ReplaceAll(n.Tokens, []byte("\\<br /\\>"), []byte("<br />"))
} }
} case ast.NodeInlineMath:
if ast.NodeInlineMath == n.Type {
withMath = true withMath = true
return ast.WalkContinue case ast.NodeLinkDest:
} dest := n.TokensStr()
if strings.HasPrefix(dest, "data:image") && strings.Contains(dest, ";base64,") {
if ast.NodeLinkDest != n.Type { processBase64Img(n, dest, assetDirPath)
return ast.WalkContinue }
}
dest := n.TokensStr()
if strings.HasPrefix(dest, "data:image") && strings.Contains(dest, ";base64,") {
processBase64Img(n, dest, assetDirPath)
return ast.WalkContinue
} }
return ast.WalkContinue return ast.WalkContinue
}) })
@ -1234,6 +1228,32 @@ func parseStdMd(markdown []byte) (ret *parse.Tree, yfmRootID, yfmTitle, yfmUpdat
return return
} }
func processHTMLBlockSvgImg(n *ast.Node, assetDirPath string) {
re := regexp.MustCompile(`(?i)<svg[^>]*>(.*?)</svg>`)
matches := re.FindStringSubmatch(string(n.Tokens))
if 1 >= len(matches) {
return
}
svgContent := matches[0]
name := util.AssetName("image.svg", ast.NewNodeID())
writePath := filepath.Join(assetDirPath, name)
if err := filelock.WriteFile(writePath, []byte(svgContent)); err != nil {
logging.LogErrorf("write svg asset file [%s] failed: %s", writePath, err)
return
}
n.Type = ast.NodeParagraph
img := &ast.Node{Type: ast.NodeImage}
img.AppendChild(&ast.Node{Type: ast.NodeBang})
img.AppendChild(&ast.Node{Type: ast.NodeOpenBracket})
img.AppendChild(&ast.Node{Type: ast.NodeLinkText, Tokens: []byte("image")})
img.AppendChild(&ast.Node{Type: ast.NodeCloseBracket})
img.AppendChild(&ast.Node{Type: ast.NodeOpenParen})
img.AppendChild(&ast.Node{Type: ast.NodeLinkDest, Tokens: []byte("assets/" + name)})
img.AppendChild(&ast.Node{Type: ast.NodeCloseParen})
n.AppendChild(img)
}
func processBase64Img(n *ast.Node, dest string, assetDirPath string) { func processBase64Img(n *ast.Node, dest string, assetDirPath string) {
base64TmpDir := filepath.Join(util.TempDir, "base64") base64TmpDir := filepath.Join(util.TempDir, "base64")
os.MkdirAll(base64TmpDir, 0755) os.MkdirAll(base64TmpDir, 0755)