浏览代码

:sparkles: 编辑器式反链面板 https://github.com/siyuan-note/siyuan/issues/3565

Liang Ding 2 年之前
父节点
当前提交
fcaddd6966
共有 2 个文件被更改,包括 50 次插入4 次删除
  1. 6 4
      kernel/model/backlink.go
  2. 44 0
      kernel/model/path.go

+ 6 - 4
kernel/model/backlink.go

@@ -384,8 +384,8 @@ func buildBacklink(refID string, refTree *parse.Tree, luteEngine *lute.Lute) (re
 	return
 }
 
-func BuildTreeBacklink(id, keyword, mentionKeyword string, beforeLen int) (boxID string, backlinks, backmentions []*Block, linkRefsCount, mentionsCount int) {
-	backlinks, backmentions = []*Block{}, []*Block{}
+func BuildTreeBacklink(id, keyword, mentionKeyword string, beforeLen int) (boxID string, backlinks, backmentions []*Path, linkRefsCount, mentionsCount int) {
+	backlinks, backmentions = []*Path{}, []*Path{}
 
 	sqlBlock := sql.GetBlock(id)
 	if nil == sqlBlock {
@@ -396,9 +396,11 @@ func BuildTreeBacklink(id, keyword, mentionKeyword string, beforeLen int) (boxID
 	refs := sql.QueryRefsByDefID(id, true)
 	refs = removeDuplicatedRefs(refs) // 同一个块中引用多个相同块时反链去重 https://github.com/siyuan-note/siyuan/issues/3317
 
-	backlinks, excludeBacklinkIDs := buildLinkRefs(id, refs)
+	linkRefs, excludeBacklinkIDs := buildLinkRefs(id, refs)
+	backlinks = toSubTree(linkRefs, keyword)
 
-	backmentions = buildTreeBackmention(sqlBlock, backlinks, mentionKeyword, excludeBacklinkIDs, beforeLen)
+	mentionRefs := buildTreeBackmention(sqlBlock, linkRefs, mentionKeyword, excludeBacklinkIDs, beforeLen)
+	backmentions = toFlatTree(mentionRefs, 0, "backlink")
 	mentionsCount = len(backmentions)
 	return
 }

+ 44 - 0
kernel/model/path.go

@@ -27,6 +27,7 @@ import (
 	"github.com/88250/gulu"
 	"github.com/88250/lute/ast"
 	"github.com/siyuan-note/logging"
+	"github.com/siyuan-note/siyuan/kernel/search"
 	"github.com/siyuan-note/siyuan/kernel/treenode"
 	"github.com/siyuan-note/siyuan/kernel/util"
 )
@@ -123,6 +124,49 @@ func toFlatTree(blocks []*Block, baseDepth int, typ string) (ret []*Path) {
 	return
 }
 
+func toSubTree(blocks []*Block, keyword string) (ret []*Path) {
+	keyword = strings.TrimSpace(keyword)
+	var blockRoots []*Block
+	for _, block := range blocks {
+		root := getBlockIn(blockRoots, block.RootID)
+		if nil == root {
+			root, _ = getBlock(block.RootID)
+			blockRoots = append(blockRoots, root)
+		}
+		block.Depth = 1
+		block.Count = len(block.Children)
+		root.Children = append(root.Children, block)
+	}
+
+	for _, root := range blockRoots {
+		treeNode := &Path{
+			ID:       root.ID,
+			Box:      root.Box,
+			Name:     path.Base(root.HPath),
+			Type:     "backlink",
+			NodeType: "NodeDocument",
+			SubType:  root.SubType,
+			Depth:    0,
+			Count:    len(root.Children),
+		}
+
+		rootPos := -1
+		var rootContent string
+		if "" != keyword {
+			rootPos, rootContent = search.MarkText(treeNode.Name, keyword, 12, Conf.Search.CaseSensitive)
+			treeNode.Name = rootContent
+		}
+		if 0 < len(treeNode.Children) || 0 < len(treeNode.Blocks) || (-1 < rootPos && "" != keyword) {
+			ret = append(ret, treeNode)
+		}
+	}
+
+	sort.Slice(ret, func(i, j int) bool {
+		return ret[i].ID > ret[j].ID
+	})
+	return
+}
+
 func getBlockIn(blocks []*Block, id string) *Block {
 	if "" == id {
 		return nil