Support for saving .sy files in the single-line format https://github.com/siyuan-note/siyuan/issues/8712

This commit is contained in:
Daniel 2023-07-09 22:24:32 +08:00
parent eb65bb4ec0
commit 9eeee3965a
No known key found for this signature in database
GPG key ID: 86211BA83DF03017
13 changed files with 55 additions and 22 deletions

View file

@ -785,6 +785,8 @@
"fileTree17": "If there are too many sub-documents, this restriction can be used to improve performance",
"fileTree18": "Allows creation of sub-documents deeper than 7 levels",
"fileTree19": "Some operating systems have technical limitations that may prevent manual copying of workspace data after creating sub-documents greater than 7 levels",
"fileTree20": "Save with a single line",
"fileTree21": "After enabling, the single-line JSON format will be used when saving .sy files, which can reduce the file size by about 30% and improve read and write efficiency by 50%",
"export11": "Content handling method of content ref block when exporting",
"export12": "Content handling method of content embed block when exporting",
"export13": "Anchor text wrapping symbol",

View file

@ -231,9 +231,9 @@
"appearanceMode": "Modo de apariencia",
"editMode": "Modo de edición",
"editReadonly": "Modo de solo lectura",
"editReadonlyTip": "Cuando está habilitado, el editor cargará el documento en modo de solo lectura. Cuando necesite editar, puede hacer clic en el botón editar en la barra superior para cambiar al modo de edición",
"editReadonlyTip": "Después de habilitarlo, el editor cargará el documento en modo de solo lectura. Cuando necesite editar, puede hacer clic en el botón editar en la barra superior para cambiar al modo de edición",
"generateConflictDoc": "Generar documentación de conflicto al sincronizar conflictos",
"generateConflictDocTip": "Cuando está habilitado, se generará un documento de conflicto cuando ocurra un conflicto de sincronización, para que pueda abrirse y verse directamente. Ya sea que esté habilitado o no, el historial de datos registrará el documento de conflicto",
"generateConflictDocTip": "Después de habilitarlo, se generará un documento de conflicto cuando ocurra un conflicto de sincronización, para que pueda abrirse y verse directamente. Ya sea que esté habilitado o no, el historial de datos registrará el documento de conflicto",
"deleteOpConfirm": "⚠️ Confirmación de operación de eliminación",
"filterKeywordEnter": "Filtrado de palabras clave Entrar",
"defBlock": "Definir bloque",
@ -279,7 +279,7 @@
"newDocBelow": "Crear documento a continuación",
"newDocAbove": "Crear documento arriba",
"fullWidth": "Ancho adaptable",
"fullWidthTip": "Cuando está habilitado, el área de edición se mostrará lo más amplia posible",
"fullWidthTip": "Después de habilitarlo, el área de edición se mostrará lo más amplia posible",
"tabLimit": "Límite de la pestaña",
"tabLimit1": "Ordenar por hora de apertura, cerrar la primera pestaña abierta",
"pasteEscaped": "Pegar texto escapado",
@ -775,7 +775,7 @@
"fileTree7": "Abrir en la pestaña actual",
"fileTree8": "La pestaña del documento recién abierto sustituirá a la pestaña no modificada",
"fileTree9": "Cerrar todas las pestañas al inicio",
"fileTree10": "Cuando está habilitado, las pestañas no fijadas que se abrieron la última vez se cerrarán automáticamente cada vez que se inicie la interfaz",
"fileTree10": "Después de habilitarlo, las pestañas no fijadas que se abrieron la última vez se cerrarán automáticamente cada vez que se inicie la interfaz",
"fileTree11": "Nueva nota diaria",
"fileTree12": "Nueva ubicación para guardar el documento",
"fileTree13": "Al usar <code class='fn__code'>Ctrl+N</code>, la ruta de guardado del nuevo documento (por ejemplo, <code class='fn__code'>/folder1/{{now | date \"20060102150405\"}}</code>, se utiliza la ruta relativa del documento actual si no empieza por <code class='fn__code'>/</code>)",
@ -785,6 +785,8 @@
"fileTree17": "Si hay demasiados subdocumentos, se puede utilizar esta restricción para mejorar el rendimiento",
"fileTree18": "Permite la creación de subdocumentos de más de 7 niveles",
"fileTree19": "Algunos sistemas operativos tienen limitaciones técnicas que pueden impedir la copia manual de los datos del espacio de trabajo después de crear subdocumentos de más de 7 niveles",
"fileTree20": "Guardar con una sola línea",
"fileTree21": "Después de habilitarlo, se usará un formato JSON de una sola línea al guardar archivos .sy, lo que puede reducir el tamaño del archivo en aproximadamente un 30 % y mejorar la eficiencia de lectura y escritura en un 50 %",
"export11": "Método de manejo de contenido del bloque de referencia de contenido al exportar",
"export12": "Método de manejo de contenido del bloque de incrustación de contenido al exportar",
"export13": "Símbolo de envoltura de texto ancla",

View file

@ -785,6 +785,8 @@
"fileTree17": "S'il y a trop de sous-documents, cette restriction peut être utilisée pour améliorer les performances.",
"fileTree18": "Permet la création de sous-documents de plus de 7 niveaux",
"fileTree19": "Certains systèmes d'exploitation ont des limitations techniques qui peuvent empêcher la copie manuelle des données de l'espace de travail après la création de sous-documents supérieurs à 7 niveaux",
"fileTree20": "Enregistrer avec une seule ligne",
"fileTree21": "Après l'activation, un format JSON à une seule ligne sera utilisé lors de l'enregistrement des fichiers .sy, ce qui peut réduire la taille du fichier d'environ 30 % et améliorer l'efficacité de lecture et d'écriture de 50 %",
"export11": "Traitement du contenu des blocs de référence lors de l'exportation",
"export12": "Gestion du contenu des blocs intégrés lors de l'exportation",
"export13": "Symbole d'enveloppement du texte d'ancrage",

View file

@ -785,6 +785,8 @@
"fileTree17": "如果子文檔非常多,可通過該項限制以提升性能",
"fileTree18": "允許建立深度大於 7 層的子文檔",
"fileTree19": "一些操作系統存在技術限制導致建立大於 7 層的子文檔後可能無法正常手動複製工作空間資料",
"fileTree20": "使用單行保存",
"fileTree21": "啟用後保存 .sy 文件時將使用單行 JSON 格式,大約能減少 30% 文件大小並提升 50% 讀寫效率",
"export11": "匯出時關於引用塊內容的處理方式",
"export12": "匯出時關於嵌入塊內容的處理方式",
"export13": "錨文字包裹符號",

View file

@ -785,6 +785,8 @@
"fileTree17": "如果子文档非常多,可通过该项限制以提升性能",
"fileTree18": "允许创建深度大于 7 层的子文档",
"fileTree19": "一些操作系统存在技术限制导致创建大于 7 层的子文档后可能无法正常手动复制工作空间数据",
"fileTree20": "使用单行保存",
"fileTree21": "启用后保存 .sy 文件时将使用单行 JSON 格式,大约能减少 30% 文件大小并提升 50% 读写效率",
"export11": "导出时关于引用块内容的处理方式",
"export12": "导出时关于嵌入块内容的处理方式",
"export13": "锚文本包裹符号",

View file

@ -43,6 +43,14 @@ export const fileTree = {
<span class="fn__space"></span>
<input class="b3-switch fn__flex-center" id="removeDocWithoutConfirm" type="checkbox"${window.siyuan.config.fileTree.removeDocWithoutConfirm ? " checked" : ""}/>
</label>
<label class="fn__flex b3-label">
<div class="fn__flex-1">
${window.siyuan.languages.fileTree20}
<div class="b3-label__text">${window.siyuan.languages.fileTree21}</div>
</div>
<span class="fn__space"></span>
<input class="b3-switch fn__flex-center" id="useSingleLineSave" type="checkbox"${window.siyuan.config.fileTree.useSingleLineSave ? " checked" : ""}/>
</label>
<label class="fn__flex b3-label config__item">
<div class="fn__flex-1">
${window.siyuan.languages.fileTree12}
@ -97,6 +105,7 @@ export const fileTree = {
closeTabsOnStart: (fileTree.element.querySelector("#closeTabsOnStart") as HTMLInputElement).checked,
allowCreateDeeper: (fileTree.element.querySelector("#allowCreateDeeper") as HTMLInputElement).checked,
removeDocWithoutConfirm: (fileTree.element.querySelector("#removeDocWithoutConfirm") as HTMLInputElement).checked,
useSingleLineSave: (fileTree.element.querySelector("#useSingleLineSave") as HTMLInputElement).checked,
maxListCount: parseInt((fileTree.element.querySelector("#maxListCount") as HTMLInputElement).value),
maxOpenTabCount: inputMaxOpenTabCount,
}, response => {

View file

@ -506,6 +506,7 @@ interface IFileTree {
alwaysSelectOpenedFile: boolean
openFilesUseCurrentTab: boolean
removeDocWithoutConfirm: boolean
useSingleLineSave: boolean
allowCreateDeeper: boolean
refCreateSavePath: string
docCreateSavePath: string

View file

@ -313,6 +313,8 @@ func setFiletree(c *gin.Context) {
model.Conf.FileTree = fileTree
model.Conf.Save()
util.UseSingleLineSave = model.Conf.FileTree.UseSingleLineSave
ret.Data = model.Conf.FileTree
}

View file

@ -30,6 +30,7 @@ type FileTree struct {
AllowCreateDeeper bool `json:"allowCreateDeeper"` // 允许创建超过 7 层深度的子文档
RemoveDocWithoutConfirm bool `json:"removeDocWithoutConfirm"` // 删除文档时是否不需要确认
CloseTabsOnStart bool `json:"closeTabsOnStart"` // 启动时关闭所有页签
UseSingleLineSave bool `json:"useSingleLineSave"` // 使用单行保存 .sy 文件
Sort int `json:"sort"` // 排序方式
}
@ -43,5 +44,6 @@ func NewFileTree() *FileTree {
MaxOpenTabCount: 8,
AllowCreateDeeper: false,
CloseTabsOnStart: false,
UseSingleLineSave: util.UseSingleLineSave,
}
}

View file

@ -165,13 +165,14 @@ func prepareWriteTree(tree *parse.Tree) (data []byte, filePath string, err error
renderer := render.NewJSONRenderer(tree, luteEngine.RenderOptions)
data = renderer.Render()
// .sy 文档数据使用格式化好的 JSON 而非单行 JSON
buf := bytes.Buffer{}
buf.Grow(4096)
if err = json.Indent(&buf, data, "", "\t"); nil != err {
return
if !util.UseSingleLineSave {
buf := bytes.Buffer{}
buf.Grow(1024 * 1024 * 2)
if err = json.Indent(&buf, data, "", "\t"); nil != err {
return
}
data = buf.Bytes()
}
data = buf.Bytes()
if err = os.MkdirAll(filepath.Dir(filePath), 0755); nil != err {
return
@ -205,19 +206,21 @@ func parseJSON2Tree(boxID, p string, jsonData []byte, luteEngine *lute.Lute) (re
}
if needFix {
renderer := render.NewJSONRenderer(ret, luteEngine.RenderOptions)
output := renderer.Render()
data := renderer.Render()
buf := bytes.Buffer{}
buf.Grow(4096)
if err = json.Indent(&buf, output, "", "\t"); nil != err {
return
if !util.UseSingleLineSave {
buf := bytes.Buffer{}
buf.Grow(1024 * 1024 * 2)
if err = json.Indent(&buf, data, "", "\t"); nil != err {
return
}
data = buf.Bytes()
}
output = buf.Bytes()
if err = os.MkdirAll(filepath.Dir(filePath), 0755); nil != err {
return
}
if err = filelock.WriteFile(filePath, output); nil != err {
if err = filelock.WriteFile(filePath, data); nil != err {
msg := fmt.Sprintf("write data [%s] failed: %s", filePath, err)
logging.LogErrorf(msg)
}

View file

@ -185,6 +185,7 @@ func InitConf() {
Conf.FileTree.DocCreateSavePath = strings.TrimSuffix(Conf.FileTree.DocCreateSavePath, "/")
Conf.FileTree.DocCreateSavePath = strings.TrimSpace(Conf.FileTree.DocCreateSavePath)
}
util.UseSingleLineSave = Conf.FileTree.UseSingleLineSave
util.CurrentCloudRegion = Conf.CloudRegion

View file

@ -190,12 +190,14 @@ func ImportSY(zipPath, boxID, toPath string) (err error) {
renderer := render.NewJSONRenderer(tree, luteEngine.RenderOptions)
data := renderer.Render()
buf := bytes.Buffer{}
buf.Grow(4096)
if err = json.Indent(&buf, data, "", "\t"); nil != err {
return
if !util.UseSingleLineSave {
buf := bytes.Buffer{}
buf.Grow(1024 * 1024 * 2)
if err = json.Indent(&buf, data, "", "\t"); nil != err {
return
}
data = buf.Bytes()
}
data = buf.Bytes()
if err = os.WriteFile(syPath, data, 0644); nil != err {
logging.LogErrorf("write .sy [%s] failed: %s", syPath, err)

View file

@ -38,6 +38,9 @@ import (
"github.com/siyuan-note/logging"
)
// UseSingleLineSave 是否使用单行保存 .sy 文件。
var UseSingleLineSave = true
// IsUILoaded 是否已经加载了 UI。
var IsUILoaded = false