From adc21c95200536ccdca9accbc9f5a6c81799e3d3 Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Sat, 10 Dec 2022 17:42:41 +0800 Subject: [PATCH 1/5] :art: Clean code --- kernel/model/file.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/model/file.go b/kernel/model/file.go index 520dea408..f8cb21b6b 100644 --- a/kernel/model/file.go +++ b/kernel/model/file.go @@ -50,9 +50,9 @@ import ( type File struct { Path string `json:"path"` - Name string `json:"name"` + Name string `json:"name"` // 标题,即 ial["title"] Icon string `json:"icon"` - Name1 string `json:"name1"` + Name1 string `json:"name1"` // 命名,即 ial["name"] Alias string `json:"alias"` Memo string `json:"memo"` Bookmark string `json:"bookmark"` From 5b45ed0c6778c27e05b1a6a7a5f7eed9a52204f2 Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Sat, 10 Dec 2022 17:44:23 +0800 Subject: [PATCH 2/5] =?UTF-8?q?:art:=20=E6=94=AF=E6=8C=81=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E5=AD=90=E6=96=87=E6=A1=A3=E5=AF=BC=E5=87=BA=20Word/P?= =?UTF-8?q?DF=20https://github.com/siyuan-note/siyuan/issues/3219?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/model/export_merge.go | 94 ++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 kernel/model/export_merge.go diff --git a/kernel/model/export_merge.go b/kernel/model/export_merge.go new file mode 100644 index 000000000..8c182620c --- /dev/null +++ b/kernel/model/export_merge.go @@ -0,0 +1,94 @@ +// 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 . + +package model + +import ( + "github.com/88250/lute/ast" + "github.com/88250/lute/parse" +) + +func mergeSubDocs(rootTree *parse.Tree) (ret *parse.Tree, err error) { + ret = rootTree + rootBlock := &Block{Box: rootTree.Box, ID: rootTree.ID, Path: rootTree.Path} + if err = buildBlockChildren(rootBlock); nil != err { + return + } + + for i := 0; i < 1024; i++ { + if err = walkBlock(ret, rootBlock); nil != err { + return + } + + if nil == rootBlock.Children { + break + } + } + return +} + +func walkBlock(tree *parse.Tree, block *Block) (err error) { + for _, c := range block.Children { + if err = walkBlock(tree, c); nil != err { + return + } + } + + for i := len(block.Children) - 1; -1 < i; i-- { + c := block.Children[i] + nodes, loadErr := loadTreeNodes(c.Box, c.Path) + if nil != loadErr { + return + } + + for j := len(nodes) - 1; -1 < j; j-- { + tree.Root.LastChild.InsertAfter(nodes[j]) + } + } + block.Children = nil + return +} + +func loadTreeNodes(box string, p string) (ret []*ast.Node, err error) { + tree, err := LoadTree(box, p) + if nil != err { + return + } + + for c := tree.Root.FirstChild; nil != c; c = c.Next { + ret = append(ret, c) + } + return +} + +func buildBlockChildren(block *Block) (err error) { + files, _, err := ListDocTree(block.Box, block.Path, Conf.FileTree.Sort) + if nil != err { + return + } + + for _, f := range files { + childBlock := &Block{Box: block.Box, ID: f.ID, Path: f.Path} + block.Children = append(block.Children, childBlock) + } + + for _, c := range block.Children { + if err = buildBlockChildren(c); nil != err { + return + } + } + return +} From b6d961f3471c1a7ea9652749426e805a85fb848c Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Sat, 10 Dec 2022 18:13:30 +0800 Subject: [PATCH 3/5] =?UTF-8?q?:art:=20=E6=94=AF=E6=8C=81=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E5=AD=90=E6=96=87=E6=A1=A3=E5=AF=BC=E5=87=BA=20Word/P?= =?UTF-8?q?DF=20https://github.com/siyuan-note/siyuan/issues/3219?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/model/export_merge.go | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/kernel/model/export_merge.go b/kernel/model/export_merge.go index 8c182620c..140e804ea 100644 --- a/kernel/model/export_merge.go +++ b/kernel/model/export_merge.go @@ -28,8 +28,10 @@ func mergeSubDocs(rootTree *parse.Tree) (ret *parse.Tree, err error) { return } - for i := 0; i < 1024; i++ { - if err = walkBlock(ret, rootBlock); nil != err { + insertPoint := rootTree.Root.LastChild + for { + i := 0 + if err = walkBlock(insertPoint, rootBlock, i); nil != err { return } @@ -40,34 +42,42 @@ func mergeSubDocs(rootTree *parse.Tree) (ret *parse.Tree, err error) { return } -func walkBlock(tree *parse.Tree, block *Block) (err error) { +func walkBlock(insertPoint *ast.Node, block *Block, level int) (err error) { + level++ for _, c := range block.Children { - if err = walkBlock(tree, c); nil != err { + if err = walkBlock(insertPoint, c, level); nil != err { return } } - for i := len(block.Children) - 1; -1 < i; i-- { - c := block.Children[i] - nodes, loadErr := loadTreeNodes(c.Box, c.Path) + for _, c := range block.Children { + nodes, loadErr := loadTreeNodes(c.Box, c.Path, level) if nil != loadErr { return } for j := len(nodes) - 1; -1 < j; j-- { - tree.Root.LastChild.InsertAfter(nodes[j]) + insertPoint.InsertAfter(nodes[j]) } } block.Children = nil return } -func loadTreeNodes(box string, p string) (ret []*ast.Node, err error) { +func loadTreeNodes(box string, p string, level int) (ret []*ast.Node, err error) { tree, err := LoadTree(box, p) if nil != err { return } + hLevel := level + if 6 < level { + hLevel = 6 + } + + heading := &ast.Node{Type: ast.NodeHeading, HeadingLevel: hLevel} + heading.AppendChild(&ast.Node{Type: ast.NodeText, Tokens: []byte(tree.Root.IALAttr("title"))}) + tree.Root.PrependChild(heading) for c := tree.Root.FirstChild; nil != c; c = c.Next { ret = append(ret, c) } From dede06d20bd3ebc58c46410eff1a1ab8d4ea9dd4 Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Sat, 10 Dec 2022 18:23:12 +0800 Subject: [PATCH 4/5] =?UTF-8?q?:art:=20=E6=94=AF=E6=8C=81=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E5=AD=90=E6=96=87=E6=A1=A3=E5=AF=BC=E5=87=BA=20Word/P?= =?UTF-8?q?DF=20https://github.com/siyuan-note/siyuan/issues/3219?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/api/export.go | 24 ++++++++++++++++++------ kernel/model/export.go | 25 +++++++++++++++++++++---- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/kernel/api/export.go b/kernel/api/export.go index aa7ed6f6a..a5d0c7820 100644 --- a/kernel/api/export.go +++ b/kernel/api/export.go @@ -160,7 +160,11 @@ func exportDocx(c *gin.Context) { id := arg["id"].(string) savePath := arg["savePath"].(string) removeAssets := arg["removeAssets"].(bool) - err := model.ExportDocx(id, savePath, removeAssets) + merge := false + if nil != arg["merge"] { + merge = arg["merge"].(bool) + } + err := model.ExportDocx(id, savePath, removeAssets, merge) if nil != err { ret.Code = 1 ret.Msg = err.Error() @@ -180,7 +184,7 @@ func exportMdHTML(c *gin.Context) { id := arg["id"].(string) savePath := arg["savePath"].(string) - name, content := model.ExportMarkdownHTML(id, savePath, false) + name, content := model.ExportMarkdownHTML(id, savePath, false, false) ret.Data = map[string]interface{}{ "id": id, "name": name, @@ -229,10 +233,14 @@ func exportPreviewHTML(c *gin.Context) { id := arg["id"].(string) keepFold := false - if arg["keepFold"] != nil { + if nil != arg["keepFold"] { keepFold = arg["keepFold"].(bool) } - name, content := model.ExportHTML(id, "", true, keepFold) + merge := false + if nil != arg["merge"] { + merge = arg["merge"].(bool) + } + name, content := model.ExportHTML(id, "", true, keepFold, merge) // 导出 PDF 预览时点击块引转换后的脚注跳转不正确 https://github.com/siyuan-note/siyuan/issues/5894 content = strings.ReplaceAll(content, "http://"+util.LocalHost+":"+util.ServerPort+"/#", "#") @@ -256,10 +264,14 @@ func exportHTML(c *gin.Context) { pdf := arg["pdf"].(bool) savePath := arg["savePath"].(string) keepFold := false - if arg["keepFold"] != nil { + if nil != arg["keepFold"] { keepFold = arg["keepFold"].(bool) } - name, content := model.ExportHTML(id, savePath, pdf, keepFold) + merge := false + if nil != arg["merge"] { + merge = arg["merge"].(bool) + } + name, content := model.ExportHTML(id, savePath, pdf, keepFold, merge) ret.Data = map[string]interface{}{ "id": id, "name": name, diff --git a/kernel/model/export.go b/kernel/model/export.go index 353b894a6..dc37da427 100644 --- a/kernel/model/export.go +++ b/kernel/model/export.go @@ -194,7 +194,7 @@ func Preview(id string) string { return luteEngine.ProtylePreview(tree, luteEngine.RenderOptions) } -func ExportDocx(id, savePath string, removeAssets bool) (err error) { +func ExportDocx(id, savePath string, removeAssets, merge bool) (err error) { if !util.IsValidPandocBin(Conf.Export.PandocBin) { return errors.New(Conf.Language(115)) } @@ -204,7 +204,7 @@ func ExportDocx(id, savePath string, removeAssets bool) (err error) { return } defer os.Remove(tmpDir) - name, content := ExportMarkdownHTML(id, tmpDir, true) + name, content := ExportMarkdownHTML(id, tmpDir, true, merge) tmpDocxPath := filepath.Join(tmpDir, name+".docx") args := []string{ // pandoc -f html --resource-path=请从这里开始 请从这里开始\index.html -o test.docx @@ -237,9 +237,18 @@ func ExportDocx(id, savePath string, removeAssets bool) (err error) { return } -func ExportMarkdownHTML(id, savePath string, docx bool) (name, dom string) { +func ExportMarkdownHTML(id, savePath string, docx, merge bool) (name, dom string) { tree, _ := loadTreeByBlockID(id) + if merge { + var mergeErr error + tree, mergeErr = mergeSubDocs(tree) + if nil != mergeErr { + logging.LogErrorf("merge sub docs failed: %s", mergeErr) + return + } + } + tree = exportTree(tree, true, true, false) name = path.Base(tree.HPath) name = util.FilterFileName(name) // 导出 PDF、HTML 和 Word 时未移除不支持的文件名符号 https://github.com/siyuan-note/siyuan/issues/5614 @@ -329,7 +338,7 @@ func ExportMarkdownHTML(id, savePath string, docx bool) (name, dom string) { return } -func ExportHTML(id, savePath string, pdf, keepFold bool) (name, dom string) { +func ExportHTML(id, savePath string, pdf, keepFold, merge bool) (name, dom string) { savePath = strings.TrimSpace(savePath) tree, _ := loadTreeByBlockID(id) var headings []*ast.Node @@ -354,6 +363,14 @@ func ExportHTML(id, savePath string, pdf, keepFold bool) (name, dom string) { } } + if merge { + var mergeErr error + tree, mergeErr = mergeSubDocs(tree) + if nil != mergeErr { + logging.LogErrorf("merge sub docs failed: %s", mergeErr) + return + } + } tree = exportTree(tree, true, true, keepFold) name = path.Base(tree.HPath) name = util.FilterFileName(name) // 导出 PDF、HTML 和 Word 时未移除不支持的文件名符号 https://github.com/siyuan-note/siyuan/issues/5614 From 4e0d9d6f883db3483814221e18e318b5242aba44 Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Sat, 10 Dec 2022 22:02:05 +0800 Subject: [PATCH 5/5] =?UTF-8?q?:bug:=20=E5=AF=BC=E5=85=A5=20Markdown=20?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E8=A7=A3=E6=9E=90=E4=BB=BB=E5=8A=A1=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E5=BC=82=E5=B8=B8=20Fix=20https://github.com/siyuan-n?= =?UTF-8?q?ote/siyuan/issues/6842?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/model/box.go | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/model/box.go b/kernel/model/box.go index 1020549a3..37a543411 100644 --- a/kernel/model/box.go +++ b/kernel/model/box.go @@ -442,6 +442,7 @@ func moveTree(tree *parse.Tree) { func parseStdMd(markdown []byte) (ret *parse.Tree) { luteEngine := lute.New() + luteEngine.SetProtyleWYSIWYG(true) luteEngine.SetFootnotes(false) luteEngine.SetToC(false) luteEngine.SetIndentCodeBlock(false)