Browse Source

:art: Improve parsing of YAML Front Matter when importing Markdown https://github.com/siyuan-note/siyuan/issues/12962

Daniel 8 tháng trước cách đây
mục cha
commit
da3a6fee16
2 tập tin đã thay đổi với 88 bổ sung43 xóa
  1. 53 12
      kernel/model/box.go
  2. 35 31
      kernel/model/import.go

+ 53 - 12
kernel/model/box.go

@@ -34,6 +34,7 @@ import (
 	"github.com/88250/lute/html"
 	"github.com/88250/lute/lex"
 	"github.com/88250/lute/parse"
+	"github.com/araddon/dateparse"
 	"github.com/siyuan-note/filelock"
 	"github.com/siyuan-note/logging"
 	"github.com/siyuan-note/siyuan/kernel/cache"
@@ -566,22 +567,62 @@ func normalizeTree(tree *parse.Tree) {
 			parseErr := yaml.Unmarshal(n.Tokens, &attrs)
 			if parseErr != nil {
 				logging.LogWarnf("parse YAML front matter [%s] failed: %s", n.Tokens, parseErr)
-			} else {
-				for attrK, attrV := range attrs {
-					validKeyName := true
-					for i := 0; i < len(attrK); i++ {
-						if !lex.IsASCIILetterNumHyphen(attrK[i]) {
-							validKeyName = false
-							break
-						}
+				return ast.WalkContinue
+			}
+
+			for attrK, attrV := range attrs {
+				// Improve parsing of YAML Front Matter when importing Markdown https://github.com/siyuan-note/siyuan/issues/12962
+				if "title" == attrK {
+					tree.Root.SetIALAttr("title", fmt.Sprint(attrV))
+					continue
+				}
+				if "date" == attrK {
+					created, parseTimeErr := dateparse.ParseIn(fmt.Sprint(attrV), time.Local)
+					if nil == parseTimeErr {
+						docID := created.Format("20060102150405") + "-" + gulu.Rand.String(7)
+						tree.Root.ID = docID
+						tree.Root.SetIALAttr("id", docID)
 					}
-					if !validKeyName {
-						logging.LogWarnf("invalid YAML key [%s] in [%s]", attrK, n.ID)
-						continue
+					continue
+				}
+				if "lastmod" == attrK {
+					updated, parseTimeErr := dateparse.ParseIn(fmt.Sprint(attrV), time.Local)
+					if nil == parseTimeErr {
+						tree.Root.SetIALAttr("updated", updated.Format("20060102150405"))
 					}
+					continue
+				}
+				if "tags" == attrK {
+					var tags string
+					for i, tag := range attrV.([]any) {
+						tagStr := strings.TrimSpace(tag.(string))
+						if "" == tag {
+							continue
+						}
+						tagStr = strings.TrimLeft(tagStr, "#,'\"")
+						tagStr = strings.TrimRight(tagStr, "#,'\"")
+						tags += tagStr
+						if i < len(attrV.([]any))-1 {
+							tags += ","
+						}
+					}
+					tree.Root.SetIALAttr("tags", tags)
+					continue
+				}
 
-					tree.Root.SetIALAttr("custom-"+attrK, fmt.Sprint(attrV))
+				validKeyName := true
+				for i := 0; i < len(attrK); i++ {
+					if !lex.IsASCIILetterNumHyphen(attrK[i]) {
+						validKeyName = false
+						break
+					}
+				}
+				if !validKeyName {
+					logging.LogWarnf("invalid YAML key [%s] in [%s]", attrK, n.ID)
+					continue
 				}
+
+				tree.Root.SetIALAttr("custom-"+attrK, fmt.Sprint(attrV))
 			}
 		}
 

+ 35 - 31
kernel/model/import.go

@@ -22,24 +22,21 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
-	"github.com/88250/lute"
 	"image"
 	"image/jpeg"
 	"image/png"
 	"io"
 	"io/fs"
-	"math/rand"
 	"os"
 	"path"
 	"path/filepath"
 	"regexp"
 	"runtime/debug"
 	"sort"
-	"strconv"
 	"strings"
-	"time"
 
 	"github.com/88250/gulu"
+	"github.com/88250/lute"
 	"github.com/88250/lute/ast"
 	"github.com/88250/lute/html"
 	"github.com/88250/lute/html/atom"
@@ -765,6 +762,17 @@ func ImportFromLocalPath(boxID, localPath string, toPath string) (err error) {
 				return nil
 			}
 
+			if "" != tree.Root.ID {
+				id = tree.Root.ID
+			}
+			if "" != tree.Root.IALAttr("title") {
+				title = tree.Root.IALAttr("title")
+			}
+			updated := tree.Root.IALAttr("updated")
+			fname := path.Base(targetPath)
+			targetPath = strings.ReplaceAll(targetPath, fname, id+".sy")
+			targetPaths[curRelPath] = targetPath
+
 			tree.ID = id
 			tree.Root.ID = id
 			tree.Root.SetIALAttr("id", tree.Root.ID)
@@ -841,7 +849,7 @@ func ImportFromLocalPath(boxID, localPath string, toPath string) (err error) {
 				return ast.WalkContinue
 			})
 
-			reassignIDUpdated(tree)
+			reassignIDUpdated(tree, id, updated)
 			importTrees = append(importTrees, tree)
 
 			hPathsIDs[tree.HPath] = tree.ID
@@ -871,6 +879,16 @@ func ImportFromLocalPath(boxID, localPath string, toPath string) (err error) {
 			return errors.New(msg)
 		}
 
+		if "" != tree.Root.ID {
+			id = tree.Root.ID
+		}
+		if "" != tree.Root.IALAttr("title") {
+			title = tree.Root.IALAttr("title")
+		}
+		updated := tree.Root.IALAttr("updated")
+		fname := path.Base(targetPath)
+		targetPath = strings.ReplaceAll(targetPath, fname, id+".sy")
+
 		tree.ID = id
 		tree.Root.ID = id
 		tree.Root.SetIALAttr("id", tree.Root.ID)
@@ -937,7 +955,7 @@ func ImportFromLocalPath(boxID, localPath string, toPath string) (err error) {
 			return ast.WalkContinue
 		})
 
-		reassignIDUpdated(tree)
+		reassignIDUpdated(tree, id, updated)
 		importTrees = append(importTrees, tree)
 	}
 
@@ -1120,7 +1138,7 @@ func imgHtmlBlock2InlineImg(tree *parse.Tree) {
 	return
 }
 
-func reassignIDUpdated(tree *parse.Tree) {
+func reassignIDUpdated(tree *parse.Tree, rootID, updated string) {
 	var blockCount int
 	ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
 		if !entering || "" == n.ID {
@@ -1131,23 +1149,22 @@ func reassignIDUpdated(tree *parse.Tree) {
 		return ast.WalkContinue
 	})
 
-	ids := make([]string, blockCount)
-	min, _ := strconv.ParseInt(time.Now().Add(-1*time.Duration(blockCount)*time.Second).Format("20060102150405"), 10, 64)
-	for i := 0; i < blockCount; i++ {
-		ids[i] = newID(fmt.Sprintf("%d", min))
-		min++
-	}
-
-	var i int
 	ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
 		if !entering || "" == n.ID {
 			return ast.WalkContinue
 		}
 
-		n.ID = ids[i]
+		n.ID = ast.NewNodeID()
+		if ast.NodeDocument == n.Type && "" != rootID {
+			n.ID = rootID
+		}
+
 		n.SetIALAttr("id", n.ID)
-		n.SetIALAttr("updated", util.TimeFromID(n.ID))
-		i++
+		if "" != updated {
+			n.SetIALAttr("updated", updated)
+		} else {
+			n.SetIALAttr("updated", util.TimeFromID(n.ID))
+		}
 		return ast.WalkContinue
 	})
 	tree.ID = tree.Root.ID
@@ -1155,19 +1172,6 @@ func reassignIDUpdated(tree *parse.Tree) {
 	tree.Root.SetIALAttr("id", tree.Root.ID)
 }
 
-func newID(t string) string {
-	return t + "-" + randStr(7)
-}
-
-func randStr(length int) string {
-	letter := []rune("abcdefghijklmnopqrstuvwxyz0123456789")
-	b := make([]rune, length)
-	for i := range b {
-		b[i] = letter[rand.Intn(len(letter))]
-	}
-	return string(b)
-}
-
 func domAttrValue(n *html.Node, attrName string) string {
 	if nil == n {
 		return ""