diff --git a/kernel/model/import.go b/kernel/model/import.go index b5b670705..aae23bd31 100644 --- a/kernel/model/import.go +++ b/kernel/model/import.go @@ -976,6 +976,14 @@ func ImportFromLocalPath(boxID, localPath string, toPath string) (err error) { return ast.WalkContinue } + if strings.HasSuffix(absolutePath, ".md") || strings.HasSuffix(absolutePath, ".markdown") { + if !strings.Contains(absolutePath, "assets") { + // 链接 .md 文件的情况下只有路径中包含 assets 才算作资源文件,其他情况算作文档链接,后续在 convertMdHyperlinks2WikiLinks 中处理 + // Supports converting relative path hyperlinks into document block references after importing Markdown https://github.com/siyuan-note/siyuan/issues/13817 + return ast.WalkContinue + } + } + existName := assetsDone[absolutePath] var name string if "" == existName { @@ -1135,8 +1143,9 @@ func ImportFromLocalPath(boxID, localPath string, toPath string) (err error) { } initSearchLinks() + convertMdHyperlinks2WikiLinks() convertWikiLinksAndTags() - buildBlockRefInText() + mergeTextAndHandlerNestedInlines() box := Conf.Box(boxID) for i, tree := range importTrees { @@ -1503,6 +1512,56 @@ func initSearchLinks() { } } +func convertMdHyperlinks2WikiLinks() { + // Supports converting relative path hyperlinks into document block references after importing Markdown https://github.com/siyuan-note/siyuan/issues/13817 + + var unlinks []*ast.Node + for _, tree := range importTrees { + ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus { + if !entering || ast.NodeTextMark != n.Type { + return ast.WalkContinue + } + + if "a" != n.TextMarkType { + return ast.WalkContinue + } + + linkText := n.TextMarkTextContent + if "" == linkText { + return ast.WalkContinue + } + linkDest := n.TextMarkAHref + if "" == linkDest { + return ast.WalkContinue + } + if strings.HasPrefix(linkDest, "assets/") { + return ast.WalkContinue + } + if !strings.HasSuffix(linkDest, ".md") && !strings.HasSuffix(linkDest, ".markdown") { + return ast.WalkContinue + } + linkDest = strings.TrimSuffix(linkDest, ".md") + linkDest = strings.TrimSuffix(linkDest, ".markdown") + + buf := bytes.Buffer{} + buf.WriteString("[[") + buf.WriteString(linkDest) + buf.WriteString("|") + buf.WriteString(linkText) + buf.WriteString("]]") + + wikilinkNode := &ast.Node{Type: ast.NodeText, Tokens: buf.Bytes()} + n.InsertBefore(wikilinkNode) + unlinks = append(unlinks, n) + return ast.WalkContinue + }) + } + + for _, n := range unlinks { + n.Unlink() + } +} + func convertWikiLinksAndTags() { for _, tree := range importTrees { convertWikiLinksAndTags0(tree) @@ -1601,8 +1660,22 @@ func convertTags(text string) (ret string) { return string(tokens) } -// buildBlockRefInText 将文本节点进行结构化处理。 -func buildBlockRefInText() { +func searchLinkID(link string) (id string) { + id = searchLinks[link] + if "" != id { + return + } + + baseName := path.Base(link) + for searchLink, searchID := range searchLinks { + if path.Base(searchLink) == baseName { + return searchID + } + } + return +} + +func mergeTextAndHandlerNestedInlines() { luteEngine := NewLute() luteEngine.SetHTMLTag2TextMark(true) for _, tree := range importTrees { @@ -1636,18 +1709,3 @@ func buildBlockRefInText() { } } } - -func searchLinkID(link string) (id string) { - id = searchLinks[link] - if "" != id { - return - } - - baseName := path.Base(link) - for searchLink, searchID := range searchLinks { - if path.Base(searchLink) == baseName { - return searchID - } - } - return -}