123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- // 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 treenode
- import (
- "crypto/sha256"
- "fmt"
- "path"
- "sort"
- "strings"
- "github.com/88250/gulu"
- "github.com/88250/lute"
- "github.com/88250/lute/ast"
- "github.com/88250/lute/parse"
- util2 "github.com/88250/lute/util"
- "github.com/siyuan-note/siyuan/kernel/util"
- )
- func StatTree(tree *parse.Tree) (ret *util.BlockStatResult) {
- runeCnt, wordCnt, linkCnt, imgCnt, refCnt := tree.Root.Stat()
- return &util.BlockStatResult{
- RuneCount: runeCnt,
- WordCount: wordCnt,
- LinkCount: linkCnt,
- ImageCount: imgCnt,
- RefCount: refCnt,
- }
- }
- func NodeHash(node *ast.Node, tree *parse.Tree, luteEngine *lute.Lute) string {
- ialArray := node.KramdownIAL
- sort.Slice(ialArray, func(i, j int) bool {
- return ialArray[i][0] < ialArray[j][0]
- })
- ial := parse.IAL2Tokens(ialArray)
- var md string
- if ast.NodeDocument != node.Type {
- md = FormatNode(node, luteEngine)
- }
- hpath := tree.HPath
- data := tree.Path + hpath + string(ial) + md
- return fmt.Sprintf("%x", sha256.Sum256(gulu.Str.ToBytes(data)))[:7]
- }
- func TreeRoot(node *ast.Node) *ast.Node {
- for p := node; nil != p; p = p.Parent {
- if ast.NodeDocument == p.Type {
- return p
- }
- }
- return &ast.Node{Type: ast.NodeDocument}
- }
- func NewTree(boxID, p, hp, title string) *parse.Tree {
- id := strings.TrimSuffix(path.Base(p), ".sy")
- root := &ast.Node{Type: ast.NodeDocument, ID: id}
- root.SetIALAttr("title", title)
- root.SetIALAttr("id", id)
- root.SetIALAttr("updated", util.TimeFromID(id))
- ret := &parse.Tree{Root: root}
- ret.Box = boxID
- ret.Path = p
- ret.HPath = hp
- ret.Root.Spec = "1"
- newPara := &ast.Node{Type: ast.NodeParagraph, ID: ast.NewNodeID()}
- newPara.SetIALAttr("id", newPara.ID)
- newPara.SetIALAttr("updated", util.TimeFromID(newPara.ID))
- ret.Root.AppendChild(newPara)
- return ret
- }
- func IsEmptyBlockIAL(n *ast.Node) bool {
- if ast.NodeKramdownBlockIAL != n.Type {
- return false
- }
- if util2.IsDocIAL(n.Tokens) {
- return false
- }
- if nil != n.Previous {
- if ast.NodeKramdownBlockIAL == n.Previous.Type {
- return true
- }
- return false
- }
- return true
- }
- func IALStr(n *ast.Node) string {
- if 1 > len(n.KramdownIAL) {
- return ""
- }
- return string(parse.IAL2Tokens(n.KramdownIAL))
- }
|