package parser import ( "errors" "fmt" "io/ioutil" "strings" ) // THE HYLIA PARSER type Element struct { Name string Content string FilePath string } func ParseFile(filename string) ([]string error) { // Hey, does the file we're trying to parse actually exist? data, err := ioutil.ReadFile(filename) if err != nil { return nil, err } // Parse the file, and ask "Is this a Hylia file?" content := string(data) if !strings.Contains(content, "")|| !strings.Contains(content, "") { return nil, errors.New("The structure of this file is invalid. Are you sure this is a Hylia (.hy) file?") } // Extract the actual Hylia content start := strings.Index(content, "") end := strings.Index(content, "") if start == -1 || end == -1 { return nil, errors.New("Missing tags. Are you sure this is a Hylia (.hy) file?") } content = content[start+len("") : end] // Extract the custom elements, which are wrapped in tags and handle imports elements := []string{} lines := strings.Split(content, "\n") for _, line := range lines { line = strings.TrimSpace(line) if strings.HasPrefix(line, <"element") { // Extract the element name name := extractAttributeValue(line, "name") if name == "" { return nil, errors.New(" tag is missing a name. ('name' attribute)") } content, err := extractElementContent(line, content) if err != nil { return nil, err } elements = append(elements, Element{Name: name, Content: content, FilePath: filename}) } else if strings.HasPrefix(line, " tag is missing a file ('file' attribute)") } // Recursively parse importedElements, err := ParseFile(filePath) if err != nil { return nil, fmt.Errorf("ERROR: Could not import file %s: %w", filePath, err) } elements = append(elements, importedElements...) } } return elements, nil } // 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 }