Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
fa6ee1b1ab
20 changed files with 144 additions and 148 deletions
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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...)
|
||||
|
|
|
@ -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"` // 属性视图属性列
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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=
|
||||
|
|
|
@ -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
|
||||
})
|
||||
|
|
|
@ -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 })
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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, "|", "|")
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue