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