-
Notifications
You must be signed in to change notification settings - Fork 0
/
lp.lua
135 lines (117 loc) · 4.54 KB
/
lp.lua
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
--[[ This file obtained from CGILua under the MIT license. Copyright 2003 Kepler Project. ]]
----------------------------------------------------------------------------
-- Lua Pages Template Preprocessor.
--
-- @release $Id: lp.lua,v 1.15 2008/12/11 17:40:24 mascarenhas Exp $
----------------------------------------------------------------------------
local assert, error, getfenv, loadstring, setfenv = assert, error, getfenv, loadstring, setfenv
local find, format, gsub, strsub, char = string.find, string.format, string.gsub, string.sub, string.char
local concat, tinsert = table.concat, table.insert
local open = io.open
module "lp"
----------------------------------------------------------------------------
-- function to do output
local outfunc = "io.write"
-- accepts the old expression field: `$| <Lua expression> |$'
local compatmode = true
--
-- Builds a piece of Lua code which outputs the (part of the) given string.
-- @param s String.
-- @param i Number with the initial position in the string.
-- @param f Number with the final position in the string (default == -1).
-- @return String with the correspondent Lua code which outputs the part of the string.
--
local function out (s, i, f)
s = strsub(s, i, f or -1)
if s == "" then return s end
-- we could use `%q' here, but this way we have better control
s = gsub(s, "([\\\n\'])", "\\%1")
-- substitute '\r' by '\'+'r' and let `loadstring' reconstruct it
s = gsub(s, "\r", "\\r")
return format(" %s('%s'); ", outfunc, s)
end
----------------------------------------------------------------------------
-- Translate the template to Lua code.
-- @param s String to translate.
-- @return String with translated code.
----------------------------------------------------------------------------
function translate (s)
s = gsub(s, "^#![^\n]+\n", "")
if compatmode then
s = gsub(s, "$|(.-)|%$", "<?lua = %1 ?>")
s = gsub(s, "<!%-%-$$(.-)$$%-%->", "<?lua %1 ?>")
end
s = gsub(s, "<%%(.-)%%>", "<?lua %1 ?>")
local res = {}
local start = 1 -- start of untranslated part in `s'
while true do
local ip, fp, target, exp, code = find(s, "<%?(%w*)[ \t]*(=?)(.-)%?>", start)
if not ip then break end
tinsert(res, out(s, start, ip-1))
if target ~= "" and target ~= "lua" then
-- not for Lua; pass whole instruction to the output
tinsert(res, out(s, ip, fp))
else
if exp == "=" then -- expression?
tinsert(res, format(" %s(%s);", outfunc, code))
else -- command
tinsert(res, format(" %s ", code))
end
end
start = fp + 1
end
tinsert(res, out(s, start))
return concat(res)
end
----------------------------------------------------------------------------
-- Defines the name of the output function.
-- @param f String with the name of the function which produces output.
function setoutfunc (f)
outfunc = f
end
----------------------------------------------------------------------------
-- Turns on or off the compatibility with old CGILua 3.X behavior.
-- @param c Boolean indicating if the compatibility mode should be used.
function setcompatmode (c)
compatmode = c
end
----------------------------------------------------------------------------
-- Internal compilation cache.
local cache = {}
----------------------------------------------------------------------------
-- Translates a template into a Lua function.
-- Does NOT execute the resulting function.
-- Uses a cache of templates.
-- @param string String with the template to be translated.
-- @param chunkname String with the name of the chunk, for debugging purposes.
-- @return Function with the resulting translation.
function compile (string, chunkname)
local f, err = cache[string]
if f then return f end
f, err = loadstring (translate (string), chunkname)
if not f then error (err, 3) end
cache[string] = f
return f
end
----------------------------------------------------------------------------
-- Translates and executes a template in a given file.
-- The translation creates a Lua function which will be executed in an
-- optionally given environment.
-- @param filename String with the name of the file containing the template.
-- @param env Table with the environment to run the resulting function.
local BOM = char(239) .. char(187) .. char(191)
function include (filename, env)
-- read the whole contents of the file
local fh = assert (open (filename))
local src = fh:read("*a")
fh:close()
if src:sub(1,3) == BOM then src = src:sub(4) end
-- translates the file into a function
local prog = compile (src, '@'..filename)
local _env
if env then
_env = getfenv (prog)
setfenv (prog, env)
end
prog ()
end