Skip to content

Commit

Permalink
Merge branch 'refactor'
Browse files Browse the repository at this point in the history
  • Loading branch information
Wuvist committed May 28, 2019
2 parents 14e3a83 + 16f7f00 commit 8a54986
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 66 deletions.
25 changes: 11 additions & 14 deletions gorazor/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import (
)

const (
go_extension = ".go"
gz_extension = ".gohtml"
goExtension = ".go"
gzExtension = ".gohtml"
)

// Generate from input to output file,
// GenFile generate from input to output file,
// gofmt will trigger an error if it fails.
func GenFile(input string, output string, options Option) error {
outdir := filepath.Dir(output)
Expand All @@ -26,30 +26,27 @@ func GenFile(input string, output string, options Option) error {
return generate(input, output, options)
}

// Generate from directory to directory, Find all the files with extension
// GenFolder generate from directory to directory, Find all the files with extension
// of .gohtml and generate it into target dir.
func GenFolder(indir string, outdir string, options Option) (err error) {
if !exists(indir) {
return errors.New("Input directory does not exsits")
} else {
if err != nil {
return err
}
return errors.New("Input directory does not exsit")
}

//Make it
if !exists(outdir) {
os.MkdirAll(outdir, 0775)
}

incdir_abs, _ := filepath.Abs(indir)
outdir_abs, _ := filepath.Abs(outdir)
incdirAbs, _ := filepath.Abs(indir)
outdirAbs, _ := filepath.Abs(outdir)

paths := []string{}

visit := func(path string, info os.FileInfo, err error) error {
if !info.IsDir() {
//Just do file with exstension .gohtml
if !strings.HasSuffix(path, gz_extension) {
if !strings.HasSuffix(path, goExtension) {
return nil
}
filename := filepath.Base(path)
Expand All @@ -64,8 +61,8 @@ func GenFolder(indir string, outdir string, options Option) (err error) {
fun := func(path string, res chan<- string) {
//adjust with the abs path, so that we keep the same directory hierarchy
input, _ := filepath.Abs(path)
output := strings.Replace(input, incdir_abs, outdir_abs, 1)
output = strings.Replace(output, gz_extension, go_extension, -1)
output := strings.Replace(input, incdirAbs, outdirAbs, 1)
output = strings.Replace(output, gzExtension, goExtension, -1)
err := GenFile(path, output, options)
if err != nil {
res <- fmt.Sprintf("%s -> %s", path, output)
Expand Down
41 changes: 21 additions & 20 deletions gorazor/gogen.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"strings"
)

// GorazorNamespace is alias to "github.com/sipin/gorazor/gorazor"
var GorazorNamespace = `"github.com/sipin/gorazor/gorazor"`

//------------------------------ Compiler ------------------------------ //
Expand All @@ -33,11 +34,13 @@ func getValStr(e interface{}) string {
}
}

// Part represent gorazor template parts
type Part struct {
ptype int
value string
}

// Compiler generate go code for gorazor template
type Compiler struct {
ast *Ast
buf string //the final result
Expand All @@ -51,23 +54,23 @@ type Compiler struct {
file string
}

func (self *Compiler) addPart(part Part) {
if len(self.parts) == 0 {
self.parts = append(self.parts, part)
func (cp *Compiler) addPart(part Part) {
if len(cp.parts) == 0 {
cp.parts = append(cp.parts, part)
return
}
last := &self.parts[len(self.parts)-1]
last := &cp.parts[len(cp.parts)-1]
if last.ptype == part.ptype {
last.value += part.value
} else {
self.parts = append(self.parts, part)
cp.parts = append(cp.parts, part)
}
}

func (self *Compiler) genPart() {
func (cp *Compiler) genPart() {
res := ""

for _, p := range self.parts {
for _, p := range cp.parts {
if p.ptype == CMKP && p.value != "" {
// do some escapings
for strings.HasSuffix(p.value, "\n") {
Expand All @@ -83,12 +86,12 @@ func (self *Compiler) genPart() {
res += p.value
}
}
self.buf = res
cp.buf = res
}

func makeCompiler(ast *Ast, options Option, input string) *Compiler {
dir := filepath.Base(filepath.Dir(input))
file := strings.Replace(filepath.Base(input), gz_extension, "", 1)
file := strings.Replace(filepath.Base(input), gzExtension, "", 1)
if options["NameNotChange"] == nil {
file = Capitalize(file)
}
Expand All @@ -107,7 +110,6 @@ func (cp *Compiler) visitBLK(child interface{}, ast *Ast) {
}

func (cp *Compiler) visitMKP(child interface{}, ast *Ast) {

cp.addPart(Part{CMKP, getValStr(child)})
}

Expand Down Expand Up @@ -352,7 +354,6 @@ func (cp *Compiler) processLayout() {
if cp.layout != "" {
foot += ")"
}
foot += "\n}\n"
cp.buf += foot
}

Expand All @@ -365,19 +366,19 @@ func (cp *Compiler) visit() {

cp.imports[`"bytes"`] = true
head := "package " + pack + "\n import (\n"
for k, _ := range cp.imports {
for k := range cp.imports {
head += k + "\n"
}
head += "\n)\n func " + fun + "("
for idx, p := range cp.params {
head += p
if idx != len(cp.params)-1 {
head += ", "
}
}
head += ") string {\n var _buffer bytes.Buffer\n"

funcArgs := strings.Join(cp.params, ", ")

head += "\n)\n"
head += "func " + fun + "(" + funcArgs + ") string {\n"
head += "var _buffer bytes.Buffer\n"
cp.buf = head + cp.buf
cp.processLayout()
foot := "\n}\n"
cp.buf += foot
}

func run(path string, Options Option) (*Compiler, error) {
Expand Down
27 changes: 14 additions & 13 deletions gorazor/layout.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,42 @@ package gorazor

import "sync"

//For gorazor just process on single one gohtml file now
//we use an singleton map to keep layout relationship
//Not a good solution but works
type LayManager struct {
layOutMap map[string][]string
fileLayOut map[string]string
// LayoutManager is the layout manager
type LayoutManager struct {
// For gorazor just process on single one gohtml file now
// we use an singleton map to keep layout relationship
// Not a good solution but works
layoutMap map[string][]string
}

var single *LayManager = nil
var single *LayoutManager
var mutexLock sync.RWMutex

// LayoutArgs returns arguments of given layout file
func LayoutArgs(file string) []string {
mutexLock.RLock()
defer mutexLock.RUnlock()
manager := newManager()
if args, ok := manager.layOutMap[file]; ok {
if args, ok := manager.layoutMap[file]; ok {
return args
}
return []string{}
}

// SetLayout arguments for layout file
func SetLayout(file string, args []string) {
mutexLock.Lock()
manager := newManager()
manager.layOutMap[file] = args
manager.layoutMap[file] = args
mutexLock.Unlock()
}

func newManager() *LayManager {
func newManager() *LayoutManager {
if single != nil {
return single
}
lay := &LayManager{}
lay.layOutMap = map[string][]string{}
lay.fileLayOut = map[string]string{}
lay := &LayoutManager{}
lay.layoutMap = map[string][]string{}
single = lay
return lay
}
7 changes: 6 additions & 1 deletion gorazor/lexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ var typeStr = [...]string{
// NameNotChange bool
type Option map[string]interface{}

// TokenMatch store matched token
type TokenMatch struct {
Type int
Text string
Expand All @@ -71,7 +72,7 @@ func rec(reg string) *regexp.Regexp {
return regexp.MustCompile("^" + reg)
}

// The order is important
// Tests stores TokenMatch list, TokenMatch order is important
var Tests = []TokenMatch{
TokenMatch{EMAIL, "EMAIL", rec(`([a-zA-Z0-9.%]+@[a-zA-Z0-9.\-]+\.(?:ca|co\.uk|com|edu|net|org))\b`)},
TokenMatch{HTML_TAG_OPEN, "HTML_TAG_OPEN", rec(`(<[a-zA-Z@]+?[^>]*?["a-zA-Z]*>)`)},
Expand All @@ -85,6 +86,7 @@ var Tests = []TokenMatch{
TokenMatch{CONTENT, "CONTENT", rec(`([^\s})@.]+?)`)},
}

// Token represent a token in code
type Token struct {
Text string
TypeStr string
Expand All @@ -93,13 +95,15 @@ type Token struct {
Pos int
}

// P for print
func (token Token) P() {
textStr := strings.Replace(token.Text, "\n", "\\n", -1)
textStr = strings.Replace(textStr, "\t", "\\t", -1)
fmt.Printf("Token: %-20s Location:(%-2d %-2d) Value: %s\n",
token.TypeStr, token.Line, token.Pos, textStr)
}

// Lexer for gorazor
type Lexer struct {
Text string
Matches []TokenMatch
Expand Down Expand Up @@ -151,6 +155,7 @@ func makeToken(val string, tokenType int) Token {
return Token{val, typeStr[tokenType], tokenType, 0, 0}
}

// Scan return gorazor doc as list for Token
func (lexer *Lexer) Scan() ([]Token, error) {
toks := []Token{}
text := strings.Replace(lexer.Text, "\r\n", "\n", -1)
Expand Down
28 changes: 15 additions & 13 deletions gorazor/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const (
EXP
)

// PAIRS stores the symbols that must come in pairs
var PAIRS = map[int]int{
AT_STAR_OPEN: AT_STAR_CLOSE,
BRACE_OPEN: BRACE_CLOSE,
Expand All @@ -26,13 +27,15 @@ var PAIRS = map[int]int{
AT_COLON: NEWLINE,
}

// Ast stores the abstract syntax tree
type Ast struct {
Parent *Ast
Children []interface{}
Mode int
TagName string
}

// ModeStr return string representation of ast mode
func (ast *Ast) ModeStr() string {
switch ast.Mode {
case PRG:
Expand Down Expand Up @@ -133,16 +136,17 @@ func (ast *Ast) closest(mode int, tag string) *Ast {
func (ast *Ast) hasNonExp() bool {
if ast.Mode != EXP {
return true
} else {
for _, c := range ast.Children {
if v, ok := c.(*Ast); ok {
if v.hasNonExp() {
return true
}
}

for _, c := range ast.Children {
if v, ok := c.(*Ast); ok {
if v.hasNonExp() {
return true
}
return false
}
return false
}

return false
}

Expand Down Expand Up @@ -175,6 +179,7 @@ func (ast *Ast) debug(depth int, max int) {
fmt.Println("]]")
}

// Parser parse the gorazor file
type Parser struct {
ast *Ast
root *Ast
Expand Down Expand Up @@ -243,7 +248,7 @@ func (parser *Parser) advanceUntilNot(tokenType int) []Token {
}

func (parser *Parser) advanceUntil(token Token, start, end, startEsc, endEsc int) ([]Token, error) {
var prev *Token = nil
var prev *Token
next := &token
res := []Token{}
nstart := 0
Expand Down Expand Up @@ -389,10 +394,8 @@ func (parser *Parser) handleBLK(token Token) error {
parser.ast.addChild(*next)
parser.skipToken()
}

case AT_STAR_OPEN:
parser.advanceUntil(token, AT_STAR_OPEN, AT_STAR_CLOSE, AT, AT)

case AT_COLON:
parser.subParse(token, MKP, true)

Expand All @@ -408,7 +411,7 @@ func (parser *Parser) handleBLK(token Token) error {
if err != nil {
return err
}
for idx, _ := range subTokens {
for idx := range subTokens {
if subTokens[idx].Type == AT {
subTokens[idx].Type = CONTENT
}
Expand Down Expand Up @@ -489,7 +492,6 @@ func (parser *Parser) handleEXP(token Token) error {
if (prev != nil && prev.Type == AT) || (next != nil && next.Type == IDENTIFIER) {
parser.ast = parser.ast.Parent
}

case BRACE_OPEN:
prev := parser.prevToken(0)
//todo: Is this really neccessary?
Expand All @@ -499,7 +501,6 @@ func (parser *Parser) handleEXP(token Token) error {
parser.deferToken(token)
parser.ast = parser.ast.beget(BLK, "")
}

case PERIOD:
next := parser.peekToken(0)
if next != nil && (next.Type == IDENTIFIER || next.Type == KEYWORD ||
Expand All @@ -521,6 +522,7 @@ func (parser *Parser) handleEXP(token Token) error {
return nil
}

// Run execute the parser
func (parser *Parser) Run() error {
curr := Token{"UNDEF", "UNDEF", UNDEF, 0, 0}
parser.root = parser.ast
Expand Down
Loading

0 comments on commit 8a54986

Please sign in to comment.