diff --git a/README.md b/README.md
index e953a17..36b992b 100644
--- a/README.md
+++ b/README.md
@@ -1,17 +1,19 @@
# FET
-FET is a go template engineer that can translate code to `html/template` code.
+FET is a go template engineer that can translate code to `html/template` code.
## Why FET
+
FET means Friendly, Easily for Templating.`html/template` has a basic support for templating, but it's not easy to use, so you need FET.
+
- Expression support
- Use `incldue` with defined variables scopes
- Use `extends` inherit base template with defined variables scopes
- Extends support for `for` loop, e.g
## Document
-
-[Document](https://github.com/fefit/fet/wiki/Wiki)
+
+[Document](https://github.com/fefit/fet/wiki/Wiki)
[中文文档](https://github.com/fefit/fet/wiki/%E4%B8%AD%E6%96%87%E6%96%87%E6%A1%A3)
@@ -26,7 +28,7 @@ it's more like the php template engineer smarty.
```
- blocks for inherit
-
+
```php
{%block "header"%}
some code here
@@ -40,13 +42,13 @@ it's more like the php template engineer smarty.
```
- loop, do not support keyword `break` `continue`
-
+
```php
// for Gofet mode
{%for item,key in list%}
// output
{%/for%}
-
+
{%for i = 0, j = 10; i < j; i++%}
// output
{%/for%}
@@ -61,19 +63,19 @@ it's more like the php template engineer smarty.
```
- if condition
-
+
```php
{%if $num > 100%}
-
+
{%elseif $num < 50%}
-
+
{%else%}
-
+
{%/if%}
```
- output
-
+
```php
{%$item.url%}
```
@@ -85,20 +87,20 @@ it's more like the php template engineer smarty.
```
- variable define
-
+
```php
{%$title = "this is a title"%}
```
-- capture
-
+- capture
+
```php
- {%capture "hello"%}
- {%/capture%}
+ {%capture "hello"%}
+ {%/capture%}
{%$fet.capture.hello%}
```
-- static variables
+- static variables
```php
{%$fet.capture.xxx%}
@@ -107,80 +109,84 @@ it's more like the php template engineer smarty.
{%$fet.config.templateDir%}
{%$fet.config.compileDir%}
{%$fet.now%}
+ {%$fet.debug%} // will output all the variables that assigned in the template to the js devtools's Console panel.
```
-- special variables
+- special variables
```php
{%$ROOT%} // will output $
{%$fet%} // will output .
```
### Expression
-
-1. operators
- `+ - * / % ! ** == >= <= != && || & ^`
+
+1. operators
+ `+ - * / % ! ** == >= <= != && || & ^`
2. keyword operators
- `and` && `or` || `not` ! `eq` == `ne` != `gt` > `ge` >= `lt` < `le` <=
- `bitor` for "|"
+ `and` && `or` || `not` ! `eq` == `ne` != `gt` > `ge` >= `lt` < `le` <=
+ `bitor` for "|"
-3. pipe
- `|` pipeline funcs
- `:` set arguments for pipeline funcs
+3. pipe
+ `|` pipeline funcs
+ `:` set arguments for pipeline funcs
-4. numbers
- hex: `0xffff`
- octal: `0o777`
- binary: `0b1000`
- scientific notation `1e10`
+4. numbers
+ hex: `0xffff`
+ octal: `0o777`
+ binary: `0b1000`
+ scientific notation `1e10`
-Be careful of the `and` and `or` operators, they don't have short circuit with conditions.
+Be careful of the `and` and `or` operators, they don't have short circuit with conditions.
-### Characters concat
- ```php
- {% $sayHello = "world" %}
- {% "hello `$sayHello`"%} // output "hello world"
- ```
- use ` `` ` for variable or expression in strings. do not use `+`.
-
-
-### Func Maps
- - Math
- `min` `max` `floor` `ceil`
-
- - Helpers
- `number_format` `truncate`
-
- - Assert
- `empty`
-
- - Length
- `count`
-
- - Output
- `safe`
- - [view more in funcs.go](./lib/funcs/funcs.go)
-
-### Config types.Mode
- - types.Smarty
- the variable and field must begin with `$`, use `foreach` tag for loops.
-
-
- - types.Gofet
- the variable and field mustn't begin with `$`, use `for` tag for loops.
+### Characters concat
+
+```php
+{% $sayHello = "world" %}
+{% "hello `$sayHello`"%} // output "hello world"
+```
+
+use ` `` ` for variable or expression in strings. do not use `+`.
+
+### Func Maps
+
+- Math
+ `min` `max` `floor` `ceil`
+
+- Helpers
+ `number_format` `truncate`
+
+- Assert
+ `empty`
+
+- Length
+ `count`
+
+- Output
+ `safe`
+- [view more in funcs.go](./lib/funcs/funcs.go)
+
+### Config types.Mode
+
+- types.Smarty
+ the variable and field must begin with `$`, use `foreach` tag for loops.
+
+* types.Gofet
+ the variable and field mustn't begin with `$`, use `for` tag for loops.
### In development
- ```bash
- # install command line tool `fetc`
- go get -v github.com/fefit/fetc
- # then init the config, will make a config file `fet.config.json`
- fetc init
- # then watch the file change, compile your fet template file immediately
- fetc watch
- ```
+```bash
+# install command line tool `fetc`
+go get -v github.com/fefit/fetc
+# then init the config, will make a config file `fet.config.json`
+fetc init
+# then watch the file change, compile your fet template file immediately
+fetc watch
+```
### Demo code
+
```go
package main
@@ -198,7 +204,7 @@ func main(){
CompileDir: "views", // default "templates_c",
Ignores: []string{"inc/*"}, // ignore compile,paths and files that will be included and extended. use filepath.Match() method.
UcaseField: false, // default false, if true will auto uppercase field name to uppercase.
- CompileOnline: false, // default false, you should compile your template files offline
+ CompileOnline: false, // default false, you should compile your template files offline
Glob: false, // default false, if true, will add {{define "xxx"}}{{end}} to wrap the compiled content,"xxx" is the relative pathname base on your templateDir, without the file extname.
AutoRoot: false, // default false,if true, if the variable is not assign in the scope, will treat it as the root field of template data, otherwise you need use '$ROOT' to index the data field.
Mode: types.Smarty, // default types.Smarty, also can be "types.Gofet"
@@ -215,49 +221,47 @@ func main(){
}
```
-### API
+
+### API
#### static methods
-- `fet.LoadConf(configFile string) (*types.FetConfig, error)`
-
- if you use the command line `fetc` build a config file `fet.config.json`, then you can use `fet.LoadConf` to get the config.
+- `fet.LoadConf(configFile string) (*types.FetConfig, error)`
+
+ if you use the command line `fetc` build a config file `fet.config.json`, then you can use `fet.LoadConf` to get the config.
+
+- `fet.New(config *types.FetConfig) (instance *Fet, error)`
-- `fet.New(config *types.FetConfig) (instance *Fet, error)`
-
get a fet instance.
#### instance methods
-- `instance.Compile(tpl string, createFile bool) (result string, err error) `
-
- compile a template file, if `createFile` is true, will create the compiled file.
+- `instance.Compile(tpl string, createFile bool) (result string, err error)`
-- `instance.CompileAll() error`
-
- compile all files need to compile.
+ compile a template file, if `createFile` is true, will create the compiled file.
+- `instance.CompileAll() error`
-- `instance.Display(tpl string, data interface{}, output io.Wirter) error`
+ compile all files need to compile.
- render the parsed html code into `output`.
+* `instance.Display(tpl string, data interface{}, output io.Wirter) error`
-- `instance.Fetch(tpl string, data interface{}) (result string, err error)`
+ render the parsed html code into `output`.
- just get the parsed `string` code, it always use `CompileOnline` mode.
+* `instance.Fetch(tpl string, data interface{}) (result string, err error)`
+ just get the parsed `string` code, it always use `CompileOnline` mode.
## Use in project
-1. `compile mode`
-
+1. `compile mode`
+
just use fet compile your template files offline, and add the FuncMap `lib/funcs/funcs.go` to your project.
-2. `install mode`
+2. `install mode`
install `fet`,and use `fet.Display(tpl, data, io.Writer)` to render the template file.
-
## License
[MIT License](./LICENSE).
diff --git a/fet.go b/fet.go
index 4adcec2..2e4ac5d 100644
--- a/fet.go
+++ b/fet.go
@@ -379,6 +379,7 @@ func (node *Node) Compile(options *CompileOptions) (result string, err error) {
addVarPrefix := "$"
isSmartyMode := conf.Mode == types.Smarty
compiledText := ""
+ noDelimit := false
if isSmartyMode {
addVarPrefix = ""
}
@@ -424,15 +425,19 @@ func (node *Node) Compile(options *CompileOptions) (result string, err error) {
if contains(currentScopes, name) {
symbol = " = "
}
- if compiledText, err = gen.Build(ast, genOptions, parseOptions); err != nil {
+ if compiledText, noDelimit, err = gen.Build(ast, genOptions, parseOptions); err != nil {
return "", node.halt("compile error:%s", err.Error())
}
result = delimit(addVarPrefix + name + localNS + symbol + compiledText)
} else {
- if compiledText, err = gen.Build(ast, genOptions, parseOptions); err != nil {
+ if compiledText, noDelimit, err = gen.Build(ast, genOptions, parseOptions); err != nil {
return "", node.halt("compile error:%s", err.Error())
}
- result = delimit(compiledText)
+ if noDelimit {
+ result = compiledText
+ } else {
+ result = delimit(compiledText)
+ }
}
case SingleType:
isInclude := name == "include"
@@ -474,7 +479,7 @@ func (node *Node) Compile(options *CompileOptions) (result string, err error) {
if key != defField {
value := prop.Raw
if ast, expErr := exp.Parse(value); expErr == nil {
- if compiledText, err = gen.Build(ast, genOptions, parseOptions); err != nil {
+ if compiledText, noDelimit, err = gen.Build(ast, genOptions, parseOptions); err != nil {
return "", node.halt("compile error:%s", err.Error())
}
incLocalScopes = append(incLocalScopes, "$"+key)
@@ -503,7 +508,7 @@ func (node *Node) Compile(options *CompileOptions) (result string, err error) {
if expErr != nil {
return "", toError(expErr)
}
- compiledText, err = gen.Build(ast, genOptions, parseOptions)
+ compiledText, noDelimit, err = gen.Build(ast, genOptions, parseOptions)
if err != nil {
return "", node.halt("parse 'foreach' error:%s", err.Error())
}
@@ -526,7 +531,7 @@ func (node *Node) Compile(options *CompileOptions) (result string, err error) {
if expErr != nil {
return "", toError(expErr)
}
- compiledText, err = gen.Build(ast, genOptions, parseOptions)
+ compiledText, noDelimit, err = gen.Build(ast, genOptions, parseOptions)
if err != nil {
return "", node.halt("parse 'for' error:%s", err.Error())
}
@@ -544,7 +549,7 @@ func (node *Node) Compile(options *CompileOptions) (result string, err error) {
if expErr != nil {
return "", toError(expErr)
}
- compiledText, err = gen.Build(ast, genOptions, parseOptions)
+ compiledText, noDelimit, err = gen.Build(ast, genOptions, parseOptions)
if err != nil {
return "", node.halt("parse 'for' statement error:%s", err.Error())
}
@@ -561,7 +566,7 @@ func (node *Node) Compile(options *CompileOptions) (result string, err error) {
if expErr != nil {
return "", toError(expErr)
}
- compiledText, err = gen.Build(ast, genOptions, parseOptions)
+ compiledText, noDelimit, err = gen.Build(ast, genOptions, parseOptions)
if err != nil {
return "", node.halt("parse 'if' statement error:%s", err.Error())
}
@@ -590,7 +595,7 @@ func (node *Node) Compile(options *CompileOptions) (result string, err error) {
if expErr != nil {
return "", toError(expErr)
}
- compiledText, err = gen.Build(ast, genOptions, parseOptions)
+ compiledText, noDelimit, err = gen.Build(ast, genOptions, parseOptions)
if err != nil {
return "", node.halt("parse 'if' statement error:%s", err.Error())
}
@@ -617,7 +622,7 @@ func (node *Node) Compile(options *CompileOptions) (result string, err error) {
if expErr != nil {
return "", toError(expErr)
}
- compiledText, err = gen.Build(ast, genOptions, parseOptions)
+ compiledText, noDelimit, err = gen.Build(ast, genOptions, parseOptions)
if err != nil {
return "", node.halt("parse 'for' loop error:%s", err.Error())
}
@@ -626,7 +631,7 @@ func (node *Node) Compile(options *CompileOptions) (result string, err error) {
return "", toError(expErr)
}
var code string
- if code, err = gen.Build(ast, genOptions, parseOptions); err != nil {
+ if code, noDelimit, err = gen.Build(ast, genOptions, parseOptions); err != nil {
return "", node.halt("parse 'for' loops error:%s", err.Error())
}
compiledText += " = " + code
diff --git a/lib/funcs/funcs.go b/lib/funcs/funcs.go
index 49e8976..06dfce4 100644
--- a/lib/funcs/funcs.go
+++ b/lib/funcs/funcs.go
@@ -14,15 +14,28 @@ import (
"github.com/fefit/dateutil"
)
+// OperatorNumberFn func for operate numbers
type OperatorNumberFn func(interface{}, interface{}) interface{}
+
+// OperatorIntFn func for int types
type OperatorIntFn func(int64, int64) int64
+
+// ResultNumberFn wrap the OperatorNumberFn
type ResultNumberFn func(args ...interface{}) interface{}
+
+// ResultIntFn wrap the OperatorIntFn
type ResultIntFn func(args ...interface{}) int64
+
+// JSON alias a json type
type JSON map[string]interface{}
+
+// LoopChan used for "for" blocks
type LoopChan struct {
Chan chan int
Loop int
}
+
+// CaptureData used for Capture
type CaptureData struct {
Variables map[string]interface{}
Data interface{}
@@ -33,11 +46,15 @@ func (lc *LoopChan) init() {
lc.Loop = -1
_, _ = lc.Next()
}
+
+// Close close the loop chan
func (lc *LoopChan) Close() (string, error) {
lc.Loop = -1
close(lc.Chan)
return "", nil
}
+
+// Next goto the next step
func (lc *LoopChan) Next() (string, error) {
lc.Loop++
lc.Chan <- lc.Loop
@@ -61,51 +78,51 @@ func Inject() template.FuncMap {
if a, b, err := toIntNumbers(a, b); err == nil {
return a + b
}
- if a, b, err := toFloatNumbers(a, b); err == nil {
- return a + b
- } else {
+ if a, b, err := toFloatNumbers(a, b); err != nil {
panic(makeHaltInfo("plus(+)", err))
+ } else {
+ return a + b
}
}, true)
injects["INJECT_MINUS"] = generateNumberFunc(func(a, b interface{}) interface{} {
if a, b, err := toIntNumbers(a, b); err == nil {
return a - b
}
- if a, b, err := toFloatNumbers(a, b); err == nil {
- return a - b
- } else {
+ if a, b, err := toFloatNumbers(a, b); err != nil {
panic(makeHaltInfo("minus(-)", err))
+ } else {
+ return a - b
}
}, true)
injects["INJECT_MULTIPLE"] = generateNumberFunc(func(a, b interface{}) interface{} {
if a, b, err := toIntNumbers(a, b); err == nil {
return a * b
}
- if a, b, err := toFloatNumbers(a, b); err == nil {
- return a * b
- } else {
+ if a, b, err := toFloatNumbers(a, b); err != nil {
panic(makeHaltInfo("multiple(*)", err))
+ } else {
+ return a * b
}
}, true)
injects["INJECT_DIVIDE"] = generateNumberFunc(func(a, b interface{}) interface{} {
- if a, b, err := toFloatNumbers(a, b); err == nil {
- return a / b
- } else {
+ if a, b, err := toFloatNumbers(a, b); err != nil {
panic(makeHaltInfo("divide(/)", err))
+ } else {
+ return a / b
}
}, false)
injects["INJECT_MOD"] = generateNumberFunc(func(a, b interface{}) interface{} {
- if a, b, err := toFloatNumbers(a, b); err == nil {
- return math.Mod(a, b)
- } else {
+ if a, b, err := toFloatNumbers(a, b); err != nil {
panic(makeHaltInfo("mod(%)", err))
+ } else {
+ return math.Mod(a, b)
}
}, false)
injects["INJECT_POWER"] = generateNumberFunc(func(a, b interface{}) interface{} {
- if a, b, err := toFloatNumbers(a, b); err == nil {
- return math.Pow(a, b)
- } else {
+ if a, b, err := toFloatNumbers(a, b); err != nil {
panic(makeHaltInfo("power(**)", err))
+ } else {
+ return math.Pow(a, b)
}
}, false)
injects["INJECT_BITAND"] = generateIntFunc(func(a, b int64) int64 {
@@ -144,13 +161,13 @@ func Helpers() template.FuncMap {
}
return b
}
- if a, b, err := toFloatNumbers(a, b); err == nil {
+ if a, b, err := toFloatNumbers(a, b); err != nil {
+ panic(makeHaltInfo("min", err))
+ } else {
if a < b {
return a
}
return b
- } else {
- panic(makeHaltInfo("min", err))
}
}, true)
helpers["max"] = generateNumberFunc(func(a, b interface{}) interface{} {
@@ -160,13 +177,13 @@ func Helpers() template.FuncMap {
}
return b
}
- if a, b, err := toFloatNumbers(a, b); err == nil {
+ if a, b, err := toFloatNumbers(a, b); err != nil {
+ panic(makeHaltInfo("max", err))
+ } else {
if a > b {
return a
}
return b
- } else {
- panic(makeHaltInfo("max", err))
}
}, true)
// format
@@ -188,6 +205,7 @@ func Helpers() template.FuncMap {
helpers["count"] = count
helpers["mrange"] = makeRange
helpers["json_encode"] = jsonEncode
+ helpers["json_decode"] = jsonDecode
// slice, don't add this line since go1.13
helpers["slice"] = slice
return helpers
@@ -567,7 +585,7 @@ func stringify(target interface{}) template.HTML {
return template.HTML(result)
}
-func jsonEncode(str string, args ...interface{}) JSON {
+func jsonDecode(str string, args ...interface{}) JSON {
if len(args) == 1 {
fns := template.FuncMap{
"stringify": stringify,
@@ -590,6 +608,14 @@ func jsonEncode(str string, args ...interface{}) JSON {
return result
}
+func jsonEncode(data interface{}, args ...interface{}) string {
+ b, err := json.Marshal(data)
+ if err != nil {
+ panic(err)
+ }
+ return string(b[:])
+}
+
func concat(str string, args ...interface{}) string {
var builder strings.Builder
builder.WriteString(str)
diff --git a/lib/funcs/funcs_test.go b/lib/funcs/funcs_test.go
index f73be24..beabe38 100644
--- a/lib/funcs/funcs_test.go
+++ b/lib/funcs/funcs_test.go
@@ -140,3 +140,14 @@ func TestTrim(t *testing.T) {
assert.Equal(t, "bc", trim(baseChar, "a"))
assert.Equal(t, "c", trim(baseChar, "ab"))
}
+
+func TestJsonEncode(t *testing.T) {
+ m := map[string]interface{}{
+ "hello": "world",
+ }
+ a := []int{1, 2, 3}
+ s := "it's a string"
+ assert.Equal(t, `{"hello":"world"}`, jsonEncode(m))
+ assert.Equal(t, `[1,2,3]`, jsonEncode(a))
+ assert.Equal(t, `"`+s+`"`, jsonEncode(s))
+}
diff --git a/lib/generator/generator.go b/lib/generator/generator.go
index 8171907..e2b7069 100644
--- a/lib/generator/generator.go
+++ b/lib/generator/generator.go
@@ -94,14 +94,14 @@ var (
)
// Build for code
-func (gen *Generator) Build(node *Node, options *GenOptions, parseOptions *ParseOptions) (string, error) {
+func (gen *Generator) Build(node *Node, options *GenOptions, parseOptions *ParseOptions) (result string, noDelimit bool, err error) {
// conf := gen.Conf
var str strings.Builder
options.Str = &str
- if err := gen.parseRecursive(node, options, parseOptions); err != nil {
- return "", err
+ if noDelimit, err = gen.parseRecursive(node, options, parseOptions); err != nil {
+ return "", noDelimit, err
}
- return str.String(), nil
+ return str.String(), noDelimit, nil
}
func (gen *Generator) wrapToFloat(node *Node, options *GenOptions, parseOptions *ParseOptions, op string) error {
@@ -119,7 +119,7 @@ func (gen *Generator) wrapToFloat(node *Node, options *GenOptions, parseOptions
str.WriteString(fn)
str.WriteString(SPACE)
}
- err := gen.parseRecursive(node, options, parseOptions)
+ _, err := gen.parseRecursive(node, options, parseOptions)
if isNative {
str.WriteString(")")
}
@@ -191,7 +191,7 @@ func (gen *Generator) parseIdentifier(options *GenOptions, parseOptions *ParseOp
return nil
}
-func (gen *Generator) parseRecursive(node *Node, options *GenOptions, parseOptions *ParseOptions) (err error) {
+func (gen *Generator) parseRecursive(node *Node, options *GenOptions, parseOptions *ParseOptions) (noDelimit bool, err error) {
str, exp := options.Str, options.Exp
noObjectIndex, parseConf, captures := parseOptions.NoObjectIndex, parseOptions.Conf, parseOptions.Captures
curType := node.Type
@@ -220,8 +220,8 @@ func (gen *Generator) parseRecursive(node *Node, options *GenOptions, parseOptio
express := string(runes[pos.StartIndex+1 : pos.EndIndex-1])
ast, _ := exp.Parse(express)
var inner string
- if inner, err = gen.Build(ast, options, parseOptions); err != nil {
- return err
+ if inner, noDelimit, err = gen.Build(ast, options, parseOptions); err != nil {
+ return noDelimit, err
}
str.WriteString(inner)
i = pos.EndIndex + 1
@@ -245,7 +245,7 @@ func (gen *Generator) parseRecursive(node *Node, options *GenOptions, parseOptio
if name == "$fet" {
str.WriteString(".")
} else if err = gen.parseIdentifier(options, parseOptions, name, ExpName); err != nil {
- return err
+ return noDelimit, err
}
}
} else if curType == "object" {
@@ -287,6 +287,11 @@ func (gen *Generator) parseRecursive(node *Node, options *GenOptions, parseOptio
switch names[0] {
case "now":
str.WriteString("now")
+ case "debug":
+ noDelimit = true
+ if parseConf.Debug {
+ str.WriteString(``)
+ }
default:
panic("unsupport static variable $fet." + names[0])
}
@@ -322,7 +327,7 @@ func (gen *Generator) parseRecursive(node *Node, options *GenOptions, parseOptio
} else {
addIndexFn()
if err = gen.parseIdentifier(options, parseOptions, string(t.Stat.Values), ObjectRoot); err != nil {
- return err
+ return noDelimit, err
}
isParsed = true
}
@@ -330,8 +335,8 @@ func (gen *Generator) parseRecursive(node *Node, options *GenOptions, parseOptio
}
if !isParsed {
addIndexFn()
- if err = gen.parseRecursive(root, options, parseOptions); err != nil {
- return err
+ if noDelimit, err = gen.parseRecursive(root, options, parseOptions); err != nil {
+ return noDelimit, err
}
}
if !isStatic {
@@ -363,17 +368,17 @@ func (gen *Generator) parseRecursive(node *Node, options *GenOptions, parseOptio
str.WriteString("\"")
} else {
if err = gen.parseIdentifier(options, parseOptions, ident, ObjectField); err != nil {
- return err
+ return noDelimit, err
}
}
} else {
- if err = gen.parseRecursive(cur, options, parseOptions); err != nil {
- return err
+ if noDelimit, err = gen.parseRecursive(cur, options, parseOptions); err != nil {
+ return noDelimit, err
}
}
} else {
- if err = gen.parseRecursive(cur, options, parseOptions); err != nil {
- return err
+ if noDelimit, err = gen.parseRecursive(cur, options, parseOptions); err != nil {
+ return noDelimit, err
}
}
}
@@ -392,7 +397,7 @@ func (gen *Generator) parseRecursive(node *Node, options *GenOptions, parseOptio
if t, ok := root.Token.(*e.IdentifierToken); ok {
name := string(t.Stat.Values)
if err = gen.parseIdentifier(options, parseOptions, name, FuncName); err != nil {
- return err
+ return noDelimit, err
}
if _, ok := NoNeedIndexFuncs[name]; ok {
parseOptions.NoObjectIndex = true
@@ -401,8 +406,8 @@ func (gen *Generator) parseRecursive(node *Node, options *GenOptions, parseOptio
}
}
if !isParsed {
- if err = gen.parseRecursive(root, options, parseOptions); err != nil {
- return err
+ if noDelimit, err = gen.parseRecursive(root, options, parseOptions); err != nil {
+ return noDelimit, err
}
}
str.WriteString(SPACE)
@@ -410,8 +415,8 @@ func (gen *Generator) parseRecursive(node *Node, options *GenOptions, parseOptio
if i > 0 {
str.WriteString(SPACE)
}
- if err = gen.parseRecursive(args[i], options, parseOptions); err != nil {
- return err
+ if noDelimit, err = gen.parseRecursive(args[i], options, parseOptions); err != nil {
+ return noDelimit, err
}
}
str.WriteString(")")
@@ -423,18 +428,18 @@ func (gen *Generator) parseRecursive(node *Node, options *GenOptions, parseOptio
str.WriteString(SPACE)
}
if err = gen.wrapToFloat(node.Left, options, parseOptions, op); err != nil {
- return err
+ return noDelimit, err
}
str.WriteString(SPACE)
if err = gen.wrapToFloat(node.Right, options, parseOptions, op); err != nil {
- return err
+ return noDelimit, err
}
str.WriteString(")")
}
if isNot {
str.WriteString(")")
}
- return nil
+ return noDelimit, nil
}
// New for Generator