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:
parent
cb7a238c80
commit
89fff8112f
8 changed files with 111 additions and 26 deletions
|
@ -1,19 +1,74 @@
|
||||||
package compiler
|
package compiler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"hylia/parser"
|
||||||
)
|
)
|
||||||
|
|
||||||
// THE HYLIA COMPILER
|
// THE HYLIA COMPILER
|
||||||
|
|
||||||
func Compile(elements []string) (string, error) {
|
func Compile(elements []parser.Element, outputFile string) error {
|
||||||
html := "<!DOCTYPE html>\n<html>\n<body>\n"
|
|
||||||
|
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 {
|
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>"
|
if head != "" {
|
||||||
return html, nil
|
_, 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
6
examples/header.hy
Normal 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
10
examples/main.hy
Normal 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
18
examples/output.html
Normal 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
3
go.mod
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
module hylia
|
||||||
|
|
||||||
|
go 1.23.3
|
BIN
hylia
Executable file
BIN
hylia
Executable file
Binary file not shown.
23
main.go
23
main.go
|
@ -8,31 +8,24 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if len(os.args) < 3 {
|
if len(os.Args) < 3 {
|
||||||
fmt.Println("Usage: hylia <input.hy> <output.html>")
|
fmt.Println("Usage: hylia <input.hy> <output.html>")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
inputFile := os.Args[1]
|
inputFile := os.Args[1]
|
||||||
outputFile := os.Args[2]
|
outputFile := os.Args[2]
|
||||||
fmt.Println("Processing input:", inputFile)
|
|
||||||
|
parsedElememts, err := parser.ParseFile(inputFile)
|
||||||
parsedElements, err := parser.ParseFile(inputFile)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("ERROR! ", err)
|
fmt.Printf("ERROR! %v\n", err)
|
||||||
return
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
htmlOutput, err := compiler.Compile(parsedElements)
|
err = compiler.Compile(parsedElememts, outputFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("ERROR! ", err)
|
fmt.Printf("ERROR! %v\n", err)
|
||||||
return
|
os.Exit(1)
|
||||||
}
|
|
||||||
|
|
||||||
err = os.WriteFile(outputFile, []byte(htmlOutput), 0644)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("ERROR! ", err)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("SUCCESS! Output saved to ", outputFile)
|
fmt.Println("SUCCESS! Output saved to ", outputFile)
|
||||||
|
|
|
@ -15,7 +15,7 @@ type Element struct {
|
||||||
FilePath string
|
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?
|
// Hey, does the file we're trying to parse actually exist?
|
||||||
data, err := ioutil.ReadFile(filename)
|
data, err := ioutil.ReadFile(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -38,11 +38,11 @@ func ParseFile(filename string) ([]string error) {
|
||||||
content = content[start+len("<hylia>") : end]
|
content = content[start+len("<hylia>") : end]
|
||||||
|
|
||||||
// Extract the custom elements, which are wrapped in <element> tags and handle imports
|
// Extract the custom elements, which are wrapped in <element> tags and handle imports
|
||||||
elements := []string{}
|
elements := []Element{}
|
||||||
lines := strings.Split(content, "\n")
|
lines := strings.Split(content, "\n")
|
||||||
for _, line := range lines {
|
for _, line := range lines {
|
||||||
line = strings.TrimSpace(line)
|
line = strings.TrimSpace(line)
|
||||||
if strings.HasPrefix(line, <"element") {
|
if strings.HasPrefix(line, "<element") {
|
||||||
// Extract the element name
|
// Extract the element name
|
||||||
name := extractAttributeValue(line, "name")
|
name := extractAttributeValue(line, "name")
|
||||||
if name == "" {
|
if name == "" {
|
||||||
|
@ -54,7 +54,7 @@ func ParseFile(filename string) ([]string error) {
|
||||||
}
|
}
|
||||||
elements = append(elements, Element{Name: name, Content: content, FilePath: filename})
|
elements = append(elements, Element{Name: name, Content: content, FilePath: filename})
|
||||||
} else if strings.HasPrefix(line, "<import") {
|
} else if strings.HasPrefix(line, "<import") {
|
||||||
filePath := extractAttributeValue(line, file)
|
filePath := extractAttributeValue(line, "file")
|
||||||
if filePath == "" {
|
if filePath == "" {
|
||||||
return nil, errors.New("<import> tag is missing a file ('file' attribute)")
|
return nil, errors.New("<import> tag is missing a file ('file' attribute)")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue