From 47f884f2bbda0c46d8a32a38ba279d7916aa0744 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Mon, 20 May 2024 23:21:59 +0800 Subject: [PATCH 1/3] :bug: Some emoji exceptions in the document title https://github.com/siyuan-note/siyuan/issues/11480 --- kernel/model/file.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/kernel/model/file.go b/kernel/model/file.go index 60301ef00..e5b73b027 100644 --- a/kernel/model/file.go +++ b/kernel/model/file.go @@ -1666,7 +1666,7 @@ func RenameDoc(boxID, p, title string) (err error) { return } - title = gulu.Str.RemoveInvisible(title) + title = removeInvisibleCharsInTitle(title) if 512 < utf8.RuneCountInString(title) { // 限制笔记本名和文档名最大长度为 `512` https://github.com/siyuan-note/siyuan/issues/6299 return errors.New(Conf.Language(106)) @@ -1706,7 +1706,7 @@ func RenameDoc(boxID, p, title string) (err error) { } func createDoc(boxID, p, title, dom string) (tree *parse.Tree, err error) { - title = gulu.Str.RemoveInvisible(title) + title = removeInvisibleCharsInTitle(title) if 512 < utf8.RuneCountInString(title) { // 限制笔记本名和文档名最大长度为 `512` https://github.com/siyuan-note/siyuan/issues/6299 err = errors.New(Conf.Language(106)) @@ -1819,6 +1819,14 @@ func createDoc(boxID, p, title, dom string) (tree *parse.Tree, err error) { return } +func removeInvisibleCharsInTitle(title string) string { + // 不要踢掉 零宽连字符,否则有的 Emoji 会变形 https://github.com/siyuan-note/siyuan/issues/11480 + title = strings.ReplaceAll(title, string(gulu.ZWJ), "__@ZWJ@__") + title = gulu.Str.RemoveInvisible(title) + title = strings.ReplaceAll(title, "__@ZWJ@__", string(gulu.ZWJ)) + return title +} + func moveSorts(rootID, fromBox, toBox string) { root := treenode.GetBlockTree(rootID) if nil == root { From dfc8d39a68c84892d234d9dc3a1b963db390633c Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Mon, 20 May 2024 23:40:15 +0800 Subject: [PATCH 2/3] :art: Improve workspace startup stability https://github.com/siyuan-note/siyuan/issues/11483 --- kernel/treenode/blocktree.go | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/kernel/treenode/blocktree.go b/kernel/treenode/blocktree.go index dc89ea428..8910cd1fc 100644 --- a/kernel/treenode/blocktree.go +++ b/kernel/treenode/blocktree.go @@ -451,6 +451,7 @@ func InitBlockTree(force bool) { return } + loadErr := atomic.Bool{} size := atomic.Int64{} waitGroup := &sync.WaitGroup{} p, _ := ants.NewPoolWithFunc(4, func(arg interface{}) { @@ -462,14 +463,15 @@ func InitBlockTree(force bool) { f, err := os.OpenFile(p, os.O_RDONLY, 0644) if nil != err { logging.LogErrorf("open block tree failed: %s", err) - os.Exit(logging.ExitCodeFileSysErr) + loadErr.Store(true) return } + defer f.Close() info, err := f.Stat() if nil != err { logging.LogErrorf("stat block tree failed: %s", err) - os.Exit(logging.ExitCodeFileSysErr) + loadErr.Store(true) return } size.Add(info.Size()) @@ -477,16 +479,7 @@ func InitBlockTree(force bool) { sliceData := map[string]*BlockTree{} if err = msgpack.NewDecoder(f).Decode(&sliceData); nil != err { logging.LogErrorf("unmarshal block tree failed: %s", err) - if err = os.RemoveAll(util.BlockTreePath); nil != err { - logging.LogErrorf("removed corrupted block tree failed: %s", err) - } - os.Exit(logging.ExitCodeFileSysErr) - return - } - - if err = f.Close(); nil != err { - logging.LogErrorf("close block tree failed: %s", err) - os.Exit(logging.ExitCodeFileSysErr) + loadErr.Store(true) return } @@ -505,6 +498,17 @@ func InitBlockTree(force bool) { waitGroup.Wait() p.Release() + if loadErr.Load() { + logging.LogInfof("cause block tree load error, remove block tree file") + if removeErr := os.RemoveAll(util.BlockTreePath); nil != removeErr { + logging.LogErrorf("remove block tree file failed: %s", removeErr) + os.Exit(logging.ExitCodeFileSysErr) + return + } + blockTrees = &sync.Map{} + return + } + elapsed := time.Since(start).Seconds() logging.LogInfof("read block tree [%s] to [%s], elapsed [%.2fs]", humanize.BytesCustomCeil(uint64(size.Load()), 2), util.BlockTreePath, elapsed) return From d3754bd63090bd5abdc533bd45ef30326f1210a3 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Tue, 21 May 2024 00:04:56 +0800 Subject: [PATCH 3/3] :art: The browser extension supports CSDN formula https://github.com/siyuan-note/siyuan/issues/5624 --- kernel/api/extension.go | 11 +++++++---- kernel/api/filetree.go | 8 +++++++- kernel/api/lute.go | 6 +++++- kernel/model/file.go | 5 ++++- kernel/model/import.go | 13 +++++++++++-- 5 files changed, 34 insertions(+), 9 deletions(-) diff --git a/kernel/api/extension.go b/kernel/api/extension.go index d8aa3e63f..7e9b259a3 100644 --- a/kernel/api/extension.go +++ b/kernel/api/extension.go @@ -121,10 +121,12 @@ func extensionCopy(c *gin.Context) { uploaded[oName] = "assets/" + fName } - luteEngine := util.NewStdLute() - md, _ := model.HTML2Markdown(dom) + md, withMath, _ := model.HTML2Markdown(dom) md = strings.TrimSpace(md) - + luteEngine := util.NewStdLute() + if withMath { + luteEngine.SetInlineMath(true) + } var unlinks []*ast.Node tree := parse.Parse("", []byte(md), luteEngine.ParseOptions) ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus { @@ -153,7 +155,8 @@ func extensionCopy(c *gin.Context) { md, _ = lute.FormatNodeSync(tree.Root, luteEngine.ParseOptions, luteEngine.RenderOptions) ret.Data = map[string]interface{}{ - "md": md, + "md": md, + "withMath": withMath, } ret.Msg = model.Conf.Language(72) } diff --git a/kernel/api/filetree.go b/kernel/api/filetree.go index 4ff87dc56..84e112f95 100644 --- a/kernel/api/filetree.go +++ b/kernel/api/filetree.go @@ -677,7 +677,13 @@ func createDocWithMd(c *gin.Context) { hPath = "/" + hPath } - id, err := model.CreateWithMarkdown(notebook, hPath, markdown, parentID, id) + withMath := false + withMathArg := arg["withMath"] + if nil != withMathArg { + withMath = withMathArg.(bool) + } + + id, err := model.CreateWithMarkdown(notebook, hPath, markdown, parentID, id, withMath) if nil != err { ret.Code = -1 ret.Msg = err.Error() diff --git a/kernel/api/lute.go b/kernel/api/lute.go index 34d0feaf7..db2ee54ed 100644 --- a/kernel/api/lute.go +++ b/kernel/api/lute.go @@ -57,13 +57,17 @@ func html2BlockDOM(c *gin.Context) { } dom := arg["dom"].(string) - markdown, err := model.HTML2Markdown(dom) + markdown, withMath, err := model.HTML2Markdown(dom) if nil != err { ret.Data = "Failed to convert" return } luteEngine := util.NewLute() + if withMath { + luteEngine.SetInlineMath(true) + } + var unlinks []*ast.Node tree := parse.Parse("", []byte(markdown), luteEngine.ParseOptions) ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus { diff --git a/kernel/model/file.go b/kernel/model/file.go index e5b73b027..62d8ca02a 100644 --- a/kernel/model/file.go +++ b/kernel/model/file.go @@ -1138,7 +1138,7 @@ func CreateDocByMd(boxID, p, title, md string, sorts []string) (tree *parse.Tree return } -func CreateWithMarkdown(boxID, hPath, md, parentID, id string) (retID string, err error) { +func CreateWithMarkdown(boxID, hPath, md, parentID, id string, withMath bool) (retID string, err error) { createDocLock.Lock() defer createDocLock.Unlock() @@ -1150,6 +1150,9 @@ func CreateWithMarkdown(boxID, hPath, md, parentID, id string) (retID string, er WaitForWritingFiles() luteEngine := util.NewLute() + if withMath { + luteEngine.SetInlineMath(true) + } dom := luteEngine.Md2BlockDOM(md, false) retID, err = createDocsByHPath(box.ID, hPath, dom, parentID, id) WaitForWritingFiles() diff --git a/kernel/model/import.go b/kernel/model/import.go index 3c933a77e..4ff0c6df3 100644 --- a/kernel/model/import.go +++ b/kernel/model/import.go @@ -55,12 +55,21 @@ import ( "github.com/siyuan-note/siyuan/kernel/util" ) -func HTML2Markdown(htmlStr string) (markdown string, err error) { +func HTML2Markdown(htmlStr string) (markdown string, withMath bool, err error) { assetDirPath := filepath.Join(util.DataDir, "assets") luteEngine := util.NewLute() tree := luteEngine.HTML2Tree(htmlStr) ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus { - if !entering || ast.NodeLinkDest != n.Type { + if !entering { + return ast.WalkContinue + } + + if ast.NodeInlineMath == n.Type { + withMath = true + return ast.WalkContinue + } + + if ast.NodeLinkDest != n.Type { return ast.WalkContinue }