🎨 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:
Daniel 2025-12-03 22:03:13 +08:00
parent 9e075581ff
commit b5c84f2354
No known key found for this signature in database
GPG key ID: 86211BA83DF03017
21 changed files with 114 additions and 41 deletions

View file

@ -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)

View file

@ -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
}

View file

@ -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 {

View file

@ -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

View file

@ -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 {

View file

@ -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)

View file

@ -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 {

View file

@ -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
}