-
Notifications
You must be signed in to change notification settings - Fork 0
/
pandoc-eval.go
92 lines (81 loc) · 1.93 KB
/
pandoc-eval.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package main
import (
"fmt"
"os"
"bytes"
pf "github.com/oltolm/go-pandocfilters"
"github.com/Azure/golua/lua"
"github.com/Azure/golua/std"
)
func must(err error) {
if err != nil {
fmt.Fprintf(os.Stderr, "fatal: %v\n", err)
os.Exit(1)
}
}
var execBuffer bytes.Buffer
var contextState *lua.State
func basePrint(state *lua.State) int {
var (
n = state.Top()
i = 1
)
state.GetGlobal("tostring")
for ; i <= n; i++ {
state.PushIndex(-1)
state.PushIndex(i)
state.Call(1, 1)
str, ok := state.TryString(-1)
if !ok {
panic(fmt.Errorf("'tostring' must return a string to 'print'"))
}
execBuffer.WriteString(str)
state.Pop()
}
return 0
}
func addLuatexFuncs(state *lua.State) {
var baseFuncs = map[string]lua.Func{
"__lf_tex_write": lua.Func(basePrint),
}
// Open base library into globals table.
state.PushGlobals()
state.SetFuncs(baseFuncs, 0)
}
func execLuaWithCapture(code string) string {
execBuffer.Reset()
contextState.ExecText(code)
return execBuffer.String()
}
func Caps(key string, value interface{}, format string, meta interface{}) interface{} {
//fmt.Fprintf(os.Stderr, "%v %v\n", key, value)
if key == "CodeBlock" || key == "Code"{
blockType := value.([]interface{})[0].([]interface{})[1].([]interface{})[0].(string)
//fmt.Fprintf(os.Stderr, "%v\n", blockType)
if (blockType == "evallua") {
code := value.([]interface{})[1].(string)
out := execLuaWithCapture(code)
if key == "CodeBlock" {
return pf.RawBlock(format, out)
}
return pf.RawInline(format, out)
}
}
return nil
}
func main() {
var opts = []lua.Option{lua.WithTrace(false), lua.WithVerbose(false)}
contextState = lua.NewState(opts...)
defer contextState.Close()
std.Open(contextState)
addLuatexFuncs(contextState)
patch_startup := `
print = __lf_tex_write
`
security_startup := `
os.execute = function(...) end
`
contextState.ExecText(patch_startup)
contextState.ExecText(security_startup)
pf.ToJSONFilter(Caps)
}