Skip to content

Commit dc670fb

Browse files
author
Alan Johnson
committed
Reorganized files.
1 parent 21f8b0e commit dc670fb

11 files changed

+255
-217
lines changed

block.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package egon
2+
3+
import (
4+
"bytes"
5+
)
6+
7+
// Block represents an element of the template.
8+
type Block interface {
9+
write(*bytes.Buffer) error
10+
}
11+
12+
// isTextBlock returns true if the block is a text block.
13+
func isTextBlock(b Block) bool {
14+
_, ok := b.(*TextBlock)
15+
return ok
16+
}

code_block.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package egon
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
)
7+
8+
// CodeBlock represents a Go code block that is printed as-is to the template.
9+
type CodeBlock struct {
10+
Pos Pos
11+
Content string
12+
}
13+
14+
func (b *CodeBlock) write(buf *bytes.Buffer) error {
15+
b.Pos.write(buf)
16+
fmt.Fprintln(buf, b.Content)
17+
return nil
18+
}

declaration_block.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package egon
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
)
7+
8+
// DeclarationBlock represents a block that declaration the function signature.
9+
type DeclarationBlock struct {
10+
Pos Pos
11+
ParamName string
12+
ParamType string
13+
}
14+
15+
func (b *DeclarationBlock) write(buf *bytes.Buffer) error {
16+
b.Pos.write(buf)
17+
fmt.Fprintf(buf, "%s %s", b.ParamName, b.ParamType)
18+
return nil
19+
}

header_block.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package egon
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
)
7+
8+
// HeaderBlock represents a Go code block that is printed at the top of the template.
9+
type HeaderBlock struct {
10+
Pos Pos
11+
Content string
12+
}
13+
14+
func (b *HeaderBlock) write(buf *bytes.Buffer) error {
15+
b.Pos.write(buf)
16+
fmt.Fprintln(buf, b.Content)
17+
return nil
18+
}

package.go

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package egon
2+
3+
import (
4+
"bytes"
5+
"errors"
6+
"fmt"
7+
"go/ast"
8+
"go/parser"
9+
"go/token"
10+
"io"
11+
)
12+
13+
// Package represents a collection of ego templates in a single package.
14+
type Package struct {
15+
Name string
16+
Templates []*Template
17+
}
18+
19+
// Write writes out the package header and templates to a writer.
20+
func (p *Package) Write(w io.Writer) error {
21+
if err := p.writeHeader(w); err != nil {
22+
return err
23+
}
24+
25+
for _, t := range p.Templates {
26+
if err := t.Write(w); err != nil {
27+
return fmt.Errorf("template: %s: %s", t.Path, err)
28+
}
29+
}
30+
31+
return nil
32+
}
33+
34+
// Writes the package name and consolidated header blocks.
35+
func (p *Package) writeHeader(w io.Writer) error {
36+
if p.Name == "" {
37+
return errors.New("package name required")
38+
}
39+
40+
// Write naive header first.
41+
var buf bytes.Buffer
42+
fmt.Fprintf(&buf, "package %s\n", p.Name)
43+
for _, t := range p.Templates {
44+
for _, b := range t.headerBlocks() {
45+
b.write(&buf)
46+
}
47+
}
48+
49+
// Parse header into Go AST.
50+
f, err := parser.ParseFile(token.NewFileSet(), "ego.go", buf.String(), parser.ImportsOnly)
51+
if err != nil {
52+
fmt.Println(buf.String())
53+
return fmt.Errorf("writeHeader: %s", err)
54+
}
55+
56+
// Reset buffer.
57+
buf.Reset()
58+
59+
// Add note that the file is auto-generated
60+
fmt.Fprintf(&buf, "// Generated by egon.\n")
61+
fmt.Fprintf(&buf, "// DO NOT EDIT\n\n")
62+
63+
fmt.Fprintf(&buf, "package %s\n", p.Name)
64+
65+
// Write deduped imports.
66+
var decls = map[string]bool{`:"fmt"`: true, `:"io"`: true}
67+
fmt.Fprint(&buf, "import (\n")
68+
fmt.Fprintln(&buf, `"fmt"`)
69+
for _, t := range p.Templates {
70+
if t.hasEscapedPrintBlock() {
71+
fmt.Fprintln(&buf, `"html"`)
72+
decls["html"] = true
73+
break
74+
}
75+
}
76+
fmt.Fprintln(&buf, `"io"`)
77+
78+
for _, d := range f.Decls {
79+
d, ok := d.(*ast.GenDecl)
80+
if !ok || d.Tok != token.IMPORT {
81+
continue
82+
}
83+
84+
for _, s := range d.Specs {
85+
s := s.(*ast.ImportSpec)
86+
var id string
87+
if s.Name != nil {
88+
id = s.Name.Name
89+
}
90+
id += ":" + s.Path.Value
91+
92+
// Ignore any imports which have already been imported.
93+
if decls[id] {
94+
continue
95+
}
96+
decls[id] = true
97+
98+
// Otherwise write it.
99+
if s.Name == nil {
100+
fmt.Fprintf(&buf, "%s\n", s.Path.Value)
101+
} else {
102+
fmt.Fprintf(&buf, "%s %s\n", s.Name.Name, s.Path.Value)
103+
}
104+
}
105+
}
106+
fmt.Fprint(&buf, ")\n")
107+
108+
// Write out to writer.
109+
buf.WriteTo(w)
110+
111+
return nil
112+
}

pos.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package egon
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
)
7+
8+
// Pos represents a position in a given file.
9+
type Pos struct {
10+
Path string
11+
LineNo int
12+
}
13+
14+
func (p *Pos) write(buf *bytes.Buffer) {
15+
if p != nil && p.Path != "" && p.LineNo > 0 {
16+
fmt.Fprintf(buf, "//line %s:%d\n", p.Path, p.LineNo)
17+
}
18+
}

print_block.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package egon
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
)
7+
8+
// PrintBlock represents a block that will HTML escape the contents before outputting
9+
type PrintBlock struct {
10+
Pos Pos
11+
Content string
12+
}
13+
14+
func (b *PrintBlock) write(buf *bytes.Buffer) error {
15+
b.Pos.write(buf)
16+
fmt.Fprintf(buf, `_, _ = fmt.Fprint(w, html.EscapeString(fmt.Sprintf("%%v", %s)))`+"\n", b.Content)
17+
return nil
18+
}

raw_print_block.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package egon
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
)
7+
8+
// RawPrintBlock represents a block of the template that is printed out to the writer.
9+
type RawPrintBlock struct {
10+
Pos Pos
11+
Content string
12+
}
13+
14+
func (b *RawPrintBlock) write(buf *bytes.Buffer) error {
15+
b.Pos.write(buf)
16+
fmt.Fprintf(buf, `_, _ = fmt.Fprintf(w, "%%v", %s)`+"\n", b.Content)
17+
return nil
18+
}

0 commit comments

Comments
 (0)