♻️ Improve av structure

This commit is contained in:
Daniel 2024-05-15 00:47:25 +08:00
parent f75d5e50b4
commit 373bce9791
No known key found for this signature in database
GPG key ID: 86211BA83DF03017
10 changed files with 819 additions and 1165 deletions

View file

@ -17,8 +17,15 @@
package sql
import (
"bytes"
"database/sql"
"strings"
"github.com/88250/gulu"
"github.com/88250/lute/ast"
"github.com/88250/lute/html"
"github.com/88250/lute/lex"
"github.com/siyuan-note/siyuan/kernel/av"
"github.com/siyuan-note/siyuan/kernel/cache"
"github.com/siyuan-note/siyuan/kernel/filesys"
"github.com/siyuan-note/siyuan/kernel/treenode"
@ -109,7 +116,7 @@ func indexNode(tx *sql.Tx, id string) (err error) {
return
}
content := treenode.NodeStaticContent(node, nil, true, indexAssetPath, true)
content := NodeStaticContent(node, nil, true, indexAssetPath, true, nil)
stmt := "UPDATE blocks SET content = ? WHERE id = ?"
if err = execStmtTx(tx, stmt, content, id); nil != err {
tx.Rollback()
@ -129,3 +136,140 @@ func indexNode(tx *sql.Tx, id string) (err error) {
}
return
}
func NodeStaticContent(node *ast.Node, excludeTypes []string, includeTextMarkATitleURL, includeAssetPath, fullAttrView bool,
GetBlockAttrsWithoutWaitWriting func(id string) (ret map[string]string)) string {
if ast.NodeAttributeView == node.Type {
if fullAttrView {
return getAttributeViewContent(node.AttributeViewID, GetBlockAttrsWithoutWaitWriting)
}
ret, _ := av.GetAttributeViewName(node.AttributeViewID)
return ret
}
return nodeStaticContent(node, excludeTypes, includeTextMarkATitleURL, includeAssetPath)
}
func nodeStaticContent(node *ast.Node, excludeTypes []string, includeTextMarkATitleURL, includeAssetPath bool) string {
if nil == node {
return ""
}
if ast.NodeDocument == node.Type {
return node.IALAttr("title")
}
if ast.NodeAttributeView == node.Type {
return ""
}
buf := bytes.Buffer{}
buf.Grow(4096)
lastSpace := false
ast.Walk(node, func(n *ast.Node, entering bool) ast.WalkStatus {
if !entering {
return ast.WalkContinue
}
if n.IsContainerBlock() {
if !lastSpace {
buf.WriteByte(' ')
lastSpace = true
}
return ast.WalkContinue
}
if gulu.Str.Contains(n.Type.String(), excludeTypes) {
return ast.WalkContinue
}
switch n.Type {
case ast.NodeTableCell:
// 表格块写入数据库表时在单元格之间添加空格 https://github.com/siyuan-note/siyuan/issues/7654
if 0 < buf.Len() && ' ' != buf.Bytes()[buf.Len()-1] {
buf.WriteByte(' ')
}
case ast.NodeImage:
linkDest := n.ChildByType(ast.NodeLinkDest)
var linkDestStr, ocrText string
if nil != linkDest {
linkDestStr = linkDest.TokensStr()
ocrText = util.GetAssetText(linkDestStr, false)
}
linkText := n.ChildByType(ast.NodeLinkText)
if nil != linkText {
buf.Write(linkText.Tokens)
buf.WriteByte(' ')
}
if "" != ocrText {
buf.WriteString(ocrText)
buf.WriteByte(' ')
}
if nil != linkDest {
if !bytes.HasPrefix(linkDest.Tokens, []byte("assets/")) || includeAssetPath {
buf.Write(linkDest.Tokens)
buf.WriteByte(' ')
}
}
if linkTitle := n.ChildByType(ast.NodeLinkTitle); nil != linkTitle {
buf.Write(linkTitle.Tokens)
}
return ast.WalkSkipChildren
case ast.NodeLinkText:
buf.Write(n.Tokens)
buf.WriteByte(' ')
case ast.NodeLinkDest:
buf.Write(n.Tokens)
buf.WriteByte(' ')
case ast.NodeLinkTitle:
buf.Write(n.Tokens)
case ast.NodeText, ast.NodeCodeBlockCode, ast.NodeMathBlockContent, ast.NodeHTMLBlock:
tokens := n.Tokens
if treenode.IsChartCodeBlockCode(n) {
// 图表块的内容在数据库 `blocks` 表 `content` 字段中被转义 https://github.com/siyuan-note/siyuan/issues/6326
tokens = html.UnescapeHTML(tokens)
}
buf.Write(tokens)
case ast.NodeTextMark:
for _, excludeType := range excludeTypes {
if strings.HasPrefix(excludeType, "NodeTextMark-") {
if n.IsTextMarkType(excludeType[len("NodeTextMark-"):]) {
return ast.WalkContinue
}
}
}
if n.IsTextMarkType("tag") {
buf.WriteByte('#')
}
buf.WriteString(n.Content())
if n.IsTextMarkType("tag") {
buf.WriteByte('#')
}
if n.IsTextMarkType("a") && includeTextMarkATitleURL {
// 搜索不到超链接元素的 URL 和标题 https://github.com/siyuan-note/siyuan/issues/7352
if "" != n.TextMarkATitle {
buf.WriteString(" " + html.UnescapeHTMLStr(n.TextMarkATitle))
}
if !strings.HasPrefix(n.TextMarkAHref, "assets/") || includeAssetPath {
buf.WriteString(" " + html.UnescapeHTMLStr(n.TextMarkAHref))
}
}
case ast.NodeBackslash:
buf.WriteByte(lex.ItemBackslash)
case ast.NodeBackslashContent:
buf.Write(n.Tokens)
case ast.NodeAudio, ast.NodeVideo:
buf.WriteString(treenode.GetNodeSrcTokens(n))
buf.WriteByte(' ')
}
lastSpace = false
return ast.WalkContinue
})
// 这里不要 trim否则无法搜索首尾空格
// Improve search and replace for spaces https://github.com/siyuan-note/siyuan/issues/10231
return buf.String()
}