mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-17 23:20:13 +01:00
🎨 Improve parsing of YAML Front Matter when importing Markdown https://github.com/siyuan-note/siyuan/issues/12962
This commit is contained in:
parent
3560fed496
commit
da3a6fee16
2 changed files with 89 additions and 44 deletions
|
|
@ -34,6 +34,7 @@ import (
|
||||||
"github.com/88250/lute/html"
|
"github.com/88250/lute/html"
|
||||||
"github.com/88250/lute/lex"
|
"github.com/88250/lute/lex"
|
||||||
"github.com/88250/lute/parse"
|
"github.com/88250/lute/parse"
|
||||||
|
"github.com/araddon/dateparse"
|
||||||
"github.com/siyuan-note/filelock"
|
"github.com/siyuan-note/filelock"
|
||||||
"github.com/siyuan-note/logging"
|
"github.com/siyuan-note/logging"
|
||||||
"github.com/siyuan-note/siyuan/kernel/cache"
|
"github.com/siyuan-note/siyuan/kernel/cache"
|
||||||
|
|
@ -566,22 +567,62 @@ func normalizeTree(tree *parse.Tree) {
|
||||||
parseErr := yaml.Unmarshal(n.Tokens, &attrs)
|
parseErr := yaml.Unmarshal(n.Tokens, &attrs)
|
||||||
if parseErr != nil {
|
if parseErr != nil {
|
||||||
logging.LogWarnf("parse YAML front matter [%s] failed: %s", n.Tokens, parseErr)
|
logging.LogWarnf("parse YAML front matter [%s] failed: %s", n.Tokens, parseErr)
|
||||||
} else {
|
return ast.WalkContinue
|
||||||
for attrK, attrV := range attrs {
|
}
|
||||||
validKeyName := true
|
|
||||||
for i := 0; i < len(attrK); i++ {
|
for attrK, attrV := range attrs {
|
||||||
if !lex.IsASCIILetterNumHyphen(attrK[i]) {
|
// Improve parsing of YAML Front Matter when importing Markdown https://github.com/siyuan-note/siyuan/issues/12962
|
||||||
validKeyName = false
|
if "title" == attrK {
|
||||||
break
|
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)
|
||||||
|
}
|
||||||
|
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 += ","
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !validKeyName {
|
tree.Root.SetIALAttr("tags", tags)
|
||||||
logging.LogWarnf("invalid YAML key [%s] in [%s]", attrK, n.ID)
|
continue
|
||||||
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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,24 +22,21 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/88250/lute"
|
|
||||||
"image"
|
"image"
|
||||||
"image/jpeg"
|
"image/jpeg"
|
||||||
"image/png"
|
"image/png"
|
||||||
"io"
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"math/rand"
|
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/88250/gulu"
|
"github.com/88250/gulu"
|
||||||
|
"github.com/88250/lute"
|
||||||
"github.com/88250/lute/ast"
|
"github.com/88250/lute/ast"
|
||||||
"github.com/88250/lute/html"
|
"github.com/88250/lute/html"
|
||||||
"github.com/88250/lute/html/atom"
|
"github.com/88250/lute/html/atom"
|
||||||
|
|
@ -765,6 +762,17 @@ func ImportFromLocalPath(boxID, localPath string, toPath string) (err error) {
|
||||||
return nil
|
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.ID = id
|
||||||
tree.Root.ID = id
|
tree.Root.ID = id
|
||||||
tree.Root.SetIALAttr("id", tree.Root.ID)
|
tree.Root.SetIALAttr("id", tree.Root.ID)
|
||||||
|
|
@ -841,7 +849,7 @@ func ImportFromLocalPath(boxID, localPath string, toPath string) (err error) {
|
||||||
return ast.WalkContinue
|
return ast.WalkContinue
|
||||||
})
|
})
|
||||||
|
|
||||||
reassignIDUpdated(tree)
|
reassignIDUpdated(tree, id, updated)
|
||||||
importTrees = append(importTrees, tree)
|
importTrees = append(importTrees, tree)
|
||||||
|
|
||||||
hPathsIDs[tree.HPath] = tree.ID
|
hPathsIDs[tree.HPath] = tree.ID
|
||||||
|
|
@ -871,6 +879,16 @@ func ImportFromLocalPath(boxID, localPath string, toPath string) (err error) {
|
||||||
return errors.New(msg)
|
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.ID = id
|
||||||
tree.Root.ID = id
|
tree.Root.ID = id
|
||||||
tree.Root.SetIALAttr("id", tree.Root.ID)
|
tree.Root.SetIALAttr("id", tree.Root.ID)
|
||||||
|
|
@ -937,7 +955,7 @@ func ImportFromLocalPath(boxID, localPath string, toPath string) (err error) {
|
||||||
return ast.WalkContinue
|
return ast.WalkContinue
|
||||||
})
|
})
|
||||||
|
|
||||||
reassignIDUpdated(tree)
|
reassignIDUpdated(tree, id, updated)
|
||||||
importTrees = append(importTrees, tree)
|
importTrees = append(importTrees, tree)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1120,7 +1138,7 @@ func imgHtmlBlock2InlineImg(tree *parse.Tree) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func reassignIDUpdated(tree *parse.Tree) {
|
func reassignIDUpdated(tree *parse.Tree, rootID, updated string) {
|
||||||
var blockCount int
|
var blockCount int
|
||||||
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
|
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
|
||||||
if !entering || "" == n.ID {
|
if !entering || "" == n.ID {
|
||||||
|
|
@ -1131,23 +1149,22 @@ func reassignIDUpdated(tree *parse.Tree) {
|
||||||
return ast.WalkContinue
|
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 {
|
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
|
||||||
if !entering || "" == n.ID {
|
if !entering || "" == n.ID {
|
||||||
return ast.WalkContinue
|
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("id", n.ID)
|
||||||
n.SetIALAttr("updated", util.TimeFromID(n.ID))
|
if "" != updated {
|
||||||
i++
|
n.SetIALAttr("updated", updated)
|
||||||
|
} else {
|
||||||
|
n.SetIALAttr("updated", util.TimeFromID(n.ID))
|
||||||
|
}
|
||||||
return ast.WalkContinue
|
return ast.WalkContinue
|
||||||
})
|
})
|
||||||
tree.ID = tree.Root.ID
|
tree.ID = tree.Root.ID
|
||||||
|
|
@ -1155,19 +1172,6 @@ func reassignIDUpdated(tree *parse.Tree) {
|
||||||
tree.Root.SetIALAttr("id", tree.Root.ID)
|
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 {
|
func domAttrValue(n *html.Node, attrName string) string {
|
||||||
if nil == n {
|
if nil == n {
|
||||||
return ""
|
return ""
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue