-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclaudeparser.go
115 lines (99 loc) · 2.64 KB
/
claudeparser.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package main
import (
"bufio"
"io"
"strings"
)
type Parser struct {
currentStsh *stsh
currentSolution *solution
currentFeature *feature
currentCommand *command
inCodeBlock bool
}
func (p *Parser) ClaudeParse(r io.Reader) (*stsh, error) {
scanner := bufio.NewScanner(r)
p.currentStsh = &stsh{}
for scanner.Scan() {
line := scanner.Text()
// Skip empty lines
if strings.TrimSpace(line) == "" {
continue
}
// Handle top level description
if strings.HasPrefix(line, ">") {
l := strings.TrimPrefix(line, ">")
p.currentStsh.comment = l
}
// Handle code blocks
if strings.HasPrefix(line, "```") {
p.inCodeBlock = !p.inCodeBlock
continue
}
// Handle command content when inside code block
if p.inCodeBlock && p.currentCommand != nil {
p.currentCommand.cmd = line
continue
}
// Determine the heading level and content
if strings.HasPrefix(line, "#") {
level := 0
for i := 0; i < len(line) && line[i] == '#'; i++ {
level++
}
content := strings.TrimSpace(line[level:])
switch level {
case 1: // Top level - stsh header
p.currentStsh.header = content
case 2: // Solution level
p.handleSolution(content)
case 3: // Feature level
p.handleFeature(content)
case 4: // Command level
p.handleCommand(content)
}
continue
}
// Handle tags
if strings.HasPrefix(line, "Tags: ") {
if p.currentCommand != nil {
tags := strings.TrimPrefix(line, "Tags: ")
p.currentCommand.tags = strings.Split(tags, ", ")
}
continue
}
// Any other text is considered description for the current command
if p.currentCommand != nil && !p.inCodeBlock {
if p.currentCommand.desc == "" {
p.currentCommand.desc = line
} else {
p.currentCommand.desc += "\n" + line
}
}
}
return p.currentStsh, scanner.Err()
}
func (p *Parser) handleSolution(header string) {
newSolution := &solution{header: header}
p.currentStsh.sols = append(p.currentStsh.sols, *newSolution)
p.currentSolution = &p.currentStsh.sols[len(p.currentStsh.sols)-1]
p.currentFeature = nil
p.currentCommand = nil
}
func (p *Parser) handleFeature(header string) {
if p.currentSolution == nil {
return
}
newFeature := &feature{header: header}
p.currentSolution.feats = append(p.currentSolution.feats, *newFeature)
p.currentFeature = &p.currentSolution.feats[len(p.currentSolution.feats)-1]
p.currentCommand = nil
}
func (p *Parser) handleCommand(header string) {
if p.currentFeature == nil {
return
}
newCommand := &command{header: header}
p.currentFeature.cmds = append(p.currentFeature.cmds, *newCommand)
p.currentCommand = &p.currentFeature.cmds[len(p.currentFeature.cmds)-1]
}