refactor(recipe): enhance parsing for multi-line step content
Replace regex-based sub-section extraction with label-indexed parsing to handle multi-line content, blank lines, and ensure reliability without duplicates. Add clarifying comments for templates and summary extraction.
This commit is contained in:
parent
824bbcb85f
commit
852142730a
@ -12,8 +12,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// stepRe still finds the headings (this one is solid)
|
||||||
stepRe = regexp.MustCompile(`(?m)^### Step (\d+): (.+)$`)
|
stepRe = regexp.MustCompile(`(?m)^### Step (\d+): (.+)$`)
|
||||||
subRe = regexp.MustCompile(`(?m)^(\*\*(?:Objective|Instructions|Expected output):\*\*)\s*(.+?)(?:\n\n|\n###|\z)`)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Load(path string, userParams map[string]any) (*Recipe, error) {
|
func Load(path string, userParams map[string]any) (*Recipe, error) {
|
||||||
@ -45,7 +45,7 @@ func Load(path string, userParams map[string]any) (*Recipe, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render templates
|
// Render templates (so {{.package_path}} becomes "internal")
|
||||||
tpl, err := template.New("recipe").Parse(string(parts[2]))
|
tpl, err := template.New("recipe").Parse(string(parts[2]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -61,7 +61,7 @@ func Load(path string, userParams map[string]any) (*Recipe, error) {
|
|||||||
r.Overview = strings.TrimSpace(body[:idx])
|
r.Overview = strings.TrimSpace(body[:idx])
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract steps — split-based to guarantee no duplicates
|
// Extract steps with robust multi-line parsing
|
||||||
matches := stepRe.FindAllStringSubmatch(body, -1)
|
matches := stepRe.FindAllStringSubmatch(body, -1)
|
||||||
for i, m := range matches {
|
for i, m := range matches {
|
||||||
stepNum := i + 1
|
stepNum := i + 1
|
||||||
@ -77,20 +77,42 @@ func Load(path string, userParams map[string]any) (*Recipe, error) {
|
|||||||
section := body[start:end]
|
section := body[start:end]
|
||||||
|
|
||||||
step := Step{Number: stepNum, Title: title}
|
step := Step{Number: stepNum, Title: title}
|
||||||
for _, sub := range subRe.FindAllStringSubmatch(section, -1) {
|
|
||||||
switch sub[1] {
|
// Simple, reliable label-based parsing (handles multi-line + blank lines)
|
||||||
|
labels := []string{"**Objective:**", "**Instructions:**", "**Expected output:**"}
|
||||||
|
for _, label := range labels {
|
||||||
|
labelStart := strings.Index(section, label)
|
||||||
|
if labelStart == -1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
contentStart := labelStart + len(label)
|
||||||
|
contentEnd := len(section)
|
||||||
|
|
||||||
|
// Find next label or end of section
|
||||||
|
for _, nextLabel := range labels {
|
||||||
|
next := strings.Index(section[contentStart:], nextLabel)
|
||||||
|
if next != -1 {
|
||||||
|
contentEnd = contentStart + next
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
content := strings.TrimSpace(section[contentStart:contentEnd])
|
||||||
|
|
||||||
|
switch label {
|
||||||
case "**Objective:**":
|
case "**Objective:**":
|
||||||
step.Objective = strings.TrimSpace(sub[2])
|
step.Objective = content
|
||||||
case "**Instructions:**":
|
case "**Instructions:**":
|
||||||
step.Instructions = strings.TrimSpace(sub[2])
|
step.Instructions = content
|
||||||
case "**Expected output:**":
|
case "**Expected output:**":
|
||||||
step.Expected = strings.TrimSpace(sub[2])
|
step.Expected = content
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r.Steps = append(r.Steps, step)
|
r.Steps = append(r.Steps, step)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Final summary = everything after the last step
|
// Final summary (everything after last step)
|
||||||
if len(matches) > 0 {
|
if len(matches) > 0 {
|
||||||
lastMatch := matches[len(matches)-1][0]
|
lastMatch := matches[len(matches)-1][0]
|
||||||
lastIdx := strings.LastIndex(body, lastMatch)
|
lastIdx := strings.LastIndex(body, lastMatch)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user