diff --git a/LICENSE.md b/LICENSE.md index 201ef1d..a53d88f 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,4 +1,5 @@ Copyright (c) 2015, Joker +Copyright (c) 2020, Gerasimos Maropoulos All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/cmd/jade/go_ast_wstr.go b/cmd/jade/go_ast_wstr.go index d948039..497c43c 100644 --- a/cmd/jade/go_ast_wstr.go +++ b/cmd/jade/go_ast_wstr.go @@ -110,7 +110,7 @@ func (ws *writeStrings) fillConstNode(decl []ast.Decl) { for _, v := range ws.constSlice { constNode.Specs = append(constNode.Specs, &ast.ValueSpec{ Names: []*ast.Ident{ - &ast.Ident{Name: v.name}, + {Name: v.name}, }, Values: []ast.Expr{ &ast.BasicLit{Kind: 9, Value: "`" + v.str + "`"}, // 9 => string diff --git a/go.mod b/go.mod index 81826e3..9ff10f3 100644 --- a/go.mod +++ b/go.mod @@ -5,3 +5,5 @@ require ( github.com/valyala/bytebufferpool v1.0.0 golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf ) + +go 1.13 diff --git a/go.sum b/go.sum index 0ca4334..66270fa 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,5 @@ github.com/Joker/hpp v1.0.0 h1:65+iuJYdRXv/XyN62C1uEmmOx3432rNG/rKlX6V7Kkc= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -8,5 +7,4 @@ golang.org/x/net v0.0.0-20190327091125-710a502c58a2 h1:17UhVDrPb40BH5k6cyeb2V/7Q golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf h1:++r/Kj1CfG42p6XntDItK1TfB5V6Vq/baDeKvV1q5gY= golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= diff --git a/jade_parse.go b/jade_parse.go index e725828..8423ca1 100644 --- a/jade_parse.go +++ b/jade_parse.go @@ -1,7 +1,6 @@ package jade import ( - "io/ioutil" "log" "os" "path/filepath" @@ -444,47 +443,40 @@ func (t *Tree) parseSubFile(path string) *ListNode { var incTree = New(path) incTree.block = t.block incTree.mixin = t.mixin - wd, _ := os.Getwd() - dir, file := filepath.Split(path) - if dir != "" && dir != "./" { - os.Chdir(dir) - } - - _, err := incTree.Parse(t.read(file)) + _, err := incTree.Parse(t.read(path)) if err != nil { d, _ := os.Getwd() t.errorf(`in '%s' subtemplate '%s': parseSubFile() error: %s`, d, path, err) } - os.Chdir(wd) return incTree.Root } +var extensions = [...]string{".jade", ".pug", ".js", ".css", ".tpl", ".md"} + func (t *Tree) read(path string) []byte { + currentTmplDir, _ := filepath.Split(t.Name) + path = currentTmplDir + path + var ( bb []byte - ext string err error ) - switch ext = filepath.Ext(path); ext { - case ".jade", ".pug", ".js", ".css", ".tpl", ".md": - bb, err = ioutil.ReadFile(path) - case "": - if _, err = os.Stat(path + ".jade"); os.IsNotExist(err) { - if _, err = os.Stat(path + ".pug"); os.IsNotExist(err) { - wd, _ := os.Getwd() - t.errorf("in '%s' subtemplate '%s': file path error: '.jade' or '.pug' file required", wd, path) - } else { - ext = ".pug" - } - } else { - ext = ".jade" + + ext := filepath.Ext(path) + + for _, s := range extensions { + if s == ext { + bb, err = t.ReadFunc(path) + break + } + + if bb, err = t.ReadFunc(path + s); err == nil { + break } - bb, err = ioutil.ReadFile(path + ext) - default: - t.errorf(`file extension %s is not supported`, ext) } + if err != nil { wd, _ := os.Getwd() t.errorf(`%s work dir: %s `, err, wd) diff --git a/parse.go b/parse.go index df14ede..2702b69 100644 --- a/parse.go +++ b/parse.go @@ -6,14 +6,20 @@ package jade import ( "fmt" + "io/ioutil" "runtime" ) // Tree is the representation of a single parsed template. type Tree struct { - Name string // name of the template represented by the tree. - Root *ListNode // top-level root of the tree. - text string // text parsed to create the template (or its parent) + Name string // name of the template represented by the tree. + // ReadFunc is used to read files that are required when parsing a template (e.g. extends $file). + // Set to a custom reader to override the default behavior from reading by system directory. + // + // See https://github.com/kataras/iris/issues/1450. + ReadFunc func(path string) ([]byte, error) + Root *ListNode // top-level root of the tree. + text string // text parsed to create the template (or its parent) // Parsing only; cleared after parse. lex *lexer @@ -30,9 +36,10 @@ func (t *Tree) Copy() *Tree { return nil } return &Tree{ - Name: t.Name, - Root: t.Root.CopyList(), - text: t.text, + Name: t.Name, + ReadFunc: t.ReadFunc, + Root: t.Root.CopyList(), + text: t.text, } } @@ -137,9 +144,15 @@ func (t *Tree) Parse(text []byte) (tree *Tree, err error) { // New allocates a new parse tree with the given name. func New(name string) *Tree { + return NewWithReadFunc(name, ioutil.ReadFile) +} + +// NewWithReadFunc same as `New` but it overrides the template's contents reader. +func NewWithReadFunc(name string, readFunc func(string) ([]byte, error)) *Tree { return &Tree{ - Name: name, - mixin: map[string]*MixinNode{}, - block: map[string]*ListNode{}, + Name: name, + ReadFunc: readFunc, + mixin: map[string]*MixinNode{}, + block: map[string]*ListNode{}, } }