mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-16 14:40:12 +01:00
Improve virtual reference keyword handling and support line breaks (#16298)
* 🎨 Improve virtual reference keyword handling and support line breaks https://ld246.com/article/1762474775795 * Update text
This commit is contained in:
parent
5ccb95ae4e
commit
f35761c1ab
18 changed files with 110 additions and 54 deletions
|
|
@ -45,6 +45,9 @@ var virtualBlockRefCache, _ = ristretto.NewCache(&ristretto.Config{
|
|||
BufferItems: 64,
|
||||
})
|
||||
|
||||
// newlineRegexp 用于匹配连续或单个换行符的正则表达式
|
||||
var newlineRegexp = regexp.MustCompile(`[\r\n]+`)
|
||||
|
||||
func getBlockVirtualRefKeywords(root *ast.Node) (ret []string) {
|
||||
val, ok := virtualBlockRefCache.Get(root.ID)
|
||||
if !ok {
|
||||
|
|
@ -121,18 +124,54 @@ func ResetVirtualBlockRefCache() {
|
|||
virtualBlockRefCache.Set("virtual_ref", keywords, 1)
|
||||
}
|
||||
|
||||
// addNewKeywords 将新关键字添加到虚拟引用关键字列表中,如果不存在则追加,保留空白字符
|
||||
func addNewKeywords(keywordsStr string, newKeywords []string) string {
|
||||
keywordsStr = strings.TrimSpace(keywordsStr)
|
||||
if 0 == len(newKeywords) {
|
||||
return keywordsStr
|
||||
}
|
||||
|
||||
var builder strings.Builder
|
||||
if "" != keywordsStr {
|
||||
if !strings.HasSuffix(keywordsStr, "\\,") {
|
||||
keywordsStr = strings.TrimSuffix(keywordsStr, ",")
|
||||
}
|
||||
builder.WriteString(keywordsStr)
|
||||
builder.WriteString(",")
|
||||
}
|
||||
|
||||
keywords := gulu.Str.RemoveDuplicatedElem(parseKeywords(keywordsStr))
|
||||
newKeywords = gulu.Str.RemoveDuplicatedElem(newKeywords)
|
||||
allKeys := make(map[string]bool)
|
||||
|
||||
// 添加新关键字
|
||||
for _, keyword := range newKeywords {
|
||||
keywordTrimmed := strings.TrimSpace(keyword)
|
||||
if "" == keywordTrimmed {
|
||||
continue
|
||||
}
|
||||
if gulu.Str.Contains(keywordTrimmed, keywords) {
|
||||
// 剔除已存在的关键字
|
||||
continue
|
||||
}
|
||||
if _, value := allKeys[keywordTrimmed]; value {
|
||||
// 剔除重复的关键字
|
||||
continue
|
||||
}
|
||||
allKeys[keywordTrimmed] = true
|
||||
builder.WriteString(strings.ReplaceAll(keyword, ",", "\\,")) // 字符串切片转换为字符串,需要转义逗号
|
||||
builder.WriteString(",")
|
||||
}
|
||||
|
||||
return strings.TrimSuffix(builder.String(), ",")
|
||||
}
|
||||
|
||||
func AddVirtualBlockRefInclude(keyword []string) {
|
||||
if 1 > len(keyword) {
|
||||
return
|
||||
}
|
||||
|
||||
include := strings.ReplaceAll(Conf.Editor.VirtualBlockRefInclude, "\\,", "__comma@sep__")
|
||||
includes := strings.Split(include, ",")
|
||||
includes = append(includes, keyword...)
|
||||
includes = gulu.Str.RemoveDuplicatedElem(includes)
|
||||
Conf.Editor.VirtualBlockRefInclude = strings.Join(includes, ",")
|
||||
Conf.Editor.VirtualBlockRefInclude = addNewKeywords(Conf.Editor.VirtualBlockRefInclude, keyword)
|
||||
Conf.Save()
|
||||
|
||||
ResetVirtualBlockRefCache()
|
||||
}
|
||||
|
||||
|
|
@ -140,14 +179,8 @@ func AddVirtualBlockRefExclude(keyword []string) {
|
|||
if 1 > len(keyword) {
|
||||
return
|
||||
}
|
||||
|
||||
exclude := strings.ReplaceAll(Conf.Editor.VirtualBlockRefExclude, "\\,", "__comma@sep__")
|
||||
excludes := strings.Split(exclude, ",")
|
||||
excludes = append(excludes, keyword...)
|
||||
excludes = gulu.Str.RemoveDuplicatedElem(excludes)
|
||||
Conf.Editor.VirtualBlockRefExclude = strings.Join(excludes, ",")
|
||||
Conf.Editor.VirtualBlockRefExclude = addNewKeywords(Conf.Editor.VirtualBlockRefExclude, keyword)
|
||||
Conf.Save()
|
||||
|
||||
ResetVirtualBlockRefCache()
|
||||
}
|
||||
|
||||
|
|
@ -213,6 +246,30 @@ func processVirtualRef(n *ast.Node, unlinks *[]*ast.Node, virtualBlockRefKeyword
|
|||
return false
|
||||
}
|
||||
|
||||
// parseKeywords 将字符串转换为关键字切片,并剔除前后的空白字符
|
||||
func parseKeywords(keywordsStr string) (keywords []string) {
|
||||
keywords = []string{}
|
||||
keywordsStr = strings.TrimSpace(keywordsStr)
|
||||
if "" == keywordsStr {
|
||||
return
|
||||
}
|
||||
// 先处理转义的逗号
|
||||
keywordsStr = strings.ReplaceAll(keywordsStr, "\\,", "__comma@sep__")
|
||||
// 再将连续或单个换行符替换为一个逗号,避免把 `\\\n` 转换为 `\,`
|
||||
keywordsStr = newlineRegexp.ReplaceAllString(keywordsStr, ",")
|
||||
// 按逗号分隔
|
||||
for part := range strings.SplitSeq(keywordsStr, ",") {
|
||||
part = strings.TrimSpace(part) // 剔除前后的空白字符
|
||||
if "" == part {
|
||||
continue
|
||||
}
|
||||
// 恢复转义的逗号
|
||||
part = strings.ReplaceAll(part, "__comma@sep__", ",")
|
||||
keywords = append(keywords, part)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getVirtualRefKeywords(root *ast.Node) (ret []string) {
|
||||
if !Conf.Editor.VirtualBlockRef {
|
||||
return
|
||||
|
|
@ -222,25 +279,16 @@ func getVirtualRefKeywords(root *ast.Node) (ret []string) {
|
|||
ret = val.([]string)
|
||||
}
|
||||
|
||||
if "" != strings.TrimSpace(Conf.Editor.VirtualBlockRefInclude) {
|
||||
include := strings.ReplaceAll(Conf.Editor.VirtualBlockRefInclude, "\\,", "__comma@sep__")
|
||||
includes := strings.Split(include, ",")
|
||||
var tmp []string
|
||||
for _, e := range includes {
|
||||
e = strings.ReplaceAll(e, "__comma@sep__", ",")
|
||||
tmp = append(tmp, e)
|
||||
}
|
||||
includes = tmp
|
||||
includes := parseKeywords(Conf.Editor.VirtualBlockRefInclude)
|
||||
if 0 < len(includes) {
|
||||
ret = append(ret, includes...)
|
||||
ret = gulu.Str.RemoveDuplicatedElem(ret)
|
||||
}
|
||||
|
||||
if "" != strings.TrimSpace(Conf.Editor.VirtualBlockRefExclude) {
|
||||
exclude := strings.ReplaceAll(Conf.Editor.VirtualBlockRefExclude, "\\,", "__comma@sep__")
|
||||
excludes := strings.Split(exclude, ",")
|
||||
excludes := parseKeywords(Conf.Editor.VirtualBlockRefExclude)
|
||||
if 0 < len(excludes) {
|
||||
var tmp, regexps []string
|
||||
for _, e := range excludes {
|
||||
e = strings.ReplaceAll(e, "__comma@sep__", ",")
|
||||
if strings.HasPrefix(e, "/") && strings.HasSuffix(e, "/") {
|
||||
regexps = append(regexps, e[1:len(e)-1])
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue