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

This commit is contained in:
Vanessa 2024-11-09 15:41:40 +08:00
commit 2b3283f060
32 changed files with 382 additions and 87 deletions

View file

@ -520,7 +520,7 @@
"htmlBlockError": "Die Ausführung des folgenden Skripts wird die Anzeige der Oberfläche beeinträchtigen, das Skript wurde angehalten.",
"fileHistory": "Dateihistorie",
"htmlBlockTip": "Mehrere HTML-Blöcke werden gebildet. Um Datenverlust zu vermeiden, bitte <code class='fn__code'>&lt;div&gt;</code>-Tags zur Umwicklung verwenden und Leerzeilen entfernen.",
"katexMacros": "KaTex-Makrodefinition",
"katexMacros": "KaTeX-Makrodefinition",
"katexMacrosTip": "Bitte verwenden Sie das JSON-Objektformat (<code class='fn__code'>{}</code>), um Makrodefinitionen einzufassen, z.B. <code class='fn__code'>{ \"\\\\foo\": \"{x^2}\" }</code>",
"systemLogTip": "Programmlaufzeithistorien sind im Systemprotokoll gespeichert. Durch den Export des Systemprotokolls und das Senden an Entwickler können Probleme besser diagnostiziert werden.",
"systemLog": "Systemprotokoll",
@ -1564,6 +1564,7 @@
"247": "Datei [%s] ist größer als die maximale Grenze [%s] und wurde beim Hochladen in die Cloud ignoriert.",
"248": "Die Zielfüberschrift befindet sich im Containerblock und kann nicht als Ablagepunkt verwendet werden.",
"249": "Aufgrund eines Konfigurationsfehlers kann nicht auf die Daten zugegriffen werden. Bitte überprüfen Sie die Einstellungen und die Berechtigungen für den Cloud-Speicher",
"250": "Die Anfrage wurde vom Cloud-Speicher begrenzt. Bitte überprüfen Sie die Einstellungen und die Berechtigungen für den Cloud-Speicher"
"250": "Die Anfrage wurde vom Cloud-Speicher begrenzt. Bitte überprüfen Sie die Einstellungen und die Berechtigungen für den Cloud-Speicher",
"251": "Insgesamt ungenutzte Assets [%d], hier nur [%d] aufgeführt"
}
}

View file

@ -520,7 +520,7 @@
"htmlBlockError": "The execution of the following script will affect the interface display, and the script has stopped running",
"fileHistory": "File history",
"htmlBlockTip": "Multiple HTML blocks are formed. To prevent data loss, please use <code class='fn__code'>&lt;div&gt;</code> tags to wrap and remove blank lines",
"katexMacros": "KaTex macro definition",
"katexMacros": "KaTeX macro definition",
"katexMacrosTip": "Please use JSON object format (<code class='fn__code'>{}</code>) to wrap macro definitions, eg <code class='fn__code'>{ \"\\\\foo\": \"{x^2}\" }</code>",
"systemLogTip": "Program running records are saved in the system log. By exporting the system log and sending it to developers, it can better help developers diagnose program problems",
"systemLog": "System log",
@ -1564,6 +1564,7 @@
"247": "File [%s] is larger than the maximum limit [%s], and has been ignored for uploading to the cloud",
"248": "The target heading is located in the container block and cannot be used as a drop point",
"249": "Unable to access data due to configuration error. Please check the settings and cloud storage permissions",
"250": "Request has been rate-limited by cloud storage. Please check the settings and cloud storage permissions"
"250": "Request has been rate-limited by cloud storage. Please check the settings and cloud storage permissions",
"251": "Total unused assets [%d], only [%d] listed here"
}
}

View file

@ -520,7 +520,7 @@
"htmlBlockError": "La ejecución del siguiente script afectará la visualización de la interfaz y el script ha dejado de ejecutarse",
"fileHistory": "Historial de archivos",
"htmlBlockTip": "Se forman varios bloques HTML. Para evitar la pérdida de datos, utilice etiquetas <code class='fn__code'>&lt;div&gt;</code> para ajustar y eliminar líneas en blanco",
"katexMacros": "Definición de macro de KaTex",
"katexMacros": "Definición de macro de KaTeX",
"katexMacrosTip": "Utilice el formato de objeto JSON (<code class='fn__code'>{}</code>) para envolver definiciones de macro, por ejemplo, <code class='fn__code'>{ \"\\\\foo\": \"{x^2}\" }</code>",
"systemLogTip": "Los registros de ejecución del programa se guardan en el registro del sistema. Al exportar el registro del sistema y enviarlo a los desarrolladores, puede ayudarlos a diagnosticar mejor los problemas del programa",
"systemLog": "Registro del sistema",
@ -1564,6 +1564,7 @@
"247": "El archivo [%s] es más grande que el límite máximo [%s] y se ha ignorado para cargarlo en la nube",
"248": "El rumbo de destino está ubicado en el bloque contenedor y no puede usarse como punto de entrega",
"249": "No se puede acceder a los datos debido a un error de configuración. Por favor, verifique las configuraciones y permisos de almacenamiento en la nube",
"250": "La solicitud ha sido limitada por el almacenamiento en la nube. Por favor, verifique las configuraciones y permisos de almacenamiento en la nube"
"250": "La solicitud ha sido limitada por el almacenamiento en la nube. Por favor, verifique las configuraciones y permisos de almacenamiento en la nube",
"251": "Total de activos no utilizados [%d], solo [%d] listados aquí"
}
}

View file

@ -520,7 +520,7 @@
"htmlBlockError": "L'exécution du script suivant affectera l'affichage de l'interface et le script a cessé de s'exécuter",
"fileHistory": "Historique des fichiers",
"htmlBlockTip": "Plusieurs blocs HTML sont formés. Pour éviter la perte de données, veuillez utiliser les balises <code class='fn__code'>&lt;div&gt;</code> pour envelopper et supprimer les lignes vides",
"katexMacros": "Définition de la macro KaTex",
"katexMacros": "Définition de la macro KaTeX",
"katexMacrosTip": "Veuillez utiliser le format d'objet JSON (<code class='fn__code'>{}</code>) pour envelopper les définitions de macro, par exemple <code class='fn__code'>{ \"\\\\foo\": \"{x^2}\" }</code>",
"systemLogTip": "Les enregistrements en cours d'exécution du programme sont enregistrés dans le journal système. En exportant le journal système et en l'envoyant aux développeurs, cela peut mieux aider les développeurs à diagnostiquer les problèmes du programme",
"systemLog": "Journal du système",
@ -1564,6 +1564,7 @@
"247": "Le fichier [%s] est plus grand que la limite maximale [%s] et a été ignoré pour le téléchargement vers le cloud",
"248": "Le cap cible est situé dans le bloc conteneur et ne peut pas être utilisé comme point de dépôt",
"249": "Impossible d'accéder aux données en raison d'une erreur de configuration. Veuillez vérifier les paramètres et les autorisations de stockage cloud",
"250": "La demande a été limitée par le stockage cloud. Veuillez vérifier les paramètres et les autorisations de stockage cloud"
"250": "La demande a été limitée par le stockage cloud. Veuillez vérifier les paramètres et les autorisations de stockage cloud",
"251": "Total des actifs inutilisés [%d], seulement [%d] listés ici"
}
}

View file

@ -520,7 +520,7 @@
"htmlBlockError": "ביצוע הסקריפט הבא ישפיע על תצוגת הממשק, והסקריפט הפסיק לפעול",
"fileHistory": "היסטוריית קובץ",
"htmlBlockTip": "בטל שורות HTML מרובות. כדי למנוע אובדן מידע, יש להשתמש בתגי <code class='fn__code'>&lt;div&gt;</code> כדי להקיף ולהסיר שורות ריקות",
"katexMacros": "הגדרת מאקרו KaTex",
"katexMacros": "הגדרת מאקרו KaTeX",
"katexMacrosTip": "נא השתמש בפורמט אובייקט JSON (<code class='fn__code'>{}</code>) כדי לעטוף הגדרות מאקרו, לדוגמה <code class='fn__code'>{ \"\\\\foo\": \"{x^2}\" }</code>",
"systemLogTip": "יומני ריצה של תוכנה נשמרים ביומן המערכת. על ידי ייצוא היומן ולשלח אותו למתכנתי תכניות, זה יכול לעזור במידה רבה לצוות המתכנתים לאבחן בעיות בתכנה",
"systemLog": "יומן מערכת",
@ -1564,6 +1564,7 @@
"247": "הקובץ [%s] גדול יותר מהמגבלה המקסימלית [%s], והוזנח להעלות בענן",
"248": "הכותרת היעד ממוקמת בבלוק המיכל ואינה יכולה לשמש כנקודת זרימה",
"249": "אין אפשרות לגשת לנתונים עקב שגיאת תצורה. אנא בדוק את ההגדרות והרשאות האחסון בענן",
"250": "הבקשה הוגבלה על ידי אחסון הענן. אנא בדוק את ההגדרות והרשאות האחסון בענן"
"250": "הבקשה הוגבלה על ידי אחסון הענן. אנא בדוק את ההגדרות והרשאות האחסון בענן",
"251": "סך כל הנכסים שלא נעשה בהם שימוש [%d], רק [%d] מופיעים כאן"
}
}

View file

@ -520,7 +520,7 @@
"htmlBlockError": "L'esecuzione dello script seguente influenzerà la visualizzazione dell'interfaccia e lo script ha smesso di funzionare",
"fileHistory": "Cronologia file",
"htmlBlockTip": "Sono stati formati più blocchi HTML. Per prevenire la perdita di dati, utilizza i tag <code class='fn__code'>&lt;div&gt;</code> per racchiudere e rimuovere le righe vuote",
"katexMacros": "Definizione macro KaTex",
"katexMacros": "Definizione macro KaTeX",
"katexMacrosTip": "Si prega di utilizzare il formato oggetto JSON (<code class='fn__code'>{}</code>) per racchiudere le definizioni delle macro, ad esempio <code class='fn__code'>{ \"\\\\foo\": \"{x^2}\" }</code>",
"systemLogTip": "I registri di esecuzione del programma sono salvati nel registro di sistema. Esportando il registro di sistema e inviandolo agli sviluppatori, è possibile aiutarli meglio a diagnosticare i problemi del programma",
"systemLog": "Registro di sistema",
@ -1564,6 +1564,7 @@
"247": "Il file [%s] è più grande del limite massimo [%s] ed è stato ignorato per il caricamento nel cloud",
"248": "L'intestazione di destinazione si trova nel blocco contenitore e non può essere utilizzata come punto di rilascio",
"249": "Impossibile accedere ai dati a causa di un errore di configurazione. Si prega di controllare attentamente le impostazioni e le autorizzazioni di archiviazione cloud",
"250": "La richiesta è stata limitata dall'archiviazione cloud. Si prega di controllare attentamente le impostazioni e le autorizzazioni di archiviazione cloud"
"250": "La richiesta è stata limitata dall'archiviazione cloud. Si prega di controllare attentamente le impostazioni e le autorizzazioni di archiviazione cloud",
"251": "Totale risorse inutilizzate [%d], qui elencate solo [%d]"
}
}

View file

@ -520,7 +520,7 @@
"htmlBlockError": "次のスクリプトはインターフェースの表示に影響するため実行が停止されました",
"fileHistory": "ファイル履歴",
"htmlBlockTip": "複数の HTML ブロックが形成されています。データの損失を防ぐために <code class='fn__code'>&lt;div&gt;</code> タグで囲んで空白行を削除してください",
"katexMacros": "KaTex マクロ定義",
"katexMacros": "KaTeX マクロ定義",
"katexMacrosTip": "JSON オブジェクト形式 (<code class='fn__code'>{}</code>) を使用してマクロ定義を囲んでください (例: <code class='fn__code'>{ \"\\\\foo\": \"{x^2}\" }</code>)",
"systemLogTip": "プログラムの実行記録はシステムログに保存されます。システムログをエクスポートして開発者に送信することで開発者がプログラムの問題を診断するのに役立ちます",
"systemLog": "システムログ",
@ -1564,6 +1564,7 @@
"247": "ファイル [%s] は制限サイズ [%s] を超えているためアップロードされませんでした",
"248": "目標の見出しがコンテナブロック内にあるためドロップできません",
"249": "設定エラーのためデータにアクセスできません。設定を一つずつ確認し、クラウドストレージの権限を確認してください",
"250": "リクエストがクラウドストレージによって制限されました。設定を一つずつ確認し、クラウドストレージの権限を確認してください"
"250": "リクエストがクラウドストレージによって制限されました。設定を一つずつ確認し、クラウドストレージの権限を確認してください",
"251": "未使用のアセットの合計 [%d]、ここにリストされているのは [%d] のみ"
}
}

View file

@ -520,7 +520,7 @@
"htmlBlockError": "Wykonanie następującego skryptu wpłynie na wygląd interfejsu i skrypt przestał działać",
"fileHistory": "Historia pliku",
"htmlBlockTip": "Tworzone są wiele bloków HTML. Aby zapobiec utracie danych, proszę używać znaczników <code class='fn__code'>&lt;div&gt;</code> do opakowania i usunięcia pustych linii",
"katexMacros": "Definicja makr KaTex",
"katexMacros": "Definicja makr KaTeX",
"katexMacrosTip": "Proszę używać formatu obiektu JSON (<code class='fn__code'>{}</code>) do opakowania definicji makr, np. <code class='fn__code'>{ \"\\\\foo\": \"{x^2}\" }</code>",
"systemLogTip": "Rekordy działania programu są zapisywane w dzienniku systemowym. Eksportując dziennik systemowy i przesyłając go programistom, można lepiej pomóc w diagnozowaniu problemów z programem",
"systemLog": "Dziennik systemowy",
@ -1564,6 +1564,7 @@
"247": "Plik [%s] jest większy niż maksymalne ograniczenie [%s], i został zignorowany przy przesyłaniu do chmury",
"248": "Docelowy nagłówek znajduje się w bloku kontenera i nie może być użyty jako punkt upuszczenia",
"249": "Z powodu błędu konfiguracji nie można uzyskać dostępu do danych. Proszę dokładnie sprawdzić ustawienia i uprawnienia do przechowywania w chmurze",
"250": "Żądanie zostało ograniczone przez przechowywanie w chmurze. Proszę dokładnie sprawdzić ustawienia i uprawnienia do przechowywania w chmurze"
"250": "Żądanie zostało ograniczone przez przechowywanie w chmurze. Proszę dokładnie sprawdzić ustawienia i uprawnienia do przechowywania w chmurze",
"251": "Łączna liczba nieużywanych zasobów [%d], tutaj wymieniono tylko [%d]"
}
}

View file

@ -520,7 +520,7 @@
"htmlBlockError": "Выполнение следующего скрипта повлияет на отображение интерфейса, и скрипт был остановлен",
"fileHistory": "История файлов",
"htmlBlockTip": "Сформированы несколько HTML блоков. Чтобы избежать потери данных, пожалуйста, используйте <code class='fn__code'>&lt;div&gt;</code> теги для обертки и удалите пустые строки",
"katexMacros": "Определение макроса KaTex",
"katexMacros": "Определение макроса KaTeX",
"katexMacrosTip": "Пожалуйста, используйте формат JSON объекта (<code class='fn__code'>{}</code>) для обертки определений макросов, например <code class='fn__code'>{ \"\\\\foo\": \"{x^2}\" }</code>",
"systemLogTip": "Записи работы программы сохраняются в системный журнал. Экспортируя системный журнал и отправив его разработчикам, это может лучше помочь разработчикам диагностировать проблемы программы",
"systemLog": "Системный журнал",
@ -1564,6 +1564,7 @@
"247": "Файл [%s] больше максимального ограничения [%s] и был проигнорирован для загрузки в облако",
"248": "Целевой заголовок находится в контейнерном блоке и не может использоваться как пункт сброса",
"249": "Из-за ошибки конфигурации невозможно получить доступ к данным. Пожалуйста, проверьте настройки и права доступа к облачному хранилищу",
"250": "Запрос был ограничен облачным хранилищем. Пожалуйста, проверьте настройки и права доступа к облачному хранилищу"
"250": "Запрос был ограничен облачным хранилищем. Пожалуйста, проверьте настройки и права доступа к облачному хранилищу",
"251": "Всего неиспользованных активов [%d], здесь перечислены только [%d]"
}
}

View file

@ -520,7 +520,7 @@
"htmlBlockError": "以下 script 執行會影響界面顯示,已經停止運行該腳本",
"fileHistory": "文件歷史",
"htmlBlockTip": "形成了多個 HTML 塊,為防止資料丟失請使用 <code class='fn__code'>&lt;div&gt;</code> 標籤包裹並去掉空行",
"katexMacros": "KaTex 宏定義",
"katexMacros": "KaTeX 宏定義",
"katexMacrosTip": "請使用 JSON 對象格式(<code class='fn__code'>{}</code>)來包裹宏定義,例如 <code class='fn__code'>{ \"\\\\foo\": \"{x^2}\" }</code>",
"systemLogTip": "系統日誌中保存了程式運行記錄,通過導出系統日誌發送給開發者可以更好地幫助開發者診斷程式問題",
"systemLog": "系統日誌",
@ -1564,6 +1564,7 @@
"247": "檔案 [%s] 大於最大限制 [%s],已忽略上傳至社群圖床",
"248": "目標標題位於容器塊中,無法作為放置點",
"249": "因配置錯誤導致無法存取數據,請仔細逐個核對配置項,並檢查雲端存儲相關權限配置",
"250": "請求已被雲端存儲限流,請仔細逐個核對配置項,並檢查雲端存儲相關權限配置"
"250": "請求已被雲端存儲限流,請仔細逐個核對配置項,並檢查雲端存儲相關權限配置",
"251": "未引用資源一共 ${x} 個,這裡僅列出 ${y} 個"
}
}

View file

@ -520,7 +520,7 @@
"htmlBlockError": "以下 script 执行会影响界面显示,已经停止运行该脚本",
"fileHistory": "文件历史",
"htmlBlockTip": "形成了多个 HTML 块,为防止数据丢失请使用 <code class='fn__code'>&lt;div&gt;</code> 标签包裹并去掉空行",
"katexMacros": "KaTex 宏定义",
"katexMacros": "KaTeX 宏定义",
"katexMacrosTip": "请使用 JSON 对象格式(<code class='fn__code'>{}</code>)来包裹宏定义,例如 <code class='fn__code'>{ \"\\\\foo\": \"{x^2}\" }</code>",
"systemLogTip": "系统日志中保存了程序运行记录,通过导出系统日志发送给开发者可以更好地帮助开发者诊断程序问题",
"systemLog": "系统日志",
@ -1564,6 +1564,7 @@
"247": "文件 [%s] 大于最大限制 [%s],已忽略上传到社区图床",
"248": "目标标题位于容器块中,无法作为放置点",
"249": "因配置错误导致无法存取数据,请仔细逐个核对配置项,并检查云端存储相关权限配置",
"250": "请求已被云端存储限流,请仔细逐个核对配置项,并检查云端存储相关权限配置"
"250": "请求已被云端存储限流,请仔细逐个核对配置项,并检查云端存储相关权限配置",
"251": "未引用资源一共 [%d] 个,这里仅列出 [%d] 个"
}
}

View file

@ -335,7 +335,7 @@ export const initNavigationMenu = (app: App, liElement: HTMLElement) => {
icon: "iconMarkdown",
click: () => {
const msgId = showMessage(window.siyuan.languages.exporting, -1);
fetchPost("/api/export/batchExportMd", {
fetchPost("/api/export/exportNotebookMd", {
notebook: notebookId,
path: "/"
}, response => {

File diff suppressed because one or more lines are too long

View file

@ -302,10 +302,13 @@ func getUnusedAssets(c *gin.Context) {
defer c.JSON(http.StatusOK, ret)
unusedAssets := model.UnusedAssets()
total := len(unusedAssets)
// List only 512 unreferenced assets https://github.com/siyuan-note/siyuan/issues/13075
if len(unusedAssets) > 512 {
unusedAssets = unusedAssets[:512]
const maxUnusedAssets = 512
if total > maxUnusedAssets {
unusedAssets = unusedAssets[:maxUnusedAssets]
util.PushMsg(fmt.Sprintf(model.Conf.Language(251), total, maxUnusedAssets), 5000)
}
ret.Data = map[string]interface{}{

View file

@ -307,7 +307,7 @@ func exportResources(c *gin.Context) {
}
}
func batchExportMd(c *gin.Context) {
func exportNotebookMd(c *gin.Context) {
ret := gulu.Ret.NewResult()
defer c.JSON(http.StatusOK, ret)
@ -318,13 +318,35 @@ func batchExportMd(c *gin.Context) {
notebook := arg["notebook"].(string)
p := arg["path"].(string)
zipPath := model.BatchExportMarkdown(notebook, p)
zipPath := model.ExportNotebookMarkdown(notebook, p)
ret.Data = map[string]interface{}{
"name": path.Base(zipPath),
"zip": zipPath,
}
}
func exportMds(c *gin.Context) {
ret := gulu.Ret.NewResult()
defer c.JSON(http.StatusOK, ret)
arg, ok := util.JsonArg(c, ret)
if !ok {
return
}
idsArg := arg["ids"].([]interface{})
var ids []string
for _, id := range idsArg {
ids = append(ids, id.(string))
}
name, zipPath := model.BatchExportPandocConvertZip(ids, "", ".md")
ret.Data = map[string]interface{}{
"name": name,
"zip": zipPath,
}
}
func exportMd(c *gin.Context) {
ret := gulu.Ret.NewResult()
defer c.JSON(http.StatusOK, ret)

View file

@ -212,6 +212,7 @@ func extensionCopy(c *gin.Context) {
unlink.Unlink()
}
parse.TextMarks2Inlines(tree) // 先将 TextMark 转换为 Inlines https://github.com/siyuan-note/siyuan/issues/13056
parse.NestedInlines2FlattedSpansHybrid(tree, false)
md, _ = lute.FormatNodeSync(tree.Root, luteEngine.ParseOptions, luteEngine.RenderOptions)

View file

@ -300,7 +300,7 @@ func generateTypeOneSVG(color string, lang string, dateInfo map[string]interface
colorScheme := getColorScheme(color)
return fmt.Sprintf(`
<svg id="dynamic_icon_type1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 504.5">
<svg id="dynamic_icon_type1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path d="M512,447.5c0,32-25,57-57,57H57c-32,0-57-25-57-57V120.5c0-31,25-57,57-57h398c32,0,57,26,57,57v327Z" style="fill: #ecf2f7;"/>
<path d="M39,0h434c21.52,0,39,17.48,39,39v146H0V39C0,17.48,17.48,0,39,0Z" style="fill: %s;"/>
<text transform="translate(22 146.5)" style="fill: #fff; font-family: -apple-system, BlinkMacSystemFont, 'Noto Sans', 'Noto Sans CJK SC', 'Microsoft YaHei'; font-size: 100px;">%s</text>
@ -316,7 +316,7 @@ func generateTypeTwoSVG(color string, lang string, dateInfo map[string]interface
colorScheme := getColorScheme(color)
return fmt.Sprintf(`
<svg id="dynamic_icon_type2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 504.5">
<svg id="dynamic_icon_type2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path d="M512,447.5c0,32-25,57-57,57H57c-32,0-57-25-57-57V120.5c0-31,25-57,57-57h398c32,0,57,26,57,57v327Z" style="fill: #ecf2f7;"/>
<path d="M39,0h434c21.52,0,39,17.48,39,39v146H0V39C0,17.48,17.48,0,39,0Z" style="fill: %s;"/>
<text transform="translate(22 146.5)" style="fill: #fff; font-family: -apple-system, BlinkMacSystemFont, 'Noto Sans', 'Noto Sans CJK SC', 'Microsoft YaHei'; font-size: 100px;">%s</text>
@ -331,7 +331,7 @@ func generateTypeThreeSVG(color string, lang string, dateInfo map[string]interfa
colorScheme := getColorScheme(color)
return fmt.Sprintf(`
<svg id="dynamic_icon_type3" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 512 504.5">
<svg id="dynamic_icon_type3" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 512 512">
<path class="cls-6" d="M512,447.5c0,32-25,57-57,57H57c-32,0-57-25-57-57V120.5c0-31,25-57,57-57h398c32,0,57,26,57,57v327Z" style="fill: #ecf2f7;"/>
<path class="cls-1" d="M39,0h434c21.5,0,39,17.5,39,39v146H0V39C0,17.5,17.5,0,39,0Z" style="fill: %s;"/>
<g style="fill: %s;">
@ -353,7 +353,7 @@ func generateTypeFourSVG(color string, lang string, dateInfo map[string]interfac
colorScheme := getColorScheme(color)
return fmt.Sprintf(`
<svg id="dynamic_icon_type4" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 512 504.5">
<svg id="dynamic_icon_type4" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 512 512">
<path class="cls-6" d="M512,447.5c0,32-25,57-57,57H57c-32,0-57-25-57-57V120.5c0-31,25-57,57-57h398c32,0,57,26,57,57v327Z" style="fill: #ecf2f7;"/>
<path class="cls-1" d="M39,0h434c21.5,0,39,17.5,39,39v146H0V39C0,17.5,17.5,0,39,0Z" style="fill: %s;"/>
<g style="fill: %s;">
@ -374,7 +374,7 @@ func generateTypeFiveSVG(color string, lang string, dateInfo map[string]interfac
colorScheme := getColorScheme(color)
return fmt.Sprintf(`
<svg id="dynamic_icon_type5" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 512 504.5">
<svg id="dynamic_icon_type5" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 512 512">
<path class="cls-6" d="M512,447.5c0,32-25,57-57,57H57c-32,0-57-25-57-57V120.5c0-31,25-57,57-57h398c32,0,57,26,57,57v327Z" style="fill: #ecf2f7;"/>
<path class="cls-1" d="M39,0h434c21.5,0,39,17.5,39,39v146H0V39C0,17.5,17.5,0,39,0Z" style="fill: %s;"/>
<g style="fill: %s;">
@ -429,7 +429,7 @@ func generateTypeSixSVG(color string, lang string, weekdayType string, dateInfo
}
return fmt.Sprintf(`
<svg id="dynamic_icon_type6" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 504.5">
<svg id="dynamic_icon_type6" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path id="center" d="M512,447.5c0,32-25,57-57,57H57c-32,0-57-25-57-57V120.5c0-31,25-57,57-57h398c32,0,57,26,57,57v327Z" style="fill: #ecf2f7;"/>
<path id="top" d="M39,0h434c21.5,0,39,14,39,31.2v116.8H0V31.2C0,14,17.5,0,39,0Z" style="fill: %s;"/>
<g id="cirle" style="fill: %s;">
@ -506,7 +506,7 @@ func generateTypeSevenSVG(color string, lang string, dateInfo map[string]interfa
}
return fmt.Sprintf(`
<svg id="dynamic_icon_type7" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 504.5">
<svg id="dynamic_icon_type7" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path id="bottom" d="M512,447.5c0,32-25,57-57,57H57c-32,0-57-25-57-57V120.5c0-31,25-57,57-57h398c32,0,57,26,57,57v327Z" style="fill: #ecf2f7;"/>
<path id="top" d="M39,0h434c21.52,0,39,17.48,39,39v146H0V39C0,17.48,17.48,0,39,0Z" style="fill: %s;"/>
<text id="year" transform="translate(46.1 78.92)" style="fill: #fff; font-family: -apple-system, BlinkMacSystemFont, 'Noto Sans', 'Noto Sans CJK SC', 'Microsoft YaHei'; font-size: 60px;">%d</text>
@ -557,7 +557,7 @@ func generateTypeEightSVG(color, content string) string {
}
return fmt.Sprintf(`
<svg id="dynamic_icon_type8" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 511">
<svg id="dynamic_icon_type8" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path d="M39,0h434c20.97,0,38,17.03,38,38v412c0,33.11-26.89,60-60,60H60c-32.56,0-59-26.44-59-59V38C1,17.03,18.03,0,39,0Z" style="fill: %s;"/>
<text x="50%%" y="55%%" dy="%s" style="font-size: %.2fpx; fill: #fff; text-anchor: middle; dominant-baseline:middle;font-family: -apple-system, BlinkMacSystemFont, 'Noto Sans', 'Noto Sans CJK SC', 'Microsoft YaHei'; ">%s</text>
</svg>

View file

@ -165,6 +165,7 @@ func html2BlockDOM(c *gin.Context) {
})
}
parse.TextMarks2Inlines(tree) // 先将 TextMark 转换为 Inlines https://github.com/siyuan-note/siyuan/issues/13056
parse.NestedInlines2FlattedSpansHybrid(tree, false)
renderer := render.NewProtyleRenderer(tree, luteEngine.RenderOptions)

View file

@ -277,7 +277,8 @@ func ServeAPI(ginServer *gin.Engine) {
ginServer.Handle("POST", "/api/asset/fullReindexAssetContent", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, fullReindexAssetContent)
ginServer.Handle("POST", "/api/asset/statAsset", model.CheckAuth, model.CheckAdminRole, statAsset)
ginServer.Handle("POST", "/api/export/batchExportMd", model.CheckAuth, model.CheckAdminRole, batchExportMd)
ginServer.Handle("POST", "/api/export/exportNotebookMd", model.CheckAuth, model.CheckAdminRole, exportNotebookMd)
ginServer.Handle("POST", "/api/export/exportMds", model.CheckAuth, model.CheckAdminRole, exportMds)
ginServer.Handle("POST", "/api/export/exportMd", model.CheckAuth, model.CheckAdminRole, exportMd)
ginServer.Handle("POST", "/api/export/exportSY", model.CheckAuth, model.CheckAdminRole, exportSY)
ginServer.Handle("POST", "/api/export/exportNotebookSY", model.CheckAuth, model.CheckAdminRole, exportNotebookSY)

View file

@ -102,12 +102,13 @@ const (
KeyTypeLineNumber KeyType = "lineNumber"
)
// Key 描述了属性视图属性的基础结构。
// Key 描述了属性视图属性字段的基础结构。
type Key struct {
ID string `json:"id"` // 列 ID
Name string `json:"name"` // 列名
Type KeyType `json:"type"` // 列类型
Icon string `json:"icon"` // 列图标
ID string `json:"id"` // 字段 ID
Name string `json:"name"` // 字段名
Type KeyType `json:"type"` // 字段类型
Icon string `json:"icon"` // 字段图标
Desc string `json:"desc"` // 字段描述
// 以下是某些列类型的特有属性
@ -154,8 +155,8 @@ type Date struct {
}
type Rollup struct {
RelationKeyID string `json:"relationKeyID"` // 关联 ID
KeyID string `json:"keyID"` // 目标 ID
RelationKeyID string `json:"relationKeyID"` // 关联字段 ID
KeyID string `json:"keyID"` // 目标字段 ID
Calc *RollupCalc `json:"calc"` // 计算方式
}
@ -171,8 +172,9 @@ type Relation struct {
}
type SelectOption struct {
Name string `json:"name"`
Color string `json:"color"`
Name string `json:"name"` // 选项名称
Color string `json:"color"` // 选项颜色
Desc string `json:"desc"` // 选项描述
}
// View 描述了视图的结构。
@ -181,6 +183,7 @@ type View struct {
Icon string `json:"icon"` // 视图图标
Name string `json:"name"` // 视图名称
HideAttrViewName bool `json:"hideAttrViewName"` // 是否隐藏属性视图名称
Desc string `json:"desc"` // 视图描述
LayoutType LayoutType `json:"type"` // 当前布局类型
Table *LayoutTable `json:"table,omitempty"` // 表格布局

View file

@ -39,6 +39,7 @@ type ViewTableColumn struct {
Hidden bool `json:"hidden"` // 是否隐藏
Pin bool `json:"pin"` // 是否固定
Width string `json:"width"` // 列宽度
Desc string `json:"desc,omitempty"` // 列描述
Calc *ColumnCalc `json:"calc,omitempty"` // 计算
}
@ -47,6 +48,7 @@ type Table struct {
ID string `json:"id"` // 表格布局 ID
Icon string `json:"icon"` // 表格图标
Name string `json:"name"` // 表格名称
Desc string `json:"desc"` // 表格描述
HideAttrViewName bool `json:"hideAttrViewName"` // 是否隐藏属性视图名称
Filters []*ViewFilter `json:"filters"` // 过滤规则
Sorts []*ViewSort `json:"sorts"` // 排序规则
@ -65,6 +67,7 @@ type TableColumn struct {
Hidden bool `json:"hidden"` // 是否隐藏
Pin bool `json:"pin"` // 是否固定
Width string `json:"width"` // 列宽度
Desc string `json:"desc"` // 列描述
Calc *ColumnCalc `json:"calc"` // 计算
// 以下是某些列类型的特有属性

View file

@ -42,23 +42,47 @@ import (
type DisplayName struct {
Default string `json:"default"`
ZhCN string `json:"zh_CN"`
DeDE string `json:"de_DE"`
EnUS string `json:"en_US"`
EsES string `json:"es_ES"`
FrFR string `json:"fr_FR"`
HeIL string `json:"he_IL"`
ItIT string `json:"it_IT"`
JaJP string `json:"ja_JP"`
PlPL string `json:"pl_PL"`
RuRU string `json:"ru_RU"`
ZhCHT string `json:"zh_CHT"`
ZhCN string `json:"zh_CN"`
}
type Description struct {
Default string `json:"default"`
ZhCN string `json:"zh_CN"`
DeDE string `json:"de_DE"`
EnUS string `json:"en_US"`
EsES string `json:"es_ES"`
FrFR string `json:"fr_FR"`
HeIL string `json:"he_IL"`
ItIT string `json:"it_IT"`
JaJP string `json:"ja_JP"`
PlPL string `json:"pl_PL"`
RuRU string `json:"ru_RU"`
ZhCHT string `json:"zh_CHT"`
ZhCN string `json:"zh_CN"`
}
type Readme struct {
Default string `json:"default"`
ZhCN string `json:"zh_CN"`
DeDE string `json:"de_DE"`
EnUS string `json:"en_US"`
EsES string `json:"es_ES"`
FrFR string `json:"fr_FR"`
HeIL string `json:"he_IL"`
ItIT string `json:"it_IT"`
JaJP string `json:"ja_JP"`
PlPL string `json:"pl_PL"`
RuRU string `json:"ru_RU"`
ZhCHT string `json:"zh_CHT"`
ZhCN string `json:"zh_CN"`
}
type Funding struct {
@ -142,25 +166,58 @@ func getPreferredReadme(readme *Readme) string {
ret := readme.Default
switch util.Lang {
case "zh_CN":
if "" != readme.ZhCN {
ret = readme.ZhCN
}
case "zh_CHT":
if "" != readme.ZhCHT {
ret = readme.ZhCHT
} else if "" != readme.ZhCN {
ret = readme.ZhCN
case "de_DE":
if "" != readme.DeDE {
ret = readme.DeDE
}
case "en_US":
if "" != readme.EnUS {
ret = readme.EnUS
}
case "es_ES":
if "" != readme.EsES {
ret = readme.EsES
}
case "fr_FR":
if "" != readme.FrFR {
ret = readme.FrFR
}
case "he_IL":
if "" != readme.HeIL {
ret = readme.HeIL
}
case "it_IT":
if "" != readme.ItIT {
ret = readme.ItIT
}
case "ja_JP":
if "" != readme.JaJP {
ret = readme.JaJP
}
case "pl_PL":
if "" != readme.PlPL {
ret = readme.PlPL
}
case "ru_RU":
if "" != readme.RuRU {
ret = readme.RuRU
}
case "zh_CHT":
if "" != readme.ZhCHT {
ret = readme.ZhCHT
}
case "zh_CN":
if "" != readme.ZhCN {
ret = readme.ZhCN
}
default:
if "" != readme.EnUS {
ret = readme.EnUS
}
}
if "" == ret {
ret = "README.md"
}
return ret
}
@ -171,25 +228,58 @@ func GetPreferredName(pkg *Package) string {
ret := pkg.DisplayName.Default
switch util.Lang {
case "zh_CN":
if "" != pkg.DisplayName.ZhCN {
ret = pkg.DisplayName.ZhCN
}
case "zh_CHT":
if "" != pkg.DisplayName.ZhCHT {
ret = pkg.DisplayName.ZhCHT
} else if "" != pkg.DisplayName.ZhCN {
ret = pkg.DisplayName.ZhCN
case "de_DE":
if "" != pkg.DisplayName.DeDE {
ret = pkg.DisplayName.DeDE
}
case "en_US":
if "" != pkg.DisplayName.EnUS {
ret = pkg.DisplayName.EnUS
}
case "es_ES":
if "" != pkg.DisplayName.EsES {
ret = pkg.DisplayName.EsES
}
case "fr_FR":
if "" != pkg.DisplayName.FrFR {
ret = pkg.DisplayName.FrFR
}
case "he_IL":
if "" != pkg.DisplayName.HeIL {
ret = pkg.DisplayName.HeIL
}
case "it_IT":
if "" != pkg.DisplayName.ItIT {
ret = pkg.DisplayName.ItIT
}
case "ja_JP":
if "" != pkg.DisplayName.JaJP {
ret = pkg.DisplayName.JaJP
}
case "pl_PL":
if "" != pkg.DisplayName.PlPL {
ret = pkg.DisplayName.PlPL
}
case "ru_RU":
if "" != pkg.DisplayName.RuRU {
ret = pkg.DisplayName.RuRU
}
case "zh_CHT":
if "" != pkg.DisplayName.ZhCHT {
ret = pkg.DisplayName.ZhCHT
}
case "zh_CN":
if "" != pkg.DisplayName.ZhCN {
ret = pkg.DisplayName.ZhCN
}
default:
if "" != pkg.DisplayName.EnUS {
ret = pkg.DisplayName.EnUS
}
}
if "" == ret {
ret = pkg.Name
}
return ret
}
@ -200,25 +290,58 @@ func getPreferredDesc(desc *Description) string {
ret := desc.Default
switch util.Lang {
case "zh_CN":
if "" != desc.ZhCN {
ret = desc.ZhCN
}
case "zh_CHT":
if "" != desc.ZhCHT {
ret = desc.ZhCHT
} else if "" != desc.ZhCN {
ret = desc.ZhCN
case "de_DE":
if "" != desc.DeDE {
ret = desc.DeDE
}
case "en_US":
if "" != desc.EnUS {
ret = desc.EnUS
}
case "es_ES":
if "" != desc.EsES {
ret = desc.EsES
}
case "fr_FR":
if "" != desc.FrFR {
ret = desc.FrFR
}
case "he_IL":
if "" != desc.HeIL {
ret = desc.HeIL
}
case "it_IT":
if "" != desc.ItIT {
ret = desc.ItIT
}
case "ja_JP":
if "" != desc.JaJP {
ret = desc.JaJP
}
case "pl_PL":
if "" != desc.PlPL {
ret = desc.PlPL
}
case "ru_RU":
if "" != desc.RuRU {
ret = desc.RuRU
}
case "zh_CHT":
if "" != desc.ZhCHT {
ret = desc.ZhCHT
}
case "zh_CN":
if "" != desc.ZhCN {
ret = desc.ZhCN
}
default:
if "" != desc.EnUS {
ret = desc.EnUS
}
}
if "" == ret {
ret = desc.EnUS
}
return ret
}

View file

@ -10,7 +10,7 @@ require (
github.com/88250/epub v0.0.0-20230830085737-c19055cd1f48
github.com/88250/go-humanize v0.0.0-20240424102817-4f78fac47ea7
github.com/88250/gulu v1.2.3-0.20240612035750-c9cf5f7a4d02
github.com/88250/lute v1.7.7-0.20241106021724-1c970cf3f601
github.com/88250/lute v1.7.7-0.20241108062550-1a256f09ffc2
github.com/88250/pdfcpu v0.3.14-0.20230401044135-c7369a99720c
github.com/88250/vitess-sqlparser v0.0.0-20210205111146-56a2ded2aba1
github.com/ClarkThan/ahocorasick v0.0.0-20231011042242-30d1ef1347f4

View file

@ -14,8 +14,8 @@ github.com/88250/go-sqlite3 v1.14.13-0.20231214121541-e7f54c482950 h1:Pa5hMiBceT
github.com/88250/go-sqlite3 v1.14.13-0.20231214121541-e7f54c482950/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/88250/gulu v1.2.3-0.20240612035750-c9cf5f7a4d02 h1:3e5+yobj655pTeKOYMbJrnc1mE51ZkbXIxquTYZuYCY=
github.com/88250/gulu v1.2.3-0.20240612035750-c9cf5f7a4d02/go.mod h1:MUfzyfmbPrRDZLqxc7aPrVYveatTHRfoUa5TynPS0i8=
github.com/88250/lute v1.7.7-0.20241106021724-1c970cf3f601 h1:AEt0XZj8XzjWt0hQ4MveQzjTiT5RyL6XPjetEn7VeKU=
github.com/88250/lute v1.7.7-0.20241106021724-1c970cf3f601/go.mod h1:VDAzL8b+oCh+e3NAlmwwLzC53ten0rZlS8NboB7ljtk=
github.com/88250/lute v1.7.7-0.20241108062550-1a256f09ffc2 h1:CCHMX0LRRWcTrFKZP/CKwB0ZN9uFXU99q7hd0T7b5Wk=
github.com/88250/lute v1.7.7-0.20241108062550-1a256f09ffc2/go.mod h1:VDAzL8b+oCh+e3NAlmwwLzC53ten0rZlS8NboB7ljtk=
github.com/88250/pdfcpu v0.3.14-0.20230401044135-c7369a99720c h1:Dl/8S9iLyPMTElnWIBxmjaLiWrkI5P4a21ivwAn5pU0=
github.com/88250/pdfcpu v0.3.14-0.20230401044135-c7369a99720c/go.mod h1:S5YT38L/GCjVjmB4PB84PymA1qfopjEhfhTNQilLpv4=
github.com/88250/vitess-sqlparser v0.0.0-20210205111146-56a2ded2aba1 h1:48T899JQDwyyRu9yXHePYlPdHtpJfrJEUGBMH3SMBWY=

View file

@ -1527,6 +1527,7 @@ func (tx *Transaction) doDuplicateAttrViewView(operation *Operation) (ret *TxErr
Hidden: col.Hidden,
Pin: col.Pin,
Width: col.Width,
Desc: col.Desc,
Calc: col.Calc,
})
}
@ -1658,6 +1659,30 @@ func (tx *Transaction) doSetAttrViewViewIcon(operation *Operation) (ret *TxErr)
return
}
func (tx *Transaction) doSetAttrViewViewDesc(operation *Operation) (ret *TxErr) {
var err error
avID := operation.AvID
attrView, err := av.ParseAttributeView(avID)
if err != nil {
logging.LogErrorf("parse attribute view [%s] failed: %s", avID, err)
return &TxErr{code: TxErrWriteAttributeView, id: avID}
}
viewID := operation.ID
view := attrView.GetView(viewID)
if nil == view {
logging.LogErrorf("get view [%s] failed: %s", viewID, err)
return &TxErr{code: TxErrWriteAttributeView, id: viewID}
}
view.Desc = strings.TrimSpace(operation.Data.(string))
if err = av.SaveAttributeView(attrView); err != nil {
logging.LogErrorf("save attribute view [%s] failed: %s", avID, err)
return &TxErr{code: TxErrWriteAttributeView, msg: err.Error(), id: avID}
}
return
}
func (tx *Transaction) doSetAttrViewName(operation *Operation) (ret *TxErr) {
err := tx.setAttributeViewName(operation)
if err != nil {
@ -2247,6 +2272,7 @@ func duplicateAttributeViewKey(operation *Operation) (err error) {
Hidden: column.Hidden,
Pin: column.Pin,
Width: column.Width,
Desc: column.Desc,
},
}, view.Table.Columns[i+1:]...)...)
break
@ -2416,6 +2442,31 @@ func setAttributeViewColIcon(operation *Operation) (err error) {
return
}
func (tx *Transaction) doSetAttrViewColumnDesc(operation *Operation) (ret *TxErr) {
err := setAttributeViewColDesc(operation)
if err != nil {
return &TxErr{code: TxErrWriteAttributeView, id: operation.AvID, msg: err.Error()}
}
return
}
func setAttributeViewColDesc(operation *Operation) (err error) {
attrView, err := av.ParseAttributeView(operation.AvID)
if err != nil {
return
}
for _, keyValues := range attrView.KeyValues {
if keyValues.Key.ID == operation.ID {
keyValues.Key.Desc = operation.Data.(string)
break
}
}
err = av.SaveAttributeView(attrView)
return
}
func (tx *Transaction) doSortAttrViewRow(operation *Operation) (ret *TxErr) {
err := sortAttributeViewRow(operation)
if err != nil {
@ -3472,6 +3523,40 @@ func updateAttributeViewColumnOption(operation *Operation) (err error) {
return
}
func (tx *Transaction) doSetAttrViewColOptionDesc(operation *Operation) (ret *TxErr) {
err := setAttributeViewColumnOptionDesc(operation)
if err != nil {
return &TxErr{code: TxErrWriteAttributeView, id: operation.AvID, msg: err.Error()}
}
return
}
func setAttributeViewColumnOptionDesc(operation *Operation) (err error) {
attrView, err := av.ParseAttributeView(operation.AvID)
if err != nil {
return
}
key, err := attrView.GetKey(operation.ID)
if err != nil {
return
}
data := operation.Data.(map[string]interface{})
name := data["name"].(string)
desc := data["desc"].(string)
for i, opt := range key.Options {
if name == opt.Name {
key.Options[i].Desc = desc
break
}
}
err = av.SaveAttributeView(attrView)
return
}
func getAttrViewViewByBlockID(attrView *av.AttributeView, blockID string) (ret *av.View, err error) {
node, _, _ := getNodeByBlockID(nil, blockID)
var viewID string

View file

@ -571,7 +571,7 @@ func buildLinkRefs(defRootID string, refs []*sql.Ref, keyword string) (ret []*Bl
if nil != refBlock && p.FContent == refBlock.Content { // 使用内容判断是否是列表项下第一个子块
// 如果是列表项下第一个子块,则后续会通过列表项传递或关联处理,所以这里就不处理这个段落了
processedParagraphs.Add(p.ID)
if !strings.Contains(p.Content, keyword) {
if !strings.Contains(p.Content, keyword) && !strings.Contains(path.Base(p.HPath), keyword) {
refsCount--
continue
}
@ -587,7 +587,7 @@ func buildLinkRefs(defRootID string, refs []*sql.Ref, keyword string) (ret []*Bl
}
}
if !strings.Contains(ref.Content, keyword) {
if !strings.Contains(ref.Content, keyword) && !strings.Contains(path.Base(ref.HPath), keyword) {
refsCount--
continue
}

View file

@ -1382,6 +1382,29 @@ func ExportStdMarkdown(id string) string {
Conf.Export.AddTitle, nil)
}
func BatchExportPandocConvertZip(ids []string, pandocTo, ext string) (name, zipPath string) {
block := treenode.GetBlockTree(ids[0])
box := Conf.Box(block.BoxID)
baseFolderName := path.Base(block.HPath)
if "." == baseFolderName {
baseFolderName = path.Base(block.Path)
}
var docPaths []string
bts := treenode.GetBlockTrees(ids)
for _, bt := range bts {
docFiles := box.ListFiles(strings.TrimSuffix(bt.Path, ".sy"))
for _, docFile := range docFiles {
docPaths = append(docPaths, docFile.path)
}
}
docPaths = util.FilterSelfChildDocs(docPaths)
zipPath = exportPandocConvertZip(false, box.ID, baseFolderName, docPaths, "gfm+footnotes+hard_line_breaks", pandocTo, ext)
name = strings.TrimSuffix(filepath.Base(block.Path), ".sy")
return
}
func ExportPandocConvertZip(id, pandocTo, ext string) (name, zipPath string) {
block := treenode.GetBlockTree(id)
if nil == block {
@ -1406,7 +1429,7 @@ func ExportPandocConvertZip(id, pandocTo, ext string) (name, zipPath string) {
return
}
func BatchExportMarkdown(boxID, folderPath string) (zipPath string) {
func ExportNotebookMarkdown(boxID, folderPath string) (zipPath string) {
box := Conf.Box(boxID)
var baseFolderName string

View file

@ -1020,6 +1020,7 @@ func parseStdMd(markdown []byte) (ret *parse.Tree, yfmRootID, yfmTitle, yfmUpdat
}
yfmRootID, yfmTitle, yfmUpdated = normalizeTree(ret)
imgHtmlBlock2InlineImg(ret)
parse.TextMarks2Inlines(ret) // 先将 TextMark 转换为 Inlines https://github.com/siyuan-note/siyuan/issues/13056
parse.NestedInlines2FlattedSpansHybrid(ret, false)
return
}
@ -1102,7 +1103,7 @@ func imgHtmlBlock2InlineImg(tree *parse.Tree) {
return ast.WalkContinue
}
if ast.NodeHTMLBlock == n.Type {
if ast.NodeHTMLBlock == n.Type || (ast.NodeText == n.Type && bytes.HasPrefix(bytes.ToLower(n.Tokens), []byte("<img "))) {
tokens := bytes.TrimSpace(n.Tokens)
if bytes.HasPrefix(tokens, []byte("<div>")) {
tokens = bytes.TrimPrefix(tokens, []byte("<div>"))
@ -1151,7 +1152,12 @@ func imgHtmlBlock2InlineImg(tree *parse.Tree) {
}
img.AppendChild(&ast.Node{Type: ast.NodeCloseParen})
n.InsertBefore(p)
if nil != n.Parent && ast.NodeText == n.Type {
// 行级 HTML 会被解析为文本,所以这里要在父级段落前面插入,避免形成段落嵌套 https://github.com/siyuan-note/siyuan/issues/13080
n.Parent.InsertBefore(p)
} else {
n.InsertBefore(p)
}
n.Unlink()
}
return

View file

@ -151,8 +151,7 @@ func OpenRepoSnapshotDoc(fileID string) (title, content string, displayInText bo
}
} else {
displayInText = true
title = path.Base(file.Path)
title = file.Path
if mimeType := mime.TypeByExtension(filepath.Ext(file.Path)); strings.HasPrefix(mimeType, "text/") || strings.Contains(mimeType, "json") {
// 如果是文本文件,直接返回文本内容
// All plain text formats are supported when comparing data snapshots https://github.com/siyuan-note/siyuan/issues/12975
@ -646,6 +645,7 @@ func checkoutRepo(id string) {
// 回滚快照时默认为当前数据创建一个快照
// When rolling back a snapshot, a snapshot is created for the current data by default https://github.com/siyuan-note/siyuan/issues/12470
FlushTxQueue()
_, err = repo.Index("Backup before checkout", map[string]interface{}{eventbus.CtxPushMsg: eventbus.CtxPushMsgToStatusBarAndProgress})
if err != nil {
logging.LogErrorf("index repository failed: %s", err)
@ -1628,7 +1628,9 @@ var promotedPurgeDataRepo bool
func indexRepoBeforeCloudSync(repo *dejavu.Repo) (beforeIndex, afterIndex *entity.Index, err error) {
start := time.Now()
beforeIndex, _ = repo.Latest()
FlushTxQueue()
afterIndex, err = repo.Index("[Sync] Cloud sync", map[string]interface{}{
eventbus.CtxPushMsg: eventbus.CtxPushMsgToStatusBar,
})

View file

@ -216,6 +216,8 @@ func performTx(tx *Transaction) (ret *TxErr) {
ret = tx.doSetAttrViewColumnPin(op)
case "setAttrViewColIcon":
ret = tx.doSetAttrViewColumnIcon(op)
case "setAttrViewColDesc":
ret = tx.doSetAttrViewColumnDesc(op)
case "insertAttrViewBlock":
ret = tx.doInsertAttrViewBlock(op)
case "removeAttrViewBlock":
@ -240,6 +242,8 @@ func performTx(tx *Transaction) (ret *TxErr) {
ret = tx.doRemoveAttrViewColOption(op)
case "updateAttrViewColOption":
ret = tx.doUpdateAttrViewColOption(op)
case "setAttrViewColOptionDesc":
ret = tx.doSetAttrViewColOptionDesc(op)
case "setAttrViewColCalc":
ret = tx.doSetAttrViewColCalc(op)
case "updateAttrViewColNumberFormat":
@ -256,6 +260,8 @@ func performTx(tx *Transaction) (ret *TxErr) {
ret = tx.doSetAttrViewViewName(op)
case "setAttrViewViewIcon":
ret = tx.doSetAttrViewViewIcon(op)
case "setAttrViewViewDesc":
ret = tx.doSetAttrViewViewDesc(op)
case "duplicateAttrViewView":
ret = tx.doDuplicateAttrViewView(op)
case "sortAttrViewView":

View file

@ -36,6 +36,7 @@ func RenderAttributeViewTable(attrView *av.AttributeView, view *av.View, query s
ID: view.ID,
Icon: view.Icon,
Name: view.Name,
Desc: view.Desc,
HideAttrViewName: view.HideAttrViewName,
Columns: []*av.TableColumn{},
Rows: []*av.TableRow{},
@ -78,6 +79,7 @@ func RenderAttributeViewTable(attrView *av.AttributeView, view *av.View, query s
Wrap: col.Wrap,
Hidden: col.Hidden,
Width: col.Width,
Desc: col.Desc,
Pin: col.Pin,
Calc: col.Calc,
})

View file

@ -433,6 +433,9 @@ func initMime() {
// 文档数据文件
mime.AddExtensionType(".sy", "application/json")
mime.AddExtensionType(".md", "text/markdown")
mime.AddExtensionType(".markdown", "text/markdown")
}
func GetDataAssetsAbsPath() (ret string) {