🎨 Highlight regular expression search results https://github.com/siyuan-note/siyuan/issues/11112

This commit is contained in:
Daniel 2024-09-21 17:29:01 +08:00
parent 783c8a092b
commit eb84c1f90f
No known key found for this signature in database
GPG key ID: 86211BA83DF03017
3 changed files with 77 additions and 5 deletions

View file

@ -804,12 +804,16 @@ func GetDoc(startID, endID, id string, index int, query string, queryTypes map[s
subTree := &parse.Tree{ID: rootID, Root: &ast.Node{Type: ast.NodeDocument}, Marks: tree.Marks}
var keywords []string
if "" != query && (0 == queryMethod || 1 == queryMethod) { // 只有关键字搜索和查询语法搜索才支持高亮
if "" != query && (0 == queryMethod || 1 == queryMethod || 3 == queryMethod) { // 只有关键字、查询语法和正则表达式搜索支持高亮
if 0 == queryMethod {
query = stringQuery(query)
}
typeFilter := buildTypeFilter(queryTypes)
keywords = highlightByQuery(query, typeFilter, rootID)
if 0 == queryMethod || 1 == queryMethod {
keywords = highlightByFTS(query, typeFilter, rootID)
} else {
keywords = highlightByRegexp(query, typeFilter, rootID)
}
}
for _, n := range nodes {

View file

@ -1290,8 +1290,8 @@ func fullTextSearchByRegexp(exp, boxFilter, pathFilter, typeFilter, orderBy stri
stmt := "SELECT * FROM `blocks` WHERE " + fieldFilter + " AND type IN " + typeFilter
stmt += boxFilter + pathFilter
stmt += " " + orderBy
stmt += " LIMIT " + strconv.Itoa(pageSize) + " OFFSET " + strconv.Itoa((page-1)*pageSize)
blocks := sql.SelectBlocksRawStmtNoParse(stmt, Conf.Search.Limit)
regex := regexp.MustCompile(exp)
blocks := sql.SelectBlocksRegex(stmt, regex, Conf.Search.Name, Conf.Search.Alias, Conf.Search.Memo, Conf.Search.IAL, page, pageSize)
ret = fromSQLBlocks(&blocks, "", beforeLen)
if 1 > len(ret) {
ret = []*Block{}
@ -1354,7 +1354,7 @@ func fullTextSearchByFTS(query, boxFilter, pathFilter, typeFilter, orderBy strin
return
}
func highlightByQuery(query, typeFilter, id string) (ret []string) {
func highlightByFTS(query, typeFilter, id string) (ret []string) {
const limit = 256
table := "blocks_fts"
if !Conf.Search.CaseSensitive {
@ -1383,6 +1383,22 @@ func highlightByQuery(query, typeFilter, id string) (ret []string) {
return
}
func highlightByRegexp(query, typeFilter, id string) (ret []string) {
fieldFilter := fieldRegexp(query)
stmt := "SELECT * FROM `blocks` WHERE " + fieldFilter + " AND type IN " + typeFilter
stmt += " AND root_id = '" + id + "'"
regex := regexp.MustCompile(query)
sqlBlocks := sql.SelectBlocksRegex(stmt, regex, Conf.Search.Name, Conf.Search.Alias, Conf.Search.Memo, Conf.Search.IAL, 1, 256)
for _, block := range sqlBlocks {
keyword := gulu.Str.SubstringsBetween(block.Content, search.SearchMarkLeft, search.SearchMarkRight)
if 0 < len(keyword) {
ret = append(ret, keyword...)
}
}
ret = gulu.Str.RemoveDuplicatedElem(ret)
return
}
func fullTextSearchCount(query, boxFilter, pathFilter, typeFilter string) (matchedBlockCount, matchedRootCount int) {
query = filterQueryInvisibleChars(query)
if ast.IsNodeIDPattern(query) {