feat: simplified evaling.
This commit is contained in:
parent
5a82d721bd
commit
0c7f2d9df0
20 changed files with 247 additions and 301 deletions
|
@ -1,10 +1,10 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"surdeus.su/util/tpp/httpx"
|
"surdeus.su/util/tpp/server"
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
httpx.Tool.Run(os.Args[1:])
|
server.Tool.Run(os.Args[1:])
|
||||||
}
|
}
|
||||||
|
|
6
go.mod
6
go.mod
|
@ -1,9 +1,11 @@
|
||||||
module surdeus.su/util/tpp
|
module surdeus.su/util/tpp
|
||||||
|
|
||||||
go 1.21.7
|
go 1.22.3
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/d5/tengo/v2 v2.17.0
|
github.com/d5/tengo/v2 v2.17.0
|
||||||
github.com/gomarkdown/markdown v0.0.0-20240419095408-642f0ee99ae2
|
github.com/gomarkdown/markdown v0.0.0-20240419095408-642f0ee99ae2
|
||||||
surdeus.su/core/cli v0.0.2
|
surdeus.su/core/cli v0.1.2
|
||||||
)
|
)
|
||||||
|
|
||||||
|
require surdeus.su/core/xgo v0.5.0 // indirect
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -4,3 +4,7 @@ github.com/gomarkdown/markdown v0.0.0-20240419095408-642f0ee99ae2 h1:yEt5djSYb4i
|
||||||
github.com/gomarkdown/markdown v0.0.0-20240419095408-642f0ee99ae2/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA=
|
github.com/gomarkdown/markdown v0.0.0-20240419095408-642f0ee99ae2/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA=
|
||||||
surdeus.su/core/cli v0.0.2 h1:RdHHk3/Fhwxz9PjaE+vTlCuF9KmhrmNUb5y4oqulrYI=
|
surdeus.su/core/cli v0.0.2 h1:RdHHk3/Fhwxz9PjaE+vTlCuF9KmhrmNUb5y4oqulrYI=
|
||||||
surdeus.su/core/cli v0.0.2/go.mod h1:UKwCmcSX+x7XX9aF3gOaaAaJcJA3gtUmL4vdnM43+fM=
|
surdeus.su/core/cli v0.0.2/go.mod h1:UKwCmcSX+x7XX9aF3gOaaAaJcJA3gtUmL4vdnM43+fM=
|
||||||
|
surdeus.su/core/cli v0.1.2 h1:qPzjawqPyZsO4Z5SaA1u141recVE65yioA83Qs7Jecs=
|
||||||
|
surdeus.su/core/cli v0.1.2/go.mod h1:r9JtQz3aEJzpYzMaNUNQHJoYkoWKNPi047qhd5uGlmA=
|
||||||
|
surdeus.su/core/xgo v0.5.0 h1:/Rk3scfFkoSb0qjHRlkUNOp9sr/fd7wAvCiT4fBRo+U=
|
||||||
|
surdeus.su/core/xgo v0.5.0/go.mod h1:6C/AHbjfvAMvt3TOzLB4eIZ40eU3ahJXtdY+kr4yXoc=
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
package httpx
|
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
package httpx
|
|
||||||
|
|
||||||
import "github.com/d5/tengo/v2"
|
|
||||||
import "github.com/d5/tengo/v2/stdlib"
|
|
||||||
import "surdeus.su/util/tpp/paths"
|
|
||||||
|
|
||||||
var Modules = map[string]tengo.Importable{
|
|
||||||
"paths": paths.Module,
|
|
||||||
}
|
|
||||||
|
|
||||||
var Stdlib = stdlib.GetModuleMap(stdlib.AllModuleNames()...)
|
|
||||||
|
|
||||||
type ModuleGetter struct{}
|
|
||||||
|
|
||||||
func (m *ModuleGetter) Get(
|
|
||||||
name string,
|
|
||||||
) tengo.Importable {
|
|
||||||
module, exist := Modules[name]
|
|
||||||
if exist {
|
|
||||||
return module
|
|
||||||
}
|
|
||||||
|
|
||||||
return Stdlib.Get(name)
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
package httpx
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/d5/tengo/v2"
|
|
||||||
"net/http"
|
|
||||||
"io"
|
|
||||||
//"log"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Request struct {
|
|
||||||
tengo.ObjectImpl
|
|
||||||
*http.Request
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Request) TypeName() string {
|
|
||||||
return "*http.Request"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Request) String() string {
|
|
||||||
return "*http.Request{...}"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Request) IndexGet(
|
|
||||||
index tengo.Object,
|
|
||||||
) (tengo.Object, error) {
|
|
||||||
key, ok := tengo.ToString(index)
|
|
||||||
if !ok {
|
|
||||||
return nil, tengo.ErrInvalidIndexValueType
|
|
||||||
}
|
|
||||||
|
|
||||||
switch key {
|
|
||||||
case "url" :
|
|
||||||
return &URL{
|
|
||||||
URL: r.URL,
|
|
||||||
}, nil
|
|
||||||
case "body" :
|
|
||||||
bts, err := io.ReadAll(r.Body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &tengo.Bytes{
|
|
||||||
Value: bts,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nothing found.
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
76
httpx/url.go
76
httpx/url.go
|
@ -1,76 +0,0 @@
|
||||||
package httpx
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/d5/tengo/v2"
|
|
||||||
"net/url"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ = tengo.Object(&Values{})
|
|
||||||
type Values struct {
|
|
||||||
tengo.ObjectImpl
|
|
||||||
url.Values
|
|
||||||
}
|
|
||||||
|
|
||||||
func (vs *Values) TypeName() string {
|
|
||||||
return "*url.Values"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (vs *Values) String() string {
|
|
||||||
return fmt.Sprintf("%v", vs.Values)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (vs *Values) IndexGet(
|
|
||||||
index tengo.Object,
|
|
||||||
) (tengo.Object, error) {
|
|
||||||
key, ok := tengo.ToString(index)
|
|
||||||
if !ok {
|
|
||||||
return nil, tengo.ErrInvalidIndexValueType
|
|
||||||
}
|
|
||||||
|
|
||||||
val, ok := vs.Values[key]
|
|
||||||
if !ok {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
arr := make([]tengo.Object, len(val))
|
|
||||||
for i, v := range val {
|
|
||||||
arr[i], _ = tengo.FromInterface(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &tengo.Array{Value: arr}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type URL struct {
|
|
||||||
tengo.ObjectImpl
|
|
||||||
*url.URL
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *URL) TypeName() string {
|
|
||||||
return "<URL>"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *URL) String() string {
|
|
||||||
return u.URL.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *URL) IndexGet(
|
|
||||||
index tengo.Object,
|
|
||||||
) (tengo.Object, error) {
|
|
||||||
key, ok := tengo.ToString(index)
|
|
||||||
if !ok {
|
|
||||||
return nil, tengo.ErrInvalidIndexValueType
|
|
||||||
}
|
|
||||||
|
|
||||||
switch key {
|
|
||||||
case "path" :
|
|
||||||
return tengo.FromInterface(u.Path)
|
|
||||||
case "query" :
|
|
||||||
return &Values{
|
|
||||||
Values: u.Query(),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nothing found.
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
3
install.sh
Executable file
3
install.sh
Executable file
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
go install ./cmd/tpp/ ./cmd/tht/
|
19
main.go
19
main.go
|
@ -1,7 +1,6 @@
|
||||||
package tpp
|
package tpp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
//"fmt"
|
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
)
|
)
|
||||||
|
@ -31,7 +30,7 @@ func (pp *Preprocessor) Process(
|
||||||
filePath string,
|
filePath string,
|
||||||
data []byte,
|
data []byte,
|
||||||
) ([]byte, error) {
|
) ([]byte, error) {
|
||||||
var b bytes.Buffer
|
//var b bytes.Buffer
|
||||||
preCode := []byte(nil)
|
preCode := []byte(nil)
|
||||||
texts := [][]byte{}
|
texts := [][]byte{}
|
||||||
codes := [][]byte{}
|
codes := [][]byte{}
|
||||||
|
@ -72,15 +71,13 @@ func (pp *Preprocessor) Process(
|
||||||
codes = append(codes, code)
|
codes = append(codes, code)
|
||||||
|
|
||||||
data = data[idxEnd + len(pp.tags[1]):]
|
data = data[idxEnd + len(pp.tags[1]):]
|
||||||
/*if len(data) > 0 && data[0] == '\n' {
|
|
||||||
data = data[1:]
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
codeRets, err := pp.tengo.Eval(
|
ret, err := pp.tengo.Eval(
|
||||||
ctx,
|
ctx,
|
||||||
recompile,
|
recompile,
|
||||||
filePath,
|
filePath,
|
||||||
|
texts,
|
||||||
preCode,
|
preCode,
|
||||||
codes,
|
codes,
|
||||||
)
|
)
|
||||||
|
@ -88,14 +85,6 @@ func (pp *Preprocessor) Process(
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := range codeRets {
|
return ret, nil
|
||||||
b.Write(texts[i])
|
|
||||||
b.Write(codeRets[i])
|
|
||||||
}
|
|
||||||
if len(texts) > len(codeRets) {
|
|
||||||
b.Write(texts[len(codeRets)])
|
|
||||||
}
|
|
||||||
|
|
||||||
return b.Bytes(), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,8 @@ htmExt := func(c){
|
||||||
if c.is_compo {
|
if c.is_compo {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.pp.print(`
|
|
||||||
</body></html>
|
c.pp.print(`</body></html>`)
|
||||||
`)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exts := {
|
exts := {
|
||||||
|
@ -15,8 +14,10 @@ exts := {
|
||||||
}
|
}
|
||||||
|
|
||||||
export func(c){
|
export func(c){
|
||||||
url_path := c.http.request.url.path
|
ext := paths.ext(c.pp.filepath)
|
||||||
ext := paths.ext(url_path)
|
ext = paths.ext(
|
||||||
|
c.pp.filepath[:len(c.pp.filepath) - len(ext)]
|
||||||
|
)
|
||||||
|
|
||||||
cl := exts[ext]
|
cl := exts[ext]
|
||||||
if !is_undefined(cl) {
|
if !is_undefined(cl) {
|
||||||
|
|
|
@ -1,22 +1,25 @@
|
||||||
fmt := import("fmt")
|
fmt := import("fmt")
|
||||||
paths := import("paths")
|
paths := import("paths")
|
||||||
|
html := import("html").new_render()
|
||||||
|
|
||||||
htmExt := func(c){
|
htmExt := func(c){
|
||||||
if c.is_compo {
|
if c.is_compo {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fmt.println("shit")
|
c.pp.print(`<!doctype html><html>`)
|
||||||
c.pp.print(`
|
|
||||||
<!doctype html>
|
c.pp.print(html.head().body(
|
||||||
<html><head>
|
func(){
|
||||||
<script src="https://unpkg.com/htmx.org@1.9.2"></script>
|
|
||||||
`)
|
|
||||||
if c.title {
|
if c.title {
|
||||||
c.pp.printf(`<title>%s</title>`, c.title)
|
return html.title().body(c.title)
|
||||||
}
|
}
|
||||||
c.pp.print(`
|
}(),
|
||||||
</head><body>
|
html.script({
|
||||||
`)
|
src: `https://unpkg.com/htmx.org@1.9.2`
|
||||||
|
})
|
||||||
|
))
|
||||||
|
|
||||||
|
c.pp.print(`<body>`)
|
||||||
}
|
}
|
||||||
|
|
||||||
exts := {
|
exts := {
|
||||||
|
@ -25,8 +28,10 @@ exts := {
|
||||||
}
|
}
|
||||||
|
|
||||||
export func(c){
|
export func(c){
|
||||||
url_path := c.http.request.url.path
|
ext := paths.ext(c.pp.filepath)
|
||||||
ext := paths.ext(url_path)
|
ext = paths.ext(
|
||||||
|
c.pp.filepath[:len(c.pp.filepath) - len(ext)]
|
||||||
|
)
|
||||||
|
|
||||||
cl := exts[ext]
|
cl := exts[ext]
|
||||||
if cl {
|
if cl {
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
package httpx
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
//"github.com/d5/tengo/v2"
|
//"github.com/d5/tengo/v2"
|
||||||
"surdeus.su/util/tpp/mdx"
|
"surdeus.su/util/tpp/mdx"
|
||||||
"surdeus.su/util/tpp/htmlx"
|
//"surdeus.su/core/xgo/xmodules/htmlx"
|
||||||
|
"surdeus.su/core/xgo/xmodules/httpx"
|
||||||
|
"surdeus.su/core/xgo/xmodules"
|
||||||
"surdeus.su/util/tpp"
|
"surdeus.su/util/tpp"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -37,7 +39,7 @@ type Handler struct {
|
||||||
// between requests.
|
// between requests.
|
||||||
global any
|
global any
|
||||||
md *mdx.Markdown
|
md *mdx.Markdown
|
||||||
html *htmlx.HTML
|
indexSuffix string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the new Handler with
|
// Returns the new Handler with
|
||||||
|
@ -45,7 +47,7 @@ type Handler struct {
|
||||||
// preprocessor extension and the global value.
|
// preprocessor extension and the global value.
|
||||||
func NewHandler(
|
func NewHandler(
|
||||||
pp *tpp.Preprocessor,
|
pp *tpp.Preprocessor,
|
||||||
src, ext string,
|
src, ext, index string,
|
||||||
global any,
|
global any,
|
||||||
) *Handler {
|
) *Handler {
|
||||||
ret := &Handler{}
|
ret := &Handler{}
|
||||||
|
@ -53,6 +55,7 @@ func NewHandler(
|
||||||
ret.ext = ext
|
ret.ext = ext
|
||||||
ret.pp = pp
|
ret.pp = pp
|
||||||
ret.global = global
|
ret.global = global
|
||||||
|
ret.indexSuffix = index
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,26 +67,23 @@ func DefaultPP(mod string) *tpp.Preprocessor {
|
||||||
s *tpp.Script,
|
s *tpp.Script,
|
||||||
) {
|
) {
|
||||||
s.SetImportDir(mod)
|
s.SetImportDir(mod)
|
||||||
s.SetImports(&ModuleGetter{})
|
s.SetImports(xmodules.Modules)
|
||||||
s.EnableFileImport(true)
|
s.EnableFileImport(true)
|
||||||
|
|
||||||
s.Add("__http_request__", ctx.Value(KeyRequest))
|
s.Add("__http_request__", ctx.Value(KeyRequest))
|
||||||
s.Add("__global__", ctx.Value(KeyGlobal))
|
s.Add("__global__", ctx.Value(KeyGlobal))
|
||||||
s.Add("__markdown__", ctx.Value(KeyMarkdown))
|
s.Add("__markdown__", ctx.Value(KeyMarkdown))
|
||||||
s.Add("__html__", ctx.Value(KeyHTML))
|
|
||||||
}).SetPreCode(func(ctx context.Context) []byte {
|
}).SetPreCode(func(ctx context.Context) []byte {
|
||||||
return []byte(`
|
return []byte(`
|
||||||
markdown := func(...args) {
|
markdown := func(...args) {
|
||||||
pp.write_raw(__markdown__(args...))
|
pp.write_raw(__markdown__(args...))
|
||||||
}
|
}
|
||||||
http := immutable({
|
__http__ := immutable({
|
||||||
request : __http_request__
|
request : __http_request__
|
||||||
})
|
})
|
||||||
html := __html__
|
context.http = __http__
|
||||||
context.http = http
|
|
||||||
context.pp = pp
|
context.pp = pp
|
||||||
context.global = __global__
|
context.global = __global__
|
||||||
context.html = html
|
|
||||||
import("./pre")(context)
|
import("./pre")(context)
|
||||||
`)
|
`)
|
||||||
}).SetPostCode(func(ctx context.Context) []byte {
|
}).SetPostCode(func(ctx context.Context) []byte {
|
||||||
|
@ -99,10 +99,6 @@ func (h *Handler) SetMD(md *mdx.Markdown) *Handler {
|
||||||
h.md = md
|
h.md = md
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
func (h *Handler) SetHTML(html *htmlx.HTML) *Handler {
|
|
||||||
h.html = html
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *Handler) ServeHTTP(
|
func (h *Handler) ServeHTTP(
|
||||||
w http.ResponseWriter,
|
w http.ResponseWriter,
|
||||||
|
@ -118,8 +114,17 @@ func (h *Handler) ServeHTTP(
|
||||||
filepath.FromSlash(h.sourcePath),
|
filepath.FromSlash(h.sourcePath),
|
||||||
filepath.FromSlash(urlPath),
|
filepath.FromSlash(urlPath),
|
||||||
)
|
)
|
||||||
filePathTpp := filePath + h.ext
|
fileStat, err := os.Stat(filePath)
|
||||||
|
if err == nil {
|
||||||
|
if fileStat.IsDir() {
|
||||||
|
filePath = filepath.Join(
|
||||||
|
filePath,
|
||||||
|
h.indexSuffix,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
filePathTpp := filePath + h.ext
|
||||||
//log.Println("pth:", urlPath, filePathTpp)
|
//log.Println("pth:", urlPath, filePathTpp)
|
||||||
file, err := os.Open(filePathTpp)
|
file, err := os.Open(filePathTpp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -141,7 +146,7 @@ func (h *Handler) ServeHTTP(
|
||||||
ctx := context.WithValue(
|
ctx := context.WithValue(
|
||||||
r.Context(),
|
r.Context(),
|
||||||
KeyRequest,
|
KeyRequest,
|
||||||
&Request{
|
&httpx.Request{
|
||||||
Request: r,
|
Request: r,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -158,17 +163,10 @@ func (h *Handler) ServeHTTP(
|
||||||
h.md,
|
h.md,
|
||||||
)
|
)
|
||||||
|
|
||||||
ctx = context.WithValue(
|
|
||||||
ctx,
|
|
||||||
KeyHTML,
|
|
||||||
h.html,
|
|
||||||
)
|
|
||||||
|
|
||||||
// Setting before the code to let it change own
|
// Setting before the code to let it change own
|
||||||
// content type.
|
// content type?
|
||||||
contentType := mime.TypeByExtension(urlExt)
|
contentType := mime.TypeByExtension(urlExt)
|
||||||
w.Header().Set("Content-Type", contentType)
|
w.Header().Set("Content-Type", contentType)
|
||||||
|
|
||||||
processedData := fileData
|
processedData := fileData
|
||||||
if shouldProcess {
|
if shouldProcess {
|
||||||
processedData, err = h.pp.Process(
|
processedData, err = h.pp.Process(
|
|
@ -1,4 +1,4 @@
|
||||||
package httpx
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
||||||
|
@ -24,13 +24,14 @@ const (
|
||||||
// Simple PHP-like server implementation.
|
// Simple PHP-like server implementation.
|
||||||
var Tool = mtool.T("tht").Func(func(flags *mtool.Flags) {
|
var Tool = mtool.T("tht").Func(func(flags *mtool.Flags) {
|
||||||
var (
|
var (
|
||||||
addr, ext, src, mod string
|
addr, ext, src, mod, index string
|
||||||
)
|
)
|
||||||
|
|
||||||
flags.StringVar(&addr, "addr", ":3000", "address to serve at")
|
flags.StringVar(&addr, "addr", ":3000", "address to serve at")
|
||||||
flags.StringVar(&mod, "mod", "./mod", "path to store Tengo modules")
|
flags.StringVar(&mod, "mod", "./mod", "path to store Tengo modules")
|
||||||
flags.StringVar(&src, "src", "./src", "directory with source files")
|
flags.StringVar(&src, "src", "./src", "directory with source files")
|
||||||
flags.StringVar(&ext, "ext", ".tpp", "extension for TPP files")
|
flags.StringVar(&ext, "ext", ".tpp", "extension for TPP files")
|
||||||
|
flags.StringVar(&index, "index", "index.htm", "index file name")
|
||||||
|
|
||||||
flags.Parse()
|
flags.Parse()
|
||||||
|
|
||||||
|
@ -39,7 +40,7 @@ var Tool = mtool.T("tht").Func(func(flags *mtool.Flags) {
|
||||||
Addr: addr,
|
Addr: addr,
|
||||||
Handler: NewHandler(
|
Handler: NewHandler(
|
||||||
DefaultPP(mod),
|
DefaultPP(mod),
|
||||||
src, ext,
|
src, ext, index,
|
||||||
map[string] tengo.Object{},
|
map[string] tengo.Object{},
|
||||||
).SetMD(mdx.MakeDefaultMarkdown()),
|
).SetMD(mdx.MakeDefaultMarkdown()),
|
||||||
}
|
}
|
5
src/check.htm.tpp
Normal file
5
src/check.htm.tpp
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<main>shit</main>
|
||||||
|
{{
|
||||||
|
pp.print("cock")
|
||||||
|
}}
|
||||||
|
<main>later</main>
|
12
src/check/index.htm.tpp
Normal file
12
src/check/index.htm.tpp
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{{#
|
||||||
|
html := import("html").new_render()
|
||||||
|
}}
|
||||||
|
{{
|
||||||
|
h := html.main().body(
|
||||||
|
html.p().body(
|
||||||
|
"some paragraph shit"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
pp.print(h)
|
||||||
|
}}
|
11
src/incorrect.htm.tpp
Normal file
11
src/incorrect.htm.tpp
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
html := import("html").new_render()
|
||||||
|
|
||||||
|
pp.print(html.html().body(
|
||||||
|
html.head().body(
|
||||||
|
html.title().body(
|
||||||
|
"some title"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
html.body().body(
|
||||||
|
)
|
||||||
|
))
|
78
src/index.htm.tpp
Normal file
78
src/index.htm.tpp
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
{{#
|
||||||
|
context.title = "The example.site main page"
|
||||||
|
|
||||||
|
fmt := import("fmt")
|
||||||
|
html := import("html").new_render()
|
||||||
|
}}
|
||||||
|
|
||||||
|
<h1>This is the example page for the THT</h1>
|
||||||
|
{{
|
||||||
|
/*if !context.global.int {
|
||||||
|
context.global.int = 0
|
||||||
|
} else {
|
||||||
|
context.global.int++
|
||||||
|
}*/
|
||||||
|
|
||||||
|
if !context.global.val {
|
||||||
|
context.global.val = 1
|
||||||
|
} else {
|
||||||
|
context.global.val += 1
|
||||||
|
}
|
||||||
|
fmt.println("global: ", context.global)
|
||||||
|
req := context.http.request
|
||||||
|
q := req.url.query
|
||||||
|
// List checking.
|
||||||
|
list := []
|
||||||
|
rng := int(q.range[0])
|
||||||
|
fmt.println("range:", q.range)
|
||||||
|
if rng {
|
||||||
|
pp.print(`<ul name="range">`)
|
||||||
|
for i:=0 ; i < rng ; i++ {
|
||||||
|
pp.printf("<li>%d</li>", i)
|
||||||
|
}
|
||||||
|
pp.print("</ul>")
|
||||||
|
}
|
||||||
|
if q.name {
|
||||||
|
pp.print("<div id=\"name\">", q.name[0], "</div>")
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
<div name="counter">
|
||||||
|
{{ pp.print(context.global.val) }}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Hello, Cock!
|
||||||
|
</div>
|
||||||
|
<div check>
|
||||||
|
{{
|
||||||
|
pp.print(req.url.path)
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
<ul>{{
|
||||||
|
for v in list {
|
||||||
|
pp.print("<li>", v, "</li>")
|
||||||
|
}
|
||||||
|
}}</ul>
|
||||||
|
|
||||||
|
{{
|
||||||
|
vals := ["die", "with", "them", "as", "you", 1, "could", "do"]
|
||||||
|
pp.print(html.div({
|
||||||
|
id: "the-uniq-shit"
|
||||||
|
}).body(
|
||||||
|
html.ul(
|
||||||
|
).body(
|
||||||
|
func(){
|
||||||
|
ret := []
|
||||||
|
for i:=0 ; i<len(vals) ; i++{
|
||||||
|
ret += [html.li({
|
||||||
|
class: "someclass"
|
||||||
|
}).body(i, ": ", vals[i])]
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}()...
|
||||||
|
)
|
||||||
|
))
|
||||||
|
}}
|
||||||
|
|
||||||
|
<script src="/script.js" ></script>
|
||||||
|
|
||||||
|
<div></div>
|
|
@ -1,27 +1,31 @@
|
||||||
{{#
|
{{#
|
||||||
context.title = "The example.site main page"
|
context.title = "The example.site main page"
|
||||||
|
|
||||||
|
fmt := import("fmt")
|
||||||
|
html := import("html").new_render()
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
|
||||||
<h1>This is the example page for the THT</h1>
|
<h1>This is the example page for the THT</h1>
|
||||||
{{
|
{{
|
||||||
/*if !context.global.int {
|
pp.print(
|
||||||
context.global.int = 0
|
html.h1().body("This is the example page for THT")
|
||||||
} else {
|
)
|
||||||
context.global.int++
|
|
||||||
}*/
|
|
||||||
|
|
||||||
fmt := import("fmt")
|
|
||||||
if !context.global.val {
|
if !context.global.val {
|
||||||
context.global.val = 1
|
context.global.val = 1
|
||||||
} else {
|
} else {
|
||||||
context.global.val += 1
|
context.global.val += 1
|
||||||
}
|
}
|
||||||
fmt.println("global: ", context.global)
|
|
||||||
req := http.request
|
req
|
||||||
|
("global: ", context.global)
|
||||||
|
}}
|
||||||
|
|
||||||
|
{{
|
||||||
|
req := context.http.request
|
||||||
q := req.url.query
|
q := req.url.query
|
||||||
// List checking.
|
// List checking.
|
||||||
list := []
|
|
||||||
rng := int(q.range[0])
|
rng := int(q.range[0])
|
||||||
fmt.println("range:", q.range)
|
fmt.println("range:", q.range)
|
||||||
if rng {
|
if rng {
|
||||||
|
@ -35,43 +39,3 @@
|
||||||
pp.print("<div id=\"name\">", q.name[0], "</div>")
|
pp.print("<div id=\"name\">", q.name[0], "</div>")
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
<div name="counter">
|
|
||||||
{{ pp.print(context.global.val) }}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Hello, Cock!
|
|
||||||
</div>
|
|
||||||
<div check>
|
|
||||||
{{
|
|
||||||
pp.print(req.url.path)
|
|
||||||
}}
|
|
||||||
</div>
|
|
||||||
<ul>{{
|
|
||||||
for v in list {
|
|
||||||
pp.print("<li>", v, "</li>")
|
|
||||||
}
|
|
||||||
}}</ul>
|
|
||||||
|
|
||||||
{{
|
|
||||||
vals := ["die", "with", "them", "as", "you", 1, "could", "do"]
|
|
||||||
pp.print(html.div({
|
|
||||||
id: "the-uniq-shit"
|
|
||||||
}).body(
|
|
||||||
html.ul(
|
|
||||||
).body(
|
|
||||||
func(){
|
|
||||||
ret := []
|
|
||||||
for i:=0 ; i<len(vals) ; i++{
|
|
||||||
ret += [html.li({
|
|
||||||
class: "someclass"
|
|
||||||
}).body(i, ": ", vals[i])]
|
|
||||||
}
|
|
||||||
return ret
|
|
||||||
}()...
|
|
||||||
)
|
|
||||||
))
|
|
||||||
}}
|
|
||||||
|
|
||||||
<script src="/script.js" ></script>
|
|
||||||
|
|
||||||
<div></div>
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ This is the markdown example shit.
|
||||||
|
|
||||||
And even more text
|
And even more text
|
||||||
|
|
||||||
> Cheap is talk, show the code.
|
> Cheap is talk, show me the code.
|
||||||
|
|
||||||
(c) Linus Torvalds
|
(c) Linus Torvalds
|
||||||
|
|
||||||
|
|
94
tengo.go
94
tengo.go
|
@ -48,39 +48,30 @@ func (pp *Tengo) Eval(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
recompile bool,
|
recompile bool,
|
||||||
filePath string,
|
filePath string,
|
||||||
|
texts [][]byte,
|
||||||
preCode []byte,
|
preCode []byte,
|
||||||
codes [][]byte,
|
codes [][]byte,
|
||||||
) ([][]byte, error) {
|
) ([]byte, error) {
|
||||||
var fullCodeBuf bytes.Buffer
|
var fullCodeBuf, retBuf bytes.Buffer
|
||||||
const retHead = `
|
const retHead = `
|
||||||
context := {}
|
context := {}
|
||||||
__ret_one__ := bytes("")
|
|
||||||
pp := immutable({
|
pp := immutable({
|
||||||
filepath: __filepath__,
|
filepath: __pp_filepath__,
|
||||||
printf : func(format, ...vals) {
|
printf : __pp_printf__,
|
||||||
__ret_one__ += __sprintf__(format, vals...)
|
print : __pp_print__,
|
||||||
},
|
println : __pp_println__,
|
||||||
|
write_raw : __pp_write_raw__
|
||||||
print : func(...vals) {
|
|
||||||
__ret_one__ += __sprint__(vals...)
|
|
||||||
},
|
|
||||||
println : func(...vals) {
|
|
||||||
__ret_one__ += __sprintln__(vals...)
|
|
||||||
},
|
|
||||||
write_raw : func(bts) {
|
|
||||||
__ret_one__ += bytes(bts)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
`
|
`
|
||||||
|
|
||||||
const retSeparator = `
|
const retSeparator = `
|
||||||
__separate__(__ret_one__)
|
__separate__()
|
||||||
__ret_one__ = ""
|
|
||||||
`
|
`
|
||||||
rets := [][]byte{}
|
//rets := [][]byte{}
|
||||||
|
|
||||||
|
|
||||||
fmt.Fprint(&fullCodeBuf, retHead)
|
fmt.Fprint(&fullCodeBuf, retHead)
|
||||||
|
|
||||||
if preCode != nil {
|
if preCode != nil {
|
||||||
fmt.Fprintln(
|
fmt.Fprintln(
|
||||||
&fullCodeBuf,
|
&fullCodeBuf,
|
||||||
|
@ -93,12 +84,22 @@ func (pp *Tengo) Eval(
|
||||||
fullCodeBuf.Write([]byte(retSeparator))
|
fullCodeBuf.Write([]byte(retSeparator))
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, code := range codes {
|
for i, code := range codes {
|
||||||
|
fmt.Fprintf(
|
||||||
|
&fullCodeBuf,
|
||||||
|
"\n__pp_write_raw__(%q)\n",
|
||||||
|
texts[i],
|
||||||
|
)
|
||||||
fmt.Fprintln(
|
fmt.Fprintln(
|
||||||
&fullCodeBuf,
|
&fullCodeBuf,
|
||||||
"\n" + string(code) + retSeparator,
|
"\n" + string(code) + retSeparator,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
fmt.Fprintf(
|
||||||
|
&fullCodeBuf,
|
||||||
|
"\n__pp_write_raw__(%q)\n",
|
||||||
|
texts[len(texts)-1],
|
||||||
|
)
|
||||||
|
|
||||||
if pp.postCode != nil {
|
if pp.postCode != nil {
|
||||||
fullCodeBuf.Write(pp.postCode(ctx))
|
fullCodeBuf.Write(pp.postCode(ctx))
|
||||||
|
@ -110,8 +111,8 @@ func (pp *Tengo) Eval(
|
||||||
pp.preCompile(ctx, script)
|
pp.preCompile(ctx, script)
|
||||||
}
|
}
|
||||||
|
|
||||||
script.Add("__filepath__", filePath)
|
script.Add("__pp_filepath__", filePath)
|
||||||
script.Add("__sprintf__", &tengo.UserFunction{
|
script.Add("__pp_printf__", &tengo.UserFunction{
|
||||||
Value: func(args ...tengo.Object) (tengo.Object, error){
|
Value: func(args ...tengo.Object) (tengo.Object, error){
|
||||||
if len(args) < 1 {
|
if len(args) < 1 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, tengo.ErrWrongNumArguments
|
||||||
|
@ -127,41 +128,64 @@ func (pp *Tengo) Eval(
|
||||||
gargs[i] = tengo.ToInterface(args[i+1])
|
gargs[i] = tengo.ToInterface(args[i+1])
|
||||||
//fmt.Printf("shit: %q\n", gargs[i])
|
//fmt.Printf("shit: %q\n", gargs[i])
|
||||||
}
|
}
|
||||||
str := fmt.Sprintf(format, gargs...)
|
fmt.Fprintf(&retBuf, format, gargs...)
|
||||||
return tengo.FromInterface([]byte(str))
|
return nil, nil
|
||||||
|
//return tengo.FromInterface([]byte(str))
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
script.Add("__sprint__", &tengo.UserFunction{
|
script.Add("__pp_print__", &tengo.UserFunction{
|
||||||
Value: func(args ...tengo.Object) (tengo.Object, error){
|
Value: func(args ...tengo.Object) (tengo.Object, error){
|
||||||
gargs := make([]any, len(args))
|
gargs := make([]any, len(args))
|
||||||
for i := range gargs {
|
for i := range gargs {
|
||||||
gargs[i] = tengo.ToInterface(args[i])
|
gargs[i] = tengo.ToInterface(args[i])
|
||||||
}
|
}
|
||||||
str := fmt.Sprint(gargs...)
|
fmt.Fprint(&retBuf, gargs...)
|
||||||
return tengo.FromInterface([]byte(str))
|
return nil, nil
|
||||||
|
//return tengo.FromInterface([]byte(str))
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
script.Add("__sprintln__", &tengo.UserFunction{
|
script.Add("__pp_println__", &tengo.UserFunction{
|
||||||
Value: func(args ...tengo.Object) (tengo.Object, error){
|
Value: func(args ...tengo.Object) (tengo.Object, error){
|
||||||
gargs := make([]any, len(args))
|
gargs := make([]any, len(args))
|
||||||
for i := range gargs {
|
for i := range gargs {
|
||||||
gargs[i] = tengo.ToInterface(args[i])
|
gargs[i] = tengo.ToInterface(args[i])
|
||||||
}
|
}
|
||||||
str := fmt.Sprintln(gargs...)
|
fmt.Fprintln(&retBuf, gargs...)
|
||||||
return tengo.FromInterface([]byte(str))
|
return nil, nil
|
||||||
|
//return tengo.FromInterface([]byte(str))
|
||||||
|
},
|
||||||
|
})
|
||||||
|
script.Add("__pp_write_raw__", &tengo.UserFunction{
|
||||||
|
Value: func(args ...tengo.Object) (tengo.Object, error){
|
||||||
|
bt := make([][]byte, len(args))
|
||||||
|
for i, o := range args {
|
||||||
|
bts, ok := tengo.ToByteSlice(o)
|
||||||
|
if !ok {
|
||||||
|
return nil, tengo.ErrInvalidArgumentType{
|
||||||
|
Expected: "string/bytes",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bt[i] = bts
|
||||||
|
}
|
||||||
|
for _, b := range bt {
|
||||||
|
retBuf.Write(b)
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
script.Add("__separate__", &tengo.UserFunction{
|
script.Add("__separate__", &tengo.UserFunction{
|
||||||
Value: func(args ...tengo.Object) (tengo.Object, error){
|
Value: func(args ...tengo.Object) (tengo.Object, error){
|
||||||
if len(args) < 1 {
|
return nil, nil
|
||||||
|
/*if len(args) < 1 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, tengo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
bts, ok := tengo.ToByteSlice(args[0])
|
bts, ok := tengo.ToByteSlice(args[0])
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, tengo.ErrInvalidArgumentType{
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
rets = append(rets, bts)
|
//rets = append(rets, retBuf.Bytes())
|
||||||
|
//retBuf.Reset()
|
||||||
return nil, nil
|
return nil, nil
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -171,5 +195,5 @@ func (pp *Tengo) Eval(
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return rets, nil
|
return retBuf.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue