107 lines
1.9 KiB
Go
107 lines
1.9 KiB
Go
|
package gluatemplate
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"fmt"
|
||
|
"github.com/yuin/gopher-lua"
|
||
|
"text/template"
|
||
|
)
|
||
|
|
||
|
func Loader(L *lua.LState) int {
|
||
|
tb := L.NewTable()
|
||
|
L.SetFuncs(tb, map[string]lua.LGFunction{
|
||
|
"dostring": doString,
|
||
|
"dofile": doFile,
|
||
|
})
|
||
|
L.Push(tb)
|
||
|
|
||
|
return 1
|
||
|
}
|
||
|
|
||
|
// render
|
||
|
func doString(L *lua.LState) int {
|
||
|
tmplcontent := L.CheckString(1)
|
||
|
var dict interface{}
|
||
|
|
||
|
tmpl, err := template.New("T").Parse(tmplcontent)
|
||
|
if err != nil {
|
||
|
L.Push(lua.LNil)
|
||
|
L.Push(lua.LString(err.Error()))
|
||
|
return 2
|
||
|
}
|
||
|
|
||
|
if L.GetTop() >= 2 {
|
||
|
dict = toGoValue(L.CheckTable(2))
|
||
|
}
|
||
|
|
||
|
var b bytes.Buffer
|
||
|
if err := tmpl.Execute(&b, dict); err != nil {
|
||
|
L.Push(lua.LNil)
|
||
|
L.Push(lua.LString(err.Error()))
|
||
|
return 2
|
||
|
}
|
||
|
s := b.String()
|
||
|
|
||
|
L.Push(lua.LString(s))
|
||
|
return 1
|
||
|
}
|
||
|
|
||
|
func doFile(L *lua.LState) int {
|
||
|
tmplfile := L.CheckString(1)
|
||
|
var dict interface{}
|
||
|
|
||
|
tmpl, err := template.ParseFiles(tmplfile)
|
||
|
if err != nil {
|
||
|
L.Push(lua.LNil)
|
||
|
L.Push(lua.LString(err.Error()))
|
||
|
return 2
|
||
|
}
|
||
|
|
||
|
if L.GetTop() >= 2 {
|
||
|
dict = toGoValue(L.CheckTable(2))
|
||
|
}
|
||
|
|
||
|
var b bytes.Buffer
|
||
|
if err := tmpl.Execute(&b, dict); err != nil {
|
||
|
L.Push(lua.LNil)
|
||
|
L.Push(lua.LString(err.Error()))
|
||
|
return 2
|
||
|
}
|
||
|
s := b.String()
|
||
|
|
||
|
L.Push(lua.LString(s))
|
||
|
return 1
|
||
|
}
|
||
|
|
||
|
// This code refers to https://github.com/yuin/gluamapper/blob/master/gluamapper.go
|
||
|
func toGoValue(lv lua.LValue) interface{} {
|
||
|
switch v := lv.(type) {
|
||
|
case *lua.LNilType:
|
||
|
return nil
|
||
|
case lua.LBool:
|
||
|
return bool(v)
|
||
|
case lua.LString:
|
||
|
return string(v)
|
||
|
case lua.LNumber:
|
||
|
return float64(v)
|
||
|
case *lua.LTable:
|
||
|
maxn := v.MaxN()
|
||
|
if maxn == 0 { // table
|
||
|
ret := make(map[interface{}]interface{})
|
||
|
v.ForEach(func(key, value lua.LValue) {
|
||
|
keystr := fmt.Sprint(toGoValue(key))
|
||
|
ret[keystr] = toGoValue(value)
|
||
|
})
|
||
|
return ret
|
||
|
} else { // array
|
||
|
ret := make([]interface{}, 0, maxn)
|
||
|
for i := 1; i <= maxn; i++ {
|
||
|
ret = append(ret, toGoValue(v.RawGetInt(i)))
|
||
|
}
|
||
|
return ret
|
||
|
}
|
||
|
default:
|
||
|
return v
|
||
|
}
|
||
|
}
|