Files
marka/renderer/encoders/encoders.go

70 lines
1.9 KiB
Go

// Package encoders contains functions for rendering template.Block to a string.
package encoders
import (
"bytes"
"fmt"
"strings"
"git.max-richter.dev/max/marka/renderer/utils"
"git.max-richter.dev/max/marka/template"
)
const emptyBlock = "\uE000"
func fixRenderedBlock(input string) string {
input = strings.ReplaceAll(input, "'@type':", "@type:")
input = strings.ReplaceAll(input, "'@context':", "@context:")
if len(input) == 0 {
return emptyBlock
}
return input
}
// RenderBlock renders a single template block using the provided data.
func RenderBlock(block template.Block, data map[string]any) (string, error) {
if block.Type == template.MatchingBlock {
return block.GetContent(), nil
}
value, found := utils.GetValueFromPath(data, block.Path)
if !found {
return "", nil // If not found and not required, return empty string
}
switch block.Codec {
case template.CodecText:
return fmt.Sprintf("%v", value), nil
case template.CodecYaml:
return RenderYaml(data, block)
case template.CodecList:
return RenderList(value, block)
case template.CodecConst:
return fmt.Sprintf("%v", block.Value), nil
default:
return "", fmt.Errorf("unknown codec: %s for path '%s'", block.Codec, block.Path)
}
}
func Render(data map[string]any, blocks []template.Block) (string, error) {
var buffer bytes.Buffer
for _, block := range blocks {
renderedContent, err := RenderBlock(block, data)
if err != nil {
return "", fmt.Errorf("failed to render block for path '%s': %w", block.Path, err)
}
renderedContent = fixRenderedBlock(renderedContent)
buffer.WriteString(renderedContent)
}
outputString := buffer.String()
outputString = strings.ReplaceAll(outputString, "\n\n"+emptyBlock+"\n\n", "\n\n")
outputString = strings.ReplaceAll(outputString, "\n"+emptyBlock+"\n", "\n")
outputString = strings.ReplaceAll(outputString, emptyBlock, "")
if !strings.HasSuffix(outputString, "\n") {
outputString += "\n"
}
return outputString, nil
}