Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
Vanessa 2023-10-24 09:44:56 +08:00
commit fa6ee1b1ab
20 changed files with 144 additions and 148 deletions

View file

@ -30,6 +30,8 @@ Below are the detailed changes in this version.
* [After `Alt+[`, `Ctrl+Enter` and `Ctrl+Click` generates a dynamic ref](https://github.com/siyuan-note/siyuan/issues/9480)
* [Add some icons](https://github.com/siyuan-note/siyuan/issues/9481)
* [Improve KaTex macros parsing](https://github.com/siyuan-note/siyuan/issues/9485)
* [Improve priority of folding processing when headings and super blocks are mixed](https://github.com/siyuan-note/siyuan/issues/9488)
* [Remove invisible characters when entering document title](https://github.com/siyuan-note/siyuan/issues/9493)
### Bugfix
@ -37,6 +39,8 @@ Below are the detailed changes in this version.
### Development
* [Enhance compatibility and the plugin command cannot be set to empty](https://github.com/siyuan-note/siyuan/issues/9231)
* [Add plugin event bus `paste`](https://github.com/siyuan-note/siyuan/issues/9452)
* [Improve database date column "Is Empty" filtering](https://github.com/siyuan-note/siyuan/issues/9463)
* [Deprecated `loaded-protyle` use `loaded-protyle-static` instead](https://github.com/siyuan-note/siyuan/issues/9468)
* [Shallow clone the corresponding database when the template contains database blocks](https://github.com/siyuan-note/siyuan/issues/9494)

View file

@ -30,6 +30,8 @@
* [按 `Alt+[` 後支援透過 `Ctrl+Enter` 和 `Ctrl+Click` 產生動態錨文本](https://github.com/siyuan-note/siyuan/issues/9480)
* [新增一些圖示](https://github.com/siyuan-note/siyuan/issues/9481)
* [改進 KaTex 宏定義解析](https://github.com/siyuan-note/siyuan/issues/9485)
* [改進標題區塊和超級區塊混用時折疊處理的優先順序](https://github.com/siyuan-note/siyuan/issues/9488)
* [輸入文件標題時移除不可見字元](https://github.com/siyuan-note/siyuan/issues/9493)
### 修復缺陷
@ -37,6 +39,8 @@
### 開發者
* [改進插件命令相容性](https://github.com/siyuan-note/siyuan/issues/9231)
* [新增插件事件 `paste`](https://github.com/siyuan-note/siyuan/issues/9452)
* [改進資料庫視圖「為空」過濾](https://github.com/siyuan-note/siyuan/issues/9463)
* [棄用 `loaded-protyle` 使用 `loaded-protyle-static` 替代](https://github.com/siyuan-note/siyuan/issues/9468)
* [模板中包含資料庫區塊時淺克隆對應資料庫](https://github.com/siyuan-note/siyuan/issues/9494)

View file

@ -30,6 +30,8 @@
* [按 `Alt+[` 后支持通过 `Ctrl+Enter` 和 `Ctrl+Click` 生成动态锚文本](https://github.com/siyuan-note/siyuan/issues/9480)
* [添加一些图标](https://github.com/siyuan-note/siyuan/issues/9481)
* [改进 KaTex 宏定义解析](https://github.com/siyuan-note/siyuan/issues/9485)
* [改进标题块和超级块混用时折叠处理的优先级](https://github.com/siyuan-note/siyuan/issues/9488)
* [输入文档标题时移除不可见字符](https://github.com/siyuan-note/siyuan/issues/9493)
### 修复缺陷
@ -37,6 +39,8 @@
### 开发者
* [改进插件命令兼容性](https://github.com/siyuan-note/siyuan/issues/9231)
* [添加插件事件 `paste`](https://github.com/siyuan-note/siyuan/issues/9452)
* [改进数据库视图“为空”过滤](https://github.com/siyuan-note/siyuan/issues/9463)
* [弃用 `loaded-protyle` 使用 `loaded-protyle-static` 替代](https://github.com/siyuan-note/siyuan/issues/9468)
* [模板中包含数据库块时浅克隆对应数据库](https://github.com/siyuan-note/siyuan/issues/9494)

View file

@ -2,30 +2,14 @@ export const removeFoldHeading = (nodeElement: Element) => {
const nodeH = parseInt(nodeElement.getAttribute("data-subtype").substr(1));
let nextElement = nodeElement.nextElementSibling;
while (nextElement) {
if (nextElement.classList.contains("sb")) {
let nextFirstElement = nextElement.firstElementChild;
while (nextFirstElement && nextFirstElement.classList.contains("sb")) {
nextFirstElement = nextFirstElement.firstElementChild;
}
if ((nextFirstElement.getAttribute("data-type") === "NodeHeading" &&
parseInt(nextFirstElement.getAttribute("data-subtype").substr(1)) > nodeH) ||
nextFirstElement.getAttribute("data-type") !== "NodeHeading") {
const tempElement = nextElement;
nextElement = nextElement.nextElementSibling;
tempElement.remove();
} else {
break;
}
const currentH = parseInt(nextElement.getAttribute("data-subtype")?.substr(1));
if (!nextElement.classList.contains("protyle-attr") && // 超级块末尾为属性
(isNaN(currentH) || currentH > nodeH)) {
const tempElement = nextElement;
nextElement = nextElement.nextElementSibling;
tempElement.remove();
} else {
const currentH = parseInt(nextElement.getAttribute("data-subtype")?.substr(1));
if (!nextElement.classList.contains("protyle-attr") && // 超级块末尾为属性
(isNaN(currentH) || currentH > nodeH)) {
const tempElement = nextElement;
nextElement = nextElement.nextElementSibling;
tempElement.remove();
} else {
break;
}
break;
}
}
};

View file

@ -80,7 +80,12 @@ func renderTemplate(c *gin.Context) {
return
}
content, err := model.RenderTemplate(p, id)
preview := false
if previewArg := arg["preview"]; nil != previewArg {
preview = previewArg.(bool)
}
content, err := model.RenderTemplate(p, id, preview)
if nil != err {
ret.Code = -1
ret.Msg = util.EscapeHTML(err.Error())

View file

@ -246,10 +246,10 @@ func getWorkspaces(c *gin.Context) {
}
}
sort.Slice(openedWorkspaces, func(i, j int) bool {
return natsort.Compare(util.RemoveEmoji(filepath.Base(openedWorkspaces[i].Path)), util.RemoveEmoji(filepath.Base(openedWorkspaces[j].Path)))
return natsort.Compare(util.RemoveEmojiInvisible(filepath.Base(openedWorkspaces[i].Path)), util.RemoveEmojiInvisible(filepath.Base(openedWorkspaces[j].Path)))
})
sort.Slice(closedWorkspaces, func(i, j int) bool {
return natsort.Compare(util.RemoveEmoji(filepath.Base(closedWorkspaces[i].Path)), util.RemoveEmoji(filepath.Base(closedWorkspaces[j].Path)))
return natsort.Compare(util.RemoveEmojiInvisible(filepath.Base(closedWorkspaces[i].Path)), util.RemoveEmojiInvisible(filepath.Base(closedWorkspaces[j].Path)))
})
workspaces = append(workspaces, openedWorkspaces...)
workspaces = append(workspaces, closedWorkspaces...)

View file

@ -46,6 +46,45 @@ type AttributeView struct {
Views []*View `json:"views"` // 视图
}
func ShallowCloneAttributeView(av *AttributeView) (ret *AttributeView) {
ret = &AttributeView{}
data, err := gulu.JSON.MarshalJSON(av)
if nil != err {
logging.LogErrorf("marshal attribute view [%s] failed: %s", av.ID, err)
return nil
}
if err = gulu.JSON.UnmarshalJSON(data, ret); nil != err {
logging.LogErrorf("unmarshal attribute view [%s] failed: %s", av.ID, err)
return nil
}
ret.ID = ast.NewNodeID()
view, err := ret.GetView()
if nil == err {
view.ID = ast.NewNodeID()
ret.ViewID = view.ID
} else {
view = NewView()
ret.ViewID = view.ID
ret.Views = append(ret.Views, view)
}
keyIDMap := map[string]string{}
for _, kv := range ret.KeyValues {
newID := ast.NewNodeID()
keyIDMap[kv.Key.ID] = newID
kv.Key.ID = newID
kv.Values = []*Value{}
}
view.Table.ID = ast.NewNodeID()
for _, column := range view.Table.Columns {
column.ID = keyIDMap[column.ID]
}
view.Table.RowIDs = []string{}
return
}
// KeyValues 描述了属性视图属性列值的结构。
type KeyValues struct {
Key *Key `json:"key"` // 属性视图属性列

View file

@ -6,7 +6,7 @@ require (
code.sajari.com/docconv v1.3.7
github.com/88250/clipboard v0.1.5
github.com/88250/epub v0.0.0-20230830085737-c19055cd1f48
github.com/88250/gulu v1.2.3-0.20230615033005-b519d6875346
github.com/88250/gulu v1.2.3-0.20231023172823-f152fc5d93ef
github.com/88250/lute v1.7.6-0.20231011010815-eeb59b60f14f
github.com/88250/pdfcpu v0.3.14-0.20230401044135-c7369a99720c
github.com/88250/vitess-sqlparser v0.0.0-20210205111146-56a2ded2aba1

View file

@ -8,8 +8,8 @@ github.com/88250/epub v0.0.0-20230830085737-c19055cd1f48 h1:qiE88Pw/9GG8hvMfpfB4
github.com/88250/epub v0.0.0-20230830085737-c19055cd1f48/go.mod h1:UgVSq5iO9pOvqs3hIGNVk6WXDiAB0v3Dlg4nssQJ7W4=
github.com/88250/go-sqlite3 v1.14.13-0.20220714142610-fbbda1ee84f5 h1:8HdZozCsXSiEXYAo8Zbi/r2Ld6Dd4MmGHgir3EaSuHQ=
github.com/88250/go-sqlite3 v1.14.13-0.20220714142610-fbbda1ee84f5/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/88250/gulu v1.2.3-0.20230615033005-b519d6875346 h1:U0wZN6zuf+vUhzdHC6DbZE/bY5FUt3FuCwn/KgObV44=
github.com/88250/gulu v1.2.3-0.20230615033005-b519d6875346/go.mod h1:pTWnjt+6qUqNnP9xltswsJxgCBVu3C7eW09u48LWX0k=
github.com/88250/gulu v1.2.3-0.20231023172823-f152fc5d93ef h1:LVJO3aj18v63T2whGGt3gL5imkJk+7ujPfFv38X7Oi8=
github.com/88250/gulu v1.2.3-0.20231023172823-f152fc5d93ef/go.mod h1:pTWnjt+6qUqNnP9xltswsJxgCBVu3C7eW09u48LWX0k=
github.com/88250/lute v1.7.6-0.20231011010815-eeb59b60f14f h1:3WsWusMYa05xg5bTG9hRe3WjEyoWboAHFa029Hbi0EQ=
github.com/88250/lute v1.7.6-0.20231011010815-eeb59b60f14f/go.mod h1:+wUqx/1kdFDbWtxn9LYJlaCOAeol2pjSO6w+WJTVQsg=
github.com/88250/pdfcpu v0.3.14-0.20230401044135-c7369a99720c h1:Dl/8S9iLyPMTElnWIBxmjaLiWrkI5P4a21ivwAn5pU0=

View file

@ -270,13 +270,13 @@ func GetBacklink2(id, keyword, mentionKeyword string, sortMode, mentionSortMode
case util.SortModeCreatedASC:
return backlinks[i].Created < backlinks[j].Created
case util.SortModeNameDESC:
return util.PinYinCompare(util.RemoveEmoji(backlinks[j].Name), util.RemoveEmoji(backlinks[i].Name))
return util.PinYinCompare(util.RemoveEmojiInvisible(backlinks[j].Name), util.RemoveEmojiInvisible(backlinks[i].Name))
case util.SortModeNameASC:
return util.PinYinCompare(util.RemoveEmoji(backlinks[i].Name), util.RemoveEmoji(backlinks[j].Name))
return util.PinYinCompare(util.RemoveEmojiInvisible(backlinks[i].Name), util.RemoveEmojiInvisible(backlinks[j].Name))
case util.SortModeAlphanumDESC:
return natsort.Compare(util.RemoveEmoji(backlinks[j].Name), util.RemoveEmoji(backlinks[i].Name))
return natsort.Compare(util.RemoveEmojiInvisible(backlinks[j].Name), util.RemoveEmojiInvisible(backlinks[i].Name))
case util.SortModeAlphanumASC:
return natsort.Compare(util.RemoveEmoji(backlinks[i].Name), util.RemoveEmoji(backlinks[j].Name))
return natsort.Compare(util.RemoveEmojiInvisible(backlinks[i].Name), util.RemoveEmojiInvisible(backlinks[j].Name))
}
return backlinks[i].ID > backlinks[j].ID
})
@ -299,13 +299,13 @@ func GetBacklink2(id, keyword, mentionKeyword string, sortMode, mentionSortMode
case util.SortModeCreatedASC:
return backmentions[i].Created < backmentions[j].Created
case util.SortModeNameDESC:
return util.PinYinCompare(util.RemoveEmoji(backmentions[j].Name), util.RemoveEmoji(backmentions[i].Name))
return util.PinYinCompare(util.RemoveEmojiInvisible(backmentions[j].Name), util.RemoveEmojiInvisible(backmentions[i].Name))
case util.SortModeNameASC:
return util.PinYinCompare(util.RemoveEmoji(backmentions[i].Name), util.RemoveEmoji(backmentions[j].Name))
return util.PinYinCompare(util.RemoveEmojiInvisible(backmentions[i].Name), util.RemoveEmojiInvisible(backmentions[j].Name))
case util.SortModeAlphanumDESC:
return natsort.Compare(util.RemoveEmoji(backmentions[j].Name), util.RemoveEmoji(backmentions[i].Name))
return natsort.Compare(util.RemoveEmojiInvisible(backmentions[j].Name), util.RemoveEmojiInvisible(backmentions[i].Name))
case util.SortModeAlphanumASC:
return natsort.Compare(util.RemoveEmoji(backmentions[i].Name), util.RemoveEmoji(backmentions[j].Name))
return natsort.Compare(util.RemoveEmojiInvisible(backmentions[i].Name), util.RemoveEmojiInvisible(backmentions[j].Name))
}
return backmentions[i].ID > backmentions[j].ID
})

View file

@ -152,21 +152,21 @@ func ListNotebooks() (ret []*Box, err error) {
switch Conf.FileTree.Sort {
case util.SortModeNameASC:
sort.Slice(ret, func(i, j int) bool {
return util.PinYinCompare(util.RemoveEmoji(ret[i].Name), util.RemoveEmoji(ret[j].Name))
return util.PinYinCompare(util.RemoveEmojiInvisible(ret[i].Name), util.RemoveEmojiInvisible(ret[j].Name))
})
case util.SortModeNameDESC:
sort.Slice(ret, func(i, j int) bool {
return util.PinYinCompare(util.RemoveEmoji(ret[j].Name), util.RemoveEmoji(ret[i].Name))
return util.PinYinCompare(util.RemoveEmojiInvisible(ret[j].Name), util.RemoveEmojiInvisible(ret[i].Name))
})
case util.SortModeUpdatedASC:
case util.SortModeUpdatedDESC:
case util.SortModeAlphanumASC:
sort.Slice(ret, func(i, j int) bool {
return natsort.Compare(util.RemoveEmoji(ret[i].Name), util.RemoveEmoji(ret[j].Name))
return natsort.Compare(util.RemoveEmojiInvisible(ret[i].Name), util.RemoveEmojiInvisible(ret[j].Name))
})
case util.SortModeAlphanumDESC:
sort.Slice(ret, func(i, j int) bool {
return natsort.Compare(util.RemoveEmoji(ret[j].Name), util.RemoveEmoji(ret[i].Name))
return natsort.Compare(util.RemoveEmojiInvisible(ret[j].Name), util.RemoveEmojiInvisible(ret[i].Name))
})
case util.SortModeCustom:
sort.Slice(ret, func(i, j int) bool { return ret[i].Sort < ret[j].Sort })

View file

@ -374,11 +374,11 @@ func ListDocTree(boxID, listPath string, sortMode int, flashcard, showHidden boo
switch sortMode {
case util.SortModeNameASC:
sort.Slice(docs, func(i, j int) bool {
return util.PinYinCompare(util.RemoveEmoji(docs[i].Name), util.RemoveEmoji(docs[j].Name))
return util.PinYinCompare(util.RemoveEmojiInvisible(docs[i].Name), util.RemoveEmojiInvisible(docs[j].Name))
})
case util.SortModeNameDESC:
sort.Slice(docs, func(i, j int) bool {
return util.PinYinCompare(util.RemoveEmoji(docs[j].Name), util.RemoveEmoji(docs[i].Name))
return util.PinYinCompare(util.RemoveEmojiInvisible(docs[j].Name), util.RemoveEmojiInvisible(docs[i].Name))
})
case util.SortModeUpdatedASC:
sort.Slice(docs, func(i, j int) bool { return docs[i].Mtime < docs[j].Mtime })
@ -386,11 +386,11 @@ func ListDocTree(boxID, listPath string, sortMode int, flashcard, showHidden boo
sort.Slice(docs, func(i, j int) bool { return docs[i].Mtime > docs[j].Mtime })
case util.SortModeAlphanumASC:
sort.Slice(docs, func(i, j int) bool {
return natsort.Compare(util.RemoveEmoji(docs[i].Name), util.RemoveEmoji(docs[j].Name))
return natsort.Compare(util.RemoveEmojiInvisible(docs[i].Name), util.RemoveEmojiInvisible(docs[j].Name))
})
case util.SortModeAlphanumDESC:
sort.Slice(docs, func(i, j int) bool {
return natsort.Compare(util.RemoveEmoji(docs[j].Name), util.RemoveEmoji(docs[i].Name))
return natsort.Compare(util.RemoveEmojiInvisible(docs[j].Name), util.RemoveEmojiInvisible(docs[i].Name))
})
case util.SortModeCustom:
fileTreeFiles := docs
@ -848,12 +848,6 @@ func loadNodesByMode(node *ast.Node, inputIndex, mode, size int, isDoc, isHeadin
if n.HeadingLevel <= level {
break
}
} else if ast.NodeSuperBlock == n.Type {
if h := treenode.SuperBlockHeading(n); nil != h {
if level >= h.HeadingLevel {
break
}
}
}
nodes = append(nodes, n)
count++
@ -1454,7 +1448,7 @@ func CreateDailyNote(boxID string) (p string, existed bool, err error) {
if !gulu.File.IsExist(tplPath) {
logging.LogWarnf("not found daily note template [%s]", tplPath)
} else {
dom, err = renderTemplate(tplPath, id)
dom, err = renderTemplate(tplPath, id, false)
if nil != err {
logging.LogWarnf("render daily note template [%s] failed: %s", boxConf.DailyNoteTemplatePath, err)
}

View file

@ -46,11 +46,14 @@ func (tx *Transaction) doFoldHeading(operation *Operation) (ret *TxErr) {
return &TxErr{code: TxErrCodeBlockNotFound, id: headingID}
}
children := treenode.HeadingChildren4Folding(heading)
children := treenode.HeadingChildren(heading)
for _, child := range children {
childrenIDs = append(childrenIDs, child.ID)
child.SetIALAttr("fold", "1")
child.SetIALAttr("heading-fold", "1")
ast.Walk(child, func(n *ast.Node, entering bool) ast.WalkStatus {
n.SetIALAttr("fold", "1")
n.SetIALAttr("heading-fold", "1")
return ast.WalkContinue
})
}
heading.SetIALAttr("fold", "1")
if err = tx.writeTree(tree); nil != err {
@ -80,10 +83,13 @@ func (tx *Transaction) doUnfoldHeading(operation *Operation) (ret *TxErr) {
return &TxErr{code: TxErrCodeBlockNotFound, id: headingID}
}
children := treenode.HeadingChildren4Folding(heading)
children := treenode.HeadingChildren(heading)
for _, child := range children {
child.RemoveIALAttr("heading-fold")
child.RemoveIALAttr("fold")
ast.Walk(child, func(n *ast.Node, entering bool) ast.WalkStatus {
n.RemoveIALAttr("heading-fold")
n.RemoveIALAttr("fold")
return ast.WalkContinue
})
}
heading.RemoveIALAttr("fold")
heading.RemoveIALAttr("heading-fold")

View file

@ -74,10 +74,17 @@ func SetPetalEnabled(name string, enabled bool, frontend string) (ret *Petal, er
func LoadPetals(frontend string) (ret []*Petal) {
ret = []*Petal{}
if Conf.Bazaar.PetalDisabled || !Conf.Bazaar.Trust {
if Conf.Bazaar.PetalDisabled {
return
}
if !Conf.Bazaar.Trust {
// 移动端没有集市模块,所以要默认开启,桌面端和 Docker 容器需要用户手动确认过信任后才能开启
if util.ContainerStd == util.Container || util.ContainerDocker == util.Container {
return
}
}
petals := getPetals()
for _, petal := range petals {
_, petal.DisplayName, petal.Incompatible = bazaar.ParseInstalledPlugin(petal.Name, frontend)

View file

@ -228,19 +228,19 @@ func sortTags(tags Tags) {
switch Conf.Tag.Sort {
case util.SortModeNameASC:
sort.Slice(tags, func(i, j int) bool {
return util.PinYinCompare(util.RemoveEmoji(tags[i].Name), util.RemoveEmoji(tags[j].Name))
return util.PinYinCompare(util.RemoveEmojiInvisible(tags[i].Name), util.RemoveEmojiInvisible(tags[j].Name))
})
case util.SortModeNameDESC:
sort.Slice(tags, func(j, i int) bool {
return util.PinYinCompare(util.RemoveEmoji(tags[i].Name), util.RemoveEmoji(tags[j].Name))
return util.PinYinCompare(util.RemoveEmojiInvisible(tags[i].Name), util.RemoveEmojiInvisible(tags[j].Name))
})
case util.SortModeAlphanumASC:
sort.Slice(tags, func(i, j int) bool {
return natsort.Compare(util.RemoveEmoji((tags)[i].Name), util.RemoveEmoji((tags)[j].Name))
return natsort.Compare(util.RemoveEmojiInvisible((tags)[i].Name), util.RemoveEmojiInvisible((tags)[j].Name))
})
case util.SortModeAlphanumDESC:
sort.Slice(tags, func(i, j int) bool {
return natsort.Compare(util.RemoveEmoji((tags)[j].Name), util.RemoveEmoji((tags)[i].Name))
return natsort.Compare(util.RemoveEmojiInvisible((tags)[j].Name), util.RemoveEmojiInvisible((tags)[i].Name))
})
case util.SortModeRefCountASC:
sort.Slice(tags, func(i, j int) bool { return (tags)[i].Count < (tags)[j].Count })
@ -248,7 +248,7 @@ func sortTags(tags Tags) {
sort.Slice(tags, func(i, j int) bool { return (tags)[i].Count > (tags)[j].Count })
default:
sort.Slice(tags, func(i, j int) bool {
return natsort.Compare(util.RemoveEmoji((tags)[i].Name), util.RemoveEmoji((tags)[j].Name))
return natsort.Compare(util.RemoveEmojiInvisible((tags)[i].Name), util.RemoveEmojiInvisible((tags)[j].Name))
})
}
}

View file

@ -20,6 +20,7 @@ import (
"bytes"
"errors"
"fmt"
"github.com/siyuan-note/siyuan/kernel/av"
"io/fs"
"os"
"path/filepath"
@ -163,11 +164,11 @@ func DocSaveAsTemplate(id, name string, overwrite bool) (code int, err error) {
return
}
func RenderTemplate(p, id string) (string, error) {
return renderTemplate(p, id)
func RenderTemplate(p, id string, preview bool) (string, error) {
return renderTemplate(p, id, preview)
}
func renderTemplate(p, id string) (string, error) {
func renderTemplate(p, id string, preview bool) (string, error) {
tree, err := loadTreeByBlockID(id)
if nil != err {
return "", err
@ -277,6 +278,25 @@ func renderTemplate(p, id string) (string, error) {
n.TextMarkInlineMathContent = strings.ReplaceAll(n.TextMarkInlineMathContent, "|", "&#124;")
}
}
if ast.NodeAttributeView == n.Type {
// 重新生成数据库视图
attrView, parseErr := av.ParseAttributeView(n.AttributeViewID)
if nil != parseErr {
logging.LogErrorf("parse attribute view [%s] failed: %s", n.AttributeViewID, parseErr)
} else {
cloned := av.ShallowCloneAttributeView(attrView)
if nil != cloned {
n.AttributeViewID = cloned.ID
if !preview {
if saveErr := av.SaveAttributeView(cloned); nil != saveErr {
logging.LogErrorf("save attribute view [%s] failed: %s", cloned.ID, saveErr)
}
}
}
}
}
return ast.WalkContinue
})
for _, n := range nodesNeedAppendChild {

View file

@ -881,12 +881,6 @@ func heading(node *ast.Node) *ast.Node {
currentLevel := 16
if ast.NodeHeading == node.Type {
currentLevel = node.HeadingLevel
} else if ast.NodeSuperBlock == node.Type {
superBlockHeading := treenode.SuperBlockHeading(node)
if nil != superBlockHeading {
node = superBlockHeading
currentLevel = node.HeadingLevel
}
}
for prev := node.Previous; nil != prev; prev = prev.Previous {

View file

@ -62,20 +62,6 @@ func IsInFoldedHeading(node, currentHeading *ast.Node) bool {
return false
}
if ast.NodeSuperBlock == node.Type {
// The super block below the folded heading contains headings of the same level and cannot be loaded https://github.com/siyuan-note/siyuan/issues/9162
if nil == currentHeading {
return false
}
sbChildHeading := SuperBlockHeading(node)
if nil != sbChildHeading {
if sbChildHeading.HeadingLevel <= currentHeading.HeadingLevel {
return false
}
}
}
heading := HeadingParent(node)
if nil == heading {
return false
@ -99,39 +85,6 @@ func GetHeadingFold(nodes []*ast.Node) (ret []*ast.Node) {
return
}
// HeadingChildren4Folding 获取标题下方所属该标题层级的所有节点,如果遇到超级块的话则递归获取超级块下方的所有节点。
// 折叠和取消折叠要用这个函数单独处理 https://github.com/siyuan-note/siyuan/issues/9435
func HeadingChildren4Folding(heading *ast.Node) (ret []*ast.Node) {
start := heading.Next
if nil == start {
return
}
if ast.NodeKramdownBlockIAL == start.Type {
start = start.Next // 跳过 heading 的 IAL
}
currentLevel := heading.HeadingLevel
for n := start; nil != n; n = n.Next {
if ast.NodeHeading == n.Type {
if currentLevel >= n.HeadingLevel {
break
}
} else if ast.NodeSuperBlock == n.Type {
ast.Walk(n, func(child *ast.Node, entering bool) ast.WalkStatus {
if !entering || !child.IsBlock() {
return ast.WalkContinue
}
ret = append(ret, child)
return ast.WalkContinue
})
continue
}
ret = append(ret, n)
}
return
}
func HeadingChildren(heading *ast.Node) (ret []*ast.Node) {
start := heading.Next
if nil == start {
@ -147,36 +100,12 @@ func HeadingChildren(heading *ast.Node) (ret []*ast.Node) {
if currentLevel >= n.HeadingLevel {
break
}
} else if ast.NodeSuperBlock == n.Type {
if h := SuperBlockHeading(n); nil != h {
if currentLevel >= h.HeadingLevel {
break
}
}
} else if ast.NodeSuperBlockCloseMarker == n.Type {
continue
}
ret = append(ret, n)
}
return
}
func SuperBlockHeading(sb *ast.Node) *ast.Node {
c := sb.FirstChild.Next.Next
if nil == c {
return nil
}
if ast.NodeHeading == c.Type {
return c
}
if ast.NodeSuperBlock == c.Type {
return SuperBlockHeading(c)
}
return nil
}
func SuperBlockLastHeading(sb *ast.Node) *ast.Node {
headings := sb.ChildrenByType(ast.NodeHeading)
if 0 < len(headings) {

View file

@ -16,7 +16,11 @@
package util
import "regexp"
import (
"regexp"
"github.com/88250/gulu"
)
var emojiRegex = regexp.MustCompile(`/([0-9#][\x{20E3}])|` +
`[\x{00ae}\x{00a9}\x{203C}\x{2047}\x{2048}\x{2049}\x{3030}\x{303D}\x{2139}\x{2122}\x{3297}\x{3299}]|` +
@ -37,6 +41,8 @@ var emojiRegex = regexp.MustCompile(`/([0-9#][\x{20E3}])|` +
`[\x{2700}-\x{27BF}]|` +
`[\x{10000}-\x{E01EF}]`)
func RemoveEmoji(text string) string {
return emojiRegex.ReplaceAllString(text, "")
func RemoveEmojiInvisible(text string) (ret string) {
ret = emojiRegex.ReplaceAllString(text, "")
ret = gulu.Str.RemoveInvisible(ret)
return
}

View file

@ -222,7 +222,7 @@ func initWorkspaceDir(workspaceArg string) {
}
if !gulu.File.IsDir(WorkspaceDir) {
logging.LogWarnf("use the default workspace [%s] since the specified workspace [%s] is not a dir", WorkspaceDir, defaultWorkspaceDir)
logging.LogWarnf("use the default workspace [%s] since the specified workspace [%s] is not a dir", defaultWorkspaceDir, WorkspaceDir)
if err := os.MkdirAll(defaultWorkspaceDir, 0755); nil != err && !os.IsExist(err) {
logging.LogErrorf("create default workspace folder [%s] failed: %s", defaultWorkspaceDir, err)
os.Exit(logging.ExitCodeInitWorkspaceErr)