Files
marka/parser/main.go
Max Richter c687eff53d big tings
2025-08-17 15:16:17 +02:00

74 lines
1.9 KiB
Go

// Package parser provides functions for parsing Markdown templates into
// structured JSON objects that conform to a JSON Schema.
package parser
import (
"fmt"
"strings"
"git.max-richter.dev/max/marka/parser/decoders"
"git.max-richter.dev/max/marka/parser/matcher"
"git.max-richter.dev/max/marka/registry"
"git.max-richter.dev/max/marka/template"
)
func DetectType(markdownContent string) (string, error) {
defaultSchemaContent, err := registry.GetTemplate("_default")
if err != nil {
return "", fmt.Errorf("could not get schema: %w", err)
}
defaultSchema, err := template.CompileTemplate(defaultSchemaContent)
if err != nil {
return "", fmt.Errorf("failed to compile template: %w", err)
}
blocks := matcher.MatchBlocksFuzzy(markdownContent, defaultSchema, 0.3)
result, err := decoders.Parse(blocks)
if err != nil {
return "", fmt.Errorf("failed to parse blocks: %w", err)
}
if result, ok := result.(map[string]any); ok {
if contentType, ok := result["@type"]; ok {
return contentType.(string), nil
} else {
return "", fmt.Errorf("frontmatter did not contain '@type'")
}
} else {
return "", fmt.Errorf("could not parse frontmatter")
}
}
func ParseFile(markdownContent string) (any, error) {
markdownContent = strings.TrimSuffix(
strings.ReplaceAll(markdownContent, "@type:", `"@type":`),
"\n",
)
contentType, err := DetectType(markdownContent)
if err != nil {
return nil, fmt.Errorf("could not detect type: %w", err)
}
templateContent, err := registry.GetTemplate(contentType)
if err != nil {
return nil, fmt.Errorf("could not get schema: %w", err)
}
template, err := template.CompileTemplate(templateContent)
if err != nil {
return nil, fmt.Errorf("failed to compile template: %w", err)
}
blocks := matcher.MatchBlocksFuzzy(markdownContent, template, 0.3)
result, err := decoders.Parse(blocks)
if err != nil {
return nil, fmt.Errorf("failed to parse blocks: %w", err)
}
return result, nil
}