Add proper elements <element name="head"> will now be treated as <head>. WARNING: I WAS A STUPID NINCOMPOOP AND BROKE NESTING ELEMENTS!!!

This commit is contained in:
conzer 2024-12-05 20:57:48 -05:00
parent cb7a238c80
commit 89fff8112f
8 changed files with 111 additions and 26 deletions

View file

@ -1,19 +1,74 @@
package compiler
import (
"strings"
"fmt"
"os"
"hylia/parser"
)
// THE HYLIA COMPILER
func Compile(elements []string) (string, error) {
html := "<!DOCTYPE html>\n<html>\n<body>\n"
func Compile(elements []parser.Element, outputFile string) error {
var head string
var body string
var other string
var errmsg string
errmsg += "Failed to write to the output file: %w"
// Take the elements into HTML
for _, element := range elements {
html += element + "\n"
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)
}
html += "</body>\n</html>"
return html, nil
if head != "" {
_, err = file.WriteString("<head>\n" + head + "</head>\n")
if err != nil {
return fmt.Errorf(errmsg, err)
}
}
if body != "" {
_, err = file.WriteString("<body>\n" + body + "</body>\n")
if err != nil {
return fmt.Errorf(errmsg, err)
}
}
if other != "" {
_, err = file.WriteString(other)
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
}

6
examples/header.hy Normal file
View file

@ -0,0 +1,6 @@
<hylia>
<element name="header">
<h1> Welcome to Hylia! </h1>
<p>This is a reusable header component.</p>
</element>
</hylia>

10
examples/main.hy Normal file
View file

@ -0,0 +1,10 @@
<hylia>
<import file="header.hy"></import>
<element name="head">
<title>Hello Hylia!</title>
</element>
<element name="body">
<header />
<p>This is the main content.</p>
</element>
</hylia>

18
examples/output.html Normal file
View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<title>Hello Hylia!</title>
</head>
<body>
<header />
<p>This is the main content.</p>
</body>
<h1> Welcome to Hylia! </h1>
<p>This is a reusable header component.</p>
</html>

3
go.mod Normal file
View file

@ -0,0 +1,3 @@
module hylia
go 1.23.3

BIN
hylia Executable file

Binary file not shown.

23
main.go
View file

@ -8,31 +8,24 @@ import (
)
func main() {
if len(os.args) < 3 {
if len(os.Args) < 3 {
fmt.Println("Usage: hylia <input.hy> <output.html>")
return
}
inputFile := os.Args[1]
outputFile := os.Args[2]
fmt.Println("Processing input:", inputFile)
parsedElements, err := parser.ParseFile(inputFile)
parsedElememts, err := parser.ParseFile(inputFile)
if err != nil {
fmt.Println("ERROR! ", err)
return
fmt.Printf("ERROR! %v\n", err)
os.Exit(1)
}
htmlOutput, err := compiler.Compile(parsedElements)
err = compiler.Compile(parsedElememts, outputFile)
if err != nil {
fmt.Println("ERROR! ", err)
return
}
err = os.WriteFile(outputFile, []byte(htmlOutput), 0644)
if err != nil {
fmt.Println("ERROR! ", err)
return
fmt.Printf("ERROR! %v\n", err)
os.Exit(1)
}
fmt.Println("SUCCESS! Output saved to ", outputFile)

View file

@ -15,7 +15,7 @@ type Element struct {
FilePath string
}
func ParseFile(filename string) ([]string error) {
func ParseFile(filename string) ([]Element, error) {
// Hey, does the file we're trying to parse actually exist?
data, err := ioutil.ReadFile(filename)
if err != nil {
@ -38,11 +38,11 @@ func ParseFile(filename string) ([]string error) {
content = content[start+len("<hylia>") : end]
// Extract the custom elements, which are wrapped in <element> tags and handle imports
elements := []string{}
elements := []Element{}
lines := strings.Split(content, "\n")
for _, line := range lines {
line = strings.TrimSpace(line)
if strings.HasPrefix(line, <"element") {
if strings.HasPrefix(line, "<element") {
// Extract the element name
name := extractAttributeValue(line, "name")
if name == "" {
@ -54,7 +54,7 @@ func ParseFile(filename string) ([]string error) {
}
elements = append(elements, Element{Name: name, Content: content, FilePath: filename})
} else if strings.HasPrefix(line, "<import") {
filePath := extractAttributeValue(line, file)
filePath := extractAttributeValue(line, "file")
if filePath == "" {
return nil, errors.New("<import> tag is missing a file ('file' attribute)")
}