Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
Vanessa 2024-01-28 13:01:52 +08:00
commit 27edf57eb0
18 changed files with 895 additions and 59 deletions

View file

@ -958,7 +958,7 @@
"export27": "Export PDF watermark",
"export28": "Watermark text or watermark file path",
"export29": "Watermark position, size and style, etc.",
"export9": "Export image watermark",
"export30": "Export image watermark",
"theme11": "Use theme in light mode",
"theme12": "Use theme in dark mode",
"theme2": "Select the icons used in the user interface",
@ -976,6 +976,7 @@
"export6": "About the handling of anchor text in PDF annotations when exporting",
"export7": "File Name - Page Number - Anchor Text",
"export8": "Just anchor text",
"export9": "Anchor hash (only for exporting Notebook)",
"graphConfig2": "Reference Count filter",
"selectOpen": "Always Select Opened Doc",
"selectOpen1": "Select Opened Doc",

View file

@ -958,7 +958,7 @@
"export27": "Exportar marca de agua PDF",
"export28": "Texto de marca de agua o ruta del archivo de marca de agua",
"export29": "Posición, tamaño y estilo de la marca de agua, etc.",
"export9": "Exportar marca de agua de imagen",
"export30": "Exportar marca de agua de imagen",
"theme11": "Usar tema en modo claro",
"theme12": "Usar tema en modo oscuro",
"theme2": "Selecciona los iconos utilizados en la interfaz de usuario",
@ -976,6 +976,7 @@
"export6": "Sobre el manejo del texto ancla en las anotaciones PDF al exportar",
"export7": "Nombre de archivo - Número de página - Texto ancla",
"export8": "Sólo texto ancla",
"export9": "Hash de anclaje (sólo para exportar Notebook)",
"graphConfig2": "Filtro de recuento de referencias",
"selectOpen": "Seleccionar siempre el documento abierto",
"selectOpen1": "Seleccionar documento abierto",

View file

@ -958,7 +958,7 @@
"export27": "Exporter le filigrane PDF",
"export28": "Texte du filigrane ou chemin du fichier de filigrane",
"export29": "Position, taille et style du filigrane, etc.",
"export9": "Exporter le filigrane de l'image",
"export30": "Exporter le filigrane de l'image",
"theme11": "Utiliser le thème en mode Clair",
"theme12": "Utiliser le thème en mode sombre",
"theme2": "Sélectionnez les icônes utilisées dans l'interface utilisateur",
@ -976,6 +976,7 @@
"export6": "À propos de la gestion du texte d'ancrage dans les annotations PDF lors de l'exportation",
"export7": "Nom de fichier - Numéro de page - Texte d'ancrage",
"export8": "Anchor text only",
"export9": "Hash d'ancrage (uniquement pour l'exportation de Notebook)",
"graphConfig2": "Filtre de compte de blocs de référence",
"selectOpen": "Localisez toujours les documents ouverts",
"selectOpen1": "Localiser les documents ouverts",

View file

@ -958,7 +958,7 @@
"export27": "導出 PDF 浮水印",
"export28": "浮水印文字或浮水印檔案路徑",
"export29": "浮水印位置、大小和樣式等",
"export9": "匯出圖片浮水印",
"export30": "匯出圖片浮水印",
"theme11": "淺色模式下使用主題",
"theme12": "深色模式下使用主題",
"theme2": "選擇外觀使用的圖示",
@ -976,6 +976,7 @@
"export6": "導出時關於 PDF 標註引出處錨文字的處理方式",
"export7": "文件名 - 頁碼 - 錨文字",
"export8": "僅錨文字",
"export9": "錨點哈希(僅支援導出筆記本)",
"graphConfig2": "引用塊次數過濾",
"selectOpen": "定位打開的文檔",
"selectOpen1": "定位打開的文檔",

View file

@ -958,7 +958,7 @@
"export27": "导出 PDF 水印",
"export28": "水印文本或水印文件路径",
"export29": "水印位置、大小和样式等",
"export9": "导出图片水印",
"export30": "导出图片水印",
"theme11": "明亮模式下使用主题",
"theme12": "暗黑模式下使用主题",
"theme2": "选择外观使用的图标",
@ -976,6 +976,7 @@
"export6": "导出时关于 PDF 标注引出处锚文本的处理方式",
"export7": "文件名 - 页码 - 锚文本",
"export8": "仅锚文本",
"export9": "锚点哈希(仅支持导出笔记本)",
"graphConfig2": "引用块次数过滤",
"selectOpen": "始终定位打开的文档",
"selectOpen1": "定位打开的文档",

View file

@ -3,9 +3,10 @@
"Spec": "1",
"Type": "NodeDocument",
"Properties": {
"icon": "1f4f8",
"id": "20221223221636-ms2b4w9",
"title": "Flashcards",
"updated": "20231013104018"
"updated": "20240128113415"
},
"Children": [
{
@ -518,6 +519,217 @@
}
]
},
{
"ID": "20240128112003-595bhoa",
"Type": "NodeHeading",
"HeadingLevel": 2,
"Properties": {
"id": "20240128112003-595bhoa",
"updated": "20240128112005"
},
"Children": [
{
"Type": "NodeText",
"Data": "Settings"
}
]
},
{
"ID": "20240128112016-je04b7i",
"Type": "NodeParagraph",
"Properties": {
"id": "20240128112016-je04b7i",
"updated": "20240128112236"
},
"Children": [
{
"Type": "NodeText",
"Data": "You can adjust the global configuration related to flashcards in "
},
{
"Type": "NodeTextMark",
"TextMarkType": "kbd",
"TextMarkTextContent": "Settings"
},
{
"Type": "NodeText",
"Data": " - "
},
{
"Type": "NodeTextMark",
"TextMarkType": "kbd",
"TextMarkTextContent": "Flashcard"
},
{
"Type": "NodeText",
"Data": ", including "
},
{
"Type": "NodeTextMark",
"TextMarkType": "kbd",
"TextMarkTextContent": "New Card Limit"
},
{
"Type": "NodeText",
"Data": " and "
},
{
"Type": "NodeTextMark",
"TextMarkType": "kbd",
"TextMarkTextContent": "Review Card Limit"
},
{
"Type": "NodeText",
"Data": " can be overridden using document block custom attributes:"
}
]
},
{
"ID": "20240128112016-aa4ipl9",
"Type": "NodeList",
"ListData": {},
"Properties": {
"id": "20240128112016-aa4ipl9",
"updated": "20240128112016"
},
"Children": [
{
"ID": "20240128112016-ta1n5t2",
"Type": "NodeListItem",
"ListData": {
"BulletChar": 42,
"Marker": "Kg=="
},
"Properties": {
"id": "20240128112016-ta1n5t2",
"updated": "20240128112016"
},
"Children": [
{
"ID": "20240128112016-jm62abq",
"Type": "NodeParagraph",
"Properties": {
"id": "20240128112016-jm62abq",
"updated": "20240128112016"
},
"Children": [
{
"Type": "NodeText",
"Data": ""
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": "riff-new-card-limit"
},
{
"Type": "NodeText",
"Data": ""
}
]
}
]
},
{
"ID": "20240128112016-3s0opfu",
"Type": "NodeListItem",
"ListData": {
"BulletChar": 42,
"Marker": "Kg=="
},
"Properties": {
"id": "20240128112016-3s0opfu",
"updated": "20240128112016"
},
"Children": [
{
"ID": "20240128112016-ozz5ukr",
"Type": "NodeParagraph",
"Properties": {
"id": "20240128112016-ozz5ukr",
"updated": "20240128112016"
},
"Children": [
{
"Type": "NodeText",
"Data": ""
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": "riff-review-card-limit"
},
{
"Type": "NodeText",
"Data": ""
}
]
}
]
}
]
},
{
"ID": "20240128112146-85828oq",
"Type": "NodeParagraph",
"Properties": {
"id": "20240128112146-85828oq",
"updated": "20240128113415"
},
"Children": [
{
"Type": "NodeText",
"Data": ""
},
{
"Type": "NodeImage",
"Data": "span",
"Children": [
{
"Type": "NodeBang"
},
{
"Type": "NodeOpenBracket"
},
{
"Type": "NodeLinkText",
"Data": "image"
},
{
"Type": "NodeCloseBracket"
},
{
"Type": "NodeOpenParen"
},
{
"Type": "NodeLinkDest",
"Data": "assets/image-20240128113001-pee8l86.png"
},
{
"Type": "NodeCloseParen"
}
]
},
{
"Type": "NodeText",
"Data": ""
}
]
},
{
"ID": "20240128112208-ulxm0sf",
"Type": "NodeParagraph",
"Properties": {
"id": "20240128112208-ulxm0sf",
"updated": "20240128112214"
},
"Children": [
{
"Type": "NodeText",
"Data": "They are configured separately on different documents and do not affect each other. For example, if the parent document is configured as 5 and the sub-document is 10, then it will be 5 when reviewing from the parent document, and the configuration of the sub-document will not be superimposed."
}
]
},
{
"ID": "20221223221639-djlafd4",
"Type": "NodeHeading",
@ -548,7 +760,7 @@
"ListData": {},
"Properties": {
"id": "20221223221639-ycrps4p",
"updated": "20221223221824"
"updated": "20240128112834"
},
"Children": [
{
@ -578,6 +790,34 @@
]
}
]
},
{
"ID": "20240128112355-nzfivrh",
"Type": "NodeListItem",
"ListData": {
"BulletChar": 42,
"Marker": "Kg=="
},
"Properties": {
"id": "20240128112355-nzfivrh",
"updated": "20240128112834"
},
"Children": [
{
"ID": "20240128112355-ie927dm",
"Type": "NodeParagraph",
"Properties": {
"id": "20240128112355-ie927dm",
"updated": "20240128112834"
},
"Children": [
{
"Type": "NodeText",
"Data": "It is not recommended to enable card decks. This method has been deprecated. If you continue to use it, you may encounter unsolvable problems"
}
]
}
]
}
]
},

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -3,9 +3,10 @@
"Spec": "1",
"Type": "NodeDocument",
"Properties": {
"icon": "1f4f8",
"id": "20221223215557-o6gfsoy",
"title": "闪卡",
"updated": "20231013103850"
"updated": "20240128112938"
},
"Children": [
{
@ -514,6 +515,217 @@
}
]
},
{
"ID": "20240128110946-hctldlf",
"Type": "NodeHeading",
"HeadingLevel": 2,
"Properties": {
"id": "20240128110946-hctldlf",
"updated": "20240128110950"
},
"Children": [
{
"Type": "NodeText",
"Data": "设置"
}
]
},
{
"ID": "20240128110950-exhbssa",
"Type": "NodeParagraph",
"Properties": {
"id": "20240128110950-exhbssa",
"updated": "20240128111232"
},
"Children": [
{
"Type": "NodeText",
"Data": "在 "
},
{
"Type": "NodeTextMark",
"TextMarkType": "kbd",
"TextMarkTextContent": "设置"
},
{
"Type": "NodeText",
"Data": " - "
},
{
"Type": "NodeTextMark",
"TextMarkType": "kbd",
"TextMarkTextContent": "闪卡"
},
{
"Type": "NodeText",
"Data": " 中可以调整闪卡相关的全局配置,其中 "
},
{
"Type": "NodeTextMark",
"TextMarkType": "kbd",
"TextMarkTextContent": "新卡上限"
},
{
"Type": "NodeText",
"Data": " 和 "
},
{
"Type": "NodeTextMark",
"TextMarkType": "kbd",
"TextMarkTextContent": "复习卡上限"
},
{
"Type": "NodeText",
"Data": " 可以使用文档块自定义属性进行覆盖:"
}
]
},
{
"ID": "20240128111227-ttw7ui4",
"Type": "NodeList",
"ListData": {},
"Properties": {
"id": "20240128111227-ttw7ui4",
"updated": "20240128111227"
},
"Children": [
{
"ID": "20240128111227-dgd3209",
"Type": "NodeListItem",
"ListData": {
"BulletChar": 42,
"Marker": "Kg=="
},
"Properties": {
"id": "20240128111227-dgd3209",
"updated": "20240128111227"
},
"Children": [
{
"ID": "20240128111227-as4jg1c",
"Type": "NodeParagraph",
"Properties": {
"id": "20240128111227-as4jg1c",
"updated": "20240128111227"
},
"Children": [
{
"Type": "NodeText",
"Data": ""
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": "riff-new-card-limit"
},
{
"Type": "NodeText",
"Data": ""
}
]
}
]
},
{
"ID": "20240128111227-x47dpnk",
"Type": "NodeListItem",
"ListData": {
"BulletChar": 42,
"Marker": "Kg=="
},
"Properties": {
"id": "20240128111227-x47dpnk",
"updated": "20240128111227"
},
"Children": [
{
"ID": "20240128111227-tbrfobt",
"Type": "NodeParagraph",
"Properties": {
"id": "20240128111227-tbrfobt",
"updated": "20240128111227"
},
"Children": [
{
"Type": "NodeText",
"Data": ""
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": "riff-review-card-limit"
},
{
"Type": "NodeText",
"Data": ""
}
]
}
]
}
]
},
{
"ID": "20240128111414-hbbh5a9",
"Type": "NodeParagraph",
"Properties": {
"id": "20240128111414-hbbh5a9",
"updated": "20240128112938"
},
"Children": [
{
"Type": "NodeText",
"Data": ""
},
{
"Type": "NodeImage",
"Data": "span",
"Children": [
{
"Type": "NodeBang"
},
{
"Type": "NodeOpenBracket"
},
{
"Type": "NodeLinkText",
"Data": "image"
},
{
"Type": "NodeCloseBracket"
},
{
"Type": "NodeOpenParen"
},
{
"Type": "NodeLinkDest",
"Data": "assets/image-20240128111414-l8l7d89.png"
},
{
"Type": "NodeCloseParen"
}
]
},
{
"Type": "NodeText",
"Data": ""
}
]
},
{
"ID": "20240128111245-8s2qyli",
"Type": "NodeParagraph",
"Properties": {
"id": "20240128111245-8s2qyli",
"updated": "20240128111317"
},
"Children": [
{
"Type": "NodeText",
"Data": "不同文档上单独配置,相互独立不影响,比如父文档上配置为 5子文档为 10那么从父文档复习的时候就是 5不会叠加子文档的配置。"
}
]
},
{
"ID": "20221223221214-wr48h8b",
"Type": "NodeHeading",
@ -544,7 +756,7 @@
"ListData": {},
"Properties": {
"id": "20221223221217-uwk0y7w",
"updated": "20221223221400"
"updated": "20240128112803"
},
"Children": [
{
@ -574,6 +786,34 @@
]
}
]
},
{
"ID": "20240128112311-auszyjt",
"Type": "NodeListItem",
"ListData": {
"BulletChar": 42,
"Marker": "Kg=="
},
"Properties": {
"id": "20240128112311-auszyjt",
"updated": "20240128112803"
},
"Children": [
{
"ID": "20240128112311-vuu0rg4",
"Type": "NodeParagraph",
"Properties": {
"id": "20240128112311-vuu0rg4",
"updated": "20240128112803"
},
"Children": [
{
"Type": "NodeText",
"Data": "不建议启用卡包,该方式已经弃用,继续使用可能会遇到无法解决的问题"
}
]
}
]
}
]
},

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -3,9 +3,10 @@
"Spec": "1",
"Type": "NodeDocument",
"Properties": {
"icon": "1f4f8",
"id": "20221223221501-mops33i",
"title": "閃卡",
"updated": "20231013104052"
"updated": "20240128113519"
},
"Children": [
{
@ -514,6 +515,217 @@
}
]
},
{
"ID": "20240128111751-bb41541",
"Type": "NodeHeading",
"HeadingLevel": 2,
"Properties": {
"id": "20240128111751-bb41541",
"updated": "20240128111854"
},
"Children": [
{
"Type": "NodeText",
"Data": "設置"
}
]
},
{
"ID": "20240128111910-2n2j702",
"Type": "NodeParagraph",
"Properties": {
"id": "20240128111910-2n2j702",
"updated": "20240128111941"
},
"Children": [
{
"Type": "NodeText",
"Data": "在 "
},
{
"Type": "NodeTextMark",
"TextMarkType": "kbd",
"TextMarkTextContent": "設置"
},
{
"Type": "NodeText",
"Data": " - "
},
{
"Type": "NodeTextMark",
"TextMarkType": "kbd",
"TextMarkTextContent": "閃卡"
},
{
"Type": "NodeText",
"Data": " 中可以調整閃卡相關的全域配置,其中 "
},
{
"Type": "NodeTextMark",
"TextMarkType": "kbd",
"TextMarkTextContent": "新卡上限"
},
{
"Type": "NodeText",
"Data": " 和 "
},
{
"Type": "NodeTextMark",
"TextMarkType": "kbd",
"TextMarkTextContent": "複習卡上限"
},
{
"Type": "NodeText",
"Data": " 可以使用文件區塊自訂屬性進行覆寫:"
}
]
},
{
"ID": "20240128111910-utitmr7",
"Type": "NodeList",
"ListData": {},
"Properties": {
"id": "20240128111910-utitmr7",
"updated": "20240128111910"
},
"Children": [
{
"ID": "20240128111910-fm03lqa",
"Type": "NodeListItem",
"ListData": {
"BulletChar": 42,
"Marker": "Kg=="
},
"Properties": {
"id": "20240128111910-fm03lqa",
"updated": "20240128111910"
},
"Children": [
{
"ID": "20240128111910-l3gn3xk",
"Type": "NodeParagraph",
"Properties": {
"id": "20240128111910-l3gn3xk",
"updated": "20240128111910"
},
"Children": [
{
"Type": "NodeText",
"Data": ""
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": "riff-new-card-limit"
},
{
"Type": "NodeText",
"Data": ""
}
]
}
]
},
{
"ID": "20240128111910-jm5o4fb",
"Type": "NodeListItem",
"ListData": {
"BulletChar": 42,
"Marker": "Kg=="
},
"Properties": {
"id": "20240128111910-jm5o4fb",
"updated": "20240128111910"
},
"Children": [
{
"ID": "20240128111910-b9hb5w9",
"Type": "NodeParagraph",
"Properties": {
"id": "20240128111910-b9hb5w9",
"updated": "20240128111910"
},
"Children": [
{
"Type": "NodeText",
"Data": ""
},
{
"Type": "NodeTextMark",
"TextMarkType": "code",
"TextMarkTextContent": "riff-review-card-limit"
},
{
"Type": "NodeText",
"Data": ""
}
]
}
]
}
]
},
{
"ID": "20240128111824-6gfrt8e",
"Type": "NodeParagraph",
"Properties": {
"id": "20240128111824-6gfrt8e",
"updated": "20240128113519"
},
"Children": [
{
"Type": "NodeText",
"Data": ""
},
{
"Type": "NodeImage",
"Data": "span",
"Children": [
{
"Type": "NodeBang"
},
{
"Type": "NodeOpenBracket"
},
{
"Type": "NodeLinkText",
"Data": "image"
},
{
"Type": "NodeCloseBracket"
},
{
"Type": "NodeOpenParen"
},
{
"Type": "NodeLinkDest",
"Data": "assets/image-20240128113232-ny2q076.png"
},
{
"Type": "NodeCloseParen"
}
]
},
{
"Type": "NodeText",
"Data": ""
}
]
},
{
"ID": "20240128111957-wa0cjkq",
"Type": "NodeParagraph",
"Properties": {
"id": "20240128111957-wa0cjkq",
"updated": "20240128111957"
},
"Children": [
{
"Type": "NodeText",
"Data": "不同文檔上單獨配置,相互獨立不影響,例如父文檔上配置為 5子文檔為 10那麼從父文檔複習的時候就是 5不會疊加子文檔的配置。"
}
]
},
{
"ID": "20221223221502-cqcjal6",
"Type": "NodeHeading",
@ -544,7 +756,7 @@
"ListData": {},
"Properties": {
"id": "20221223221502-n4qqurn",
"updated": "20221223221502"
"updated": "20240128112842"
},
"Children": [
{
@ -574,6 +786,34 @@
]
}
]
},
{
"ID": "20240128112426-7avqfo1",
"Type": "NodeListItem",
"ListData": {
"BulletChar": 42,
"Marker": "Kg=="
},
"Properties": {
"id": "20240128112426-7avqfo1",
"updated": "20240128112842"
},
"Children": [
{
"ID": "20240128112426-gzlcn7u",
"Type": "NodeParagraph",
"Properties": {
"id": "20240128112426-gzlcn7u",
"updated": "20240128112842"
},
"Children": [
{
"Type": "NodeText",
"Data": "不建議啟用卡包,該方式已經棄用,繼續使用可能會遇到無法解決的問題"
}
]
}
]
}
]
},

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -46,6 +46,7 @@ export const exportConfig = {
<option value="2" ${window.siyuan.config.export.blockRefMode === 2 ? "selected" : ""}>${window.siyuan.languages.export2}</option>
<option value="3" ${window.siyuan.config.export.blockRefMode === 3 ? "selected" : ""}>${window.siyuan.languages.export3}</option>
<option value="4" ${window.siyuan.config.export.blockRefMode === 4 ? "selected" : ""}>${window.siyuan.languages.export4}</option>
<option value="5" ${window.siyuan.config.export.blockRefMode === 5 ? "selected" : ""}>${window.siyuan.languages.export9}</option>
</select>
</div>
<div class="fn__flex b3-label config__item">
@ -88,7 +89,7 @@ export const exportConfig = {
<textarea class="b3-text-field fn__block" id="pdfWatermarkDesc"></textarea>
</div>
<div class="b3-label config__item">
${window.siyuan.languages.export9}
${window.siyuan.languages.export30}
<div class="b3-label__text">${window.siyuan.languages.export28}</div>
<div class="fn__hr"></div>
<input class="b3-text-field fn__block" id="imageWatermarkStr">

View file

@ -42,7 +42,7 @@ export const exportImage = (id: string) => {
<input id="keepFold" class="b3-switch fn__flex-center" type="checkbox" ${window.siyuan.storage[Constants.LOCAL_EXPORTIMG].keepFold ? "checked" : ""}>
</label>
<label class="fn__flex" style="margin-left: 24px">
${window.siyuan.languages.export9}
${window.siyuan.languages.export30}
<span class="fn__space"></span>
<input id="watermark" class="b3-switch fn__flex-center" type="checkbox" ${window.siyuan.storage[Constants.LOCAL_EXPORTIMG].watermark ? "checked" : ""}>
</label>

View file

@ -317,6 +317,7 @@ func ServeAPI(ginServer *gin.Engine) {
ginServer.Handle("POST", "/api/setting/addVirtualBlockRefInclude", model.CheckAuth, model.CheckReadonly, addVirtualBlockRefInclude)
ginServer.Handle("POST", "/api/setting/addVirtualBlockRefExclude", model.CheckAuth, model.CheckReadonly, addVirtualBlockRefExclude)
ginServer.Handle("POST", "/api/setting/setSnippet", model.CheckAuth, model.CheckReadonly, setConfSnippet)
ginServer.Handle("POST", "/api/setting/setEditorReadOnly", model.CheckAuth, model.CheckReadonly, setEditorReadOnly)
ginServer.Handle("POST", "/api/graph/resetGraph", model.CheckAuth, model.CheckReadonly, resetGraph)
ginServer.Handle("POST", "/api/graph/resetLocalGraph", model.CheckAuth, model.CheckReadonly, resetLocalGraph)

View file

@ -29,6 +29,27 @@ import (
"github.com/siyuan-note/siyuan/kernel/util"
)
func setEditorReadOnly(c *gin.Context) {
ret := gulu.Ret.NewResult()
defer c.JSON(http.StatusOK, ret)
arg, ok := util.JsonArg(c, ret)
if !ok {
return
}
readOnly := arg["readonly"].(bool)
oldReadOnly := model.Conf.Editor.ReadOnly
model.Conf.Editor.ReadOnly = readOnly
model.Conf.Save()
if oldReadOnly != model.Conf.Editor.ReadOnly {
util.BroadcastByType("protyle", "readonly", 0, "", model.Conf.Editor.ReadOnly)
util.BroadcastByType("main", "readonly", 0, "", model.Conf.Editor.ReadOnly)
}
}
func setConfSnippet(c *gin.Context) {
ret := gulu.Ret.NewResult()
defer c.JSON(http.StatusOK, ret)

View file

@ -17,23 +17,29 @@
package conf
type Export struct {
ParagraphBeginningSpace bool `json:"paragraphBeginningSpace"` // 是否使用中文排版段落开头空两格
AddTitle bool `json:"addTitle"` // 是否添加标题
BlockRefMode int `json:"blockRefMode"` // 内容块引用导出模式2锚文本块链3仅锚文本4块引转脚注0使用原始文本1使用 Blockquote。0 和 1 都已经废弃 https://github.com/siyuan-note/siyuan/issues/3155
BlockEmbedMode int `json:"blockEmbedMode"` // 内容块引用导出模式0使用原始文本1使用 Blockquote
BlockRefTextLeft string `json:"blockRefTextLeft"` // 内容块引用导出锚文本左侧符号,默认留空
BlockRefTextRight string `json:"blockRefTextRight"` // 内容块引用导出锚文本右侧符号,默认留空
TagOpenMarker string `json:"tagOpenMarker"` // 标签开始标记符,默认是 #
TagCloseMarker string `json:"tagCloseMarker"` // 标签结束标记符,默认是 #
FileAnnotationRefMode int `json:"fileAnnotationRefMode"` // 文件标注引用导出模式0文件名 - 页码 - 锚文本1仅锚文本
PandocBin string `json:"pandocBin"` // Pandoc 可执行文件路径
MarkdownYFM bool `json:"markdownYFM"` // Markdown 导出时是否添加 YAML Front Matter https://github.com/siyuan-note/siyuan/issues/7727
PDFFooter string `json:"pdfFooter"` // PDF 导出时页脚内容
DocxTemplate string `json:"docxTemplate"` // Docx 导出时模板文件路径
PDFWatermarkStr string `json:"pdfWatermarkStr"` // PDF 导出时水印文本或水印文件路径
PDFWatermarkDesc string `json:"pdfWatermarkDesc"` // PDF 导出时水印位置、大小和样式等
ImageWatermarkStr string `json:"imageWatermarkStr"` // 图片导出时水印文本或水印文件路径
ImageWatermarkDesc string `json:"imageWatermarkDesc"` // 图片导出时水印位置、大小和样式等
ParagraphBeginningSpace bool `json:"paragraphBeginningSpace"` // 是否使用中文排版段落开头空两格
AddTitle bool `json:"addTitle"` // 是否添加标题
// 内容块引用导出模式
// 2锚文本块链
// 3仅锚文本
// 4块引转脚注
// 5锚点哈希 https://github.com/siyuan-note/siyuan/issues/10265
// 0使用原始文本1使用 Blockquote。0 和 1 都已经废弃 https://github.com/siyuan-note/siyuan/issues/3155
BlockRefMode int `json:"blockRefMode"`
BlockEmbedMode int `json:"blockEmbedMode"` // 内容块引用导出模式0使用原始文本1使用 Blockquote
BlockRefTextLeft string `json:"blockRefTextLeft"` // 内容块引用导出锚文本左侧符号,默认留空
BlockRefTextRight string `json:"blockRefTextRight"` // 内容块引用导出锚文本右侧符号,默认留空
TagOpenMarker string `json:"tagOpenMarker"` // 标签开始标记符,默认是 #
TagCloseMarker string `json:"tagCloseMarker"` // 标签结束标记符,默认是 #
FileAnnotationRefMode int `json:"fileAnnotationRefMode"` // 文件标注引用导出模式0文件名 - 页码 - 锚文本1仅锚文本
PandocBin string `json:"pandocBin"` // Pandoc 可执行文件路径
MarkdownYFM bool `json:"markdownYFM"` // Markdown 导出时是否添加 YAML Front Matter https://github.com/siyuan-note/siyuan/issues/7727
PDFFooter string `json:"pdfFooter"` // PDF 导出时页脚内容
DocxTemplate string `json:"docxTemplate"` // Docx 导出时模板文件路径
PDFWatermarkStr string `json:"pdfWatermarkStr"` // PDF 导出时水印文本或水印文件路径
PDFWatermarkDesc string `json:"pdfWatermarkDesc"` // PDF 导出时水印位置、大小和样式等
ImageWatermarkStr string `json:"imageWatermarkStr"` // 图片导出时水印文本或水印文件路径
ImageWatermarkDesc string `json:"imageWatermarkDesc"` // 图片导出时水印位置、大小和样式等
}
func NewExport() *Export {

View file

@ -248,7 +248,7 @@ func Export2Liandi(id string) (err error) {
4, 1, 0,
"#", "#",
"", "",
false)
false, nil)
result := gulu.Ret.NewResult()
request := httpclient.NewCloudRequest30s()
request = request.
@ -1316,7 +1316,7 @@ func ExportStdMarkdown(id string) string {
Conf.Export.BlockRefMode, Conf.Export.BlockEmbedMode, Conf.Export.FileAnnotationRefMode,
Conf.Export.TagOpenMarker, Conf.Export.TagCloseMarker,
Conf.Export.BlockRefTextLeft, Conf.Export.BlockRefTextRight,
Conf.Export.AddTitle)
Conf.Export.AddTitle, nil)
}
func ExportPandocConvertZip(id, pandocTo, ext string) (name, zipPath string) {
@ -1338,7 +1338,7 @@ func ExportPandocConvertZip(id, pandocTo, ext string) (name, zipPath string) {
docPaths = append(docPaths, docFile.path)
}
zipPath = exportPandocConvertZip(boxID, baseFolderName, docPaths, "gfm+footnotes+hard_line_breaks", pandocTo, ext)
zipPath = exportPandocConvertZip(false, boxID, baseFolderName, docPaths, "gfm+footnotes+hard_line_breaks", pandocTo, ext)
name = strings.TrimSuffix(filepath.Base(block.Path), ".sy")
return
}
@ -1366,7 +1366,7 @@ func BatchExportMarkdown(boxID, folderPath string) (zipPath string) {
for _, docFile := range docFiles {
docPaths = append(docPaths, docFile.path)
}
zipPath = exportPandocConvertZip(boxID, baseFolderName, docPaths, "", "", ".md")
zipPath = exportPandocConvertZip(true, boxID, baseFolderName, docPaths, "", "", ".md")
return
}
@ -1762,10 +1762,10 @@ func walkRelationAvs(avID string, exportAvIDs *hashset.Set) {
}
func ExportMarkdownContent(id string) (hPath, exportedMd string) {
return exportMarkdownContent(id)
return exportMarkdownContent(id, Conf.Export.BlockRefMode, nil)
}
func exportMarkdownContent(id string) (hPath, exportedMd string) {
func exportMarkdownContent(id string, exportRefMode int, defBlockIDs []string) (hPath, exportedMd string) {
tree, err := loadTreeByBlockID(id)
if nil != err {
logging.LogErrorf("load tree by block id [%s] failed: %s", id, err)
@ -1773,10 +1773,10 @@ func exportMarkdownContent(id string) (hPath, exportedMd string) {
}
hPath = tree.HPath
exportedMd = exportMarkdownContent0(tree, "", false,
Conf.Export.BlockRefMode, Conf.Export.BlockEmbedMode, Conf.Export.FileAnnotationRefMode,
exportRefMode, Conf.Export.BlockEmbedMode, Conf.Export.FileAnnotationRefMode,
Conf.Export.TagOpenMarker, Conf.Export.TagCloseMarker,
Conf.Export.BlockRefTextLeft, Conf.Export.BlockRefTextRight,
Conf.Export.AddTitle)
Conf.Export.AddTitle, defBlockIDs)
docIAL := parse.IAL2Map(tree.Root.KramdownIAL)
exportedMd = yfm(docIAL) + exportedMd
return
@ -1786,7 +1786,8 @@ func exportMarkdownContent0(tree *parse.Tree, cloudAssetsBase string, assetsDest
blockRefMode, blockEmbedMode, fileAnnotationRefMode int,
tagOpenMarker, tagCloseMarker string,
blockRefTextLeft, blockRefTextRight string,
addTitle bool) (ret string) {
addTitle bool,
defBlockIDs []string) (ret string) {
tree = exportTree(tree, false, true, false,
blockRefMode, blockEmbedMode, fileAnnotationRefMode,
tagOpenMarker, tagCloseMarker,
@ -1818,7 +1819,6 @@ func exportMarkdownContent0(tree *parse.Tree, cloudAssetsBase string, assetsDest
})
}
// When exporting Markdown, `<br />` nodes in non-tables are replaced with `\n` text nodes https://github.com/siyuan-note/siyuan/issues/9509
var unlinks []*ast.Node
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
if !entering {
@ -1827,10 +1827,45 @@ func exportMarkdownContent0(tree *parse.Tree, cloudAssetsBase string, assetsDest
if ast.NodeBr == n.Type {
if !n.ParentIs(ast.NodeTableCell) {
// When exporting Markdown, `<br />` nodes in non-tables are replaced with `\n` text nodes https://github.com/siyuan-note/siyuan/issues/9509
n.InsertBefore(&ast.Node{Type: ast.NodeText, Tokens: []byte("\n")})
unlinks = append(unlinks, n)
}
}
if 5 == blockRefMode { // 锚点哈希
if n.IsBlock() && gulu.Str.Contains(n.ID, defBlockIDs) {
// 如果是定义块,则在开头处添加锚点
anchorSpan := &ast.Node{Type: ast.NodeInlineHTML, Tokens: []byte("<span id=\"" + n.ID + "\"></span>")}
if ast.NodeDocument != n.Type {
firstLeaf := treenode.FirstLeafBlock(n)
if nil != firstLeaf && nil != firstLeaf.FirstChild {
firstLeaf.FirstChild.InsertBefore(anchorSpan)
} else {
n.AppendChild(anchorSpan)
}
}
}
if treenode.IsBlockRef(n) {
// 如果是引用元素,则将其转换为超链接,指向 xxx.md#block-id
defID, linkText := getExportBlockRefLinkText(n, blockRefTextLeft, blockRefTextRight)
if gulu.Str.Contains(defID, defBlockIDs) {
var href string
bt := treenode.GetBlockTree(defID)
if nil != bt {
href += strings.TrimPrefix(bt.HPath, "/") + ".md"
if "d" != bt.Type {
href += "#" + defID
}
}
blockRefLink := &ast.Node{Type: ast.NodeTextMark, TextMarkType: "a", TextMarkTextContent: linkText, TextMarkAHref: href}
blockRefLink.KramdownIAL = n.KramdownIAL
n.InsertBefore(blockRefLink)
unlinks = append(unlinks, n)
}
}
}
return ast.WalkContinue
})
for _, unlink := range unlinks {
@ -2017,16 +2052,7 @@ func exportTree(tree *parse.Tree, wysiwyg, expandKaTexMacros, keepFold bool,
// 处理引用节点
defID, linkText, _ := treenode.GetBlockRef(n)
if "" == linkText {
linkText = sql.GetRefText(defID)
}
linkText = html.UnescapeHTMLStr(linkText) // 块引锚文本导出时 `&` 变为实体 `&amp;` https://github.com/siyuan-note/siyuan/issues/7659
if Conf.Editor.BlockRefDynamicAnchorTextMaxLen < utf8.RuneCountInString(linkText) {
linkText = gulu.Str.SubStr(linkText, Conf.Editor.BlockRefDynamicAnchorTextMaxLen) + "..."
}
linkText = blockRefTextLeft + linkText + blockRefTextRight
defID, linkText := getExportBlockRefLinkText(n, blockRefTextLeft, blockRefTextRight)
defTree, _ := loadTreeByBlockID(defID)
if nil == defTree {
return ast.WalkContinue
@ -2034,21 +2060,24 @@ func exportTree(tree *parse.Tree, wysiwyg, expandKaTexMacros, keepFold bool,
switch blockRefMode {
case 2: // 锚文本块链
var blockRefLink *ast.Node
blockRefLink = &ast.Node{Type: ast.NodeTextMark, TextMarkType: "a", TextMarkTextContent: linkText, TextMarkAHref: "siyuan://blocks/" + defID}
blockRefLink := &ast.Node{Type: ast.NodeTextMark, TextMarkType: "a", TextMarkTextContent: linkText, TextMarkAHref: "siyuan://blocks/" + defID}
blockRefLink.KramdownIAL = n.KramdownIAL
n.InsertBefore(blockRefLink)
unlinks = append(unlinks, n)
case 3: // 仅锚文本
var blockRefLink *ast.Node
blockRefLink = &ast.Node{Type: ast.NodeTextMark, TextMarkType: "text", TextMarkTextContent: linkText}
blockRefLink := &ast.Node{Type: ast.NodeTextMark, TextMarkType: "text", TextMarkTextContent: linkText}
blockRefLink.KramdownIAL = n.KramdownIAL
n.InsertBefore(blockRefLink)
unlinks = append(unlinks, n)
case 4: // 脚注
refFoot := getRefAsFootnotes(defID, &refFootnotes)
n.InsertBefore(&ast.Node{Type: ast.NodeText, Tokens: []byte(linkText)})
n.InsertBefore(&ast.Node{Type: ast.NodeFootnotesRef, Tokens: []byte("^" + refFoot.refNum), FootnotesRefId: refFoot.refNum, FootnotesRefLabel: []byte("^" + refFoot.refNum)})
unlinks = append(unlinks, n)
case 5: // 锚点哈希
// 此处不做任何处理
}
unlinks = append(unlinks, n)
if nil != n.Next && ast.NodeKramdownSpanIAL == n.Next.Type {
// 引用加排版标记(比如颜色)重叠时丢弃后面的排版属性节点
unlinks = append(unlinks, n.Next)
@ -2555,7 +2584,7 @@ func processFileAnnotationRef(refID string, n *ast.Node, fileAnnotationRefMode i
return ast.WalkSkipChildren
}
func exportPandocConvertZip(boxID, baseFolderName string, docPaths []string,
func exportPandocConvertZip(exportNotebook bool, boxID, baseFolderName string, docPaths []string,
pandocFrom, pandocTo, ext string) (zipPath string) {
dir, name := path.Split(baseFolderName)
name = util.FilterFileName(name)
@ -2574,6 +2603,41 @@ func exportPandocConvertZip(boxID, baseFolderName string, docPaths []string,
return
}
exportRefMode := Conf.Export.BlockRefMode
if !exportNotebook && 5 == exportRefMode {
// 非笔记本导出不支持锚点哈希,将其切换为锚文本块链
exportRefMode = 2
}
var defBlockIDs []string
if exportNotebook && 5 == exportRefMode {
// Add a Ref export mode `Anchor hash` for notebook Markdown exporting https://github.com/siyuan-note/siyuan/issues/10265
// 导出笔记本时导出锚点哈希,这里先记录下所有定义块的 ID
for _, p := range docPaths {
docIAL := box.docIAL(p)
if nil == docIAL {
continue
}
id := docIAL["id"]
tree, err := loadTreeByBlockID(id)
if nil != err {
continue
}
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)
defBlockIDs = append(defBlockIDs, defID)
}
return ast.WalkContinue
})
}
defBlockIDs = gulu.Str.RemoveDuplicatedElem(defBlockIDs)
}
luteEngine := util.NewLute()
for _, p := range docPaths {
docIAL := box.docIAL(p)
@ -2582,7 +2646,7 @@ func exportPandocConvertZip(boxID, baseFolderName string, docPaths []string,
}
id := docIAL["id"]
hPath, md := exportMarkdownContent(id)
hPath, md := exportMarkdownContent(id, exportRefMode, defBlockIDs)
dir, name = path.Split(hPath)
dir = util.FilterFilePath(dir) // 导出文档时未移除不支持的文件名符号 https://github.com/siyuan-note/siyuan/issues/4590
name = util.FilterFileName(name)
@ -2610,6 +2674,10 @@ func exportPandocConvertZip(boxID, baseFolderName string, docPaths []string,
asset = asset[:strings.LastIndex(asset, "?")]
}
if !strings.HasPrefix(asset, "assets/") {
continue
}
srcPath, err := GetAssetAbsPath(asset)
if nil != err {
logging.LogWarnf("get asset [%s] abs path failed: %s", asset, err)
@ -2666,3 +2734,16 @@ func exportPandocConvertZip(boxID, baseFolderName string, docPaths []string,
zipPath = "/export/" + url.PathEscape(filepath.Base(zipPath))
return
}
func getExportBlockRefLinkText(blockRef *ast.Node, blockRefTextLeft, blockRefTextRight string) (defID, linkText string) {
defID, linkText, _ = treenode.GetBlockRef(blockRef)
if "" == linkText {
linkText = sql.GetRefText(defID)
}
linkText = html.UnescapeHTMLStr(linkText) // 块引锚文本导出时 `&` 变为实体 `&amp;` https://github.com/siyuan-note/siyuan/issues/7659
if Conf.Editor.BlockRefDynamicAnchorTextMaxLen < utf8.RuneCountInString(linkText) {
linkText = gulu.Str.SubStr(linkText, Conf.Editor.BlockRefDynamicAnchorTextMaxLen) + "..."
}
linkText = blockRefTextLeft + linkText + blockRefTextRight
return
}

View file

@ -28,7 +28,6 @@ import (
"github.com/88250/gulu"
"github.com/88250/lute"
"github.com/88250/lute/ast"
"github.com/88250/lute/html"
"github.com/88250/lute/parse"
"github.com/siyuan-note/filelock"
"github.com/siyuan-note/siyuan/kernel/util"
@ -88,7 +87,9 @@ func IALStr(n *ast.Node) string {
if 1 > len(n.KramdownIAL) {
return ""
}
return html.UnescapeString(string(parse.IAL2Tokens(n.KramdownIAL)))
// 这里不能进行转义,否则会导致从数据库中读取后转换为 IAL 时解析错误
// 所以 Some symbols should not be escaped to avoid inaccurate searches https://github.com/siyuan-note/siyuan/issues/10185 无法被修复了
return string(parse.IAL2Tokens(n.KramdownIAL))
}
func RootChildIDs(rootID string) (ret []string) {