mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-16 14:40:12 +01:00
🎨 The old version of the application no longer supports opening the new version of the document https://github.com/siyuan-note/siyuan/issues/16505
Signed-off-by: Daniel <845765@qq.com>
This commit is contained in:
parent
9e075581ff
commit
b5c84f2354
21 changed files with 114 additions and 41 deletions
|
|
@ -1704,6 +1704,7 @@
|
|||
"271": "اكتملت عملية تحسين فهرس البيانات، تم تحرير [%s] من مساحة القرص",
|
||||
"272": "حقل غير مسمى",
|
||||
"273": "لا تقم بإنشاء مساحة العمل في مسار جذر القسم، يرجى إنشاء مجلد جديد كمساحة عمل",
|
||||
"274": "يحتوي هذا المجلد على ملفات أخرى، يرجى إنشاء مجلد جديد كمساحة عمل"
|
||||
"274": "يحتوي هذا المجلد على ملفات أخرى، يرجى إنشاء مجلد جديد كمساحة عمل",
|
||||
"275": "يتعذر فتح المستند الذي تم إنشاؤه بواسطة إصدار أحدث. يرجى الترقية إلى أحدث إصدار ثم المحاولة مرة أخرى"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1704,6 +1704,7 @@
|
|||
"271": "Datenindex-Optimierung abgeschlossen, [%s] Speicherplatz freigegeben",
|
||||
"272": "Unbenanntes Feld",
|
||||
"273": "Erstellen Sie den Arbeitsbereich nicht im Stammverzeichnis der Partition, erstellen Sie bitte einen neuen Ordner als Arbeitsbereich",
|
||||
"274": "Dieser Ordner enthält andere Dateien, erstellen Sie bitte einen neuen Ordner als Arbeitsbereich"
|
||||
"274": "Dieser Ordner enthält andere Dateien, erstellen Sie bitte einen neuen Ordner als Arbeitsbereich",
|
||||
"275": "Dokumente, die mit einer neueren Version erstellt wurden, können nicht geöffnet werden. Bitte aktualisieren Sie auf die neueste Version und versuchen Sie es erneut"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1704,6 +1704,7 @@
|
|||
"271": "Data index optimization completed, [%s] disk space freed",
|
||||
"272": "Unnamed field",
|
||||
"273": "Do not create the workspace in the partition root path, please create a new folder as the workspace",
|
||||
"274": "This folder contains other files, please create a new folder as the workspace"
|
||||
"274": "This folder contains other files, please create a new folder as the workspace",
|
||||
"275": "Cannot open documents created by a newer version. Please upgrade to the latest version and try again"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1704,6 +1704,7 @@
|
|||
"271": "Optimización del índice de datos completada, se liberaron [%s] de espacio en disco",
|
||||
"272": "Campo sin nombre",
|
||||
"273": "No cree el espacio de trabajo en la ruta raíz de la partición, cree una nueva carpeta como espacio de trabajo",
|
||||
"274": "Esta carpeta contiene otros archivos, cree una nueva carpeta como espacio de trabajo"
|
||||
"274": "Esta carpeta contiene otros archivos, cree una nueva carpeta como espacio de trabajo",
|
||||
"275": "No se puede abrir el documento creado con una versión más reciente. Actualiza a la última versión e inténtalo de nuevo"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1704,6 +1704,7 @@
|
|||
"271": "Optimisation de l'index des données terminée, [%s] d'espace disque libéré",
|
||||
"272": "Champ sans nom",
|
||||
"273": "Ne créez pas l’espace de travail à la racine de la partition, créez un nouveau dossier comme espace de travail",
|
||||
"274": "Ce dossier contient d’autres fichiers, créez un nouveau dossier comme espace de travail"
|
||||
"274": "Ce dossier contient d’autres fichiers, créez un nouveau dossier comme espace de travail",
|
||||
"275": "Impossible d'ouvrir le document créé par une version plus récente. Veuillez mettre à jour vers la dernière version et réessayer"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1704,6 +1704,7 @@
|
|||
"271": "אופטימיזציית אינדקס הנתונים הושלמה, שוחררו [%s] שטח דיסק",
|
||||
"272": "שדה ללא שם",
|
||||
"273": "אל תיצור סביבת עבודה בנתיב השורש של המחיצה, צור תיקיה חדשה כסביבת עבודה",
|
||||
"274": "התיקיה הזו מכילה קבצים נוספים, צור תיקיה חדשה כסביבת עבודה"
|
||||
"274": "התיקיה הזו מכילה קבצים נוספים, צור תיקיה חדשה כסביבת עבודה",
|
||||
"275": "לא ניתן לפתוח את המסמך שנוצר בגרסה חדשה יותר. יש לעדכן לגרסה העדכנית ביותר ולנסות שוב"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1704,6 +1704,7 @@
|
|||
"271": "Ottimizzazione dell'indice dei dati completata, liberati [%s] di spazio su disco",
|
||||
"272": "Campo senza nome",
|
||||
"273": "Non creare lo spazio di lavoro nella directory radice della partizione, crea una nuova cartella come spazio di lavoro",
|
||||
"274": "Questa cartella contiene altri file, crea una nuova cartella come spazio di lavoro"
|
||||
"274": "Questa cartella contiene altri file, crea una nuova cartella come spazio di lavoro",
|
||||
"275": "Impossibile aprire il documento creato con una versione più recente. Aggiorna all'ultima versione e riprova"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1704,6 +1704,7 @@
|
|||
"271": "データインデックスの最適化が完了しました。合計 [%s] のディスク容量が解放されました",
|
||||
"272": "未命名フィールド",
|
||||
"273": "パーティションのルートパスにワークスペースを作成しないでください。新しいフォルダーをワークスペースとして作成してください",
|
||||
"274": "このフォルダーには他のファイルが含まれています。新しいフォルダーをワークスペースとして作成してください"
|
||||
"274": "このフォルダーには他のファイルが含まれています。新しいフォルダーをワークスペースとして作成してください",
|
||||
"275": "新しいバージョンで作成された文書を開くことができません。最新バージョンにアップデートしてから再試行してください"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1704,6 +1704,7 @@
|
|||
"271": "Optymalizacja indeksu danych zakończona, zwolniono [%s] miejsca na dysku",
|
||||
"272": "Nienazwane pole",
|
||||
"273": "Nie twórz przestrzeni roboczej w katalogu głównym partycji, utwórz nowy folder jako przestrzeń roboczą",
|
||||
"274": "Ten folder zawiera inne pliki, utwórz nowy folder jako przestrzeń roboczą"
|
||||
"274": "Ten folder zawiera inne pliki, utwórz nowy folder jako przestrzeń roboczą",
|
||||
"275": "Nie można otworzyć dokumentu utworzonego w nowszej wersji. Zaktualizuj program do najnowszej wersji i spróbuj ponownie"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1704,6 +1704,7 @@
|
|||
"271": "Otimização do índice de dados concluída, [%s] de espaço liberado",
|
||||
"272": "Campo sem nome",
|
||||
"273": "Não crie o espaço de trabalho na raiz da partição, crie uma nova pasta para o espaço de trabalho",
|
||||
"274": "Esta pasta contém outros arquivos, crie uma nova pasta para o espaço de trabalho"
|
||||
"274": "Esta pasta contém outros arquivos, crie uma nova pasta para o espaço de trabalho",
|
||||
"275": "Não é possível abrir o documento criado por uma versão mais recente. Atualize para a versão mais recente e tente novamente"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1704,6 +1704,7 @@
|
|||
"271": "Оптимизация индекса данных завершена, освобождено [%s] дискового пространства",
|
||||
"272": "Неименованное поле",
|
||||
"273": "Не создавайте рабочее пространство в корневом каталоге раздела, создайте отдельную папку для рабочего пространства",
|
||||
"274": "Эта папка содержит другие файлы, создайте отдельную папку для рабочего пространства"
|
||||
"274": "Эта папка содержит другие файлы, создайте отдельную папку для рабочего пространства",
|
||||
"275": "Невозможно открыть документ, созданный в более новой версии. Пожалуйста, обновите приложение до последней версии и попробуйте снова"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1704,6 +1704,7 @@
|
|||
"271": "資料索引優化完畢,共釋放 [%s] 磁碟空間",
|
||||
"272": "未命名欄位",
|
||||
"273": "請勿在分區根路徑上建立工作空間,請新建一個資料夾作為工作空間",
|
||||
"274": "該資料夾包含其他檔案,請新建一個資料夾作為工作空間"
|
||||
"274": "該資料夾包含其他檔案,請新建一個資料夾作為工作空間",
|
||||
"275": "無法打開由新版本建立的檔案,請升級到最新版本後再試"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1704,6 +1704,7 @@
|
|||
"271": "数据索引优化完毕,共释放 [%s] 磁盘空间",
|
||||
"272": "未命名字段",
|
||||
"273": "请勿在分区根路径上创建工作空间,请新建一个文件夹作为工作空间",
|
||||
"274": "该文件夹包含了其他文件,请新建一个文件夹作为工作空间"
|
||||
"274": "该文件夹包含了其他文件,请新建一个文件夹作为工作空间",
|
||||
"275": "无法打开新版本创建的文档,请升级到最新版本后再试"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import (
|
|||
"github.com/siyuan-note/logging"
|
||||
"github.com/siyuan-note/siyuan/kernel/filesys"
|
||||
"github.com/siyuan-note/siyuan/kernel/model"
|
||||
"github.com/siyuan-note/siyuan/kernel/treenode"
|
||||
"github.com/siyuan-note/siyuan/kernel/util"
|
||||
)
|
||||
|
||||
|
|
@ -660,6 +661,10 @@ func getBlockInfo(c *gin.Context) {
|
|||
ret.Code = 3
|
||||
ret.Msg = model.Conf.Language(56)
|
||||
return
|
||||
} else if errors.Is(err, treenode.ErrSpecTooNew) {
|
||||
ret.Code = -1
|
||||
ret.Msg = model.Conf.Language(275)
|
||||
return
|
||||
}
|
||||
|
||||
block, _ := model.GetBlock(id, tree)
|
||||
|
|
|
|||
|
|
@ -125,10 +125,9 @@ func LoadTree(boxID, p string, luteEngine *lute.Lute) (ret *parse.Tree, err erro
|
|||
}
|
||||
|
||||
func LoadTreeByData(data []byte, boxID, p string, luteEngine *lute.Lute) (ret *parse.Tree, err error) {
|
||||
ret = parseJSON2Tree(boxID, p, data, luteEngine)
|
||||
if nil == ret {
|
||||
logging.LogErrorf("parse tree [%s] failed", p)
|
||||
err = errors.New("parse tree failed")
|
||||
ret, err = parseJSON2Tree(boxID, p, data, luteEngine)
|
||||
if nil != err {
|
||||
logging.LogErrorf("parse tree [%s] failed: %s", p, err)
|
||||
return
|
||||
}
|
||||
ret.Path = p
|
||||
|
|
@ -245,12 +244,9 @@ func prepareWriteTree(tree *parse.Tree) (data []byte, filePath string, err error
|
|||
treenode.UpsertBlockTree(tree)
|
||||
}
|
||||
|
||||
treenode.UpgradeSpec(tree)
|
||||
|
||||
filePath = filepath.Join(util.DataDir, tree.Box, tree.Path)
|
||||
if oldSpec := tree.Root.Spec; "" == oldSpec {
|
||||
parse.NestedInlines2FlattedSpans(tree, false)
|
||||
tree.Root.Spec = "1"
|
||||
logging.LogInfof("migrated tree [%s] from spec [%s] to [%s]", filePath, oldSpec, tree.Root.Spec)
|
||||
}
|
||||
tree.Root.SetIALAttr("type", "doc")
|
||||
renderer := render.NewJSONRenderer(tree, luteEngine.RenderOptions)
|
||||
data = renderer.Render()
|
||||
|
|
@ -277,8 +273,7 @@ func afterWriteTree(tree *parse.Tree) {
|
|||
cache.PutDocIAL(tree.Path, docIAL)
|
||||
}
|
||||
|
||||
func parseJSON2Tree(boxID, p string, jsonData []byte, luteEngine *lute.Lute) (ret *parse.Tree) {
|
||||
var err error
|
||||
func parseJSON2Tree(boxID, p string, jsonData []byte, luteEngine *lute.Lute) (ret *parse.Tree, err error) {
|
||||
var needFix bool
|
||||
ret, needFix, err = dataparser.ParseJSON(jsonData, luteEngine.ParseOptions)
|
||||
if err != nil {
|
||||
|
|
@ -289,12 +284,12 @@ func parseJSON2Tree(boxID, p string, jsonData []byte, luteEngine *lute.Lute) (re
|
|||
ret.Box = boxID
|
||||
ret.Path = p
|
||||
|
||||
filePath := filepath.Join(util.DataDir, ret.Box, ret.Path)
|
||||
if oldSpec := ret.Root.Spec; "" == oldSpec {
|
||||
parse.NestedInlines2FlattedSpans(ret, false)
|
||||
ret.Root.Spec = "1"
|
||||
if err = treenode.CheckSpec(ret); errors.Is(err, treenode.ErrSpecTooNew) {
|
||||
return
|
||||
}
|
||||
|
||||
if treenode.UpgradeSpec(ret) {
|
||||
needFix = true
|
||||
logging.LogInfof("migrated tree [%s] from spec [%s] to [%s]", filePath, oldSpec, ret.Root.Spec)
|
||||
}
|
||||
|
||||
if pathID := util.GetTreeID(p); pathID != ret.Root.ID {
|
||||
|
|
@ -318,6 +313,7 @@ func parseJSON2Tree(boxID, p string, jsonData []byte, luteEngine *lute.Lute) (re
|
|||
data = buf.Bytes()
|
||||
}
|
||||
|
||||
filePath := filepath.Join(util.DataDir, ret.Box, ret.Path)
|
||||
if err = os.MkdirAll(filepath.Dir(filePath), 0755); err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1748,7 +1748,7 @@ func createDoc(boxID, p, title, dom string) (tree *parse.Tree, err error) {
|
|||
tree.HPath = hPath
|
||||
tree.ID = id
|
||||
tree.Root.ID = id
|
||||
tree.Root.Spec = "1"
|
||||
tree.Root.Spec = treenode.CurrentSpec
|
||||
updated := util.TimeFromID(id)
|
||||
tree.Root.KramdownIAL = [][]string{{"id", id}, {"title", html.EscapeAttrVal(title)}, {"updated", updated}}
|
||||
if nil == tree.Root.FirstChild {
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import (
|
|||
"github.com/88250/lute/editor"
|
||||
"github.com/88250/lute/render"
|
||||
"github.com/siyuan-note/logging"
|
||||
"github.com/siyuan-note/siyuan/kernel/treenode"
|
||||
"github.com/siyuan-note/siyuan/kernel/util"
|
||||
)
|
||||
|
||||
|
|
@ -63,13 +64,13 @@ func AutoSpace(rootID string) (err error) {
|
|||
formatRenderer := render.NewFormatRenderer(tree, luteEngine.RenderOptions)
|
||||
md := formatRenderer.Render()
|
||||
newTree := parseKTree(md)
|
||||
newTree.Root.Spec = "1"
|
||||
newTree.Root.Spec = treenode.CurrentSpec
|
||||
// 第二次格式化启用自动空格
|
||||
luteEngine.SetAutoSpace(true)
|
||||
formatRenderer = render.NewFormatRenderer(newTree, luteEngine.RenderOptions)
|
||||
md = formatRenderer.Render()
|
||||
newTree = parseKTree(md)
|
||||
newTree.Root.Spec = "1"
|
||||
newTree.Root.Spec = treenode.CurrentSpec
|
||||
newTree.Root.ID = tree.ID
|
||||
newTree.Root.KramdownIAL = rootIAL
|
||||
newTree.ID = tree.ID
|
||||
|
|
|
|||
|
|
@ -427,7 +427,7 @@ func Heading2Doc(srcHeadingID, targetBoxID, targetPath, previousPath string) (sr
|
|||
|
||||
newTree.Box, newTree.Path = targetBoxID, newTargetPath
|
||||
newTree.Root.SetIALAttr("updated", util.CurrentTimeSecondsStr())
|
||||
newTree.Root.Spec = "1"
|
||||
newTree.Root.Spec = treenode.CurrentSpec
|
||||
if "" != previousPath {
|
||||
box.addSort(previousPath, newTree.ID)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -418,10 +418,7 @@ func ImportSY(zipPath, boxID, toPath string) (err error) {
|
|||
for _, tree := range trees {
|
||||
util.PushEndlessProgress(Conf.language(73) + " " + fmt.Sprintf(Conf.language(70), tree.Root.IALAttr("title")))
|
||||
syPath := filepath.Join(unzipRootPath, tree.Path)
|
||||
if "" == tree.Root.Spec {
|
||||
parse.NestedInlines2FlattedSpans(tree, false)
|
||||
tree.Root.Spec = "1"
|
||||
}
|
||||
treenode.UpgradeSpec(tree)
|
||||
renderer := render.NewJSONRenderer(tree, luteEngine.RenderOptions)
|
||||
data := renderer.Render()
|
||||
|
||||
|
|
@ -943,7 +940,7 @@ func ImportFromLocalPath(boxID, localPath string, toPath string) (err error) {
|
|||
tree.Path = targetPath
|
||||
targetPaths[curRelPath] = targetPath
|
||||
tree.HPath = hPath
|
||||
tree.Root.Spec = "1"
|
||||
tree.Root.Spec = treenode.CurrentSpec
|
||||
|
||||
docDirLocalPath := filepath.Dir(filepath.Join(boxLocalPath, targetPath))
|
||||
assetDirPath := getAssetsDir(boxLocalPath, docDirLocalPath)
|
||||
|
|
@ -1075,7 +1072,7 @@ func ImportFromLocalPath(boxID, localPath string, toPath string) (err error) {
|
|||
tree.Box = boxID
|
||||
tree.Path = targetPath
|
||||
tree.HPath = path.Join(baseHPath, title)
|
||||
tree.Root.Spec = "1"
|
||||
tree.Root.Spec = treenode.CurrentSpec
|
||||
|
||||
docDirLocalPath := filepath.Dir(filepath.Join(boxLocalPath, targetPath))
|
||||
assetDirPath := getAssetsDir(boxLocalPath, docDirLocalPath)
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ func ListItem2Doc(srcListItemID, targetBoxID, targetPath, previousPath string) (
|
|||
|
||||
newTree.Box, newTree.Path = targetBoxID, newTargetPath
|
||||
newTree.Root.SetIALAttr("updated", util.CurrentTimeSecondsStr())
|
||||
newTree.Root.Spec = "1"
|
||||
newTree.Root.Spec = treenode.CurrentSpec
|
||||
if "" != previousPath {
|
||||
box.addSort(previousPath, newTree.ID)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import (
|
|||
"io/fs"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/88250/gulu"
|
||||
|
|
@ -29,6 +30,7 @@ import (
|
|||
"github.com/88250/lute/ast"
|
||||
"github.com/88250/lute/parse"
|
||||
"github.com/siyuan-note/filelock"
|
||||
"github.com/siyuan-note/logging"
|
||||
"github.com/siyuan-note/siyuan/kernel/util"
|
||||
)
|
||||
|
||||
|
|
@ -71,7 +73,7 @@ func NewTree(boxID, p, hp, title string) *parse.Tree {
|
|||
root.SetIALAttr("id", id)
|
||||
root.SetIALAttr("updated", util.TimeFromID(id))
|
||||
ret := &parse.Tree{Root: root, ID: id, Box: boxID, Path: p, HPath: hp}
|
||||
ret.Root.Spec = "1"
|
||||
ret.Root.Spec = CurrentSpec
|
||||
newPara := &ast.Node{Type: ast.NodeParagraph, ID: ast.NewNodeID(), Box: boxID, Path: p}
|
||||
newPara.SetIALAttr("id", newPara.ID)
|
||||
newPara.SetIALAttr("updated", util.TimeFromID(newPara.ID))
|
||||
|
|
@ -129,3 +131,62 @@ func NewSpanAnchor(id string) (ret *ast.Node) {
|
|||
func ContainOnlyDefaultIAL(tree *parse.Tree) bool {
|
||||
return 5 > len(tree.Root.KramdownIAL)
|
||||
}
|
||||
|
||||
var CurrentSpec = "2"
|
||||
|
||||
var ErrSpecTooNew = fmt.Errorf("the document spec is too new")
|
||||
|
||||
func CheckSpec(tree *parse.Tree) (err error) {
|
||||
if CurrentSpec == tree.Root.Spec || "" == tree.Root.Spec {
|
||||
return
|
||||
}
|
||||
|
||||
spec, err := strconv.Atoi(tree.Root.Spec)
|
||||
if nil != err {
|
||||
logging.LogErrorf("parse spec [%s] failed: %s", tree.Root.Spec, err)
|
||||
return
|
||||
}
|
||||
|
||||
currentSpec, _ := strconv.Atoi(CurrentSpec)
|
||||
if spec > currentSpec {
|
||||
logging.LogErrorf("tree spec [%s] is newer than current spec [%s]", tree.Root.Spec, CurrentSpec)
|
||||
return ErrSpecTooNew
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func UpgradeSpec(tree *parse.Tree) (upgraded bool) {
|
||||
if CurrentSpec == tree.Root.Spec {
|
||||
return
|
||||
}
|
||||
|
||||
upgradeSpec1(tree)
|
||||
upgradeSpec2(tree)
|
||||
return true
|
||||
}
|
||||
|
||||
func upgradeSpec2(tree *parse.Tree) {
|
||||
oldSpec, err := strconv.Atoi(tree.Root.Spec)
|
||||
if nil != err {
|
||||
logging.LogErrorf("parse spec [%s] failed: %s", tree.Root.Spec, err)
|
||||
return
|
||||
}
|
||||
|
||||
if 2 <= oldSpec {
|
||||
return
|
||||
}
|
||||
|
||||
// 增加了 Callout
|
||||
|
||||
tree.Root.Spec = "2"
|
||||
}
|
||||
|
||||
func upgradeSpec1(tree *parse.Tree) {
|
||||
if "" != tree.Root.Spec {
|
||||
return
|
||||
}
|
||||
|
||||
parse.NestedInlines2FlattedSpans(tree, false)
|
||||
tree.Root.Spec = "1"
|
||||
return
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue