starting stuff
This commit is contained in:
parent
8a66ea7971
commit
ed3c7d4278
7 changed files with 121 additions and 10 deletions
|
@ -61,6 +61,7 @@ func Compile(elements []parser.Element, variables map[string]string, outputFile
|
||||||
|
|
||||||
func writeElements(elements []parser.Element, file *os.File, variables map[string]string) error {
|
func writeElements(elements []parser.Element, file *os.File, variables map[string]string) error {
|
||||||
for _, element := range elements {
|
for _, element := range elements {
|
||||||
|
|
||||||
if element.Name == "head" {
|
if element.Name == "head" {
|
||||||
_, err := file.WriteString(fmt.Sprintf("<head>\n"))
|
_, err := file.WriteString(fmt.Sprintf("<head>\n"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
<hylia>
|
<hylia>
|
||||||
<element name="body">
|
<class name="hi">
|
||||||
I am in the body element.
|
<h1>test hello</h1>
|
||||||
</element>
|
</class>
|
||||||
<p>I am not in the body element.</p>
|
|
||||||
<element name="outside">
|
|
||||||
I am outside the body element, but inside the outside element.
|
|
||||||
</element>
|
|
||||||
</hylia>
|
</hylia>
|
|
@ -1,9 +1,11 @@
|
||||||
<hylia>
|
<hylia>
|
||||||
|
<import src="header.hy" />
|
||||||
<element name="head">
|
<element name="head">
|
||||||
<title>Hello Hylia!</title>
|
<title>Hello Hylia!</title>
|
||||||
</element>
|
</element>
|
||||||
<var name="testvar"><h1>Hello!</h1><br><h2>Hello again!</h2></var>
|
<var name="testvar"><h1>Hello!</h1><br><h2>Hello again!</h2></var>
|
||||||
<element name="body">
|
<element name="body">
|
||||||
|
<hi />
|
||||||
<h1>Hello Hylia!</h1>
|
<h1>Hello Hylia!</h1>
|
||||||
<p>This is an example content.</p>
|
<p>This is an example content.</p>
|
||||||
{{testvar}}
|
{{testvar}}
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Hello Hylia!</title>
|
||||||
|
</head>
|
||||||
<body>
|
<body>
|
||||||
I am in the body element.
|
<hi />
|
||||||
|
<h1>Hello Hylia!</h1>
|
||||||
|
<p>This is an example content.</p>
|
||||||
|
<h1>Hello!</h1><br><h2>Hello again!</h2>
|
||||||
</body>
|
</body>
|
||||||
I am outside the body element, but inside the outside element.
|
|
||||||
</html>
|
</html>
|
||||||
|
|
BIN
hylia
Executable file
BIN
hylia
Executable file
Binary file not shown.
35
importer/import.go
Normal file
35
importer/import.go
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
package importer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Class struct {
|
||||||
|
Name string
|
||||||
|
Content string
|
||||||
|
FilePath string
|
||||||
|
}
|
||||||
|
|
||||||
|
func ImportClasses(filePath string) (map[string]Class, error) {
|
||||||
|
content, err := ioutil.ReadFile(filePath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error reading file '%s': %w", filePath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
classes := make(map[string]Class)
|
||||||
|
lines := strings.Split(string(content), "\n")
|
||||||
|
var currentClass *Class
|
||||||
|
var nestedContent strings.Builder
|
||||||
|
|
||||||
|
for _, line := range lines {
|
||||||
|
line = strings.TrimSpace(line)
|
||||||
|
if strings.HasPrefix(line, "<class") {
|
||||||
|
name := extractAttributeValue(line, "name")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"strings"
|
"strings"
|
||||||
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
|
||||||
// THE HYLIA PARSER
|
// THE HYLIA PARSER
|
||||||
|
@ -28,14 +29,52 @@ func ParseFile(filename string) ([]Element, map[string]string, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("failed to parse elements: %w", err)
|
return nil, nil, fmt.Errorf("failed to parse elements: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
importedElements := []Element{}
|
||||||
|
importedVariables := map[string]string{}
|
||||||
|
|
||||||
|
for _, element := range elements {
|
||||||
|
if element.Name == "import" {
|
||||||
|
importPath := extractAttributeValue("import", "src")
|
||||||
|
if importPath == "" {
|
||||||
|
return nil, nil, fmt.Errorf("Import is missing a source ('src' attribute)")
|
||||||
|
}
|
||||||
|
|
||||||
|
importFullPath := resolvePath(filename, importPath)
|
||||||
|
|
||||||
|
childElements, childVariables, err := ParseFile(importFullPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("failed to parse elements: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
importedElements = append(importedElements, childElements...)
|
||||||
|
for k, v := range childVariables {
|
||||||
|
importedVariables[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range importedVariables {
|
||||||
|
if _, exists := variables[k]; !exists {
|
||||||
|
variables[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
elements = append(importedElements, elements...)
|
||||||
|
|
||||||
return elements, variables, nil
|
return elements, variables, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func resolvePath(basePath, relativePath string) string {
|
||||||
|
dir := filepath.Dir(basePath)
|
||||||
|
return filepath.Join(dir, relativePath)
|
||||||
|
}
|
||||||
|
|
||||||
func parseElements(content, filename string) ([]Element, map[string]string, error) {
|
func parseElements(content, filename string) ([]Element, map[string]string, error) {
|
||||||
elements := []Element{}
|
elements := []Element{}
|
||||||
variables := make(map[string]string)
|
variables := make(map[string]string)
|
||||||
|
classes := make(map[string]Element)
|
||||||
|
|
||||||
lines := strings.Split(content, "\n")
|
lines := strings.Split(content, "\n")
|
||||||
var currentElement *Element
|
var currentElement *Element
|
||||||
|
@ -80,7 +119,40 @@ func parseElements(content, filename string) ([]Element, map[string]string, erro
|
||||||
nestedContent.Reset()
|
nestedContent.Reset()
|
||||||
currentElement = nil
|
currentElement = nil
|
||||||
}
|
}
|
||||||
} else {
|
} else if strings.HasPrefix(line, "<class") {
|
||||||
|
if currentElement != nil {
|
||||||
|
currentElement.Content = nestedContent.String()
|
||||||
|
parsedNested, nestedVars, _ := parseElements(nestedContent.String(), filename)
|
||||||
|
currentElement.NestedElements = parsedNested
|
||||||
|
mergeVariables(variables, nestedVars)
|
||||||
|
elements = append(elements, *currentElement)
|
||||||
|
nestedContent.Reset()
|
||||||
|
currentElement = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
name := extractAttributeValue(line, "name")
|
||||||
|
if name == "" {
|
||||||
|
return nil, nil, errors.New("class is missing a name ('name' attribute)")
|
||||||
|
}
|
||||||
|
|
||||||
|
currentElement = &Element{Name: name, FilePath: filename}
|
||||||
|
} else if strings.HasPrefix(line, "</class>") {
|
||||||
|
if currentElement != nil {
|
||||||
|
currentElement.Content = nestedContent.String()
|
||||||
|
parsedNested, nestedVars, _ := parseElements(nestedContent.String(), filename)
|
||||||
|
currentElement.NestedElements = parsedNested
|
||||||
|
mergeVariables(variables, nestedVars)
|
||||||
|
if classes == nil {
|
||||||
|
classes = make(map[string]Element)
|
||||||
|
}
|
||||||
|
classes[currentElement.Name] = *currentElement
|
||||||
|
|
||||||
|
nestedContent.Reset()
|
||||||
|
currentElement = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
if currentElement != nil {
|
if currentElement != nil {
|
||||||
nestedContent.WriteString(line + "\n")
|
nestedContent.WriteString(line + "\n")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue