Added int attribute type
This commit is contained in:
parent
38d31f8a25
commit
cd2230f625
@ -4,6 +4,7 @@
|
|||||||
package attribute
|
package attribute
|
||||||
|
|
||||||
import "gitlab.codemonkeysoftware.net/b/hatmill"
|
import "gitlab.codemonkeysoftware.net/b/hatmill"
|
||||||
|
import "strconv"
|
||||||
|
|
||||||
// Accept creates a "accept" attribute
|
// Accept creates a "accept" attribute
|
||||||
func Accept(value string) hatmill.Attrib {
|
func Accept(value string) hatmill.Attrib {
|
||||||
@ -146,18 +147,18 @@ func Class(value string) hatmill.Attrib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Cols creates a "cols" attribute
|
// Cols creates a "cols" attribute
|
||||||
func Cols(value string) hatmill.Attrib {
|
func Cols(value int) hatmill.Attrib {
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "cols",
|
Key: "cols",
|
||||||
Value: value,
|
Value: strconv.FormatInt(int64(value), 10),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Colspan creates a "colspan" attribute
|
// Colspan creates a "colspan" attribute
|
||||||
func Colspan(value string) hatmill.Attrib {
|
func Colspan(value int) hatmill.Attrib {
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "colspan",
|
Key: "colspan",
|
||||||
Value: value,
|
Value: strconv.FormatInt(int64(value), 10),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,10 +327,10 @@ func Headers(value string) hatmill.Attrib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Height creates a "height" attribute
|
// Height creates a "height" attribute
|
||||||
func Height(value string) hatmill.Attrib {
|
func Height(value int) hatmill.Attrib {
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "height",
|
Key: "height",
|
||||||
Value: value,
|
Value: strconv.FormatInt(int64(value), 10),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -490,11 +491,11 @@ func Max(value string) hatmill.Attrib {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Maxlengh creates a "maxlengh" attribute
|
// Maxlength creates a "maxlength" attribute
|
||||||
func Maxlengh(value string) hatmill.Attrib {
|
func Maxlength(value int) hatmill.Attrib {
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "maxlengh",
|
Key: "maxlength",
|
||||||
Value: value,
|
Value: strconv.FormatInt(int64(value), 10),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -523,10 +524,10 @@ func Min(value string) hatmill.Attrib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Minlength creates a "minlength" attribute
|
// Minlength creates a "minlength" attribute
|
||||||
func Minlength(value string) hatmill.Attrib {
|
func Minlength(value int) hatmill.Attrib {
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "minlength",
|
Key: "minlength",
|
||||||
Value: value,
|
Value: strconv.FormatInt(int64(value), 10),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -652,18 +653,18 @@ func Reversed() hatmill.Attrib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Rows creates a "rows" attribute
|
// Rows creates a "rows" attribute
|
||||||
func Rows(value string) hatmill.Attrib {
|
func Rows(value int) hatmill.Attrib {
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "rows",
|
Key: "rows",
|
||||||
Value: value,
|
Value: strconv.FormatInt(int64(value), 10),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rowspan creates a "rowspan" attribute
|
// Rowspan creates a "rowspan" attribute
|
||||||
func Rowspan(value string) hatmill.Attrib {
|
func Rowspan(value int) hatmill.Attrib {
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "rowspan",
|
Key: "rowspan",
|
||||||
Value: value,
|
Value: strconv.FormatInt(int64(value), 10),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -699,10 +700,10 @@ func Shape(value string) hatmill.Attrib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Size creates a "size" attribute
|
// Size creates a "size" attribute
|
||||||
func Size(value string) hatmill.Attrib {
|
func Size(value int) hatmill.Attrib {
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "size",
|
Key: "size",
|
||||||
Value: value,
|
Value: strconv.FormatInt(int64(value), 10),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -803,10 +804,10 @@ func Summary(value string) hatmill.Attrib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Tabindex creates a "tabindex" attribute
|
// Tabindex creates a "tabindex" attribute
|
||||||
func Tabindex(value string) hatmill.Attrib {
|
func Tabindex(value int) hatmill.Attrib {
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "tabindex",
|
Key: "tabindex",
|
||||||
Value: value,
|
Value: strconv.FormatInt(int64(value), 10),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -859,10 +860,10 @@ func Value(value string) hatmill.Attrib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Width creates a "width" attribute
|
// Width creates a "width" attribute
|
||||||
func Width(value string) hatmill.Attrib {
|
func Width(value int) hatmill.Attrib {
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "width",
|
Key: "width",
|
||||||
Value: value,
|
Value: strconv.FormatInt(int64(value), 10),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
20
defs.json
20
defs.json
@ -18,8 +18,8 @@
|
|||||||
{"name": "checked", "type": "bool"},
|
{"name": "checked", "type": "bool"},
|
||||||
{"name": "cite", "type": "string"},
|
{"name": "cite", "type": "string"},
|
||||||
{"name": "class", "type": "string"},
|
{"name": "class", "type": "string"},
|
||||||
{"name": "cols", "type": "string"},
|
{"name": "cols", "type": "int"},
|
||||||
{"name": "colspan", "type": "string"},
|
{"name": "colspan", "type": "int"},
|
||||||
{"name": "content", "type": "string"},
|
{"name": "content", "type": "string"},
|
||||||
{"name": "contenteditable", "type": "string"},
|
{"name": "contenteditable", "type": "string"},
|
||||||
{"name": "contextmenu", "type": "string"},
|
{"name": "contextmenu", "type": "string"},
|
||||||
@ -41,7 +41,7 @@
|
|||||||
{"name": "form", "type": "string"},
|
{"name": "form", "type": "string"},
|
||||||
{"name": "formaction", "type": "string"},
|
{"name": "formaction", "type": "string"},
|
||||||
{"name": "headers", "type": "string"},
|
{"name": "headers", "type": "string"},
|
||||||
{"name": "height", "type": "string"},
|
{"name": "height", "type": "int"},
|
||||||
{"name": "hidden", "type": "bool"},
|
{"name": "hidden", "type": "bool"},
|
||||||
{"name": "high", "type": "string"},
|
{"name": "high", "type": "string"},
|
||||||
{"name": "href", "type": "string"},
|
{"name": "href", "type": "string"},
|
||||||
@ -62,11 +62,11 @@
|
|||||||
{"name": "low", "type": "string"},
|
{"name": "low", "type": "string"},
|
||||||
{"name": "manifest", "type": "string"},
|
{"name": "manifest", "type": "string"},
|
||||||
{"name": "max", "type": "string"},
|
{"name": "max", "type": "string"},
|
||||||
{"name": "maxlengh", "type": "string"},
|
{"name": "maxlength", "type": "int"},
|
||||||
{"name": "media", "type": "string"},
|
{"name": "media", "type": "string"},
|
||||||
{"name": "method", "type": "string"},
|
{"name": "method", "type": "string"},
|
||||||
{"name": "min", "type": "string"},
|
{"name": "min", "type": "string"},
|
||||||
{"name": "minlength", "type": "string"},
|
{"name": "minlength", "type": "int"},
|
||||||
{"name": "multiple", "type": "bool"},
|
{"name": "multiple", "type": "bool"},
|
||||||
{"name": "muted", "type": "bool"},
|
{"name": "muted", "type": "bool"},
|
||||||
{"name": "name", "type": "string"},
|
{"name": "name", "type": "string"},
|
||||||
@ -83,13 +83,13 @@
|
|||||||
{"name": "rel", "type": "string"},
|
{"name": "rel", "type": "string"},
|
||||||
{"name": "required", "type": "bool"},
|
{"name": "required", "type": "bool"},
|
||||||
{"name": "reversed", "type": "bool"},
|
{"name": "reversed", "type": "bool"},
|
||||||
{"name": "rows", "type": "string"},
|
{"name": "rows", "type": "int"},
|
||||||
{"name": "rowspan", "type": "string"},
|
{"name": "rowspan", "type": "int"},
|
||||||
{"name": "sandbox", "type": "string"},
|
{"name": "sandbox", "type": "string"},
|
||||||
{"name": "scope", "type": "string"},
|
{"name": "scope", "type": "string"},
|
||||||
{"name": "selected", "type": "bool"},
|
{"name": "selected", "type": "bool"},
|
||||||
{"name": "shape", "type": "string"},
|
{"name": "shape", "type": "string"},
|
||||||
{"name": "size", "type": "string"},
|
{"name": "size", "type": "int"},
|
||||||
{"name": "sizes", "type": "string"},
|
{"name": "sizes", "type": "string"},
|
||||||
{"name": "slot", "type": "string"},
|
{"name": "slot", "type": "string"},
|
||||||
{"name": "span", "type": "string"},
|
{"name": "span", "type": "string"},
|
||||||
@ -102,14 +102,14 @@
|
|||||||
{"name": "step", "type": "string"},
|
{"name": "step", "type": "string"},
|
||||||
{"name": "style", "type": "string"},
|
{"name": "style", "type": "string"},
|
||||||
{"name": "summary", "type": "string"},
|
{"name": "summary", "type": "string"},
|
||||||
{"name": "tabindex", "type": "string"},
|
{"name": "tabindex", "type": "int"},
|
||||||
{"name": "target", "type": "string"},
|
{"name": "target", "type": "string"},
|
||||||
{"name": "title", "type": "string"},
|
{"name": "title", "type": "string"},
|
||||||
{"name": "translate", "type": "string"},
|
{"name": "translate", "type": "string"},
|
||||||
{"name": "type", "type": "string"},
|
{"name": "type", "type": "string"},
|
||||||
{"name": "usemap", "type": "string"},
|
{"name": "usemap", "type": "string"},
|
||||||
{"name": "value", "type": "string"},
|
{"name": "value", "type": "string"},
|
||||||
{"name": "width", "type": "string"},
|
{"name": "width", "type": "int"},
|
||||||
{"name": "wrap", "type": "string"}
|
{"name": "wrap", "type": "string"}
|
||||||
],
|
],
|
||||||
"elements": [
|
"elements": [
|
||||||
|
@ -190,9 +190,10 @@ func Example() {
|
|||||||
he.Img(ha.Src("./me.jpg"), ha.Id("profile-photo")),
|
he.Img(ha.Src("./me.jpg"), ha.Id("profile-photo")),
|
||||||
hatmill.Text(html.EscapeString(userInput)),
|
hatmill.Text(html.EscapeString(userInput)),
|
||||||
he.Div(ha.Disabled(), ha.CustomData("coolness", "awesome"))(),
|
he.Div(ha.Disabled(), ha.CustomData("coolness", "awesome"))(),
|
||||||
|
he.Textarea(ha.Height(25))(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
hatmill.WriteDocument(os.Stdout, document)
|
hatmill.WriteDocument(os.Stdout, document)
|
||||||
// Output: <!DOCTYPE html><html><head><meta http-equiv='refresh' content='5'></head><body><div><img src='./me.jpg' id='profile-photo'><script>launchMissiles();</script><div disabled data-coolness='awesome'></div></div></body></html>
|
// Output: <!DOCTYPE html><html><head><meta http-equiv='refresh' content='5'></head><body><div><img src='./me.jpg' id='profile-photo'><script>launchMissiles();</script><div disabled data-coolness='awesome'></div><textarea height='25'></textarea></div></body></html>
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,14 @@ func identifier(s string) string {
|
|||||||
return strings.Join(words, "")
|
return strings.Join(words, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
var attribTypes = map[string]string {
|
type AttribTypeInfo struct {
|
||||||
"string": `// %[1]s creates a "%[2]s" attribute
|
Template string
|
||||||
|
Imports []string
|
||||||
|
}
|
||||||
|
|
||||||
|
var attribTypes = map[string]AttribTypeInfo{
|
||||||
|
"string": {
|
||||||
|
Template: `// %[1]s creates a "%[2]s" attribute
|
||||||
func %[1]s(value string) hatmill.Attrib {
|
func %[1]s(value string) hatmill.Attrib {
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "%[2]s",
|
Key: "%[2]s",
|
||||||
@ -28,14 +34,39 @@ var attribTypes = map[string]string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
},
|
||||||
|
|
||||||
"bool": `// %[1]s creates a "%[2]s" attribute
|
"bool": {
|
||||||
|
Template: `// %[1]s creates a "%[2]s" attribute
|
||||||
func %[1]s() hatmill.Attrib {
|
func %[1]s() hatmill.Attrib {
|
||||||
return hatmill.Attrib{
|
return hatmill.Attrib{
|
||||||
Key: "%[2]s",
|
Key: "%[2]s",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
},
|
||||||
|
|
||||||
|
"int": {
|
||||||
|
Template: `// %[1]s creates a "%[2]s" attribute
|
||||||
|
func %[1]s(value int) hatmill.Attrib {
|
||||||
|
return hatmill.Attrib{
|
||||||
|
Key: "%[2]s",
|
||||||
|
Value: strconv.FormatInt(int64(value), 10),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
Imports: []string{"strconv"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Def represents a top-level definition and its required imports.
|
||||||
|
type Def struct {
|
||||||
|
Source string
|
||||||
|
Imports []string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Spec interface {
|
||||||
|
Generate() Def
|
||||||
}
|
}
|
||||||
|
|
||||||
type AttribSpec struct {
|
type AttribSpec struct {
|
||||||
@ -43,35 +74,12 @@ type AttribSpec struct {
|
|||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AttribSpecs []AttribSpec
|
func (spec AttribSpec) Generate() Def {
|
||||||
|
template := attribTypes[spec.Type].Template
|
||||||
func (a AttribSpecs) Code() Code {
|
return Def{
|
||||||
var c Code
|
Source: fmt.Sprintf(template, identifier(spec.Name), spec.Name),
|
||||||
const hatmillImport = "gitlab.codemonkeysoftware.net/b/hatmill"
|
Imports: attribTypes[spec.Type].Imports,
|
||||||
|
|
||||||
c.Imports = append(c.Imports, hatmillImport)
|
|
||||||
for _, spec := range a {
|
|
||||||
c.Defs = append(c.Defs, spec.Generate())
|
|
||||||
}
|
}
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
type ElemSpecs []ElemSpec
|
|
||||||
|
|
||||||
func (e ElemSpecs) Code() Code {
|
|
||||||
var c Code
|
|
||||||
const hatmillImport = "gitlab.codemonkeysoftware.net/b/hatmill"
|
|
||||||
|
|
||||||
c.Imports = append(c.Imports, hatmillImport)
|
|
||||||
for _, spec := range e {
|
|
||||||
c.Defs = append(c.Defs, spec.Generate())
|
|
||||||
}
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
func (def AttribSpec) Generate() string {
|
|
||||||
template := attribTypes[def.Type]
|
|
||||||
return fmt.Sprintf(template, identifier(def.Name), def.Name)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ElemSpec struct {
|
type ElemSpec struct {
|
||||||
@ -79,7 +87,7 @@ type ElemSpec struct {
|
|||||||
Void bool `json:"void"`
|
Void bool `json:"void"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (def ElemSpec) Generate() string {
|
func (spec ElemSpec) Generate() Def {
|
||||||
const (
|
const (
|
||||||
parentTemplate = `// %[1]s creates a <%[2]s> element.
|
parentTemplate = `// %[1]s creates a <%[2]s> element.
|
||||||
func %[1]s(attribs ...hatmill.Attrib) func(children ...hatmill.Term) hatmill.ParentElement {
|
func %[1]s(attribs ...hatmill.Attrib) func(children ...hatmill.Term) hatmill.ParentElement {
|
||||||
@ -105,48 +113,52 @@ func (def ElemSpec) Generate() string {
|
|||||||
)
|
)
|
||||||
|
|
||||||
template := parentTemplate
|
template := parentTemplate
|
||||||
if def.Void {
|
if spec.Void {
|
||||||
template = voidTemplate
|
template = voidTemplate
|
||||||
}
|
}
|
||||||
return fmt.Sprintf(template, identifier(def.Name), def.Name)
|
return Def{
|
||||||
|
Source: fmt.Sprintf(template, identifier(spec.Name), spec.Name),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Specs struct {
|
func Render(defs []Def, pkgName string) ([]byte, error) {
|
||||||
Attributes AttribSpecs `json:"attributes"`
|
|
||||||
Elements ElemSpecs `json:"elements"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Code is a very slight abstraction of a source code file.
|
|
||||||
type Code struct {
|
|
||||||
Package string
|
|
||||||
Imports []string
|
|
||||||
Defs []string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c Code) Bytes() ([]byte, error) {
|
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
buf.WriteString(`// GENERATED BY gitlab.codemonkeysoftware.net/b/hatmill/internal/codegen
|
buf.WriteString(`// GENERATED BY gitlab.codemonkeysoftware.net/b/hatmill/internal/codegen
|
||||||
// DO NOT EDIT!
|
// DO NOT EDIT!
|
||||||
|
|
||||||
`)
|
`)
|
||||||
fmt.Fprintln(buf, "package ", c.Package)
|
fmt.Fprintln(buf, "package ", pkgName)
|
||||||
for _, imp := range c.Imports {
|
buf.WriteString(`import "gitlab.codemonkeysoftware.net/b/hatmill"
|
||||||
|
`)
|
||||||
|
|
||||||
|
// Print each import only once.
|
||||||
|
imports := make(map[string]struct{})
|
||||||
|
for _, def := range defs {
|
||||||
|
for _, imp := range def.Imports {
|
||||||
|
imports[imp] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for imp := range imports {
|
||||||
fmt.Fprintf(buf, "import \"%s\"\n", imp)
|
fmt.Fprintf(buf, "import \"%s\"\n", imp)
|
||||||
}
|
}
|
||||||
for _, def := range c.Defs {
|
|
||||||
buf.WriteString(def)
|
for _, def := range defs {
|
||||||
}
|
buf.WriteString(def.Source)
|
||||||
return format.Source(buf.Bytes())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Coder interface {
|
formatted, err := format.Source(buf.Bytes())
|
||||||
Code() Code
|
if err != nil {
|
||||||
|
err = fmt.Errorf("generated invalid code: %s\nSource code:\n%s", err, buf)
|
||||||
|
}
|
||||||
|
return formatted, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func WriteCodeFile(c Coder, path, pkg string) error {
|
func WriteCodeFile(specs []Spec, path, pkgName string) error {
|
||||||
code := c.Code()
|
var defs []Def
|
||||||
code.Package = pkg
|
for _, spec := range specs {
|
||||||
b, err := code.Bytes()
|
defs = append(defs, spec.Generate())
|
||||||
|
}
|
||||||
|
b, err := Render(defs, pkgName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -166,19 +178,32 @@ func main() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var specs Specs
|
var specs struct {
|
||||||
|
AttribSpecs []AttribSpec `json:"attributes"`
|
||||||
|
ElemSpecs []ElemSpec `json:"elements"`
|
||||||
|
}
|
||||||
|
|
||||||
err = json.Unmarshal(input, &specs)
|
err = json.Unmarshal(input, &specs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = WriteCodeFile(specs.Attributes, *attribPath, *attribPkg)
|
var attribSpecs []Spec
|
||||||
|
for _, spec := range specs.AttribSpecs {
|
||||||
|
attribSpecs = append(attribSpecs, spec)
|
||||||
|
}
|
||||||
|
err = WriteCodeFile(attribSpecs, *attribPath, *attribPkg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = WriteCodeFile(specs.Elements, *elemPath, *elemPkg)
|
var elemSpecs []Spec
|
||||||
|
for _, spec := range specs.ElemSpecs {
|
||||||
|
elemSpecs = append(elemSpecs, spec)
|
||||||
|
}
|
||||||
|
err = WriteCodeFile(elemSpecs, *elemPath, *elemPkg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user