This commit is contained in:
Daniel 2024-12-18 17:17:24 +08:00
parent 5fb2b78911
commit b81de5d2da
No known key found for this signature in database
GPG Key ID: 86211BA83DF03017
4 changed files with 32 additions and 42 deletions

View File

@ -380,8 +380,7 @@ export const initNavigationMenu = (app: App, liElement: HTMLElement) => {
click: () => { click: () => {
const msgId = showMessage(window.siyuan.languages.exporting, -1); const msgId = showMessage(window.siyuan.languages.exporting, -1);
fetchPost("/api/export/exportNotebookMd", { fetchPost("/api/export/exportNotebookMd", {
notebook: notebookId, notebook: notebookId
path: "/"
}, response => { }, response => {
hideMessage(msgId); hideMessage(msgId);
openByMobile(response.data.zip); openByMobile(response.data.zip);

View File

@ -317,8 +317,7 @@ func exportNotebookMd(c *gin.Context) {
} }
notebook := arg["notebook"].(string) notebook := arg["notebook"].(string)
p := arg["path"].(string) zipPath := model.ExportNotebookMarkdown(notebook)
zipPath := model.ExportNotebookMarkdown(notebook, p)
ret.Data = map[string]interface{}{ ret.Data = map[string]interface{}{
"name": path.Base(zipPath), "name": path.Base(zipPath),
"zip": zipPath, "zip": zipPath,

View File

@ -272,7 +272,7 @@ func Export2Liandi(id string) (err error) {
".md", 4, 1, 0, ".md", 4, 1, 0,
"#", "#", "#", "#",
"", "", "", "",
false, nil, true) false, nil, true, &map[string]*parse.Tree{})
result := gulu.Ret.NewResult() result := gulu.Ret.NewResult()
request := httpclient.NewCloudRequest30s() request := httpclient.NewCloudRequest30s()
request = request. request = request.
@ -578,7 +578,7 @@ func Preview(id string) (retStdHTML string) {
blockRefMode, Conf.Export.BlockEmbedMode, Conf.Export.FileAnnotationRefMode, blockRefMode, Conf.Export.BlockEmbedMode, Conf.Export.FileAnnotationRefMode,
Conf.Export.TagOpenMarker, Conf.Export.TagCloseMarker, Conf.Export.TagOpenMarker, Conf.Export.TagCloseMarker,
Conf.Export.BlockRefTextLeft, Conf.Export.BlockRefTextRight, Conf.Export.BlockRefTextLeft, Conf.Export.BlockRefTextRight,
Conf.Export.AddTitle, true, true) Conf.Export.AddTitle, true, true, &map[string]*parse.Tree{})
luteEngine := NewLute() luteEngine := NewLute()
luteEngine.SetFootnotes(true) luteEngine.SetFootnotes(true)
addBlockIALNodes(tree, false) addBlockIALNodes(tree, false)
@ -681,7 +681,7 @@ func ExportMarkdownHTML(id, savePath string, docx, merge bool) (name, dom string
blockRefMode, Conf.Export.BlockEmbedMode, Conf.Export.FileAnnotationRefMode, blockRefMode, Conf.Export.BlockEmbedMode, Conf.Export.FileAnnotationRefMode,
Conf.Export.TagOpenMarker, Conf.Export.TagCloseMarker, Conf.Export.TagOpenMarker, Conf.Export.TagCloseMarker,
Conf.Export.BlockRefTextLeft, Conf.Export.BlockRefTextRight, Conf.Export.BlockRefTextLeft, Conf.Export.BlockRefTextRight,
Conf.Export.AddTitle, true, true) Conf.Export.AddTitle, true, true, &map[string]*parse.Tree{})
name = path.Base(tree.HPath) name = path.Base(tree.HPath)
name = util.FilterFileName(name) // 导出 PDF、HTML 和 Word 时未移除不支持的文件名符号 https://github.com/siyuan-note/siyuan/issues/5614 name = util.FilterFileName(name) // 导出 PDF、HTML 和 Word 时未移除不支持的文件名符号 https://github.com/siyuan-note/siyuan/issues/5614
savePath = strings.TrimSpace(savePath) savePath = strings.TrimSpace(savePath)
@ -840,7 +840,7 @@ func ExportHTML(id, savePath string, pdf, image, keepFold, merge bool) (name, do
blockRefMode, Conf.Export.BlockEmbedMode, Conf.Export.FileAnnotationRefMode, blockRefMode, Conf.Export.BlockEmbedMode, Conf.Export.FileAnnotationRefMode,
Conf.Export.TagOpenMarker, Conf.Export.TagCloseMarker, Conf.Export.TagOpenMarker, Conf.Export.TagCloseMarker,
Conf.Export.BlockRefTextLeft, Conf.Export.BlockRefTextRight, Conf.Export.BlockRefTextLeft, Conf.Export.BlockRefTextRight,
Conf.Export.AddTitle, true, true) Conf.Export.AddTitle, true, true, &map[string]*parse.Tree{})
name = path.Base(tree.HPath) name = path.Base(tree.HPath)
name = util.FilterFileName(name) // 导出 PDF、HTML 和 Word 时未移除不支持的文件名符号 https://github.com/siyuan-note/siyuan/issues/5614 name = util.FilterFileName(name) // 导出 PDF、HTML 和 Word 时未移除不支持的文件名符号 https://github.com/siyuan-note/siyuan/issues/5614
@ -1440,7 +1440,7 @@ func ExportStdMarkdown(id string) string {
".md", Conf.Export.BlockRefMode, Conf.Export.BlockEmbedMode, Conf.Export.FileAnnotationRefMode, ".md", Conf.Export.BlockRefMode, Conf.Export.BlockEmbedMode, Conf.Export.FileAnnotationRefMode,
Conf.Export.TagOpenMarker, Conf.Export.TagCloseMarker, Conf.Export.TagOpenMarker, Conf.Export.TagCloseMarker,
Conf.Export.BlockRefTextLeft, Conf.Export.BlockRefTextRight, Conf.Export.BlockRefTextLeft, Conf.Export.BlockRefTextRight,
Conf.Export.AddTitle, defBlockIDs, true) Conf.Export.AddTitle, defBlockIDs, true, &map[string]*parse.Tree{})
} }
func ExportPandocConvertZip(ids []string, pandocTo, ext string) (name, zipPath string) { func ExportPandocConvertZip(ids []string, pandocTo, ext string) (name, zipPath string) {
@ -1468,32 +1468,21 @@ func ExportPandocConvertZip(ids []string, pandocTo, ext string) (name, zipPath s
return return
} }
func ExportNotebookMarkdown(boxID, folderPath string) (zipPath string) { func ExportNotebookMarkdown(boxID string) (zipPath string) {
box := Conf.Box(boxID) box := Conf.Box(boxID)
docFiles := box.ListFiles("/")
var baseFolderName string
if "/" == folderPath {
baseFolderName = box.Name
} else {
block := treenode.GetBlockTreeRootByHPath(box.ID, folderPath)
if nil == block {
logging.LogErrorf("not found block")
return
}
baseFolderName = path.Base(block.HPath)
}
if "" == baseFolderName {
baseFolderName = Conf.language(105)
}
docFiles := box.ListFiles(folderPath)
var docPaths []string var docPaths []string
for _, docFile := range docFiles { for _, docFile := range docFiles {
id := strings.TrimSuffix(path.Base(docFile.path), ".sy")
if !ast.IsNodeIDPattern(id) {
continue
}
docPaths = append(docPaths, docFile.path) docPaths = append(docPaths, docFile.path)
} }
defBlockIDs, trees, docPaths := prepareExportTrees(docPaths) defBlockIDs, trees, docPaths := prepareExportTrees(docPaths)
zipPath = exportPandocConvertZip(baseFolderName, docPaths, defBlockIDs, "", "", ".md", trees) zipPath = exportPandocConvertZip(box.Name, docPaths, defBlockIDs, "", "", ".md", trees)
return return
} }
@ -1927,11 +1916,11 @@ func walkRelationAvs(avID string, exportAvIDs *hashset.Set) {
} }
func ExportMarkdownContent(id string) (hPath, exportedMd string) { func ExportMarkdownContent(id string) (hPath, exportedMd string) {
return exportMarkdownContent(id, ".md", Conf.Export.BlockRefMode, nil, true) return exportMarkdownContent(id, ".md", Conf.Export.BlockRefMode, nil, true, &map[string]*parse.Tree{})
} }
func exportMarkdownContent(id, ext string, exportRefMode int, defBlockIDs []string, singleFile bool) (hPath, exportedMd string) { func exportMarkdownContent(id, ext string, exportRefMode int, defBlockIDs []string, singleFile bool, treeCache *map[string]*parse.Tree) (hPath, exportedMd string) {
tree, err := LoadTreeByBlockID(id) tree, err := loadTreeWithCache(id, treeCache)
if err != nil { if err != nil {
logging.LogErrorf("load tree by block id [%s] failed: %s", id, err) logging.LogErrorf("load tree by block id [%s] failed: %s", id, err)
return return
@ -1941,7 +1930,7 @@ func exportMarkdownContent(id, ext string, exportRefMode int, defBlockIDs []stri
ext, exportRefMode, Conf.Export.BlockEmbedMode, Conf.Export.FileAnnotationRefMode, ext, exportRefMode, Conf.Export.BlockEmbedMode, Conf.Export.FileAnnotationRefMode,
Conf.Export.TagOpenMarker, Conf.Export.TagCloseMarker, Conf.Export.TagOpenMarker, Conf.Export.TagCloseMarker,
Conf.Export.BlockRefTextLeft, Conf.Export.BlockRefTextRight, Conf.Export.BlockRefTextLeft, Conf.Export.BlockRefTextRight,
Conf.Export.AddTitle, defBlockIDs, singleFile) Conf.Export.AddTitle, defBlockIDs, singleFile, treeCache)
docIAL := parse.IAL2Map(tree.Root.KramdownIAL) docIAL := parse.IAL2Map(tree.Root.KramdownIAL)
exportedMd = yfm(docIAL) + exportedMd exportedMd = yfm(docIAL) + exportedMd
return return
@ -1950,12 +1939,12 @@ func exportMarkdownContent(id, ext string, exportRefMode int, defBlockIDs []stri
func exportMarkdownContent0(tree *parse.Tree, cloudAssetsBase string, assetsDestSpace2Underscore bool, func exportMarkdownContent0(tree *parse.Tree, cloudAssetsBase string, assetsDestSpace2Underscore bool,
ext string, blockRefMode, blockEmbedMode, fileAnnotationRefMode int, ext string, blockRefMode, blockEmbedMode, fileAnnotationRefMode int,
tagOpenMarker, tagCloseMarker string, blockRefTextLeft, blockRefTextRight string, tagOpenMarker, tagCloseMarker string, blockRefTextLeft, blockRefTextRight string,
addTitle bool, defBlockIDs []string, singleFile bool) (ret string) { addTitle bool, defBlockIDs []string, singleFile bool, treeCache *map[string]*parse.Tree) (ret string) {
tree = exportTree(tree, false, false, false, tree = exportTree(tree, false, false, false,
blockRefMode, blockEmbedMode, fileAnnotationRefMode, blockRefMode, blockEmbedMode, fileAnnotationRefMode,
tagOpenMarker, tagCloseMarker, tagOpenMarker, tagCloseMarker,
blockRefTextLeft, blockRefTextRight, blockRefTextLeft, blockRefTextRight,
addTitle, 0 < len(defBlockIDs), singleFile) addTitle, 0 < len(defBlockIDs), singleFile, treeCache)
luteEngine := NewLute() luteEngine := NewLute()
luteEngine.SetFootnotes(true) luteEngine.SetFootnotes(true)
luteEngine.SetKramdownIAL(false) luteEngine.SetKramdownIAL(false)
@ -2066,7 +2055,7 @@ func exportTree(tree *parse.Tree, wysiwyg, keepFold, avHiddenCol bool,
blockRefMode, blockEmbedMode, fileAnnotationRefMode int, blockRefMode, blockEmbedMode, fileAnnotationRefMode int,
tagOpenMarker, tagCloseMarker string, tagOpenMarker, tagCloseMarker string,
blockRefTextLeft, blockRefTextRight string, blockRefTextLeft, blockRefTextRight string,
addTitle, addDocAnchorSpan, singleFile bool) (ret *parse.Tree) { addTitle, addDocAnchorSpan, singleFile bool, treeCache *map[string]*parse.Tree) (ret *parse.Tree) {
luteEngine := NewLute() luteEngine := NewLute()
ret = tree ret = tree
id := tree.Root.ID id := tree.Root.ID
@ -2075,17 +2064,15 @@ func exportTree(tree *parse.Tree, wysiwyg, keepFold, avHiddenCol bool,
depth := 0 depth := 0
resolveEmbedR(ret.Root, blockEmbedMode, luteEngine, &[]string{}, &depth) resolveEmbedR(ret.Root, blockEmbedMode, luteEngine, &[]string{}, &depth)
treeCache := map[string]*parse.Tree{}
treeCache[id] = ret
// 将块超链接转换为引用 // 将块超链接转换为引用
depth = 0 depth = 0
blockLink2Ref(ret, ret.ID, &treeCache, &depth) blockLink2Ref(ret, ret.ID, treeCache, &depth)
// 收集引用转脚注+锚点哈希 // 收集引用转脚注+锚点哈希
var refFootnotes []*refAsFootnotes var refFootnotes []*refAsFootnotes
if 4 == blockRefMode && singleFile { if 4 == blockRefMode && singleFile {
depth = 0 depth = 0
collectFootnotesDefs(ret, ret.ID, &refFootnotes, &treeCache, &depth) collectFootnotesDefs(ret, ret.ID, &refFootnotes, treeCache, &depth)
} }
currentTreeNodeIDs := map[string]bool{} currentTreeNodeIDs := map[string]bool{}
@ -2193,7 +2180,7 @@ func exportTree(tree *parse.Tree, wysiwyg, keepFold, avHiddenCol bool,
if 4 == blockRefMode { // 脚注+锚点哈希 if 4 == blockRefMode { // 脚注+锚点哈希
unlinks = nil unlinks = nil
footnotesDefBlock := resolveFootnotesDefs(&refFootnotes, ret, currentTreeNodeIDs, blockRefTextLeft, blockRefTextRight, &treeCache) footnotesDefBlock := resolveFootnotesDefs(&refFootnotes, ret, currentTreeNodeIDs, blockRefTextLeft, blockRefTextRight, treeCache)
if nil != footnotesDefBlock { if nil != footnotesDefBlock {
// 如果是聚焦导出,可能存在没有使用的脚注定义块,在这里进行清理 // 如果是聚焦导出,可能存在没有使用的脚注定义块,在这里进行清理
// Improve focus export conversion of block refs to footnotes https://github.com/siyuan-note/siyuan/issues/10647 // Improve focus export conversion of block refs to footnotes https://github.com/siyuan-note/siyuan/issues/10647
@ -3011,7 +2998,7 @@ func exportPandocConvertZip(baseFolderName string, docPaths, defBlockIDs []strin
luteEngine := util.NewLute() luteEngine := util.NewLute()
for i, p := range docPaths { for i, p := range docPaths {
id := util.GetTreeID(p) id := util.GetTreeID(p)
hPath, md := exportMarkdownContent(id, ext, exportRefMode, defBlockIDs, false) hPath, md := exportMarkdownContent(id, ext, exportRefMode, defBlockIDs, false, treeCache)
dir, name = path.Split(hPath) dir, name = path.Split(hPath)
dir = util.FilterFilePath(dir) // 导出文档时未移除不支持的文件名符号 https://github.com/siyuan-note/siyuan/issues/4590 dir = util.FilterFilePath(dir) // 导出文档时未移除不支持的文件名符号 https://github.com/siyuan-note/siyuan/issues/4590
name = util.FilterFileName(name) name = util.FilterFileName(name)
@ -3121,6 +3108,10 @@ func prepareExportTrees(docPaths []string) (defBlockIDs []string, trees *map[str
treeCache := &map[string]*parse.Tree{} treeCache := &map[string]*parse.Tree{}
defBlockIDs = []string{} defBlockIDs = []string{}
for _, p := range docPaths { for _, p := range docPaths {
if strings.HasSuffix(p, ".sy") {
continue
}
id := util.GetTreeID(p) id := util.GetTreeID(p)
tree, err := loadTreeWithCache(id, treeCache) tree, err := loadTreeWithCache(id, treeCache)
if err != nil { if err != nil {

View File

@ -210,7 +210,8 @@ func LoadTreeByBlockIDWithReindex(id string) (ret *parse.Tree, err error) {
func LoadTreeByBlockID(id string) (ret *parse.Tree, err error) { func LoadTreeByBlockID(id string) (ret *parse.Tree, err error) {
if !ast.IsNodeIDPattern(id) { if !ast.IsNodeIDPattern(id) {
logging.LogErrorf("block id is invalid [id=%s]", id) stack := logging.ShortStack()
logging.LogErrorf("block id is invalid [id=%s], stack: [%s]", id, stack)
return nil, ErrTreeNotFound return nil, ErrTreeNotFound
} }