fix: most of the template blocks
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
@@ -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 {
|
||||
|
@@ -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.",
|
||||
},
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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))
|
||||
|
Reference in New Issue
Block a user