package main import ( "bufio" "bytes" "fmt" "go/format" "io/ioutil" "log" "os" "strings" ) const packageName = "hatmill" func genElements() { const ( elementInputPath = "elements.txt" elementOutputPath = "elements.go" parentType = "parent" emptyType = "empty" parentTemplate = `// %[1]s creates a <%[2]s> element. func %[1]s(attribs ...Attrib) func(children ...Term) *ParentElement { return func(children ...Term) *ParentElement { return &ParentElement{ EmptyElement: EmptyElement{ TagName: "%[2]s", Attribs: attribs, }, Children: children, } } } ` emptyTemplate = `// %[1]s creates a <%[2]s> element. func %[1]s(attribs ...Attrib) EmptyElement { return EmptyElement{ TagName: "%[2]s", Attribs: attribs, } } ` ) inputFile, err := os.Open(elementInputPath) if err != nil { log.Fatal(err) } defer inputFile.Close() var output bytes.Buffer fmt.Fprintln(&output, "// GENERATED BY gitlab.codemonkeysoftware.net/b/hatmill/internal/elementgen") fmt.Fprintln(&output, "// DO NOT EDIT!\n") fmt.Fprintln(&output, "package ", packageName, "\n") scanner := bufio.NewScanner(inputFile) for scanner.Scan() { line := scanner.Text() if line == "" { continue } var tagName, elemType string _, err = fmt.Sscanf(line, "%s %s", &tagName, &elemType) if err != nil { log.Fatalf("error parsing input line: %s", err) } var template string switch elemType { case parentType: template = parentTemplate case emptyType: template = emptyTemplate default: log.Fatal("unknown element type: ", elemType) } fmt.Fprintf(&output, template, strings.Title(tagName), tagName) } if err := scanner.Err(); err != nil { log.Fatalf("error scanning input: %s", err) } formatted, err := format.Source(output.Bytes()) if err != nil { log.Fatalf("error formatting output: %s", err) } err = ioutil.WriteFile(elementOutputPath, formatted, 0644) if err != nil { log.Fatalf("error writing output: %s", err) } } func genAttribs() { const ( inputPath = "attribs.txt" outputPath = "attribs.go" boolType = "bool" stringType = "string" stringTemplate = `func %s(value string) Attrib { return Attrib{ Key: "%s", Value: value, } } ` boolTemplate = `func %s() Attrib { return Attrib{ Key: "%s", } } ` ) inputFile, err := os.Open(inputPath) if err != nil { log.Fatal(err) } defer inputFile.Close() var output bytes.Buffer fmt.Fprintln(&output, "// GENERATED BY gitlab.codemonkeysoftware.net/b/hatmill/internal/attribgen") fmt.Fprintln(&output, "// DO NOT EDIT!\n") fmt.Fprintln(&output, "package ", packageName, "\n") scanner := bufio.NewScanner(inputFile) for scanner.Scan() { line := scanner.Text() if line == "" { continue } var attribName, attribType string _, err = fmt.Sscanf(line, "%s %s", &attribName, &attribType) if err != nil { log.Fatalf("error parsing input line: %s", err) } var template string switch attribType { case boolType: template = boolTemplate case stringType: template = stringTemplate default: log.Fatal("unknown attribute type: ", attribType) } fmt.Fprintf(&output, template, strings.Title(attribName), attribName) } if err := scanner.Err(); err != nil { log.Fatalf("error scanning input: %s", err) } formatted, err := format.Source(output.Bytes()) if err != nil { log.Fatalf("error formatting output: %s", err) } err = ioutil.WriteFile(outputPath, formatted, 0644) if err != nil { log.Fatalf("error writing output: %s", err) } } func main() { genElements() genAttribs() }