From 4b6b4183ae9955f9323cf4070f1603e8ea26e6d6 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Sat, 20 Apr 2024 09:34:18 +0800 Subject: [PATCH 1/2] :art: Improve find replace doc title --- kernel/model/search.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kernel/model/search.go b/kernel/model/search.go index 76c65381a..1b812d998 100644 --- a/kernel/model/search.go +++ b/kernel/model/search.go @@ -522,12 +522,14 @@ func FindReplace(keyword, replacement string, replaceTypes map[string]bool, ids title := node.IALAttr("title") if 0 == method { if strings.Contains(title, keyword) { - renameRootTitles[node.ID] = strings.ReplaceAll(title, keyword, replacement) + docTitleReplacement := strings.ReplaceAll(replacement, "/", "") + renameRootTitles[node.ID] = strings.ReplaceAll(title, keyword, docTitleReplacement) renameRoots = append(renameRoots, node) } } else if 3 == method { if nil != r && r.MatchString(title) { - renameRootTitles[node.ID] = r.ReplaceAllString(title, replacement) + docTitleReplacement := strings.ReplaceAll(replacement, "/", "") + renameRootTitles[node.ID] = r.ReplaceAllString(title, docTitleReplacement) renameRoots = append(renameRoots, node) } } From d1647f9222618ffd76fc2bcade6222c7f470bfef Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Sat, 20 Apr 2024 10:02:44 +0800 Subject: [PATCH 2/2] :art: Supports replacing text elements with other elements https://github.com/siyuan-note/siyuan/issues/11058 --- kernel/model/search.go | 54 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/kernel/model/search.go b/kernel/model/search.go index 1b812d998..f1849adbe 100644 --- a/kernel/model/search.go +++ b/kernel/model/search.go @@ -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)) {