🎨 改进提及和虚拟引用搜索分词 Fix https://github.com/siyuan-note/siyuan/issues/6165

This commit is contained in:
Liang Ding 2022-10-13 01:00:59 +08:00
parent a9a8d041ef
commit 1828ecfde4
No known key found for this signature in database
GPG key ID: 136F30F901A2231D
4 changed files with 51 additions and 29 deletions

View file

@ -300,10 +300,14 @@ func buildBacklink(refID string, refTree *parse.Tree, mentionKeywords []string,
}
if ast.NodeText == n.Type {
text := string(n.Tokens)
text = search.EncloseHighlighting(text, mentionKeywords, "<span data-type=\"search-mark\">", "</span>", Conf.Search.CaseSensitive)
n.Tokens = gulu.Str.ToBytes(text)
newText := markReplaceSpan(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("\\<span data-type=\"search-mark\">"), []byte("\\\\<span data-type=\"search-mark\">"))
n.Tokens = bytes.ReplaceAll(n.Tokens, []byte("\\"+searchMarkSpanStart), []byte("\\\\"+searchMarkSpanEnd))
linkTree := parse.Inline("", n.Tokens, luteEngine.ParseOptions)
var children []*ast.Node
for c := linkTree.Root.FirstChild.FirstChild; nil != c; c = c.Next {
@ -789,8 +793,21 @@ func searchBackmention(mentionKeywords []string, keyword string, excludeBacklink
text = strings.ToLower(text)
var contain bool
for _, mentionKeyword := range mentionKeywords {
if strings.Contains(text, strings.ToLower(mentionKeyword)) {
contain = true
parts := strings.Split(text, " ")
for _, part := range parts {
if gulu.Str.IsASCII(mentionKeyword) {
if part == mentionKeyword {
contain = true
break
}
} else {
if strings.Contains(part, strings.ToLower(mentionKeyword)) {
contain = true
break
}
}
}
if contain {
break
}
}

View file

@ -449,6 +449,8 @@ func StatTree(id string) (ret *util.BlockStatResult) {
}
const (
searchMarkSpanStart = "<span data-type=\"search-mark\">"
searchMarkSpanEnd = "</span>"
virtualBlockRefSpanStart = "<span data-type=\"virtual-block-ref\">"
virtualBlockRefSpanEnd = "</span>"
)
@ -657,10 +659,10 @@ func GetDoc(startID, endID, id string, index int, keyword string, mode int, size
if hitBlock {
// 搜索高亮
text := string(n.Tokens)
text = search.EncloseHighlighting(text, keywords, "<span data-type=\"search-mark\">", "</span>", Conf.Search.CaseSensitive)
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("\\<span data-type=\"search-mark\">"), []byte("\\\\<span data-type=\"search-mark\">"))
n.Tokens = bytes.ReplaceAll(n.Tokens, []byte("\\"+searchMarkSpanStart), []byte("\\\\"+searchMarkSpanEnd))
linkTree := parse.Inline("", n.Tokens, luteEngine.ParseOptions)
var children []*ast.Node
for c := linkTree.Root.FirstChild.FirstChild; nil != c; c = c.Next {
@ -680,26 +682,7 @@ func GetDoc(startID, endID, id string, index int, keyword string, mode int, size
parentBlock := treenode.ParentBlock(n)
if nil != parentBlock && 1 > refCount[parentBlock.ID] {
content := string(n.Tokens)
parts := strings.Split(content, " ")
for i, part := range parts {
if "" == part {
continue
}
for _, k := range virtualBlockRefKeywords {
if gulu.Str.IsASCII(k) {
if part == k {
parts[i] = virtualBlockRefSpanStart + k + virtualBlockRefSpanEnd
}
} else {
if strings.Contains(part, k) {
parts[i] = strings.ReplaceAll(part, k, virtualBlockRefSpanStart+k+virtualBlockRefSpanEnd)
}
}
}
}
newContent := strings.Join(parts, " ")
newContent := markReplaceSpan(content, virtualBlockRefKeywords, virtualBlockRefSpanStart, virtualBlockRefSpanEnd)
if content != newContent {
// 虚拟引用排除命中自身块命名和别名的情况 https://github.com/siyuan-note/siyuan/issues/3185
var blockKeys []string

View file

@ -182,10 +182,10 @@ func GetDocHistoryContent(historyPath, keyword string) (id, rootID, content stri
if 0 < len(keywords) {
// 搜索高亮
text := string(n.Tokens)
text = search.EncloseHighlighting(text, keywords, "<span data-type=\"search-mark\">", "</span>", false)
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("\\<span data-type=\"search-mark\">"), []byte("\\\\<span data-type=\"search-mark\">"))
n.Tokens = bytes.ReplaceAll(n.Tokens, []byte("\\"+searchMarkSpanStart), []byte("\\\\"+searchMarkSpanStart))
linkTree := parse.Inline("", n.Tokens, luteEngine.ParseOptions)
var children []*ast.Node
for c := linkTree.Root.FirstChild.FirstChild; nil != c; c = c.Next {

View file

@ -639,3 +639,25 @@ func stringQuery(query string) string {
}
return strings.TrimSpace(buf.String())
}
func markReplaceSpan(text string, keywords []string, replacementStart, replacementEnd string) string {
parts := strings.Split(text, " ")
for i, part := range parts {
if "" == part {
continue
}
for _, k := range keywords {
if gulu.Str.IsASCII(k) {
if part == k {
parts[i] = replacementStart + k + replacementEnd
}
} else {
if strings.Contains(part, k) {
parts[i] = strings.ReplaceAll(part, k, replacementStart+k+replacementEnd)
}
}
}
}
return strings.Join(parts, " ")
}