mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-23 10:00:13 +01:00
✨ 行级元素支持多重样式类型 https://github.com/siyuan-note/siyuan/issues/2911
This commit is contained in:
parent
dcee38bcfa
commit
c5f0b96929
13 changed files with 133 additions and 85 deletions
2
app/stage/protyle/js/lute/lute.min.js
vendored
2
app/stage/protyle/js/lute/lute.min.js
vendored
File diff suppressed because one or more lines are too long
|
|
@ -7,7 +7,7 @@ require (
|
||||||
github.com/88250/css v0.1.2
|
github.com/88250/css v0.1.2
|
||||||
github.com/88250/flock v0.8.2
|
github.com/88250/flock v0.8.2
|
||||||
github.com/88250/gulu v1.2.3-0.20220916075322-eb117059d70a
|
github.com/88250/gulu v1.2.3-0.20220916075322-eb117059d70a
|
||||||
github.com/88250/lute v1.7.5-0.20220916031248-441b66b72883
|
github.com/88250/lute v1.7.5-0.20220916090743-91ee79ea1ba7
|
||||||
github.com/88250/pdfcpu v0.3.13
|
github.com/88250/pdfcpu v0.3.13
|
||||||
github.com/88250/vitess-sqlparser v0.0.0-20210205111146-56a2ded2aba1
|
github.com/88250/vitess-sqlparser v0.0.0-20210205111146-56a2ded2aba1
|
||||||
github.com/ConradIrwin/font v0.0.0-20210318200717-ce8d41cc0732
|
github.com/ConradIrwin/font v0.0.0-20210318200717-ce8d41cc0732
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,8 @@ github.com/88250/go-sqlite3 v1.14.13-0.20220714142610-fbbda1ee84f5 h1:8HdZozCsXS
|
||||||
github.com/88250/go-sqlite3 v1.14.13-0.20220714142610-fbbda1ee84f5/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
github.com/88250/go-sqlite3 v1.14.13-0.20220714142610-fbbda1ee84f5/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||||
github.com/88250/gulu v1.2.3-0.20220916075322-eb117059d70a h1:qQdnk8clbgA+MXtf5bXOTOby32iQYjqMOn6oBIMV/Tk=
|
github.com/88250/gulu v1.2.3-0.20220916075322-eb117059d70a h1:qQdnk8clbgA+MXtf5bXOTOby32iQYjqMOn6oBIMV/Tk=
|
||||||
github.com/88250/gulu v1.2.3-0.20220916075322-eb117059d70a/go.mod h1:I1qBzsksFL2ciGSuqDE7R3XW4BUMrfDgOvSXEk7FsAI=
|
github.com/88250/gulu v1.2.3-0.20220916075322-eb117059d70a/go.mod h1:I1qBzsksFL2ciGSuqDE7R3XW4BUMrfDgOvSXEk7FsAI=
|
||||||
github.com/88250/lute v1.7.5-0.20220916031248-441b66b72883 h1:7uCW8I6P5934DhzUpJmZcaanRl8ws+X76sw4uca4gRM=
|
github.com/88250/lute v1.7.5-0.20220916090743-91ee79ea1ba7 h1:ddXXCU+Np3iJoFV34NShb/NwaSrnG+9ZGonxd5SdJow=
|
||||||
github.com/88250/lute v1.7.5-0.20220916031248-441b66b72883/go.mod h1:cEoBGi0zArPqAsp0MdG9SKinvH/xxZZWXU7sRx8vHSA=
|
github.com/88250/lute v1.7.5-0.20220916090743-91ee79ea1ba7/go.mod h1:cEoBGi0zArPqAsp0MdG9SKinvH/xxZZWXU7sRx8vHSA=
|
||||||
github.com/88250/pdfcpu v0.3.13 h1:touMWMZkCGalMIbEg9bxYp7rETM+zwb9hXjwhqi4I7Q=
|
github.com/88250/pdfcpu v0.3.13 h1:touMWMZkCGalMIbEg9bxYp7rETM+zwb9hXjwhqi4I7Q=
|
||||||
github.com/88250/pdfcpu v0.3.13/go.mod h1:S5YT38L/GCjVjmB4PB84PymA1qfopjEhfhTNQilLpv4=
|
github.com/88250/pdfcpu v0.3.13/go.mod h1:S5YT38L/GCjVjmB4PB84PymA1qfopjEhfhTNQilLpv4=
|
||||||
github.com/88250/vitess-sqlparser v0.0.0-20210205111146-56a2ded2aba1 h1:48T899JQDwyyRu9yXHePYlPdHtpJfrJEUGBMH3SMBWY=
|
github.com/88250/vitess-sqlparser v0.0.0-20210205111146-56a2ded2aba1 h1:48T899JQDwyyRu9yXHePYlPdHtpJfrJEUGBMH3SMBWY=
|
||||||
|
|
|
||||||
|
|
@ -1117,27 +1117,22 @@ func exportTree(tree *parse.Tree, wysiwyg, expandKaTexMacros bool) (ret *parse.T
|
||||||
return ast.WalkSkipChildren
|
return ast.WalkSkipChildren
|
||||||
}
|
}
|
||||||
|
|
||||||
if ast.NodeBlockRef != n.Type {
|
if !treenode.IsBlockRef(n) {
|
||||||
return ast.WalkContinue
|
return ast.WalkContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理引用节点
|
// 处理引用节点
|
||||||
|
|
||||||
var linkText string
|
defID, linkText, _ := treenode.GetBlockRef(n)
|
||||||
id := n.ChildByType(ast.NodeBlockRefID).TokensStr()
|
if "" == linkText {
|
||||||
if anchor := n.ChildByType(ast.NodeBlockRefText); nil != anchor {
|
linkText = sql.GetRefText(defID)
|
||||||
linkText = anchor.Text()
|
|
||||||
} else if anchor = n.ChildByType(ast.NodeBlockRefDynamicText); nil != anchor {
|
|
||||||
linkText = anchor.Text()
|
|
||||||
} else {
|
|
||||||
linkText = sql.GetRefText(id)
|
|
||||||
}
|
}
|
||||||
if Conf.Editor.BlockRefDynamicAnchorTextMaxLen < utf8.RuneCountInString(linkText) {
|
if Conf.Editor.BlockRefDynamicAnchorTextMaxLen < utf8.RuneCountInString(linkText) {
|
||||||
linkText = gulu.Str.SubStr(linkText, Conf.Editor.BlockRefDynamicAnchorTextMaxLen) + "..."
|
linkText = gulu.Str.SubStr(linkText, Conf.Editor.BlockRefDynamicAnchorTextMaxLen) + "..."
|
||||||
}
|
}
|
||||||
linkText = Conf.Export.BlockRefTextLeft + linkText + Conf.Export.BlockRefTextRight
|
linkText = Conf.Export.BlockRefTextLeft + linkText + Conf.Export.BlockRefTextRight
|
||||||
|
|
||||||
defTree, _ := loadTreeByBlockID(id)
|
defTree, _ := loadTreeByBlockID(defID)
|
||||||
if nil == defTree {
|
if nil == defTree {
|
||||||
return ast.WalkContinue
|
return ast.WalkContinue
|
||||||
}
|
}
|
||||||
|
|
@ -1150,13 +1145,12 @@ func exportTree(tree *parse.Tree, wysiwyg, expandKaTexMacros bool) (ret *parse.T
|
||||||
blockRefLink.AppendChild(&ast.Node{Type: ast.NodeLinkText, Tokens: []byte(linkText)})
|
blockRefLink.AppendChild(&ast.Node{Type: ast.NodeLinkText, Tokens: []byte(linkText)})
|
||||||
blockRefLink.AppendChild(&ast.Node{Type: ast.NodeCloseBracket})
|
blockRefLink.AppendChild(&ast.Node{Type: ast.NodeCloseBracket})
|
||||||
blockRefLink.AppendChild(&ast.Node{Type: ast.NodeOpenParen})
|
blockRefLink.AppendChild(&ast.Node{Type: ast.NodeOpenParen})
|
||||||
blockRefLink.AppendChild(&ast.Node{Type: ast.NodeLinkDest, Tokens: []byte("siyuan://blocks/" + id)})
|
blockRefLink.AppendChild(&ast.Node{Type: ast.NodeLinkDest, Tokens: []byte("siyuan://blocks/" + defID)})
|
||||||
blockRefLink.AppendChild(&ast.Node{Type: ast.NodeCloseParen})
|
blockRefLink.AppendChild(&ast.Node{Type: ast.NodeCloseParen})
|
||||||
n.InsertBefore(blockRefLink)
|
n.InsertBefore(blockRefLink)
|
||||||
case 3: // 仅锚文本
|
case 3: // 仅锚文本
|
||||||
n.InsertBefore(&ast.Node{Type: ast.NodeText, Tokens: []byte(linkText)})
|
n.InsertBefore(&ast.Node{Type: ast.NodeText, Tokens: []byte(linkText)})
|
||||||
case 4: // 脚注
|
case 4: // 脚注
|
||||||
defID := n.ChildByType(ast.NodeBlockRefID).TokensStr()
|
|
||||||
refFoot := getRefAsFootnotes(defID, &refFootnotes)
|
refFoot := getRefAsFootnotes(defID, &refFootnotes)
|
||||||
n.InsertBefore(&ast.Node{Type: ast.NodeText, Tokens: []byte(linkText)})
|
n.InsertBefore(&ast.Node{Type: ast.NodeText, Tokens: []byte(linkText)})
|
||||||
n.InsertBefore(&ast.Node{Type: ast.NodeFootnotesRef, Tokens: []byte("^" + refFoot.refNum), FootnotesRefId: refFoot.refNum, FootnotesRefLabel: []byte("^" + refFoot.refNum)})
|
n.InsertBefore(&ast.Node{Type: ast.NodeFootnotesRef, Tokens: []byte("^" + refFoot.refNum), FootnotesRefId: refFoot.refNum, FootnotesRefLabel: []byte("^" + refFoot.refNum)})
|
||||||
|
|
@ -1295,8 +1289,8 @@ func resolveFootnotesDefs(refFootnotes *[]*refAsFootnotes, rootID string) (footn
|
||||||
return ast.WalkContinue
|
return ast.WalkContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
if ast.NodeBlockRef == n.Type {
|
if treenode.IsBlockRef(n) {
|
||||||
defID := n.ChildByType(ast.NodeBlockRefID).TokensStr()
|
defID, _, _ := treenode.GetBlockRef(n)
|
||||||
if f := getRefAsFootnotes(defID, refFootnotes); nil != f {
|
if f := getRefAsFootnotes(defID, refFootnotes); nil != f {
|
||||||
n.InsertBefore(&ast.Node{Type: ast.NodeText, Tokens: []byte(Conf.Export.BlockRefTextLeft + f.refAnchorText + Conf.Export.BlockRefTextRight)})
|
n.InsertBefore(&ast.Node{Type: ast.NodeText, Tokens: []byte(Conf.Export.BlockRefTextLeft + f.refAnchorText + Conf.Export.BlockRefTextRight)})
|
||||||
n.InsertBefore(&ast.Node{Type: ast.NodeFootnotesRef, Tokens: []byte("^" + f.refNum), FootnotesRefId: f.refNum, FootnotesRefLabel: []byte("^" + f.refNum)})
|
n.InsertBefore(&ast.Node{Type: ast.NodeFootnotesRef, Tokens: []byte("^" + f.refNum), FootnotesRefId: f.refNum, FootnotesRefLabel: []byte("^" + f.refNum)})
|
||||||
|
|
@ -1412,8 +1406,8 @@ func collectFootnotesDefs0(node *ast.Node, refFootnotes *[]*refAsFootnotes, tree
|
||||||
return ast.WalkContinue
|
return ast.WalkContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
if ast.NodeBlockRef == n.Type {
|
if treenode.IsBlockRef(n) {
|
||||||
defID := n.ChildByType(ast.NodeBlockRefID).TokensStr()
|
defID, _, _ := treenode.GetBlockRef(n)
|
||||||
if nil == getRefAsFootnotes(defID, refFootnotes) {
|
if nil == getRefAsFootnotes(defID, refFootnotes) {
|
||||||
anchorText := sql.GetRefText(defID)
|
anchorText := sql.GetRefText(defID)
|
||||||
if Conf.Editor.BlockRefDynamicAnchorTextMaxLen < utf8.RuneCountInString(anchorText) {
|
if Conf.Editor.BlockRefDynamicAnchorTextMaxLen < utf8.RuneCountInString(anchorText) {
|
||||||
|
|
@ -1463,12 +1457,11 @@ func exportRefTrees0(tree *parse.Tree, retTrees *map[string]*parse.Tree) {
|
||||||
return ast.WalkContinue
|
return ast.WalkContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
if ast.NodeBlockRef == n.Type {
|
if treenode.IsBlockRef(n) {
|
||||||
defIDNode := n.ChildByType(ast.NodeBlockRefID)
|
defID, _, _ := treenode.GetBlockRef(n)
|
||||||
if nil == defIDNode {
|
if "" == defID {
|
||||||
return ast.WalkSkipChildren
|
return ast.WalkContinue
|
||||||
}
|
}
|
||||||
defID := defIDNode.TokensStr()
|
|
||||||
defBlock := treenode.GetBlockTree(defID)
|
defBlock := treenode.GetBlockTree(defID)
|
||||||
if nil == defBlock {
|
if nil == defBlock {
|
||||||
return ast.WalkSkipChildren
|
return ast.WalkSkipChildren
|
||||||
|
|
|
||||||
|
|
@ -637,7 +637,7 @@ func GetDoc(startID, endID, id string, index int, keyword string, mode int, size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ast.NodeBlockRef == n.Type {
|
if treenode.IsBlockRef(n) {
|
||||||
appendRefTextRenderResultForBlockRef(n)
|
appendRefTextRenderResultForBlockRef(n)
|
||||||
return ast.WalkSkipChildren
|
return ast.WalkSkipChildren
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -178,7 +178,7 @@ func GetDocHistoryContent(historyPath, keyword string) (id, rootID, content stri
|
||||||
n.RemoveIALAttr("heading-fold")
|
n.RemoveIALAttr("heading-fold")
|
||||||
n.RemoveIALAttr("fold")
|
n.RemoveIALAttr("fold")
|
||||||
|
|
||||||
if ast.NodeBlockRef == n.Type {
|
if treenode.IsBlockRef(n) {
|
||||||
appendRefTextRenderResultForBlockRef(n)
|
appendRefTextRenderResultForBlockRef(n)
|
||||||
return ast.WalkSkipChildren
|
return ast.WalkSkipChildren
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -183,7 +183,7 @@ func toSubTree(blocks []*Block, keyword string) (ret []*Path) {
|
||||||
|
|
||||||
unfold := true
|
unfold := true
|
||||||
for liFirstBlockSpan := li.FirstChild.FirstChild; nil != liFirstBlockSpan; liFirstBlockSpan = liFirstBlockSpan.Next {
|
for liFirstBlockSpan := li.FirstChild.FirstChild; nil != liFirstBlockSpan; liFirstBlockSpan = liFirstBlockSpan.Next {
|
||||||
if ast.NodeBlockRef == liFirstBlockSpan.Type {
|
if treenode.IsBlockRef(liFirstBlockSpan) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if "" != strings.TrimSpace(liFirstBlockSpan.Text()) {
|
if "" != strings.TrimSpace(liFirstBlockSpan.Text()) {
|
||||||
|
|
@ -278,7 +278,7 @@ func toSubTree(blocks []*Block, keyword string) (ret []*Path) {
|
||||||
|
|
||||||
unfold := true
|
unfold := true
|
||||||
for headingFirstSpan := h.FirstChild; nil != headingFirstSpan; headingFirstSpan = headingFirstSpan.Next {
|
for headingFirstSpan := h.FirstChild; nil != headingFirstSpan; headingFirstSpan = headingFirstSpan.Next {
|
||||||
if ast.NodeBlockRef == headingFirstSpan.Type {
|
if treenode.IsBlockRef(headingFirstSpan) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if "" != strings.TrimSpace(headingFirstSpan.Text()) {
|
if "" != strings.TrimSpace(headingFirstSpan.Text()) {
|
||||||
|
|
|
||||||
|
|
@ -237,23 +237,18 @@ func renderTemplate(p, id string) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func appendRefTextRenderResultForBlockRef(blockRef *ast.Node) {
|
func appendRefTextRenderResultForBlockRef(blockRef *ast.Node) {
|
||||||
if ast.NodeBlockRef != blockRef.Type {
|
if !treenode.IsBlockRef(blockRef) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
refText := blockRef.ChildByType(ast.NodeBlockRefText)
|
refID, text, _ := treenode.GetBlockRef(blockRef)
|
||||||
if nil != refText {
|
if "" != text {
|
||||||
return
|
|
||||||
}
|
|
||||||
refText = blockRef.ChildByType(ast.NodeBlockRefDynamicText)
|
|
||||||
if nil != refText {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 动态解析渲染 ((id)) 的锚文本
|
// 动态解析渲染 ((id)) 的锚文本
|
||||||
// 现行版本已经不存在该语法情况,这里保留是为了迁移历史数据
|
// 现行版本已经不存在该语法情况,这里保留是为了迁移历史数据
|
||||||
refID := blockRef.ChildByType(ast.NodeBlockRefID)
|
text = sql.GetRefText(refID)
|
||||||
text := sql.GetRefText(refID.TokensStr())
|
|
||||||
if Conf.Editor.BlockRefDynamicAnchorTextMaxLen < utf8.RuneCountInString(text) {
|
if Conf.Editor.BlockRefDynamicAnchorTextMaxLen < utf8.RuneCountInString(text) {
|
||||||
text = gulu.Str.SubStr(text, Conf.Editor.BlockRefDynamicAnchorTextMaxLen) + "..."
|
text = gulu.Str.SubStr(text, Conf.Editor.BlockRefDynamicAnchorTextMaxLen) + "..."
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -883,7 +883,9 @@ func (tx *Transaction) doUpdate(operation *Operation) (ret *TxErr) {
|
||||||
// 剔除空白的行级公式
|
// 剔除空白的行级公式
|
||||||
unlinks = append(unlinks, n)
|
unlinks = append(unlinks, n)
|
||||||
}
|
}
|
||||||
} else if ast.NodeBlockRefID == n.Type {
|
} else if ast.NodeBlockRef == n.Type {
|
||||||
|
sql.CacheRef(subTree, n)
|
||||||
|
} else if ast.NodeTextMark == n.Type && n.IsTextMarkType("block-ref") {
|
||||||
sql.CacheRef(subTree, n)
|
sql.CacheRef(subTree, n)
|
||||||
}
|
}
|
||||||
return ast.WalkContinue
|
return ast.WalkContinue
|
||||||
|
|
@ -1098,27 +1100,28 @@ func updateRefText(refNode *ast.Node, changedDefNodes map[string]*ast.Node) (cha
|
||||||
if !entering {
|
if !entering {
|
||||||
return ast.WalkContinue
|
return ast.WalkContinue
|
||||||
}
|
}
|
||||||
if ast.NodeBlockRef == n.Type && nil != n.ChildByType(ast.NodeBlockRefDynamicText) {
|
if !treenode.IsBlockRef(n) {
|
||||||
defIDNode := n.ChildByType(ast.NodeBlockRefID)
|
return ast.WalkContinue
|
||||||
if nil == defIDNode {
|
}
|
||||||
return ast.WalkSkipChildren
|
|
||||||
}
|
defID, _, subtype := treenode.GetBlockRef(n)
|
||||||
defID := defIDNode.TokensStr()
|
if "s" == subtype || "" == defID {
|
||||||
defNode := changedDefNodes[defID]
|
return ast.WalkContinue
|
||||||
if nil == defNode {
|
}
|
||||||
return ast.WalkSkipChildren
|
|
||||||
}
|
defNode := changedDefNodes[defID]
|
||||||
if ast.NodeDocument != defNode.Type && defNode.IsContainerBlock() {
|
if nil == defNode {
|
||||||
defNode = treenode.FirstLeafBlock(defNode)
|
|
||||||
}
|
|
||||||
defContent := renderBlockText(defNode)
|
|
||||||
if Conf.Editor.BlockRefDynamicAnchorTextMaxLen < utf8.RuneCountInString(defContent) {
|
|
||||||
defContent = gulu.Str.SubStr(defContent, Conf.Editor.BlockRefDynamicAnchorTextMaxLen) + "..."
|
|
||||||
}
|
|
||||||
treenode.SetDynamicBlockRefText(n, defContent)
|
|
||||||
changed = true
|
|
||||||
return ast.WalkSkipChildren
|
return ast.WalkSkipChildren
|
||||||
}
|
}
|
||||||
|
if ast.NodeDocument != defNode.Type && defNode.IsContainerBlock() {
|
||||||
|
defNode = treenode.FirstLeafBlock(defNode)
|
||||||
|
}
|
||||||
|
defContent := renderBlockText(defNode)
|
||||||
|
if Conf.Editor.BlockRefDynamicAnchorTextMaxLen < utf8.RuneCountInString(defContent) {
|
||||||
|
defContent = gulu.Str.SubStr(defContent, Conf.Editor.BlockRefDynamicAnchorTextMaxLen) + "..."
|
||||||
|
}
|
||||||
|
treenode.SetDynamicBlockRefText(n, defContent)
|
||||||
|
changed = true
|
||||||
return ast.WalkContinue
|
return ast.WalkContinue
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -52,10 +52,14 @@ func resetTree(tree *parse.Tree, titleSuffix string) {
|
||||||
// 收集所有引用
|
// 收集所有引用
|
||||||
refIDs := map[string]string{}
|
refIDs := map[string]string{}
|
||||||
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
|
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
|
||||||
if !entering || ast.NodeBlockRefID != n.Type {
|
if !entering || !treenode.IsBlockRef(n) {
|
||||||
return ast.WalkContinue
|
return ast.WalkContinue
|
||||||
}
|
}
|
||||||
refIDs[n.TokensStr()] = "1"
|
defID, _, _ := treenode.GetBlockRef(n)
|
||||||
|
if "" == defID {
|
||||||
|
return ast.WalkContinue
|
||||||
|
}
|
||||||
|
refIDs[defID] = "1"
|
||||||
return ast.WalkContinue
|
return ast.WalkContinue
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -78,11 +82,15 @@ func resetTree(tree *parse.Tree, titleSuffix string) {
|
||||||
|
|
||||||
// 重置内部引用
|
// 重置内部引用
|
||||||
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
|
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
|
||||||
if !entering || ast.NodeBlockRefID != n.Type {
|
if !entering || !treenode.IsBlockRef(n) {
|
||||||
return ast.WalkContinue
|
return ast.WalkContinue
|
||||||
}
|
}
|
||||||
if "1" != refIDs[n.TokensStr()] {
|
defID, _, _ := treenode.GetBlockRef(n)
|
||||||
n.Tokens = []byte(refIDs[n.TokensStr()])
|
if "" == defID {
|
||||||
|
return ast.WalkContinue
|
||||||
|
}
|
||||||
|
if "1" != refIDs[defID] {
|
||||||
|
n.Tokens = []byte(refIDs[defID])
|
||||||
}
|
}
|
||||||
return ast.WalkContinue
|
return ast.WalkContinue
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -112,8 +112,8 @@ func GetRefsCacheByDefID(defID string) (ret []*Ref) {
|
||||||
|
|
||||||
var defIDRefsCache = gcache.New(30*time.Minute, 5*time.Minute) // [defBlockID]map[refBlockID]*Ref
|
var defIDRefsCache = gcache.New(30*time.Minute, 5*time.Minute) // [defBlockID]map[refBlockID]*Ref
|
||||||
|
|
||||||
func CacheRef(tree *parse.Tree, refIDNode *ast.Node) {
|
func CacheRef(tree *parse.Tree, refNode *ast.Node) {
|
||||||
ref := buildRef(tree, refIDNode)
|
ref := buildRef(tree, refNode)
|
||||||
putRefCache(ref)
|
putRefCache(ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -269,7 +269,7 @@ func refsFromTree(tree *parse.Tree) (refs []*Ref, fileAnnotationRefs []*FileAnno
|
||||||
return ast.WalkContinue
|
return ast.WalkContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
if ast.NodeBlockRefID == n.Type {
|
if treenode.IsBlockRef(n) {
|
||||||
ref := buildRef(tree, n)
|
ref := buildRef(tree, n)
|
||||||
refs = append(refs, ref)
|
refs = append(refs, ref)
|
||||||
} else if ast.NodeFileAnnotationRefID == n.Type {
|
} else if ast.NodeFileAnnotationRefID == n.Type {
|
||||||
|
|
@ -306,9 +306,9 @@ func refsFromTree(tree *parse.Tree) (refs []*Ref, fileAnnotationRefs []*FileAnno
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildRef(tree *parse.Tree, refIDNode *ast.Node) *Ref {
|
func buildRef(tree *parse.Tree, refNode *ast.Node) *Ref {
|
||||||
markdown := treenode.FormatNode(refIDNode.Parent, luteEngine)
|
markdown := treenode.FormatNode(refNode, luteEngine)
|
||||||
defBlockID := refIDNode.TokensStr()
|
defBlockID, text, _ := treenode.GetBlockRef(refNode)
|
||||||
var defBlockParentID, defBlockRootID, defBlockPath string
|
var defBlockParentID, defBlockRootID, defBlockPath string
|
||||||
defBlock := treenode.GetBlockTree(defBlockID)
|
defBlock := treenode.GetBlockTree(defBlockID)
|
||||||
if nil != defBlock {
|
if nil != defBlock {
|
||||||
|
|
@ -316,8 +316,7 @@ func buildRef(tree *parse.Tree, refIDNode *ast.Node) *Ref {
|
||||||
defBlockRootID = defBlock.RootID
|
defBlockRootID = defBlock.RootID
|
||||||
defBlockPath = defBlock.Path
|
defBlockPath = defBlock.Path
|
||||||
}
|
}
|
||||||
text := treenode.GetDynamicBlockRefText(refIDNode.Parent)
|
parentBlock := treenode.ParentBlock(refNode)
|
||||||
parentBlock := treenode.ParentBlock(refIDNode)
|
|
||||||
return &Ref{
|
return &Ref{
|
||||||
ID: ast.NewNodeID(),
|
ID: ast.NewNodeID(),
|
||||||
DefBlockID: defBlockID,
|
DefBlockID: defBlockID,
|
||||||
|
|
@ -330,7 +329,7 @@ func buildRef(tree *parse.Tree, refIDNode *ast.Node) *Ref {
|
||||||
Path: tree.Path,
|
Path: tree.Path,
|
||||||
Content: text,
|
Content: text,
|
||||||
Markdown: markdown,
|
Markdown: markdown,
|
||||||
Type: treenode.TypeAbbr(refIDNode.Type.String()),
|
Type: treenode.TypeAbbr(refNode.Type.String()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,50 @@ import (
|
||||||
"github.com/siyuan-note/logging"
|
"github.com/siyuan-note/logging"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func GetBlockRef(n *ast.Node) (blockRefID, blockRefText, blockRefSubtype string) {
|
||||||
|
if !IsBlockRef(n) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if ast.NodeBlockRef == n.Type {
|
||||||
|
id := n.ChildByType(ast.NodeBlockRefID)
|
||||||
|
if nil == id {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
blockRefID = id.TokensStr()
|
||||||
|
text := n.ChildByType(ast.NodeBlockRefText)
|
||||||
|
if nil != text {
|
||||||
|
blockRefText = text.Text()
|
||||||
|
blockRefSubtype = "s"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
text = n.ChildByType(ast.NodeBlockRefDynamicText)
|
||||||
|
if nil != text {
|
||||||
|
blockRefText = text.Text()
|
||||||
|
blockRefSubtype = "d"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ast.NodeTextMark == n.Type {
|
||||||
|
blockRefID = n.TextMarkBlockRefID
|
||||||
|
blockRefText = n.TextMarkTextContent
|
||||||
|
blockRefSubtype = n.TextMarkBlockRefSubtype
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsBlockRef(n *ast.Node) bool {
|
||||||
|
if nil == n {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if ast.NodeBlockRef == n.Type {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if ast.NodeTextMark == n.Type {
|
||||||
|
return n.IsTextMarkType("block-ref")
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// NestedInlines2FlattedSpans 将嵌套的行级节点转换为平铺的文本标记节点。
|
// NestedInlines2FlattedSpans 将嵌套的行级节点转换为平铺的文本标记节点。
|
||||||
func NestedInlines2FlattedSpans(tree *parse.Tree) {
|
func NestedInlines2FlattedSpans(tree *parse.Tree) {
|
||||||
defer logging.Recover()
|
defer logging.Recover()
|
||||||
|
|
@ -391,25 +435,31 @@ func GetLegacyDynamicBlockRefDefIDs(node *ast.Node) (ret []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetDynamicBlockRefText(blockRef *ast.Node, refText string) {
|
func SetDynamicBlockRefText(blockRef *ast.Node, refText string) {
|
||||||
if nil == blockRef {
|
if !IsBlockRef(blockRef) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
idNode := blockRef.ChildByType(ast.NodeBlockRefID)
|
if ast.NodeBlockRef == blockRef.Type {
|
||||||
if nil == idNode {
|
idNode := blockRef.ChildByType(ast.NodeBlockRefID)
|
||||||
|
if nil == idNode {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var spacesRefTexts []*ast.Node // 可能会有多个空格,或者遗留错误插入的锚文本节点,这里做一次订正
|
||||||
|
for n := idNode.Next; ast.NodeCloseParen != n.Type; n = n.Next {
|
||||||
|
spacesRefTexts = append(spacesRefTexts, n)
|
||||||
|
}
|
||||||
|
for _, toRemove := range spacesRefTexts {
|
||||||
|
toRemove.Unlink()
|
||||||
|
}
|
||||||
|
refText = strings.TrimSpace(refText)
|
||||||
|
idNode.InsertAfter(&ast.Node{Type: ast.NodeBlockRefDynamicText, Tokens: []byte(refText)})
|
||||||
|
idNode.InsertAfter(&ast.Node{Type: ast.NodeBlockRefSpace})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var spacesRefTexts []*ast.Node // 可能会有多个空格,或者遗留错误插入的锚文本节点,这里做一次订正
|
blockRef.TextMarkBlockRefSubtype = "d"
|
||||||
for n := idNode.Next; ast.NodeCloseParen != n.Type; n = n.Next {
|
blockRef.TextMarkTextContent = refText
|
||||||
spacesRefTexts = append(spacesRefTexts, n)
|
|
||||||
}
|
|
||||||
for _, toRemove := range spacesRefTexts {
|
|
||||||
toRemove.Unlink()
|
|
||||||
}
|
|
||||||
refText = strings.TrimSpace(refText)
|
|
||||||
idNode.InsertAfter(&ast.Node{Type: ast.NodeBlockRefDynamicText, Tokens: []byte(refText)})
|
|
||||||
idNode.InsertAfter(&ast.Node{Type: ast.NodeBlockRefSpace})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetDynamicBlockRefText(blockRef *ast.Node) string {
|
func GetDynamicBlockRefText(blockRef *ast.Node) string {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue