🎨 Supports replacing text elements with other elements https://github.com/siyuan-note/siyuan/issues/11058

This commit is contained in:
Daniel 2024-04-20 10:02:44 +08:00
parent 4b6b4183ae
commit d1647f9222
No known key found for this signature in database
GPG key ID: 86211BA83DF03017

View file

@ -534,6 +534,8 @@ func FindReplace(keyword, replacement string, replaceTypes map[string]bool, ids
}
}
} else {
luteEngine := util.NewLute()
var unlinks []*ast.Node
ast.Walk(node, func(n *ast.Node, entering bool) ast.WalkStatus {
if !entering {
return ast.WalkContinue
@ -545,7 +547,9 @@ func FindReplace(keyword, replacement string, replaceTypes map[string]bool, ids
return ast.WalkContinue
}
replaceNodeTokens(n, method, keyword, replacement, r)
if replaceTextNode(n, method, keyword, replacement, r, luteEngine) {
unlinks = append(unlinks, n)
}
case ast.NodeLinkDest:
if !replaceTypes["imgSrc"] {
return ast.WalkContinue
@ -728,6 +732,10 @@ func FindReplace(keyword, replacement string, replaceTypes map[string]bool, ids
return ast.WalkContinue
})
for _, unlink := range unlinks {
unlink.Unlink()
}
if err = writeTreeUpsertQueue(tree); nil != err {
return
}
@ -765,6 +773,50 @@ func replaceNodeTextMarkTextContent(n *ast.Node, method int, keyword string, rep
}
}
// replaceTextNode 替换文本节点为其他节点。
// Supports replacing text elements with other elements https://github.com/siyuan-note/siyuan/issues/11058
func replaceTextNode(text *ast.Node, method int, keyword string, replacement string, r *regexp.Regexp, luteEngine *lute.Lute) bool {
if 0 == method {
if bytes.Contains(text.Tokens, []byte(keyword)) {
newContent := bytes.ReplaceAll(text.Tokens, []byte(keyword), []byte(replacement))
tree := parse.Inline("", newContent, luteEngine.ParseOptions)
if nil == tree.Root.FirstChild {
return false
}
parse.NestedInlines2FlattedSpans(tree, false)
var replaceNodes []*ast.Node
for rNode := tree.Root.FirstChild.FirstChild; nil != rNode; rNode = rNode.Next {
replaceNodes = append(replaceNodes, rNode)
}
for _, rNode := range replaceNodes {
text.InsertBefore(rNode)
}
return true
}
} else if 3 == method {
if nil != r && r.MatchString(string(text.Tokens)) {
newContent := bytes.ReplaceAll(text.Tokens, []byte(keyword), []byte(replacement))
tree := parse.Inline("", newContent, luteEngine.ParseOptions)
if nil == tree.Root.FirstChild {
return false
}
var replaceNodes []*ast.Node
for rNode := tree.Root.FirstChild; nil != rNode; rNode = rNode.Next {
replaceNodes = append(replaceNodes, rNode)
}
for _, rNode := range replaceNodes {
text.InsertBefore(rNode)
}
return true
}
}
return false
}
func replaceNodeTokens(n *ast.Node, method int, keyword string, replacement string, r *regexp.Regexp) {
if 0 == method {
if bytes.Contains(n.Tokens, []byte(keyword)) {