fix: most of the template blocks

This commit is contained in:
Max Richter
2025-09-30 19:28:56 +02:00
parent d35f3e5e2e
commit 2a1572f99d
20 changed files with 210 additions and 187 deletions

View File

@@ -20,21 +20,27 @@ func ParseBlock(input string, block template.Block) (any, error) {
case template.CodecHashtags:
return Keywords(input, block)
}
return nil, fmt.Errorf("unknown codec: %s", block.Codec)
fmt.Printf("%#v\n", block)
return nil, fmt.Errorf("unknown codec '%s'", block.Codec)
}
func Parse(matches []matcher.Block) (any, error) {
var result any
for _, m := range matches {
for i, m := range matches {
if m.Block.Path == "@index" {
continue
}
input := m.GetContent()
value, err := ParseBlock(input, m.Block)
var blockIdentifier any
blockIdentifier = m.Block.Path
if blockIdentifier == "" {
blockIdentifier = fmt.Sprintf("#%d", i)
}
if err != nil {
return nil, fmt.Errorf("failed to parse block(%s): %w", m.Block.Path, err)
return nil, fmt.Errorf("failed to parse block(%s) -> %w", blockIdentifier, err)
}
result = utils.SetPathValue(m.Block.Path, value, result)
}

View File

@@ -50,7 +50,6 @@ func MatchBlocksFuzzy(markdown string, templateBlocks []template.Block, maxDist
}
}
// Handle the last block
if len(templateBlocks) > 0 {
lastBlock := templateBlocks[len(templateBlocks)-1]
if lastBlock.Type == template.DataBlock {

View File

@@ -10,7 +10,7 @@ import (
"git.max-richter.dev/max/marka/testdata"
)
func TestFuzzyFindAll(t *testing.T) {
func TestMatch_FuzzyFindAll(t *testing.T) {
recipeMd := testdata.Read(t, "baguette/input.md")
tests := []struct {
@@ -36,13 +36,14 @@ func TestFuzzyFindAll(t *testing.T) {
}
}
func TestFuzzyBlockMatch(t *testing.T) {
func TestMatch_FuzzyBlockBaguette(t *testing.T) {
recipeMd := testdata.Read(t, "baguette/input.md")
schemaMd, err := registry.GetTemplate("Recipe")
if err != nil {
t.Errorf("Failed to load template: %s", err.Error())
t.FailNow()
}
blocks, err := template.CompileTemplate(schemaMd)
if err != nil {
t.Errorf("Failed to compile template: %s", err.Error())
@@ -51,9 +52,8 @@ func TestFuzzyBlockMatch(t *testing.T) {
matches := matcher.MatchBlocksFuzzy(string(recipeMd), blocks, 0.3)
for _, b := range blocks {
fmt.Printf("Block: %+v\n", b)
fmt.Printf("Content: '%q'\n\n", b.GetContent())
for _, m := range matches {
fmt.Printf("Content: '%s'->'%q'\n\n", m.Block.Path, m.GetContent())
}
expected := []struct {
@@ -66,10 +66,7 @@ func TestFuzzyBlockMatch(t *testing.T) {
value: "Baguette",
},
{
value: "\nMy favourite baguette recipe",
},
{
value: "",
value: "My favourite baguette recipe",
},
{
value: "- Flour\n- Water\n- Salt",
@@ -87,11 +84,10 @@ func TestFuzzyBlockMatch(t *testing.T) {
if expected[i].value != m.GetContent() {
t.Errorf("Match %d did not match expected: %q", i, expected[i].value)
}
fmt.Printf("match: %s->%q\n", m.Block.Path, m.GetContent())
}
}
func TestFuzzyBlockMatchSalad(t *testing.T) {
func TestMatch_FuzzyBlockSalad(t *testing.T) {
recipeMd := testdata.Read(t, "recipe_salad/input.md")
schemaMd, err := registry.GetTemplate("Recipe")
if err != nil {
@@ -115,9 +111,6 @@ func TestFuzzyBlockMatchSalad(t *testing.T) {
{
value: "Simple Salad",
},
{
value: "#healthy #salad",
},
{
value: "A quick green salad.",
},

View File

@@ -5,7 +5,6 @@ package parser
import (
"fmt"
"strings"
"time"
"git.max-richter.dev/max/marka/parser/decoders"
"git.max-richter.dev/max/marka/parser/matcher"
@@ -53,79 +52,33 @@ func MatchBlocks(markdownContent, templateContent string) ([]matcher.Block, erro
}
func ParseFile(markdownContent string) (any, error) {
timings := make(map[string]int64)
startDetectType := time.Now()
markdownContent = strings.TrimSuffix(markdownContent, "\n")
contentType, err := DetectType(markdownContent)
if err != nil {
return nil, fmt.Errorf("could not detect type -> %w", err)
}
timings["detect_type"] = time.Since(startDetectType).Milliseconds()
startGetTemplate := time.Now()
templateContent, err := registry.GetTemplate(contentType)
if err != nil {
return nil, fmt.Errorf("could not get schema -> %w", err)
}
timings["get_template"] = time.Since(startGetTemplate).Milliseconds()
startTemplate := time.Now()
tpl, err := template.CompileTemplate(templateContent)
if err != nil {
return nil, fmt.Errorf("failed to compile template -> %w", err)
}
timings["template_compilation"] = time.Since(startTemplate).Milliseconds()
startMarkdown := time.Now()
blocks := matcher.MatchBlocksFuzzy(markdownContent, tpl, 0.3)
fmt.Println("Blocks: ", len(blocks))
for i, b := range blocks {
fmt.Printf("Block %d %+v\n", i, b)
fmt.Printf("Content %d: %q\n\n", i, b.GetContent())
return nil, fmt.Errorf("could not get template -> %w", err)
}
result, err := decoders.Parse(blocks)
if err != nil {
return nil, fmt.Errorf("failed to parse blocks -> %w", err)
}
timings["markdown_parsing"] = time.Since(startMarkdown).Milliseconds()
response := map[string]any{
"data": result,
"timings": timings,
}
return response, nil
return ParseFileWithTemplate(markdownContent, templateContent)
}
func ParseFileWithTemplate(markdownContent string, templateContent string) (any, error) {
timings := make(map[string]int64)
startTemplate := time.Now()
markdownContent = strings.TrimSuffix(markdownContent, "\n")
tpl, err := template.CompileTemplate(templateContent)
if err != nil {
return nil, fmt.Errorf("failed to compile template -> %w", err)
}
timings["template_compilation"] = time.Since(startTemplate).Milliseconds()
startMarkdown := time.Now()
blocks := matcher.MatchBlocksFuzzy(markdownContent, tpl, 0.3)
result, err := decoders.Parse(blocks)
if err != nil {
return nil, fmt.Errorf("failed to parse blocks -> %w", err)
}
timings["markdown_parsing"] = time.Since(startMarkdown).Milliseconds()
response := map[string]any{
"data": result,
"timings": timings,
return nil, fmt.Errorf("failed to compile blocks -> %w", err)
}
return response, nil
return result, nil
}

View File

@@ -9,7 +9,30 @@ import (
"github.com/google/go-cmp/cmp"
)
func TestParseRecipe_Golden(t *testing.T) {
func TestParse_DetectType(t *testing.T) {
recipe := testdata.Read(t, "recipe_salad/input.md")
article := testdata.Read(t, "article_simple/input.md")
recipeType, err := parser.DetectType(string(recipe))
if err != nil {
t.Fatalf("failed to detect recipeType: %v", err)
}
articleType, err := parser.DetectType(string(article))
if err != nil {
t.Fatalf("failed to detect articleType: %v", err)
}
if recipeType != "Recipe" {
t.Errorf("recipeType did not match expected type 'Recipe' -> %s", recipeType)
}
if articleType != "Article" {
t.Errorf("articleType did not match expected type 'Article' -> %s", articleType)
}
}
func TestParse_RecipeSalad(t *testing.T) {
inputContent := testdata.Read(t, "recipe_salad/input.md")
output := testdata.Read(t, "recipe_salad/output.json")
@@ -18,19 +41,17 @@ func TestParseRecipe_Golden(t *testing.T) {
t.Fatalf("ParseFile: %v", err)
}
gotMap := got.(map[string]any)
var want map[string]any
if err := json.Unmarshal(output, &want); err != nil {
t.Fatalf("unmarshal expected.json: %v", err)
}
if diff := cmp.Diff(want, gotMap["data"]); diff != "" {
if diff := cmp.Diff(want, got); diff != "" {
t.Fatalf("JSON mismatch (-want +got):\n%s", diff)
}
}
func TestParseRecipe_NoDescription(t *testing.T) {
func TestParse_RecipeNoDescription(t *testing.T) {
inputContent := testdata.Read(t, "recipe_no_description/input.md")
got, err := parser.ParseFile(string(inputContent))
@@ -49,7 +70,7 @@ func TestParseRecipe_NoDescription(t *testing.T) {
}
}
func TestParseRecipe_Baguette(t *testing.T) {
func TestParse_Baguette(t *testing.T) {
inputContent := testdata.Read(t, "baguette/input.md")
got, err := parser.ParseFile(string(inputContent))
@@ -68,7 +89,7 @@ func TestParseRecipe_Baguette(t *testing.T) {
}
}
func TestParseArticle_Simple(t *testing.T) {
func TestParse_Article(t *testing.T) {
inputContent := testdata.Read(t, "article_simple/input.md")
got, err := parser.ParseFile(string(inputContent))