mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-05-12 15:11:10 +08:00
Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
f4f9610a90
@ -21,6 +21,8 @@
|
|||||||
<a title="Twitter" target="_blank" href="https://twitter.com/b3logos"><img alt="Twitter Follow" src="https://img.shields.io/twitter/follow/b3logos?label=Follow&style=social"></a>
|
<a title="Twitter" target="_blank" href="https://twitter.com/b3logos"><img alt="Twitter Follow" src="https://img.shields.io/twitter/follow/b3logos?label=Follow&style=social"></a>
|
||||||
<a title="Discord" target="_blank" href="https://discord.gg/dmMbCqVX7G"><img alt="Chat on Discord" src="https://img.shields.io/discord/808152298789666826?label=Discord&logo=Discord&style=social"></a>
|
<a title="Discord" target="_blank" href="https://discord.gg/dmMbCqVX7G"><img alt="Chat on Discord" src="https://img.shields.io/discord/808152298789666826?label=Discord&logo=Discord&style=social"></a>
|
||||||
<br><br>
|
<br><br>
|
||||||
|
<a href="https://trendshift.io/repositories/3949" target="_blank"><img src="https://trendshift.io/api/badge/repositories/3949" alt="siyuan-note%2Fsiyuan | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
|
||||||
|
<br><br>
|
||||||
<a href="https://www.producthunt.com/products/siyuan/reviews?utm_source=badge-product_rating&utm_medium=badge&utm_souce=badge-siyuan" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/product_rating.svg?product_id=534576&theme=light" alt="SiYuan - A privacy-first personal knowledge management software | Product Hunt" style="width: 242px; height: 108px;" width="242" height="108" /></a>
|
<a href="https://www.producthunt.com/products/siyuan/reviews?utm_source=badge-product_rating&utm_medium=badge&utm_souce=badge-siyuan" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/product_rating.svg?product_id=534576&theme=light" alt="SiYuan - A privacy-first personal knowledge management software | Product Hunt" style="width: 242px; height: 108px;" width="242" height="108" /></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
<a title="Twitter" target="_blank" href="https://twitter.com/b3logos"><img alt="Twitter Follow" src="https://img.shields.io/twitter/follow/b3logos?label=Follow&style=social"></a>
|
<a title="Twitter" target="_blank" href="https://twitter.com/b3logos"><img alt="Twitter Follow" src="https://img.shields.io/twitter/follow/b3logos?label=Follow&style=social"></a>
|
||||||
<a title="Discord" target="_blank" href="https://discord.gg/dmMbCqVX7G"><img alt="Chat on Discord" src="https://img.shields.io/discord/808152298789666826?label=Discord&logo=Discord&style=social"></a>
|
<a title="Discord" target="_blank" href="https://discord.gg/dmMbCqVX7G"><img alt="Chat on Discord" src="https://img.shields.io/discord/808152298789666826?label=Discord&logo=Discord&style=social"></a>
|
||||||
<br><br>
|
<br><br>
|
||||||
|
<a href="https://trendshift.io/repositories/3949" target="_blank"><img src="https://trendshift.io/api/badge/repositories/3949" alt="siyuan-note%2Fsiyuan | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
|
||||||
|
<br><br>
|
||||||
<a href="https://www.producthunt.com/products/siyuan/reviews?utm_source=badge-product_rating&utm_medium=badge&utm_souce=badge-siyuan" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/product_rating.svg?product_id=534576&theme=light" alt="SiYuan - A privacy-first personal knowledge management software | Product Hunt" style="width: 242px; height: 108px;" width="242" height="108" /></a>
|
<a href="https://www.producthunt.com/products/siyuan/reviews?utm_source=badge-product_rating&utm_medium=badge&utm_souce=badge-siyuan" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/product_rating.svg?product_id=534576&theme=light" alt="SiYuan - A privacy-first personal knowledge management software | Product Hunt" style="width: 242px; height: 108px;" width="242" height="108" /></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
<a title="Twitter" target="_blank" href="https://twitter.com/b3logos"><img alt="Twitter Follow" src="https://img.shields.io/twitter/follow/b3logos?label=Follow&style=social"></a>
|
<a title="Twitter" target="_blank" href="https://twitter.com/b3logos"><img alt="Twitter Follow" src="https://img.shields.io/twitter/follow/b3logos?label=Follow&style=social"></a>
|
||||||
<a title="Discord" target="_blank" href="https://discord.gg/dmMbCqVX7G"><img alt="Chat on Discord" src="https://img.shields.io/discord/808152298789666826?label=Discord&logo=Discord&style=social"></a>
|
<a title="Discord" target="_blank" href="https://discord.gg/dmMbCqVX7G"><img alt="Chat on Discord" src="https://img.shields.io/discord/808152298789666826?label=Discord&logo=Discord&style=social"></a>
|
||||||
<br><br>
|
<br><br>
|
||||||
|
<a href="https://trendshift.io/repositories/3949" target="_blank"><img src="https://trendshift.io/api/badge/repositories/3949" alt="siyuan-note%2Fsiyuan | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
|
||||||
|
<br><br>
|
||||||
<a href="https://www.producthunt.com/products/siyuan/reviews?utm_source=badge-product_rating&utm_medium=badge&utm_souce=badge-siyuan" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/product_rating.svg?product_id=534576&theme=light" alt="SiYuan - A privacy-first personal knowledge management software | Product Hunt" style="width: 242px; height: 108px;" width="242" height="108" /></a>
|
<a href="https://www.producthunt.com/products/siyuan/reviews?utm_source=badge-product_rating&utm_medium=badge&utm_souce=badge-siyuan" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/product_rating.svg?product_id=534576&theme=light" alt="SiYuan - A privacy-first personal knowledge management software | Product Hunt" style="width: 242px; height: 108px;" width="242" height="108" /></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -392,7 +392,7 @@ export const repos = {
|
|||||||
<option value="3" ${window.siyuan.config.sync.mode === 3 ? "selected" : ""}>${window.siyuan.languages.syncMode3}</option>
|
<option value="3" ${window.siyuan.config.sync.mode === 3 ? "selected" : ""}>${window.siyuan.languages.syncMode3}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<label class="fn__flex b3-label${(window.siyuan.config.sync.mode !== 1 || window.siyuan.config.system.container === "docker" || window.siyuan.config.sync.provider !== 0) ? " fn__none" : ""}">
|
<label class="fn__flex b3-label${(window.siyuan.config.sync.mode !== 1) ? " fn__none" : ""}">
|
||||||
<div class="fn__flex-1">
|
<div class="fn__flex-1">
|
||||||
${window.siyuan.languages.syncInterval}
|
${window.siyuan.languages.syncInterval}
|
||||||
<div class="b3-label__text">${window.siyuan.languages.syncIntervalTip}</div>
|
<div class="b3-label__text">${window.siyuan.languages.syncIntervalTip}</div>
|
||||||
@ -477,9 +477,12 @@ export const repos = {
|
|||||||
fetchPost("/api/sync/setSyncMode", {mode: parseInt(syncModeElement.value, 10)}, () => {
|
fetchPost("/api/sync/setSyncMode", {mode: parseInt(syncModeElement.value, 10)}, () => {
|
||||||
if (syncModeElement.value === "1" && window.siyuan.config.sync.provider === 0 && window.siyuan.config.system.container !== "docker") {
|
if (syncModeElement.value === "1" && window.siyuan.config.sync.provider === 0 && window.siyuan.config.system.container !== "docker") {
|
||||||
syncPerceptionElement.parentElement.classList.remove("fn__none");
|
syncPerceptionElement.parentElement.classList.remove("fn__none");
|
||||||
syncIntervalElement.parentElement.classList.remove("fn__none");
|
|
||||||
} else {
|
} else {
|
||||||
syncPerceptionElement.parentElement.classList.add("fn__none");
|
syncPerceptionElement.parentElement.classList.add("fn__none");
|
||||||
|
}
|
||||||
|
if (syncModeElement.value === "1") {
|
||||||
|
syncIntervalElement.parentElement.classList.remove("fn__none");
|
||||||
|
} else {
|
||||||
syncIntervalElement.parentElement.classList.add("fn__none");
|
syncIntervalElement.parentElement.classList.add("fn__none");
|
||||||
}
|
}
|
||||||
window.siyuan.config.sync.mode = parseInt(syncModeElement.value, 10);
|
window.siyuan.config.sync.mode = parseInt(syncModeElement.value, 10);
|
||||||
@ -502,9 +505,12 @@ export const repos = {
|
|||||||
syncConfigElement.classList.add("fn__none");
|
syncConfigElement.classList.add("fn__none");
|
||||||
if (window.siyuan.config.sync.mode !== 1 || window.siyuan.config.system.container === "docker" || window.siyuan.config.sync.provider !== 0) {
|
if (window.siyuan.config.sync.mode !== 1 || window.siyuan.config.system.container === "docker" || window.siyuan.config.sync.provider !== 0) {
|
||||||
syncPerceptionElement.parentElement.classList.add("fn__none");
|
syncPerceptionElement.parentElement.classList.add("fn__none");
|
||||||
syncIntervalElement.parentElement.classList.add("fn__none");
|
|
||||||
} else {
|
} else {
|
||||||
syncPerceptionElement.parentElement.classList.remove("fn__none");
|
syncPerceptionElement.parentElement.classList.remove("fn__none");
|
||||||
|
}
|
||||||
|
if (window.siyuan.config.sync.mode !== 1) {
|
||||||
|
syncIntervalElement.parentElement.classList.add("fn__none");
|
||||||
|
} else {
|
||||||
syncIntervalElement.parentElement.classList.remove("fn__none");
|
syncIntervalElement.parentElement.classList.remove("fn__none");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -243,7 +243,7 @@ export const setInlineStyle = (set = true) => {
|
|||||||
unicode-range: U+263a, U+2194-2199, U+2934-2935, U+2639, U+26a0, U+25b6, U+25c0, U+23cf, U+2640, U+2642, U+203c, U+2049,
|
unicode-range: U+263a, U+2194-2199, U+2934-2935, U+2639, U+26a0, U+25b6, U+25c0, U+23cf, U+2640, U+2642, U+203c, U+2049,
|
||||||
U+2611, U+303d, U+00a9, U+00ae, U+2122, U+1f170-1f171, U+24c2, U+1f17e, U+1f17f, U+1f22f, U+1f250, U+1f21a,
|
U+2611, U+303d, U+00a9, U+00ae, U+2122, U+1f170-1f171, U+24c2, U+1f17e, U+1f17f, U+1f22f, U+1f250, U+1f21a,
|
||||||
U+1f232-1f23a, U+1f251, U+3297, U+3299, U+25aa, U+25ab, U+2660, U+2666, U+2665, U+2663, U+1f636, U+1f62e, U+1f642,
|
U+1f232-1f23a, U+1f251, U+3297, U+3299, U+25aa, U+25ab, U+2660, U+2666, U+2665, U+2663, U+1f636, U+1f62e, U+1f642,
|
||||||
U+1f635, U+2620, U+2763, U+2764, U+1f441, U+270c, U+261d, U+270d, U+200d, U+e50a, U+3030;
|
U+1f635, U+2620, U+2763, U+2764, U+1f441, U+270c, U+261d, U+270d, U+200d, U+e50a, U+3030, U+21aa, U+21a9;
|
||||||
}`;
|
}`;
|
||||||
}
|
}
|
||||||
style += `.b3-typography, .protyle-wysiwyg, .protyle-title {font-size:${window.siyuan.config.editor.fontSize}px !important}
|
style += `.b3-typography, .protyle-wysiwyg, .protyle-title {font-size:${window.siyuan.config.editor.fontSize}px !important}
|
||||||
|
@ -67,7 +67,7 @@ func exportEPUB(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
id := arg["id"].(string)
|
id := arg["id"].(string)
|
||||||
name, zipPath := model.ExportPandocConvertZip(id, "epub", ".epub")
|
name, zipPath := model.ExportPandocConvertZip([]string{id}, "epub", ".epub")
|
||||||
ret.Data = map[string]interface{}{
|
ret.Data = map[string]interface{}{
|
||||||
"name": name,
|
"name": name,
|
||||||
"zip": zipPath,
|
"zip": zipPath,
|
||||||
@ -84,7 +84,7 @@ func exportRTF(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
id := arg["id"].(string)
|
id := arg["id"].(string)
|
||||||
name, zipPath := model.ExportPandocConvertZip(id, "rtf", ".rtf")
|
name, zipPath := model.ExportPandocConvertZip([]string{id}, "rtf", ".rtf")
|
||||||
ret.Data = map[string]interface{}{
|
ret.Data = map[string]interface{}{
|
||||||
"name": name,
|
"name": name,
|
||||||
"zip": zipPath,
|
"zip": zipPath,
|
||||||
@ -101,7 +101,7 @@ func exportODT(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
id := arg["id"].(string)
|
id := arg["id"].(string)
|
||||||
name, zipPath := model.ExportPandocConvertZip(id, "odt", ".odt")
|
name, zipPath := model.ExportPandocConvertZip([]string{id}, "odt", ".odt")
|
||||||
ret.Data = map[string]interface{}{
|
ret.Data = map[string]interface{}{
|
||||||
"name": name,
|
"name": name,
|
||||||
"zip": zipPath,
|
"zip": zipPath,
|
||||||
@ -118,7 +118,7 @@ func exportMediaWiki(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
id := arg["id"].(string)
|
id := arg["id"].(string)
|
||||||
name, zipPath := model.ExportPandocConvertZip(id, "mediawiki", ".wiki")
|
name, zipPath := model.ExportPandocConvertZip([]string{id}, "mediawiki", ".wiki")
|
||||||
ret.Data = map[string]interface{}{
|
ret.Data = map[string]interface{}{
|
||||||
"name": name,
|
"name": name,
|
||||||
"zip": zipPath,
|
"zip": zipPath,
|
||||||
@ -135,7 +135,7 @@ func exportOrgMode(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
id := arg["id"].(string)
|
id := arg["id"].(string)
|
||||||
name, zipPath := model.ExportPandocConvertZip(id, "org", ".org")
|
name, zipPath := model.ExportPandocConvertZip([]string{id}, "org", ".org")
|
||||||
ret.Data = map[string]interface{}{
|
ret.Data = map[string]interface{}{
|
||||||
"name": name,
|
"name": name,
|
||||||
"zip": zipPath,
|
"zip": zipPath,
|
||||||
@ -152,7 +152,7 @@ func exportOPML(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
id := arg["id"].(string)
|
id := arg["id"].(string)
|
||||||
name, zipPath := model.ExportPandocConvertZip(id, "opml", ".opml")
|
name, zipPath := model.ExportPandocConvertZip([]string{id}, "opml", ".opml")
|
||||||
ret.Data = map[string]interface{}{
|
ret.Data = map[string]interface{}{
|
||||||
"name": name,
|
"name": name,
|
||||||
"zip": zipPath,
|
"zip": zipPath,
|
||||||
@ -169,7 +169,7 @@ func exportTextile(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
id := arg["id"].(string)
|
id := arg["id"].(string)
|
||||||
name, zipPath := model.ExportPandocConvertZip(id, "textile", ".textile")
|
name, zipPath := model.ExportPandocConvertZip([]string{id}, "textile", ".textile")
|
||||||
ret.Data = map[string]interface{}{
|
ret.Data = map[string]interface{}{
|
||||||
"name": name,
|
"name": name,
|
||||||
"zip": zipPath,
|
"zip": zipPath,
|
||||||
@ -186,7 +186,7 @@ func exportAsciiDoc(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
id := arg["id"].(string)
|
id := arg["id"].(string)
|
||||||
name, zipPath := model.ExportPandocConvertZip(id, "asciidoc", ".adoc")
|
name, zipPath := model.ExportPandocConvertZip([]string{id}, "asciidoc", ".adoc")
|
||||||
ret.Data = map[string]interface{}{
|
ret.Data = map[string]interface{}{
|
||||||
"name": name,
|
"name": name,
|
||||||
"zip": zipPath,
|
"zip": zipPath,
|
||||||
@ -203,7 +203,7 @@ func exportReStructuredText(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
id := arg["id"].(string)
|
id := arg["id"].(string)
|
||||||
name, zipPath := model.ExportPandocConvertZip(id, "rst", ".rst")
|
name, zipPath := model.ExportPandocConvertZip([]string{id}, "rst", ".rst")
|
||||||
ret.Data = map[string]interface{}{
|
ret.Data = map[string]interface{}{
|
||||||
"name": name,
|
"name": name,
|
||||||
"zip": zipPath,
|
"zip": zipPath,
|
||||||
@ -340,7 +340,7 @@ func exportMds(c *gin.Context) {
|
|||||||
ids = append(ids, id.(string))
|
ids = append(ids, id.(string))
|
||||||
}
|
}
|
||||||
|
|
||||||
name, zipPath := model.BatchExportPandocConvertZip(ids, "", ".md")
|
name, zipPath := model.ExportPandocConvertZip(ids, "", ".md")
|
||||||
ret.Data = map[string]interface{}{
|
ret.Data = map[string]interface{}{
|
||||||
"name": name,
|
"name": name,
|
||||||
"zip": zipPath,
|
"zip": zipPath,
|
||||||
@ -357,7 +357,7 @@ func exportMd(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
id := arg["id"].(string)
|
id := arg["id"].(string)
|
||||||
name, zipPath := model.ExportPandocConvertZip(id, "", ".md")
|
name, zipPath := model.ExportPandocConvertZip([]string{id}, "", ".md")
|
||||||
ret.Data = map[string]interface{}{
|
ret.Data = map[string]interface{}{
|
||||||
"name": name,
|
"name": name,
|
||||||
"zip": zipPath,
|
"zip": zipPath,
|
||||||
|
@ -269,10 +269,10 @@ func Export2Liandi(id string) (err error) {
|
|||||||
title := path.Base(tree.HPath)
|
title := path.Base(tree.HPath)
|
||||||
tags := tree.Root.IALAttr("tags")
|
tags := tree.Root.IALAttr("tags")
|
||||||
content := exportMarkdownContent0(tree, util.GetCloudForumAssetsServer()+time.Now().Format("2006/01")+"/siyuan/"+Conf.GetUser().UserId+"/", true,
|
content := exportMarkdownContent0(tree, util.GetCloudForumAssetsServer()+time.Now().Format("2006/01")+"/siyuan/"+Conf.GetUser().UserId+"/", true,
|
||||||
4, 1, 0,
|
".md", 4, 1, 0,
|
||||||
"#", "#",
|
"#", "#",
|
||||||
"", "",
|
"", "",
|
||||||
false, nil)
|
false, nil, true)
|
||||||
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)
|
Conf.Export.AddTitle, true, true)
|
||||||
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)
|
Conf.Export.AddTitle, true, true)
|
||||||
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)
|
Conf.Export.AddTitle, true, true)
|
||||||
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
|
||||||
|
|
||||||
@ -1421,7 +1421,6 @@ func ExportStdMarkdown(id string) string {
|
|||||||
var defID string
|
var defID string
|
||||||
if treenode.IsBlockLink(n) {
|
if treenode.IsBlockLink(n) {
|
||||||
defID = strings.TrimPrefix(n.TextMarkAHref, "siyuan://blocks/")
|
defID = strings.TrimPrefix(n.TextMarkAHref, "siyuan://blocks/")
|
||||||
|
|
||||||
} else if treenode.IsBlockRef(n) {
|
} else if treenode.IsBlockRef(n) {
|
||||||
defID, _, _ = treenode.GetBlockRef(n)
|
defID, _, _ = treenode.GetBlockRef(n)
|
||||||
}
|
}
|
||||||
@ -1438,13 +1437,13 @@ func ExportStdMarkdown(id string) string {
|
|||||||
defBlockIDs = gulu.Str.RemoveDuplicatedElem(defBlockIDs)
|
defBlockIDs = gulu.Str.RemoveDuplicatedElem(defBlockIDs)
|
||||||
|
|
||||||
return exportMarkdownContent0(tree, cloudAssetsBase, false,
|
return exportMarkdownContent0(tree, cloudAssetsBase, false,
|
||||||
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)
|
Conf.Export.AddTitle, defBlockIDs, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func BatchExportPandocConvertZip(ids []string, pandocTo, ext string) (name, zipPath string) {
|
func ExportPandocConvertZip(ids []string, pandocTo, ext string) (name, zipPath string) {
|
||||||
block := treenode.GetBlockTree(ids[0])
|
block := treenode.GetBlockTree(ids[0])
|
||||||
box := Conf.Box(block.BoxID)
|
box := Conf.Box(block.BoxID)
|
||||||
baseFolderName := path.Base(block.HPath)
|
baseFolderName := path.Base(block.HPath)
|
||||||
@ -1463,31 +1462,8 @@ func BatchExportPandocConvertZip(ids []string, pandocTo, ext string) (name, zipP
|
|||||||
}
|
}
|
||||||
docPaths = util.FilterSelfChildDocs(docPaths)
|
docPaths = util.FilterSelfChildDocs(docPaths)
|
||||||
|
|
||||||
zipPath = exportPandocConvertZip(baseFolderName, docPaths, "gfm+footnotes+hard_line_breaks", pandocTo, ext)
|
defBlockIDs, trees, docPaths := prepareExportTrees(docPaths)
|
||||||
name = util.GetTreeID(block.Path)
|
zipPath = exportPandocConvertZip(baseFolderName, docPaths, defBlockIDs, "gfm+footnotes+hard_line_breaks", pandocTo, ext, trees)
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func ExportPandocConvertZip(id, pandocTo, ext string) (name, zipPath string) {
|
|
||||||
block := treenode.GetBlockTree(id)
|
|
||||||
if nil == block {
|
|
||||||
logging.LogErrorf("not found block [%s]", id)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
boxID := block.BoxID
|
|
||||||
box := Conf.Box(boxID)
|
|
||||||
baseFolderName := path.Base(block.HPath)
|
|
||||||
if "." == baseFolderName {
|
|
||||||
baseFolderName = path.Base(block.Path)
|
|
||||||
}
|
|
||||||
docPaths := []string{block.Path}
|
|
||||||
docFiles := box.ListFiles(strings.TrimSuffix(block.Path, ".sy"))
|
|
||||||
for _, docFile := range docFiles {
|
|
||||||
docPaths = append(docPaths, docFile.path)
|
|
||||||
}
|
|
||||||
|
|
||||||
zipPath = exportPandocConvertZip(baseFolderName, docPaths, "gfm+footnotes+hard_line_breaks", pandocTo, ext)
|
|
||||||
name = util.GetTreeID(block.Path)
|
name = util.GetTreeID(block.Path)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1515,7 +1491,9 @@ func ExportNotebookMarkdown(boxID, folderPath string) (zipPath string) {
|
|||||||
for _, docFile := range docFiles {
|
for _, docFile := range docFiles {
|
||||||
docPaths = append(docPaths, docFile.path)
|
docPaths = append(docPaths, docFile.path)
|
||||||
}
|
}
|
||||||
zipPath = exportPandocConvertZip(baseFolderName, docPaths, "", "", ".md")
|
|
||||||
|
defBlockIDs, trees, docPaths := prepareExportTrees(docPaths)
|
||||||
|
zipPath = exportPandocConvertZip(baseFolderName, docPaths, defBlockIDs, "", "", ".md", trees)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1642,7 +1620,7 @@ func exportSYZip(boxID, rootDirPath, baseFolderName string, docPaths []string) (
|
|||||||
util.PushEndlessProgress(Conf.language(65) + " " + fmt.Sprintf(Conf.language(70), fmt.Sprintf("%d/%d %s", count, len(docPaths), tree.Root.IALAttr("title"))))
|
util.PushEndlessProgress(Conf.language(65) + " " + fmt.Sprintf(Conf.language(70), fmt.Sprintf("%d/%d %s", count, len(docPaths), tree.Root.IALAttr("title"))))
|
||||||
|
|
||||||
refs := map[string]*parse.Tree{}
|
refs := map[string]*parse.Tree{}
|
||||||
exportRefTrees(tree, &refs, &treeCache)
|
exportRefTrees(tree, &[]string{}, &refs, &treeCache)
|
||||||
for refTreeID, refTree := range refs {
|
for refTreeID, refTree := range refs {
|
||||||
if nil == trees[refTreeID] {
|
if nil == trees[refTreeID] {
|
||||||
refTrees[refTreeID] = refTree
|
refTrees[refTreeID] = refTree
|
||||||
@ -1949,10 +1927,10 @@ func walkRelationAvs(avID string, exportAvIDs *hashset.Set) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ExportMarkdownContent(id string) (hPath, exportedMd string) {
|
func ExportMarkdownContent(id string) (hPath, exportedMd string) {
|
||||||
return exportMarkdownContent(id, Conf.Export.BlockRefMode, nil)
|
return exportMarkdownContent(id, ".md", Conf.Export.BlockRefMode, nil, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func exportMarkdownContent(id string, exportRefMode int, defBlockIDs []string) (hPath, exportedMd string) {
|
func exportMarkdownContent(id, ext string, exportRefMode int, defBlockIDs []string, singleFile bool) (hPath, exportedMd string) {
|
||||||
tree, err := LoadTreeByBlockID(id)
|
tree, err := LoadTreeByBlockID(id)
|
||||||
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)
|
||||||
@ -1960,26 +1938,24 @@ func exportMarkdownContent(id string, exportRefMode int, defBlockIDs []string) (
|
|||||||
}
|
}
|
||||||
hPath = tree.HPath
|
hPath = tree.HPath
|
||||||
exportedMd = exportMarkdownContent0(tree, "", false,
|
exportedMd = exportMarkdownContent0(tree, "", false,
|
||||||
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)
|
Conf.Export.AddTitle, defBlockIDs, singleFile)
|
||||||
docIAL := parse.IAL2Map(tree.Root.KramdownIAL)
|
docIAL := parse.IAL2Map(tree.Root.KramdownIAL)
|
||||||
exportedMd = yfm(docIAL) + exportedMd
|
exportedMd = yfm(docIAL) + exportedMd
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func exportMarkdownContent0(tree *parse.Tree, cloudAssetsBase string, assetsDestSpace2Underscore bool,
|
func exportMarkdownContent0(tree *parse.Tree, cloudAssetsBase string, assetsDestSpace2Underscore bool,
|
||||||
blockRefMode, blockEmbedMode, fileAnnotationRefMode int,
|
ext string, blockRefMode, blockEmbedMode, fileAnnotationRefMode int,
|
||||||
tagOpenMarker, tagCloseMarker string,
|
tagOpenMarker, tagCloseMarker string, blockRefTextLeft, blockRefTextRight string,
|
||||||
blockRefTextLeft, blockRefTextRight string,
|
addTitle bool, defBlockIDs []string, singleFile bool) (ret string) {
|
||||||
addTitle bool,
|
|
||||||
defBlockIDs []string) (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))
|
addTitle, 0 < len(defBlockIDs), singleFile)
|
||||||
luteEngine := NewLute()
|
luteEngine := NewLute()
|
||||||
luteEngine.SetFootnotes(true)
|
luteEngine.SetFootnotes(true)
|
||||||
luteEngine.SetKramdownIAL(false)
|
luteEngine.SetKramdownIAL(false)
|
||||||
@ -2057,7 +2033,7 @@ func exportMarkdownContent0(tree *parse.Tree, cloudAssetsBase string, assetsDest
|
|||||||
var href string
|
var href string
|
||||||
bt := treenode.GetBlockTree(defID)
|
bt := treenode.GetBlockTree(defID)
|
||||||
if nil != bt {
|
if nil != bt {
|
||||||
href += bt.HPath + ".md"
|
href += bt.HPath + ext
|
||||||
if "d" != bt.Type {
|
if "d" != bt.Type {
|
||||||
href += "#" + defID
|
href += "#" + defID
|
||||||
}
|
}
|
||||||
@ -2090,7 +2066,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 bool) (ret *parse.Tree) {
|
addTitle, addDocAnchorSpan, singleFile bool) (ret *parse.Tree) {
|
||||||
luteEngine := NewLute()
|
luteEngine := NewLute()
|
||||||
ret = tree
|
ret = tree
|
||||||
id := tree.Root.ID
|
id := tree.Root.ID
|
||||||
@ -2107,7 +2083,7 @@ func exportTree(tree *parse.Tree, wysiwyg, keepFold, avHiddenCol bool,
|
|||||||
|
|
||||||
// 收集引用转脚注+锚点哈希
|
// 收集引用转脚注+锚点哈希
|
||||||
var refFootnotes []*refAsFootnotes
|
var refFootnotes []*refAsFootnotes
|
||||||
if 4 == blockRefMode {
|
if 4 == blockRefMode && singleFile {
|
||||||
depth = 0
|
depth = 0
|
||||||
collectFootnotesDefs(ret, ret.ID, &refFootnotes, &treeCache, &depth)
|
collectFootnotesDefs(ret, ret.ID, &refFootnotes, &treeCache, &depth)
|
||||||
}
|
}
|
||||||
@ -2266,8 +2242,10 @@ func exportTree(tree *parse.Tree, wysiwyg, keepFold, avHiddenCol bool,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if 4 == blockRefMode { // 脚注+锚点哈希
|
if 4 == blockRefMode { // 脚注+锚点哈希
|
||||||
anchorSpan := treenode.NewSpanAnchor(id)
|
if addDocAnchorSpan {
|
||||||
ret.Root.PrependChild(anchorSpan)
|
anchorSpan := treenode.NewSpanAnchor(id)
|
||||||
|
ret.Root.PrependChild(anchorSpan)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2965,84 +2943,6 @@ type refAsFootnotes struct {
|
|||||||
refAnchorText string
|
refAnchorText string
|
||||||
}
|
}
|
||||||
|
|
||||||
func exportRefTrees(tree *parse.Tree, retTrees, treeCache *map[string]*parse.Tree) {
|
|
||||||
if nil != (*retTrees)[tree.ID] {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
(*retTrees)[tree.ID] = tree
|
|
||||||
|
|
||||||
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
|
|
||||||
if !entering {
|
|
||||||
return ast.WalkContinue
|
|
||||||
}
|
|
||||||
|
|
||||||
if treenode.IsBlockRef(n) {
|
|
||||||
defID, _, _ := treenode.GetBlockRef(n)
|
|
||||||
if "" == defID {
|
|
||||||
return ast.WalkContinue
|
|
||||||
}
|
|
||||||
defBlock := treenode.GetBlockTree(defID)
|
|
||||||
if nil == defBlock {
|
|
||||||
return ast.WalkSkipChildren
|
|
||||||
}
|
|
||||||
|
|
||||||
var defTree *parse.Tree
|
|
||||||
var err error
|
|
||||||
if (*treeCache)[defBlock.RootID] != nil {
|
|
||||||
defTree = (*treeCache)[defBlock.RootID]
|
|
||||||
} else {
|
|
||||||
defTree, err = LoadTreeByBlockID(defBlock.RootID)
|
|
||||||
if err != nil {
|
|
||||||
return ast.WalkSkipChildren
|
|
||||||
}
|
|
||||||
(*treeCache)[defBlock.RootID] = defTree
|
|
||||||
}
|
|
||||||
|
|
||||||
exportRefTrees(defTree, retTrees, treeCache)
|
|
||||||
} else if ast.NodeAttributeView == n.Type {
|
|
||||||
// 导出数据库所在文档时一并导出绑定块所在文档
|
|
||||||
// Export the binding block docs when exporting the doc where the database is located https://github.com/siyuan-note/siyuan/issues/11486
|
|
||||||
|
|
||||||
avID := n.AttributeViewID
|
|
||||||
if "" == avID {
|
|
||||||
return ast.WalkContinue
|
|
||||||
}
|
|
||||||
|
|
||||||
attrView, _ := av.ParseAttributeView(avID)
|
|
||||||
if nil == attrView {
|
|
||||||
return ast.WalkContinue
|
|
||||||
}
|
|
||||||
|
|
||||||
blockKeyValues := attrView.GetBlockKeyValues()
|
|
||||||
if nil == blockKeyValues {
|
|
||||||
return ast.WalkContinue
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, val := range blockKeyValues.Values {
|
|
||||||
defBlock := treenode.GetBlockTree(val.BlockID)
|
|
||||||
if nil == defBlock {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
var defTree *parse.Tree
|
|
||||||
var err error
|
|
||||||
if (*treeCache)[defBlock.RootID] != nil {
|
|
||||||
defTree = (*treeCache)[defBlock.RootID]
|
|
||||||
} else {
|
|
||||||
defTree, err = LoadTreeByBlockID(defBlock.RootID)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
(*treeCache)[defBlock.RootID] = defTree
|
|
||||||
}
|
|
||||||
|
|
||||||
exportRefTrees(defTree, retTrees, treeCache)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ast.WalkContinue
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func processFileAnnotationRef(refID string, n *ast.Node, fileAnnotationRefMode int) ast.WalkStatus {
|
func processFileAnnotationRef(refID string, n *ast.Node, fileAnnotationRefMode int) ast.WalkStatus {
|
||||||
p := refID[:strings.LastIndex(refID, "/")]
|
p := refID[:strings.LastIndex(refID, "/")]
|
||||||
absPath, err := GetAssetAbsPath(p)
|
absPath, err := GetAssetAbsPath(p)
|
||||||
@ -3090,8 +2990,8 @@ func processFileAnnotationRef(refID string, n *ast.Node, fileAnnotationRefMode i
|
|||||||
return ast.WalkSkipChildren
|
return ast.WalkSkipChildren
|
||||||
}
|
}
|
||||||
|
|
||||||
func exportPandocConvertZip(baseFolderName string, docPaths []string,
|
func exportPandocConvertZip(baseFolderName string, docPaths, defBlockIDs []string,
|
||||||
pandocFrom, pandocTo, ext string) (zipPath string) {
|
pandocFrom, pandocTo, ext string, treeCache *map[string]*parse.Tree) (zipPath string) {
|
||||||
defer util.ClearPushProgress(100)
|
defer util.ClearPushProgress(100)
|
||||||
|
|
||||||
dir, name := path.Split(baseFolderName)
|
dir, name := path.Split(baseFolderName)
|
||||||
@ -3111,49 +3011,6 @@ func exportPandocConvertZip(baseFolderName string, docPaths []string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
exportRefMode := Conf.Export.BlockRefMode
|
exportRefMode := Conf.Export.BlockRefMode
|
||||||
var defBlockIDs []string
|
|
||||||
if 4 == exportRefMode { // 脚注+锚点哈希
|
|
||||||
// 导出锚点哈希,这里先记录下所有定义块的 ID
|
|
||||||
walked := map[string]bool{}
|
|
||||||
for _, p := range docPaths {
|
|
||||||
if walked[p] {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
id := util.GetTreeID(p)
|
|
||||||
tree, err := LoadTreeByBlockID(id)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
|
|
||||||
if !entering {
|
|
||||||
return ast.WalkContinue
|
|
||||||
}
|
|
||||||
|
|
||||||
var defID string
|
|
||||||
if treenode.IsBlockLink(n) {
|
|
||||||
defID = strings.TrimPrefix(n.TextMarkAHref, "siyuan://blocks/")
|
|
||||||
|
|
||||||
} else if treenode.IsBlockRef(n) {
|
|
||||||
defID, _, _ = treenode.GetBlockRef(n)
|
|
||||||
}
|
|
||||||
|
|
||||||
if "" != defID {
|
|
||||||
if defBt := treenode.GetBlockTree(defID); nil != defBt {
|
|
||||||
docPaths = append(docPaths, defBt.Path)
|
|
||||||
docPaths = gulu.Str.RemoveDuplicatedElem(docPaths)
|
|
||||||
defBlockIDs = append(defBlockIDs, defID)
|
|
||||||
defBlockIDs = gulu.Str.RemoveDuplicatedElem(defBlockIDs)
|
|
||||||
walked[defBt.Path] = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ast.WalkContinue
|
|
||||||
})
|
|
||||||
}
|
|
||||||
defBlockIDs = gulu.Str.RemoveDuplicatedElem(defBlockIDs)
|
|
||||||
docPaths = gulu.Str.RemoveDuplicatedElem(docPaths)
|
|
||||||
}
|
|
||||||
|
|
||||||
wrotePathHash := map[string]string{}
|
wrotePathHash := map[string]string{}
|
||||||
assetsPathMap, err := allAssetAbsPaths()
|
assetsPathMap, err := allAssetAbsPaths()
|
||||||
if nil != err {
|
if nil != err {
|
||||||
@ -3164,7 +3021,7 @@ func exportPandocConvertZip(baseFolderName string, docPaths []string,
|
|||||||
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, exportRefMode, defBlockIDs)
|
hPath, md := exportMarkdownContent(id, ext, exportRefMode, defBlockIDs, false)
|
||||||
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)
|
||||||
@ -3269,41 +3126,139 @@ func getExportBlockRefLinkText(blockRef *ast.Node, blockRefTextLeft, blockRefTex
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDestViewVal(attrView *av.AttributeView, keyID, blockID string) *av.TableColumn {
|
func prepareExportTrees(docPaths []string) (defBlockIDs []string, trees *map[string]*parse.Tree, relatedDocPaths []string) {
|
||||||
rollupKey, _ := attrView.GetKey(keyID)
|
trees = &map[string]*parse.Tree{}
|
||||||
if nil == rollupKey || nil == rollupKey.Rollup {
|
treeCache := &map[string]*parse.Tree{}
|
||||||
return nil
|
defBlockIDs = []string{}
|
||||||
|
for _, p := range docPaths {
|
||||||
|
id := util.GetTreeID(p)
|
||||||
|
tree, err := LoadTreeByBlockID(id)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
exportRefTrees(tree, &defBlockIDs, trees, treeCache)
|
||||||
}
|
}
|
||||||
|
|
||||||
relKey, _ := attrView.GetKey(rollupKey.Rollup.RelationKeyID)
|
for _, tree := range *trees {
|
||||||
if nil == relKey || nil == relKey.Relation {
|
relatedDocPaths = append(relatedDocPaths, tree.Path)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
relatedDocPaths = gulu.Str.RemoveDuplicatedElem(relatedDocPaths)
|
||||||
relVal := attrView.GetValue(relKey.ID, blockID)
|
return
|
||||||
if nil == relVal || nil == relVal.Relation {
|
}
|
||||||
return nil
|
|
||||||
}
|
func exportRefTrees(tree *parse.Tree, defBlockIDs *[]string, retTrees, treeCache *map[string]*parse.Tree) {
|
||||||
|
if nil != (*retTrees)[tree.ID] {
|
||||||
destAv, _ := av.ParseAttributeView(relKey.Relation.AvID)
|
return
|
||||||
if nil == destAv {
|
}
|
||||||
return nil
|
(*retTrees)[tree.ID] = tree
|
||||||
}
|
|
||||||
|
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
|
||||||
destKey, _ := destAv.GetKey(rollupKey.Rollup.KeyID)
|
if !entering {
|
||||||
if nil == destKey {
|
return ast.WalkContinue
|
||||||
return nil
|
}
|
||||||
}
|
|
||||||
|
if treenode.IsBlockRef(n) {
|
||||||
destView, _ := destAv.GetCurrentView(destAv.ViewID)
|
defID, _, _ := treenode.GetBlockRef(n)
|
||||||
if nil == destView {
|
if "" == defID {
|
||||||
return nil
|
return ast.WalkContinue
|
||||||
}
|
}
|
||||||
|
defBlock := treenode.GetBlockTree(defID)
|
||||||
destTable := sql.RenderAttributeViewTable(destAv, destView, "")
|
if nil == defBlock {
|
||||||
if nil == destTable {
|
return ast.WalkSkipChildren
|
||||||
return nil
|
}
|
||||||
}
|
|
||||||
|
var defTree *parse.Tree
|
||||||
return destTable.GetColumn(rollupKey.Rollup.KeyID)
|
var err error
|
||||||
|
if (*treeCache)[defBlock.RootID] != nil {
|
||||||
|
defTree = (*treeCache)[defBlock.RootID]
|
||||||
|
} else {
|
||||||
|
defTree, err = LoadTreeByBlockID(defBlock.RootID)
|
||||||
|
if err != nil {
|
||||||
|
return ast.WalkSkipChildren
|
||||||
|
}
|
||||||
|
(*treeCache)[defBlock.RootID] = defTree
|
||||||
|
}
|
||||||
|
*defBlockIDs = append(*defBlockIDs, defID)
|
||||||
|
|
||||||
|
exportRefTrees(defTree, defBlockIDs, retTrees, treeCache)
|
||||||
|
} else if treenode.IsBlockLink(n) {
|
||||||
|
defID := strings.TrimPrefix(n.TextMarkAHref, "siyuan://blocks/")
|
||||||
|
if "" == defID {
|
||||||
|
return ast.WalkContinue
|
||||||
|
}
|
||||||
|
defBlock := treenode.GetBlockTree(defID)
|
||||||
|
if nil == defBlock {
|
||||||
|
return ast.WalkSkipChildren
|
||||||
|
}
|
||||||
|
|
||||||
|
var defTree *parse.Tree
|
||||||
|
var err error
|
||||||
|
if (*treeCache)[defBlock.RootID] != nil {
|
||||||
|
defTree = (*treeCache)[defBlock.RootID]
|
||||||
|
} else {
|
||||||
|
defTree, err = LoadTreeByBlockID(defBlock.RootID)
|
||||||
|
if err != nil {
|
||||||
|
return ast.WalkSkipChildren
|
||||||
|
}
|
||||||
|
(*treeCache)[defBlock.RootID] = defTree
|
||||||
|
}
|
||||||
|
*defBlockIDs = append(*defBlockIDs, defID)
|
||||||
|
|
||||||
|
exportRefTrees(defTree, defBlockIDs, retTrees, treeCache)
|
||||||
|
} else if ast.NodeAttributeView == n.Type {
|
||||||
|
// 导出数据库所在文档时一并导出绑定块所在文档
|
||||||
|
// Export the binding block docs when exporting the doc where the database is located https://github.com/siyuan-note/siyuan/issues/11486
|
||||||
|
|
||||||
|
avID := n.AttributeViewID
|
||||||
|
if "" == avID {
|
||||||
|
return ast.WalkContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
attrView, _ := av.ParseAttributeView(avID)
|
||||||
|
if nil == attrView {
|
||||||
|
return ast.WalkContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
blockKeyValues := attrView.GetBlockKeyValues()
|
||||||
|
if nil == blockKeyValues {
|
||||||
|
return ast.WalkContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, val := range blockKeyValues.Values {
|
||||||
|
defBlock := treenode.GetBlockTree(val.BlockID)
|
||||||
|
if nil == defBlock {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var defTree *parse.Tree
|
||||||
|
var err error
|
||||||
|
if (*treeCache)[defBlock.RootID] != nil {
|
||||||
|
defTree = (*treeCache)[defBlock.RootID]
|
||||||
|
} else {
|
||||||
|
defTree, err = LoadTreeByBlockID(defBlock.RootID)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
(*treeCache)[defBlock.RootID] = defTree
|
||||||
|
}
|
||||||
|
*defBlockIDs = append(*defBlockIDs, val.BlockID)
|
||||||
|
|
||||||
|
exportRefTrees(defTree, defBlockIDs, retTrees, treeCache)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ast.WalkContinue
|
||||||
|
})
|
||||||
|
|
||||||
|
*defBlockIDs = gulu.Str.RemoveDuplicatedElem(*defBlockIDs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadTreeWithCache(id string, treeCache *map[string]*parse.Tree) (tree *parse.Tree, err error) {
|
||||||
|
if tree = (*treeCache)[id]; nil != tree {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
tree, err = LoadTreeByBlockID(id)
|
||||||
|
if nil == err && nil != tree {
|
||||||
|
(*treeCache)[id] = tree
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user