mirror of
https://github.com/siyuan-note/siyuan.git
synced 2026-01-29 19:56:10 +01:00
Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
7b2f1a0efc
5 changed files with 146 additions and 12 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
104
kernel/model/export_merge.go
Normal file
104
kernel/model/export_merge.go
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
insertPoint := rootTree.Root.LastChild
|
||||
for {
|
||||
i := 0
|
||||
if err = walkBlock(insertPoint, rootBlock, i); nil != err {
|
||||
return
|
||||
}
|
||||
|
||||
if nil == rootBlock.Children {
|
||||
break
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func walkBlock(insertPoint *ast.Node, block *Block, level int) (err error) {
|
||||
level++
|
||||
for _, c := range block.Children {
|
||||
if err = walkBlock(insertPoint, c, level); nil != err {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
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-- {
|
||||
insertPoint.InsertAfter(nodes[j])
|
||||
}
|
||||
}
|
||||
block.Children = nil
|
||||
return
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
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
|
||||
}
|
||||
|
|
@ -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"`
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue