|
@@ -534,6 +534,8 @@ func FindReplace(keyword, replacement string, replaceTypes map[string]bool, ids
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
|
|
+ luteEngine := util.NewLute()
|
|
|
|
+ var unlinks []*ast.Node
|
|
ast.Walk(node, func(n *ast.Node, entering bool) ast.WalkStatus {
|
|
ast.Walk(node, func(n *ast.Node, entering bool) ast.WalkStatus {
|
|
if !entering {
|
|
if !entering {
|
|
return ast.WalkContinue
|
|
return ast.WalkContinue
|
|
@@ -545,7 +547,9 @@ func FindReplace(keyword, replacement string, replaceTypes map[string]bool, ids
|
|
return ast.WalkContinue
|
|
return ast.WalkContinue
|
|
}
|
|
}
|
|
|
|
|
|
- replaceNodeTokens(n, method, keyword, replacement, r)
|
|
|
|
|
|
+ if replaceTextNode(n, method, keyword, replacement, r, luteEngine) {
|
|
|
|
+ unlinks = append(unlinks, n)
|
|
|
|
+ }
|
|
case ast.NodeLinkDest:
|
|
case ast.NodeLinkDest:
|
|
if !replaceTypes["imgSrc"] {
|
|
if !replaceTypes["imgSrc"] {
|
|
return ast.WalkContinue
|
|
return ast.WalkContinue
|
|
@@ -728,6 +732,10 @@ func FindReplace(keyword, replacement string, replaceTypes map[string]bool, ids
|
|
return ast.WalkContinue
|
|
return ast.WalkContinue
|
|
})
|
|
})
|
|
|
|
|
|
|
|
+ for _, unlink := range unlinks {
|
|
|
|
+ unlink.Unlink()
|
|
|
|
+ }
|
|
|
|
+
|
|
if err = writeTreeUpsertQueue(tree); nil != err {
|
|
if err = writeTreeUpsertQueue(tree); nil != err {
|
|
return
|
|
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) {
|
|
func replaceNodeTokens(n *ast.Node, method int, keyword string, replacement string, r *regexp.Regexp) {
|
|
if 0 == method {
|
|
if 0 == method {
|
|
if bytes.Contains(n.Tokens, []byte(keyword)) {
|
|
if bytes.Contains(n.Tokens, []byte(keyword)) {
|