build: add modified luadoc for use with LuCI sources
[project/luci.git] / contrib / luadoc / lua / luadoc / lp.lua
1 ----------------------------------------------------------------------------
2 -- Lua Pages Template Preprocessor.
3 --
4 -- @release $Id: lp.lua,v 1.7 2007/04/18 14:28:39 tomas Exp $
5 ----------------------------------------------------------------------------
6
7 local assert, error, getfenv, loadstring, setfenv = assert, error, getfenv, loadstring, setfenv
8 local find, format, gsub, strsub = string.find, string.format, string.gsub, string.sub
9 local concat, tinsert = table.concat, table.insert
10 local open = io.open
11
12 module (...)
13
14 ----------------------------------------------------------------------------
15 -- function to do output
16 local outfunc = "io.write"
17 -- accepts the old expression field: `$| <Lua expression> |$'
18 local compatmode = true
19
20 --
21 -- Builds a piece of Lua code which outputs the (part of the) given string.
22 -- @param s String.
23 -- @param i Number with the initial position in the string.
24 -- @param f Number with the final position in the string (default == -1).
25 -- @return String with the correspondent Lua code which outputs the part of the string.
26 --
27 local function out (s, i, f)
28         s = strsub(s, i, f or -1)
29         if s == "" then return s end
30         -- we could use `%q' here, but this way we have better control
31         s = gsub(s, "([\\\n\'])", "\\%1")
32         -- substitute '\r' by '\'+'r' and let `loadstring' reconstruct it
33         s = gsub(s, "\r", "\\r")
34         return format(" %s('%s'); ", outfunc, s)
35 end
36
37
38 ----------------------------------------------------------------------------
39 -- Translate the template to Lua code.
40 -- @param s String to translate.
41 -- @return String with translated code.
42 ----------------------------------------------------------------------------
43 function translate (s)
44         if compatmode then
45                 s = gsub(s, "$|(.-)|%$", "<?lua = %1 ?>")
46                 s = gsub(s, "<!%-%-$$(.-)$$%-%->", "<?lua %1 ?>")
47         end
48         s = gsub(s, "<%%(.-)%%>", "<?lua %1 ?>")
49         local res = {}
50         local start = 1   -- start of untranslated part in `s'
51         while true do
52                 local ip, fp, target, exp, code = find(s, "<%?(%w*)[ \t]*(=?)(.-)%?>", start)
53                 if not ip then break end
54                 tinsert(res, out(s, start, ip-1))
55                 if target ~= "" and target ~= "lua" then
56                         -- not for Lua; pass whole instruction to the output
57                         tinsert(res, out(s, ip, fp))
58                 else
59                         if exp == "=" then   -- expression?
60                                 tinsert(res, format(" %s(%s);", outfunc, code))
61                         else  -- command
62                                 tinsert(res, format(" %s ", code))
63                         end
64                 end
65                 start = fp + 1
66         end
67         tinsert(res, out(s, start))
68         return concat(res)
69 end
70
71
72 ----------------------------------------------------------------------------
73 -- Defines the name of the output function.
74 -- @param f String with the name of the function which produces output.
75
76 function setoutfunc (f)
77         outfunc = f
78 end
79
80 ----------------------------------------------------------------------------
81 -- Turns on or off the compatibility with old CGILua 3.X behavior.
82 -- @param c Boolean indicating if the compatibility mode should be used.
83
84 function setcompatmode (c)
85         compatmode = c
86 end
87
88 ----------------------------------------------------------------------------
89 -- Internal compilation cache.
90
91 local cache = {}
92
93 ----------------------------------------------------------------------------
94 -- Translates a template into a Lua function.
95 -- Does NOT execute the resulting function.
96 -- Uses a cache of templates.
97 -- @param string String with the template to be translated.
98 -- @param chunkname String with the name of the chunk, for debugging purposes.
99 -- @return Function with the resulting translation.
100
101 function compile (string, chunkname)
102         local f, err = cache[string]
103         if f then return f end
104         f, err = loadstring (translate (string), chunkname)
105         if not f then error (err, 3) end
106         cache[string] = f
107         return f
108 end
109
110 ----------------------------------------------------------------------------
111 -- Translates and executes a template in a given file.
112 -- The translation creates a Lua function which will be executed in an
113 -- optionally given environment.
114 -- @param filename String with the name of the file containing the template.
115 -- @param env Table with the environment to run the resulting function.
116
117 function include (filename, env)
118         -- read the whole contents of the file
119         local fh = assert (open (filename))
120         local src = fh:read("*a")
121         fh:close()
122         -- translates the file into a function
123         local prog = compile (src, '@'..filename)
124         local _env
125         if env then
126                 _env = getfenv (prog)
127                 setfenv (prog, env)
128         end
129         prog ()
130 end