hylia/compiler/compiler.go

123 lines
2.7 KiB
Go
Raw Permalink Normal View History

package compiler
import (
"fmt"
"os"
2024-12-06 04:53:34 +00:00
"strings"
"hylia/parser"
)
// THE HYLIA COMPILER
2024-12-06 04:53:34 +00:00
func Compile(elements []parser.Element, variables map[string]string, outputFile string) error {
var head string
var body string
var other string
var errmsg string
errmsg += "Failed to write to the output file: %w"
for _, element := range elements {
switch element.Name {
case "head":
head += element.Content + "\n"
case "body":
body += element.Content + "\n"
default:
other += element.Content + "\n"
}
}
file, err := os.Create(outputFile)
if err != nil {
return fmt.Errorf("Failed to create output file: %w", err)
}
defer file.Close()
// Write the HTML structure to compile into
_, err = file.WriteString("<!DOCTYPE html>\n<html>\n")
if err != nil {
return fmt.Errorf("Failed to write to the output file: %w", err)
}
2024-12-06 04:53:34 +00:00
err = writeElements(elements, file, variables)
if err != nil {
return fmt.Errorf(errmsg, err)
}
// Close the HTML structs
_, err = file.WriteString("</html>\n")
if err != nil {
return fmt.Errorf("Failed to write to the output file: %w", err)
}
return nil
2024-12-06 04:53:34 +00:00
}
func writeElements(elements []parser.Element, file *os.File, variables map[string]string) error {
for _, element := range elements {
2024-12-07 18:44:53 +00:00
2024-12-06 04:53:34 +00:00
if element.Name == "head" {
_, err := file.WriteString(fmt.Sprintf("<head>\n"))
if err != nil {
return fmt.Errorf("Failed to write element %s: %w", element.Name, err)
}
}
if element.Name == "body" {
_, err := file.WriteString(fmt.Sprintf("<body>\n"))
if err != nil {
return fmt.Errorf("Failed to write element %s: %w", element.Name, err)
}
}
content := replaceVariables(element.Content, variables)
if strings.TrimSpace(content) != "" {
_, err := file.WriteString(strings.TrimSpace(content) + "\n")
if err != nil {
return err
}
}
// recursively process nested elements
if element.NestedElements != nil && len(element.NestedElements) > 0 {
err := writeElements(element.NestedElements, file, variables)
if err != nil {
return err
}
}
if element.Name == "head" {
_, err := file.WriteString(fmt.Sprintf("</head>\n"))
if err != nil {
return fmt.Errorf("Failed to write element %s: %w", element.Name, err)
}
}
if element.Name == "body" {
_, err := file.WriteString(fmt.Sprintf("</body>\n"))
if err != nil {
return fmt.Errorf("Failed to write element %s: %w", element.Name, err)
}
}
}
return nil
}
func replaceVariables(content string, variables map[string]string) string {
for key, value := range variables {
placeholder := fmt.Sprintf("{{%s}}", key)
content = strings.ReplaceAll(content, placeholder, value)
}
return content
}