feat: added keyword codec (partially works)

This commit is contained in:
2025-08-19 19:06:08 +02:00
parent 210b31aef8
commit 69c2550f44
24 changed files with 964 additions and 80 deletions

View File

@@ -17,6 +17,8 @@ func ParseBlock(input string, block template.Block) (any, error) {
return Yaml(input, block)
case template.CodecList:
return List(input, block)
case template.CodecHashtags:
return Keywords(input, block)
}
return nil, fmt.Errorf("unknown codec: %s", block.Codec)
}

View File

@@ -0,0 +1,19 @@
package decoders
import (
"strings"
"git.max-richter.dev/max/marka/template"
)
func Keywords(input string, block template.Block) (value any, error error) {
var tags []any
split := strings.SplitSeq(input, "#")
for tag := range split {
tag = strings.TrimSpace(tag)
if tag != "" {
tags = append(tags, tag)
}
}
return tags, nil
}

View File

@@ -18,16 +18,24 @@ func Yaml(input string, block template.Block) (value any, error error) {
var out any
for _, f := range block.Fields {
if f.Hidden {
if f.Path == "@schema" {
continue
}
if f.CodecType == template.CodecConst {
if f.Value != nil {
out = utils.SetPathValue(f.Path, f.Value, out)
}
} else {
if value, ok := res[f.Path]; ok {
out = utils.SetPathValue(f.Path, value, out)
continue
}
if value, ok := renderUtils.GetValueFromPath(res, f.Path); ok {
out = utils.SetPathValue(f.Path, value, out)
continue
}
}
}

View File

@@ -32,7 +32,7 @@ func MatchBlocksFuzzy(markdown string, templateBlocks []template.Block, maxDist
lastIndex := 0
for i, b := range templateBlocks {
if b.Type == template.MatchingBlock {
start, end := FuzzyFind(markdown, lastIndex, b.GetContent(), 0.3)
start, end := FuzzyFind(markdown, lastIndex, b.GetContent(), 0.2)
if end != -1 {
if i > 0 {
previousBlock := templateBlocks[i-1]

View File

@@ -49,23 +49,22 @@ func TestFuzzyBlockMatch(t *testing.T) {
t.FailNow()
}
for _, b := range blocks {
fmt.Printf("block: %#v\n", b)
}
matches := matcher.MatchBlocksFuzzy(string(recipeMd), blocks, 0.3)
expected := []struct {
value string
}{
{
value: "author.name: Max Richter",
value: "@type: Recipe\nauthor.name: Max Richter",
},
{
value: "Baguette",
},
{
value: "My favourite baguette recipe",
value: "\nMy favourite baguette recipe",
},
{
value: "",
},
{
value: "- Flour\n- Water\n- Salt",
@@ -83,5 +82,57 @@ func TestFuzzyBlockMatch(t *testing.T) {
if expected[i].value != m.GetContent() {
t.Errorf("Match %d did not match expected: %q", i, m.GetContent())
}
fmt.Printf("match: %s->%q\n", m.Block.Path, m.GetContent())
}
}
func TestFuzzyBlockMatchSalad(t *testing.T) {
recipeMd := testdata.Read(t, "recipe_salad/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())
t.FailNow()
}
matches := matcher.MatchBlocksFuzzy(string(recipeMd), blocks, 0.3)
expected := []struct {
value string
}{
{
value: "@type: Recipe\nauthor.name: Alex Chef\ncookTime: PT0M\nimage: https://example.com/salad.jpg\nprepTime: PT10M\nrecipeYield: 2 servings",
},
{
value: "Simple Salad",
},
{
value: "#healthy #salad",
},
{
value: "A quick green salad.",
},
{
value: "- 100 g lettuce\n- 5 cherry tomatoes\n- 1 tbsp olive oil\n- Pinch of salt",
},
{
value: "1. Wash and dry the lettuce.\n2. Halve the cherry tomatoes.\n3. Toss with olive oil and salt.\n",
},
}
for i, m := range matches {
if i > len(expected)-1 {
t.Errorf("No expected result for match: %d -> %q", i, m.GetContent())
t.FailNow()
}
if expected[i].value != m.GetContent() {
t.Errorf("Match %d did not match expected: %q", i, m.GetContent())
}
fmt.Printf("match: %s->%q\n", m.Block.Path, m.GetContent())
}
}