Added element function generator

This commit is contained in:
Brandon Dyck 2019-03-21 21:31:24 -06:00
parent 809ec2cff2
commit 8517cab0f5
6 changed files with 184 additions and 24 deletions

44
elements.go Normal file
View File

@ -0,0 +1,44 @@
// GENERATED BY gitlab.codemonkeysoftware.net/b/hatmill/internal/elementgen
// DO NOT EDIT!
package hatmill
func Div(attribs ...Attrib) func(children ...Term) *ParentElement {
return func(children ...Term) *ParentElement {
return &ParentElement{
EmptyElement: EmptyElement{
TagName: "div",
Attribs: attribs,
},
Children: children,
}
}
}
func Img(attribs ...Attrib) EmptyElement {
return EmptyElement{
TagName: "img",
Attribs: attribs,
}
}
func Span(attribs ...Attrib) func(children ...Term) *ParentElement {
return func(children ...Term) *ParentElement {
return &ParentElement{
EmptyElement: EmptyElement{
TagName: "span",
Attribs: attribs,
},
Children: children,
}
}
}
func Html(attribs ...Attrib) func(children ...Term) *ParentElement {
return func(children ...Term) *ParentElement {
return &ParentElement{
EmptyElement: EmptyElement{
TagName: "html",
Attribs: attribs,
},
Children: children,
}
}
}

4
elements.txt Normal file
View File

@ -0,0 +1,4 @@
div parent
img empty
span parent
html parent

17
example/example.go Normal file
View File

@ -0,0 +1,17 @@
package main
import (
"os"
h "gitlab.codemonkeysoftware.com/b/hatmill"
)
func main() {
document := h.Html()(
h.Div()(
h.Img(h.Id("profile-photo")),
h.Text("hello hatmill!"),
h.Div(h.Disabled())(),
),
)
h.WriteDocument(os.Stdout, document)
}

View File

@ -2,11 +2,13 @@ package hatmill
import "io" import "io"
// Html is one of EmptyElement, ParentElement, or Text. //go:generate go run ./internal/elementgen/main.go
type Html interface {
// Term represents a fragment of HTML markup, and is one of EmptyElement, ParentElement, or Text.
type Term interface {
io.WriterTo io.WriterTo
// isHtml is a no-op method to prevent external Html implementations, because // isHtml is a no-op method to prevent external Term implementations, because
// Go doesn't have sum types. // Go doesn't have sum types.
isHtml() isHtml()
} }
@ -73,7 +75,7 @@ func (e EmptyElement) WriteTo(w io.Writer) (n int64, err error) {
type ParentElement struct { type ParentElement struct {
EmptyElement EmptyElement
Children []Html Children []Term
} }
func (e *ParentElement) isHtml() {} func (e *ParentElement) isHtml() {}
@ -108,24 +110,24 @@ func (t Text) WriteTo(w io.Writer) (n int64, err error) {
// Html5 functions // Html5 functions
func Div(attribs ...Attrib) func(children ...Html) *ParentElement { // func Div(attribs ...Attrib) func(children ...Term) *ParentElement {
return func(children ...Html) *ParentElement { // return func(children ...Term) *ParentElement {
return &ParentElement{ // return &ParentElement{
EmptyElement: EmptyElement{ // EmptyElement: EmptyElement{
TagName: "div", // TagName: "div",
Attribs: attribs, // Attribs: attribs,
}, // },
Children: children, // Children: children,
} // }
} // }
} // }
//
func Img(attribs ...Attrib) EmptyElement { // func Img(attribs ...Attrib) EmptyElement {
return EmptyElement{ // return EmptyElement{
TagName: "img", // TagName: "img",
Attribs: attribs, // Attribs: attribs,
} // }
} // }
func Id(id string) Attrib { func Id(id string) Attrib {
return Attrib{ return Attrib{

View File

@ -122,7 +122,7 @@ func TestEmptyElement(t *testing.T) {
properties.TestingRun(t) properties.TestingRun(t)
} }
var htmlTextGen = gen.AnyString().Map(func(s string) hatmill.Html { var htmlTextGen = gen.AnyString().Map(func(s string) hatmill.Term {
return hatmill.Text(s) return hatmill.Text(s)
}) })
@ -147,7 +147,7 @@ func TestParentElement(t *testing.T) {
)) ))
properties.Property("WriteTo writes element correctly with children", prop.ForAll( properties.Property("WriteTo writes element correctly with children", prop.ForAll(
func(tagName string, attribs []hatmill.Attrib, children []hatmill.Html) bool { func(tagName string, attribs []hatmill.Attrib, children []hatmill.Term) bool {
elem := &hatmill.ParentElement { elem := &hatmill.ParentElement {
EmptyElement: hatmill.EmptyElement{ EmptyElement: hatmill.EmptyElement{
TagName: tagName, TagName: tagName,

View File

@ -0,0 +1,93 @@
package main
import (
"bufio"
"bytes"
"fmt"
"go/format"
"io/ioutil"
"log"
"os"
"strings"
)
const (
inputPath = "elements.txt"
outputPath = "elements.go"
packageName = "hatmill"
parentType = "parent"
emptyType = "empty"
parentTemplate = `func %s(attribs ...Attrib) func(children ...Term) *ParentElement {
return func(children ...Term) *ParentElement {
return &ParentElement{
EmptyElement: EmptyElement{
TagName: "%s",
Attribs: attribs,
},
Children: children,
}
}
}
`
emptyTemplate = `func %s(attribs ...Attrib) EmptyElement {
return EmptyElement{
TagName: "%s",
Attribs: attribs,
}
}
`
)
func main() {
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/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(outputPath, formatted, 0644)
if err != nil {
log.Fatalf("error writing output: %s", err)
}
}