From a8bc7a05757cd7383b7832f4d43ab9ebfa5f0cb2 Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Thu, 15 Sep 2022 15:38:09 +0800 Subject: [PATCH] =?UTF-8?q?:art:=20=E8=A1=8C=E7=BA=A7=E5=85=83=E7=B4=A0?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=B5=8C=E5=A5=97=E5=92=8C=E4=BA=A4=E5=8F=89?= =?UTF-8?q?=20https://github.com/siyuan-note/siyuan/issues/2911?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/model/file.go | 4 +- kernel/model/import.go | 2 + kernel/treenode/node.go | 89 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 1 deletion(-) diff --git a/kernel/model/file.go b/kernel/model/file.go index d08ab341d..6ee65b307 100644 --- a/kernel/model/file.go +++ b/kernel/model/file.go @@ -614,7 +614,7 @@ func GetDoc(startID, endID, id string, index int, keyword string, mode int, size } } - subTree := &parse.Tree{Root: &ast.Node{Type: ast.NodeDocument}, Marks: tree.Marks} + subTree := &parse.Tree{ID: rootID, Root: &ast.Node{Type: ast.NodeDocument}, Marks: tree.Marks} keyword = strings.Join(strings.Split(keyword, " "), search.TermSep) keywords := search.SplitKeyword(keyword) @@ -728,6 +728,8 @@ func GetDoc(startID, endID, id string, index int, keyword string, mode int, size subTree.Root.AppendChild(n) } + treenode.NestedInlines2FlattedSpans(subTree) + luteEngine.RenderOptions.NodeIndexStart = index dom = luteEngine.Tree2BlockDOM(subTree, luteEngine.RenderOptions) return diff --git a/kernel/model/import.go b/kernel/model/import.go index 5a46b8c49..a92d131e0 100644 --- a/kernel/model/import.go +++ b/kernel/model/import.go @@ -451,6 +451,7 @@ func ImportFromLocalPath(boxID, localPath string, toPath string) (err error) { tree.Path = targetPath targetPaths[curRelPath] = targetPath tree.HPath = hPath + treenode.NestedInlines2FlattedSpans(tree) docDirLocalPath := filepath.Dir(filepath.Join(boxLocalPath, targetPath)) assetDirPath := getAssetsDir(boxLocalPath, docDirLocalPath) @@ -538,6 +539,7 @@ func ImportFromLocalPath(boxID, localPath string, toPath string) (err error) { tree.Box = boxID tree.Path = targetPath tree.HPath = path.Join(baseHPath, title) + treenode.NestedInlines2FlattedSpans(tree) docDirLocalPath := filepath.Dir(filepath.Join(boxLocalPath, targetPath)) assetDirPath := getAssetsDir(boxLocalPath, docDirLocalPath) diff --git a/kernel/treenode/node.go b/kernel/treenode/node.go index a4cb25b74..2fdbee84b 100644 --- a/kernel/treenode/node.go +++ b/kernel/treenode/node.go @@ -31,6 +31,95 @@ import ( "github.com/siyuan-note/logging" ) +// NestedInlines2FlattedSpans 将嵌套的行级节点转换为平铺的文本标记节点。 +func NestedInlines2FlattedSpans(tree *parse.Tree) { + var tags []string + var unlinks []*ast.Node + var span *ast.Node + ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus { + switch n.Type { + case ast.NodeCodeSpan: + processNestedNode(n, "code", &tags, &unlinks, entering) + case ast.NodeTag: + processNestedNode(n, "tag", &tags, &unlinks, entering) + case ast.NodeInlineMath: + processNestedNode(n, "inline-math", &tags, &unlinks, entering) + case ast.NodeEmphasis: + processNestedNode(n, "em", &tags, &unlinks, entering) + case ast.NodeStrong: + processNestedNode(n, "strong", &tags, &unlinks, entering) + case ast.NodeStrikethrough: + processNestedNode(n, "s", &tags, &unlinks, entering) + case ast.NodeMark: + processNestedNode(n, "mark", &tags, &unlinks, entering) + case ast.NodeUnderline: + processNestedNode(n, "u", &tags, &unlinks, entering) + case ast.NodeSub: + processNestedNode(n, "sub", &tags, &unlinks, entering) + case ast.NodeSup: + processNestedNode(n, "sup", &tags, &unlinks, entering) + case ast.NodeKbd: + processNestedNode(n, "kbd", &tags, &unlinks, entering) + case ast.NodeLink: + processNestedNode(n, "a", &tags, &unlinks, entering) + case ast.NodeText, ast.NodeCodeSpanContent, ast.NodeInlineMathContent, ast.NodeLinkText: + if 1 > len(tags) { + return ast.WalkContinue + } + + if entering { + span = &ast.Node{Type: ast.NodeTextMark, TextMarkType: strings.Join(tags, " "), TextMarkTextContent: string(n.Tokens)} + if ast.NodeInlineMathContent == n.Type { + span.TextMarkTextContent = "" + span.TextMarkInlineMathContent = string(n.Tokens) + } + if ast.NodeLinkText == n.Type && !n.ParentIs(ast.NodeImage) { + var link *ast.Node + for p := n.Parent; nil != p; p = p.Parent { + if ast.NodeLink == p.Type { + link = p + break + } + } + if nil != link { + dest := link.ChildByType(ast.NodeLinkDest) + if nil != dest { + span.TextMarkAHref = string(dest.Tokens) + } + title := link.ChildByType(ast.NodeLinkTitle) + if nil != title { + span.TextMarkATitle = string(title.Tokens) + } + } + } + } else { + n.Parent.InsertBefore(span) + } + } + return ast.WalkContinue + }) + + for _, n := range unlinks { + n.Unlink() + } +} + +func processNestedNode(n *ast.Node, tag string, tags *[]string, unlinks *[]*ast.Node, entering bool) { + if entering { + *tags = append(*tags, tag) + } else { + *tags = (*tags)[:len(*tags)-1] + *unlinks = append(*unlinks, n) + for c := n.FirstChild; nil != c; { + next := c.Next + if ast.NodeTextMark == c.Type { + n.InsertBefore(c) + } + c = next + } + } +} + func NodeStaticMdContent(node *ast.Node, luteEngine *lute.Lute) (md, content string) { md = FormatNode(node, luteEngine) content = NodeStaticContent(node)