Something went wrong. Try again.
A privacy-first, self-hosted, fully open source personal knowledge management software, written in typescript and golang. (PERSONAL FORK)
Something went wrong. Try again.
Go
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208// SiYuan - Refactor your thinking// 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 ( "errors" "fmt" "sort" "strings"
"github.com/88250/gulu" "github.com/88250/lute/parse" "github.com/siyuan-note/logging" "github.com/siyuan-note/siyuan/kernel/av" "github.com/siyuan-note/siyuan/kernel/cache" "github.com/siyuan-note/siyuan/kernel/sql" "github.com/siyuan-note/siyuan/kernel/treenode" "github.com/siyuan-note/siyuan/kernel/util")
func RemoveBookmark(bookmark string) (err error) { util.PushEndlessProgress(Conf.Language(116))
bookmarks := sql.QueryBookmarkBlocksByKeyword(bookmark) treeBlocks := map[string][]string{} for _, tag := range bookmarks { if blocks, ok := treeBlocks[tag.RootID]; !ok { treeBlocks[tag.RootID] = []string{tag.ID} } else { treeBlocks[tag.RootID] = append(blocks, tag.ID) } }
for treeID, blocks := range treeBlocks { util.PushEndlessProgress("[" + treeID + "]") tree, e := LoadTreeByBlockID(treeID) if nil != e { util.PushClearProgress() return e }
for _, blockID := range blocks { node := treenode.GetNodeInTree(tree, blockID) if nil == node { continue }
if bookmarkAttrVal := node.IALAttr("bookmark"); bookmarkAttrVal == bookmark { node.RemoveIALAttr("bookmark") cache.PutBlockIAL(node.ID, parse.IAL2Map(node.KramdownIAL)) } }
util.PushEndlessProgress(fmt.Sprintf(Conf.Language(111), util.EscapeHTML(tree.Root.IALAttr("title")))) if err = writeTreeUpsertQueue(tree); err != nil { util.ClearPushProgress(100) return } util.RandomSleep(50, 150) }
util.ReloadUI() return}
func RenameBookmark(oldBookmark, newBookmark string) (err error) { if invalidChar := treenode.ContainsMarker(newBookmark); "" != invalidChar { return errors.New(fmt.Sprintf(Conf.Language(112), invalidChar)) }
newBookmark = strings.TrimSpace(newBookmark) if "" == newBookmark { return errors.New(Conf.Language(126)) }
if oldBookmark == newBookmark { return }
util.PushEndlessProgress(Conf.Language(110))
bookmarks := sql.QueryBookmarkBlocksByKeyword(oldBookmark) treeBlocks := map[string][]string{} for _, tag := range bookmarks { if blocks, ok := treeBlocks[tag.RootID]; !ok { treeBlocks[tag.RootID] = []string{tag.ID} } else { treeBlocks[tag.RootID] = append(blocks, tag.ID) } }
for treeID, blocks := range treeBlocks { util.PushEndlessProgress("[" + treeID + "]") tree, e := LoadTreeByBlockID(treeID) if nil != e { util.ClearPushProgress(100) return e }
for _, blockID := range blocks { node := treenode.GetNodeInTree(tree, blockID) if nil == node { continue }
if bookmarkAttrVal := node.IALAttr("bookmark"); bookmarkAttrVal == oldBookmark { node.SetIALAttr("bookmark", newBookmark) cache.PutBlockIAL(node.ID, parse.IAL2Map(node.KramdownIAL)) } }
util.PushEndlessProgress(fmt.Sprintf(Conf.Language(111), util.EscapeHTML(tree.Root.IALAttr("title")))) if err = writeTreeUpsertQueue(tree); err != nil { util.ClearPushProgress(100) return } util.RandomSleep(50, 150) }
util.ReloadUI() return}
type BookmarkLabel stringtype BookmarkBlocks []*Block
type Bookmark struct { Name BookmarkLabel `json:"name"` Blocks []*Block `json:"blocks"` Type string `json:"type"` // "bookmark" Depth int `json:"depth"` Count int `json:"count"`}
type Bookmarks []*Bookmark
func (s Bookmarks) Len() int { return len(s) }func (s Bookmarks) Swap(i, j int) { s[i], s[j] = s[j], s[i] }func (s Bookmarks) Less(i, j int) bool { return s[i].Name < s[j].Name }
func BookmarkLabels() (ret []string) { ret = sql.QueryBookmarkLabels() return}
func BuildBookmark() (ret *Bookmarks) { FlushTxQueue() sql.FlushQueue()
ret = &Bookmarks{} sqlBlocks := sql.QueryBookmarkBlocks()
labelBlocks := map[BookmarkLabel]BookmarkBlocks{} blocks := fromSQLBlocks(&sqlBlocks, "", 0) luteEngine := NewLute() for _, block := range blocks { if "" != block.Name { // Blocks in the bookmark panel display their name instead of content https://github.com/siyuan-note/siyuan/issues/8514 block.Content = block.Name } else if "NodeAttributeView" == block.Type { // Display database title in bookmark panel https://github.com/siyuan-note/siyuan/issues/11666 avID := gulu.Str.SubStringBetween(block.Markdown, "av-id=\"", "\"") block.Content, _ = av.GetAttributeViewName(avID) } else { // Improve bookmark panel rendering https://github.com/siyuan-note/siyuan/issues/9361 tree, err := LoadTreeByBlockID(block.ID) if err != nil { logging.LogErrorf("parse block [%s] failed: %s", block.ID, err) } else { n := treenode.GetNodeInTree(tree, block.ID) block.Content = renderOutline(n, luteEngine) } }
label := BookmarkLabel(block.IAL["bookmark"]) if bs, ok := labelBlocks[label]; ok { bs = append(bs, block) labelBlocks[label] = bs } else { labelBlocks[label] = []*Block{block} } }
for label, bs := range labelBlocks { for _, b := range bs { b.Depth = 1 } *ret = append(*ret, &Bookmark{Name: label, Blocks: bs, Type: "bookmark", Count: len(bs)}) }
sort.Sort(ret) return}