From 09c2a03cefa687832257d3b816da50db3cfcc0f2 Mon Sep 17 00:00:00 2001
From: ai_xiaopei <xiaopei@aisim.cn>
Date: Sat, 25 Jul 2026 23:48:11 +0800
Subject: [PATCH] feat: 实现输出格式化
---
internal/vault/parser.go | 96 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 96 insertions(+), 0 deletions(-)
diff --git a/internal/vault/parser.go b/internal/vault/parser.go
new file mode 100644
index 0000000..6764af4
--- /dev/null
+++ b/internal/vault/parser.go
@@ -0,0 +1,96 @@
+package vault
+
+import (
+ "bufio"
+ "os"
+ "regexp"
+ "strings"
+
+ "gopkg.in/yaml.v3"
+)
+
+// FileMeta 文件元数据
+type FileMeta struct {
+ Path string // 相对路径
+ Title string // frontmatter title
+ Section string // 所属板块
+ Tags []string // frontmatter tags
+ Entities []string // frontmatter entities
+ Wikilinks []string // 正文中的 [[xxx]] 链接
+ Content string // 纯文本内容(去 frontmatter)
+}
+
+// Frontmatter YAML 结构
+type Frontmatter struct {
+ Title string `yaml:"title"`
+ Tags []string `yaml:"tags"`
+ Entities []string `yaml:"entities"`
+ Aliases []string `yaml:"aliases"`
+}
+
+var wikilinkRe = regexp.MustCompile(`\[\[([^\]]+)\]\]`)
+
+// ParseFile 解析单个 markdown 文件
+func ParseFile(absPath, relPath string) (*FileMeta, error) {
+ f, err := os.Open(absPath)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+
+ meta := &FileMeta{
+ Path: relPath,
+ Section: GetSection(relPath),
+ }
+
+ scanner := bufio.NewScanner(f)
+ inFrontmatter := false
+ fmLines := []string{}
+ contentLines := []string{}
+ lineNum := 0
+
+ for scanner.Scan() {
+ line := scanner.Text()
+ lineNum++
+
+ if lineNum == 1 && line == "---" {
+ inFrontmatter = true
+ continue
+ }
+ if inFrontmatter && line == "---" {
+ inFrontmatter = false
+ continue
+ }
+ if inFrontmatter {
+ fmLines = append(fmLines, line)
+ } else {
+ contentLines = append(contentLines, line)
+ }
+ }
+
+ // 解析 frontmatter
+ if len(fmLines) > 0 {
+ var fm Frontmatter
+ if err := yaml.Unmarshal([]byte(strings.Join(fmLines, "\n")), &fm); err == nil {
+ meta.Title = fm.Title
+ meta.Tags = fm.Tags
+ meta.Entities = fm.Entities
+ }
+ }
+
+ // 提取 wikilinks 和内容
+ content := strings.Join(contentLines, "\n")
+ meta.Content = content
+
+ matches := wikilinkRe.FindAllStringSubmatch(content, -1)
+ seen := make(map[string]bool)
+ for _, m := range matches {
+ link := m[1]
+ if !seen[link] {
+ meta.Wikilinks = append(meta.Wikilinks, link)
+ seen[link] = true
+ }
+ }
+
+ return meta, nil
+}
--
Gitblit v1.9.1