From 0b4631791084d9d443ce002a124ca266c305d169 Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Wed, 26 Oct 2022 09:51:09 +0800 Subject: [PATCH] =?UTF-8?q?:recycle:=20=E9=87=8D=E6=9E=84=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=E9=AB=98=E4=BA=AE=E6=A0=87=E8=AE=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/model/backlink.go | 5 ++- kernel/model/file.go | 69 +++------------------------------------- kernel/model/history.go | 19 +---------- kernel/model/search.go | 33 +++++++++++-------- 4 files changed, 28 insertions(+), 98 deletions(-) diff --git a/kernel/model/backlink.go b/kernel/model/backlink.go index 5b1b6d38f..66da9cc01 100644 --- a/kernel/model/backlink.go +++ b/kernel/model/backlink.go @@ -301,14 +301,13 @@ func buildBacklink(refID string, refTree *parse.Tree, mentionKeywords []string, } if ast.NodeText == n.Type { text := string(n.Tokens) - newText := markReplaceSpan(text, mentionKeywords, searchMarkSpanStart, searchMarkSpanEnd) + newText := markReplaceSpanWithSplit(text, mentionKeywords, searchMarkSpanStart, searchMarkSpanEnd) if text == newText { return ast.WalkContinue } n.Tokens = gulu.Str.ToBytes(newText) if bytes.Contains(n.Tokens, []byte("search-mark")) { - n.Tokens = bytes.ReplaceAll(n.Tokens, []byte("\\"+searchMarkSpanStart), []byte("\\\\"+searchMarkSpanEnd)) n.Tokens = lex.EscapeMarkers(n.Tokens) linkTree := parse.Inline("", n.Tokens, luteEngine.ParseOptions) var children []*ast.Node @@ -794,7 +793,7 @@ func searchBackmention(mentionKeywords []string, keyword string, excludeBacklink continue } - newText := markReplaceSpan(text, mentionKeywords, searchMarkSpanStart, searchMarkSpanEnd) + newText := markReplaceSpanWithSplit(text, mentionKeywords, searchMarkSpanStart, searchMarkSpanEnd) if text != newText { tmp = append(tmp, b) } diff --git a/kernel/model/file.go b/kernel/model/file.go index bf4f6ae83..55c28e850 100644 --- a/kernel/model/file.go +++ b/kernel/model/file.go @@ -17,7 +17,6 @@ package model import ( - "bytes" "errors" "fmt" "io/fs" @@ -34,7 +33,6 @@ import ( "github.com/88250/gulu" "github.com/88250/lute/ast" "github.com/88250/lute/html" - "github.com/88250/lute/lex" "github.com/88250/lute/parse" util2 "github.com/88250/lute/util" "github.com/dustin/go-humanize" @@ -598,15 +596,9 @@ func GetDoc(startID, endID, id string, index int, keyword string, mode int, size } else { nodes, eof = loadNodesByMode(node, inputIndex, mode, size, isDoc, isHeading) } - refCount := sql.QueryRootChildrenRefCount(rootID) - var virtualBlockRefKeywords []string - if Conf.Editor.VirtualBlockRef { - virtualBlockRefKeywords = getVirtualRefKeywords() - // 虚拟引用排除当前文档名 https://github.com/siyuan-note/siyuan/issues/4537 - virtualBlockRefKeywords = gulu.Str.ExcludeElem(virtualBlockRefKeywords, []string{tree.Root.IALAttr("title")}) - virtualBlockRefKeywords = prepareMarkKeywords(virtualBlockRefKeywords) - } + refCount := sql.QueryRootChildrenRefCount(rootID) + virtualBlockRefKeywords := getVirtualRefKeywords(tree.Root.IALAttr("title")) subTree := &parse.Tree{ID: rootID, Root: &ast.Node{Type: ast.NodeDocument}, Marks: tree.Marks} keyword = strings.Join(strings.Split(keyword, " "), search.TermSep) @@ -648,65 +640,14 @@ func GetDoc(startID, endID, id string, index int, keyword string, mode int, size } } if hitBlock { - // 搜索高亮 - text := string(n.Tokens) - text = search.EncloseHighlighting(text, keywords, searchMarkSpanStart, searchMarkSpanEnd, Conf.Search.CaseSensitive) - n.Tokens = gulu.Str.ToBytes(text) - if bytes.Contains(n.Tokens, []byte("search-mark")) { - n.Tokens = bytes.ReplaceAll(n.Tokens, []byte("\\"+searchMarkSpanStart), []byte("\\\\"+searchMarkSpanEnd)) - n.Tokens = lex.EscapeMarkers(n.Tokens) - linkTree := parse.Inline("", n.Tokens, luteEngine.ParseOptions) - var children []*ast.Node - for c := linkTree.Root.FirstChild.FirstChild; nil != c; c = c.Next { - children = append(children, c) - } - for _, c := range children { - n.InsertBefore(c) - } - unlinks = append(unlinks, n) + if markReplaceSpan(n, &unlinks, string(n.Tokens), keywords, searchMarkSpanStart, searchMarkSpanEnd, luteEngine) { return ast.WalkContinue } } } - // 虚拟引用 - if Conf.Editor.VirtualBlockRef && 0 < len(virtualBlockRefKeywords) { - parentBlock := treenode.ParentBlock(n) - if nil != parentBlock && 1 > refCount[parentBlock.ID] { - content := string(n.Tokens) - newContent := markReplaceSpan(content, virtualBlockRefKeywords, virtualBlockRefSpanStart, virtualBlockRefSpanEnd) - if content != newContent { - // 虚拟引用排除命中自身块命名和别名的情况 https://github.com/siyuan-note/siyuan/issues/3185 - var blockKeys []string - if name := parentBlock.IALAttr("name"); "" != name { - blockKeys = append(blockKeys, name) - } - if alias := parentBlock.IALAttr("alias"); "" != alias { - blockKeys = append(blockKeys, alias) - } - if 0 < len(blockKeys) { - keys := gulu.Str.SubstringsBetween(newContent, virtualBlockRefSpanStart, virtualBlockRefSpanEnd) - for _, k := range keys { - if gulu.Str.Contains(k, blockKeys) { - return ast.WalkContinue - } - } - } - - n.Tokens = []byte(newContent) - n.Tokens = lex.EscapeMarkers(n.Tokens) - linkTree := parse.Inline("", n.Tokens, luteEngine.ParseOptions) - var children []*ast.Node - for c := linkTree.Root.FirstChild.FirstChild; nil != c; c = c.Next { - children = append(children, c) - } - for _, c := range children { - n.InsertBefore(c) - } - unlinks = append(unlinks, n) - return ast.WalkContinue - } - } + if processVirtualRef(n, &unlinks, virtualBlockRefKeywords, refCount, luteEngine) { + return ast.WalkContinue } } return ast.WalkContinue diff --git a/kernel/model/history.go b/kernel/model/history.go index 7a7945fc9..78d735e6f 100644 --- a/kernel/model/history.go +++ b/kernel/model/history.go @@ -17,7 +17,6 @@ package model import ( - "bytes" "encoding/json" "fmt" "io/fs" @@ -32,7 +31,6 @@ import ( "github.com/88250/gulu" "github.com/88250/lute" "github.com/88250/lute/ast" - "github.com/88250/lute/lex" "github.com/88250/lute/parse" "github.com/88250/lute/render" "github.com/siyuan-note/filelock" @@ -181,22 +179,7 @@ func GetDocHistoryContent(historyPath, keyword string) (id, rootID, content stri if ast.NodeText == n.Type { if 0 < len(keywords) { - // 搜索高亮 - text := string(n.Tokens) - text = search.EncloseHighlighting(text, keywords, searchMarkSpanStart, searchMarkSpanEnd, false) - n.Tokens = gulu.Str.ToBytes(text) - if bytes.Contains(n.Tokens, []byte("search-mark")) { - n.Tokens = bytes.ReplaceAll(n.Tokens, []byte("\\"+searchMarkSpanStart), []byte("\\\\"+searchMarkSpanStart)) - n.Tokens = lex.EscapeMarkers(n.Tokens) - linkTree := parse.Inline("", n.Tokens, luteEngine.ParseOptions) - var children []*ast.Node - for c := linkTree.Root.FirstChild.FirstChild; nil != c; c = c.Next { - children = append(children, c) - } - for _, c := range children { - n.InsertBefore(c) - } - unlinks = append(unlinks, n) + if markReplaceSpan(n, &unlinks, string(n.Tokens), keywords, searchMarkSpanStart, searchMarkSpanEnd, luteEngine) { return ast.WalkContinue } } diff --git a/kernel/model/search.go b/kernel/model/search.go index 760d119a0..5994fa606 100644 --- a/kernel/model/search.go +++ b/kernel/model/search.go @@ -19,15 +19,16 @@ package model import ( "bytes" "path" - "sort" "strconv" "strings" "time" "unicode/utf8" "github.com/88250/gulu" + "github.com/88250/lute" "github.com/88250/lute/ast" "github.com/88250/lute/html" + "github.com/88250/lute/lex" "github.com/88250/lute/parse" "github.com/jinzhu/copier" "github.com/siyuan-note/logging" @@ -642,22 +643,28 @@ func stringQuery(query string) string { return strings.TrimSpace(buf.String()) } -func prepareMarkKeywords(keywords []string) (ret []string) { - keywords = gulu.Str.RemoveDuplicatedElem(keywords) - for _, k := range keywords { - if strings.ContainsAny(k, "?*!@#$%^&()[]{}\\|;:'\",.<>~`") { - continue +// markReplaceSpan 用于处理搜索高亮。 +func markReplaceSpan(n *ast.Node, unlinks *[]*ast.Node, text string, keywords []string, replacementStart, replacementEnd string, luteEngine *lute.Lute) bool { + text = search.EncloseHighlighting(text, keywords, searchMarkSpanStart, searchMarkSpanEnd, Conf.Search.CaseSensitive) + n.Tokens = gulu.Str.ToBytes(text) + if bytes.Contains(n.Tokens, []byte("search-mark")) { + n.Tokens = lex.EscapeMarkers(n.Tokens) + linkTree := parse.Inline("", n.Tokens, luteEngine.ParseOptions) + var children []*ast.Node + for c := linkTree.Root.FirstChild.FirstChild; nil != c; c = c.Next { + children = append(children, c) } - ret = append(ret, k) + for _, c := range children { + n.InsertBefore(c) + } + *unlinks = append(*unlinks, n) + return true } - - sort.SliceStable(ret, func(i, j int) bool { - return len(ret[i]) < len(ret[j]) - }) - return + return false } -func markReplaceSpan(text string, keywords []string, replacementStart, replacementEnd string) (ret string) { +// markReplaceSpanWithSplit 用于处理虚拟引用和反链提及高亮。 +func markReplaceSpanWithSplit(text string, keywords []string, replacementStart, replacementEnd string) (ret string) { // 调用该函数前参数 keywords 必须使用 prepareMarkKeywords 函数进行预处理 parts := strings.Split(text, " ")