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/5013
This commit is contained in:
parent
e650b8100c
commit
f40ed985e1
1214 changed files with 345766 additions and 9 deletions
179
kernel/model/block.go
Normal file
179
kernel/model/block.go
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
// SiYuan - Build Your Eternal Digital Garden
|
||||
// Copyright (c) 2020-present, b3log.org
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/88250/lute"
|
||||
"github.com/88250/lute/ast"
|
||||
"github.com/siyuan-note/siyuan/kernel/sql"
|
||||
"github.com/siyuan-note/siyuan/kernel/treenode"
|
||||
)
|
||||
|
||||
// Block 描述了内容块。
|
||||
type Block struct {
|
||||
Box string `json:"box"`
|
||||
Path string `json:"path"`
|
||||
HPath string `json:"hPath"`
|
||||
ID string `json:"id"`
|
||||
RootID string `json:"rootID"`
|
||||
ParentID string `json:"parentID"`
|
||||
Name string `json:"name"`
|
||||
Alias string `json:"alias"`
|
||||
Memo string `json:"memo"`
|
||||
Tag string `json:"tag"`
|
||||
Content string `json:"content"`
|
||||
FContent string `json:"fcontent"`
|
||||
Markdown string `json:"markdown"`
|
||||
Folded bool `json:"folded"`
|
||||
Type string `json:"type"`
|
||||
SubType string `json:"subType"`
|
||||
RefText string `json:"refText"`
|
||||
Defs []*Block `json:"-"` // 当前块引用了这些块,避免序列化 JSON 时产生循环引用
|
||||
Refs []*Block `json:"refs"` // 当前块被这些块引用
|
||||
DefID string `json:"defID"`
|
||||
DefPath string `json:"defPath"`
|
||||
IAL map[string]string `json:"ial"`
|
||||
Children []*Block `json:"children"`
|
||||
Depth int `json:"depth"`
|
||||
Count int `json:"count"`
|
||||
}
|
||||
|
||||
func (block *Block) IsContainerBlock() bool {
|
||||
switch block.Type {
|
||||
case "NodeDocument", "NodeBlockquote", "NodeList", "NodeListItem", "NodeSuperBlock":
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type Path struct {
|
||||
ID string `json:"id"` // 块 ID
|
||||
Box string `json:"box"` // 块 Box
|
||||
Name string `json:"name"` // 当前路径
|
||||
Full string `json:"full"` // 全路径
|
||||
Type string `json:"type"` // "path"
|
||||
NodeType string `json:"nodeType"` // 节点类型
|
||||
SubType string `json:"subType"` // 节点子类型
|
||||
Blocks []*Block `json:"blocks"` // 子块节点
|
||||
Children []*Path `json:"children"` // 子路径节点
|
||||
Depth int `json:"depth"` // 层级深度
|
||||
Count int `json:"count"` // 子块计数
|
||||
}
|
||||
|
||||
func RecentUpdatedBlocks() (ret []*Block) {
|
||||
ret = []*Block{}
|
||||
|
||||
sqlBlocks := sql.QueryRecentUpdatedBlocks()
|
||||
if 1 > len(sqlBlocks) {
|
||||
return
|
||||
}
|
||||
|
||||
ret = fromSQLBlocks(&sqlBlocks, "", 0)
|
||||
return
|
||||
}
|
||||
|
||||
func GetBlockDOM(id string) (ret string) {
|
||||
if "" == id {
|
||||
return
|
||||
}
|
||||
|
||||
tree, err := loadTreeByBlockID(id)
|
||||
if nil != err {
|
||||
return
|
||||
}
|
||||
node := treenode.GetNodeInTree(tree, id)
|
||||
luteEngine := NewLute()
|
||||
ret = lute.RenderNodeBlockDOM(node, luteEngine.ParseOptions, luteEngine.RenderOptions)
|
||||
return
|
||||
}
|
||||
|
||||
func GetBlock(id string) (ret *Block, err error) {
|
||||
ret, err = getBlock(id)
|
||||
return
|
||||
}
|
||||
|
||||
func getBlock(id string) (ret *Block, err error) {
|
||||
if "" == id {
|
||||
return
|
||||
}
|
||||
|
||||
tree, err := loadTreeByBlockID(id)
|
||||
if nil != err {
|
||||
return
|
||||
}
|
||||
|
||||
node := treenode.GetNodeInTree(tree, id)
|
||||
sqlBlock := sql.BuildBlockFromNode(node, tree)
|
||||
if nil == sqlBlock {
|
||||
return
|
||||
}
|
||||
ret = fromSQLBlock(sqlBlock, "", 0)
|
||||
return
|
||||
}
|
||||
|
||||
func getBlockRendered(id string, headingMode int) (ret *Block) {
|
||||
tree, _ := loadTreeByBlockID(id)
|
||||
if nil == tree {
|
||||
return
|
||||
}
|
||||
def := treenode.GetNodeInTree(tree, id)
|
||||
if nil == def {
|
||||
return
|
||||
}
|
||||
|
||||
var unlinks, nodes []*ast.Node
|
||||
ast.Walk(def, func(n *ast.Node, entering bool) ast.WalkStatus {
|
||||
if !entering {
|
||||
return ast.WalkContinue
|
||||
}
|
||||
|
||||
if ast.NodeHeading == n.Type {
|
||||
if "1" == n.IALAttr("fold") {
|
||||
children := treenode.FoldedHeadingChildren(n)
|
||||
for _, c := range children {
|
||||
unlinks = append(unlinks, c)
|
||||
}
|
||||
}
|
||||
}
|
||||
return ast.WalkContinue
|
||||
})
|
||||
for _, n := range unlinks {
|
||||
n.Unlink()
|
||||
}
|
||||
nodes = append(nodes, def)
|
||||
if 0 == headingMode && ast.NodeHeading == def.Type && "1" != def.IALAttr("fold") {
|
||||
children := treenode.HeadingChildren(def)
|
||||
for _, c := range children {
|
||||
if "1" == c.IALAttr("heading-fold") {
|
||||
// 嵌入块包含折叠标题时不应该显示其下方块 https://github.com/siyuan-note/siyuan/issues/4765
|
||||
continue
|
||||
}
|
||||
nodes = append(nodes, c)
|
||||
}
|
||||
}
|
||||
|
||||
b := treenode.GetBlockTree(def.ID)
|
||||
if nil == b {
|
||||
return
|
||||
}
|
||||
|
||||
luteEngine := NewLute()
|
||||
luteEngine.RenderOptions.ProtyleContenteditable = false // 不可编辑
|
||||
dom := renderBlockDOMByNodes(nodes, luteEngine)
|
||||
ret = &Block{Box: def.Box, Path: def.Path, HPath: b.HPath, ID: def.ID, Type: def.Type.String(), Content: dom}
|
||||
return
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue