package parser import ( "errors" "fmt" "io/ioutil" "strings" ) // THE HYLIA PARSER type Element struct { Name string Content string FilePath string NestedElements []Element Variables map[string]string } func ParseFile(filename string) ([]Element, map[string]string, error) { // Hey, does the file we're trying to parse actually exist? data, err := ioutil.ReadFile(filename) if err != nil { return nil, nil, err } elements, variables, err := parseElements(string(data), filename) if err != nil { return nil, nil, fmt.Errorf("failed to parse elements: %w", err) } return elements, variables, nil } func parseElements(content, filename string) ([]Element, map[string]string, error) { elements := []Element{} variables := make(map[string]string) lines := strings.Split(content, "\n") var currentElement *Element var nestedContent strings.Builder for _, line := range lines { line = strings.TrimSpace(line) if strings.HasPrefix(line, "") valueEnd := strings.Index(line, "") if valueStart == -1 || valueEnd == -1 { return nil, nil, errors.New("invalid variable structure") } value := strings.TrimSpace(line[valueStart+1 : valueEnd]) variables[name] = value } else if strings.HasPrefix(line, "") { 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 } } else { if currentElement != nil { nestedContent.WriteString(line + "\n") } } } return elements, variables, nil } func mergeVariables(target, source map[string]string) { for key, value := range source { target[key] = value } } // Extracts an attribute func extractAttributeValue(tag, attribute string) string { prefix := fmt.Sprintf(`%s="`, attribute) start := strings.Index(tag, prefix) if start == -1 { return "" } start += len(prefix) end := strings.Index(tag[start:], `"`) if end == -1 { return "" } return tag[start : start+end] } // Extracts an func extractElementContent(tag, content string) (string, error) { start := strings.Index(content, tag) if start == -1 { return "", errors.New("element tag not found in content") } end := strings.Index(content[start:], "") if end == -1 { return "", errors.New("missing end tag of element") } return content[start+len(tag) : start+end], nil }