---- Manually compile a given template into an executable Lua function
--- @param template LuCI template
--- @return Lua template function
-function compile(template)
- local expr = {}
-
- -- Search all <% %> expressions
- local function expr_add(ws1, skip1, command, skip2, ws2)
- expr[#expr+1] = command
- return ( #skip1 > 0 and "" or ws1 ) ..
- "<%" .. tostring(#expr) .. "%>" ..
- ( #skip2 > 0 and "" or ws2 )
- end
-
- -- Save all expressiosn to table "expr"
- template = template:gsub("(%s*)<%%(%-?)(.-)(%-?)%%>(%s*)", expr_add)
-
- local function sanitize(s)
- s = "%q" % s
- return s:sub(2, #s-1)
- end
-
- -- Escape and sanitize all the template (all non-expressions)
- template = sanitize(template)
-
- -- Template module header/footer declaration
- local header = 'write("'
- local footer = '")'
-
- template = header .. template .. footer
-
- -- Replacements
- local r_include = '")\ninclude("%s")\nwrite("'
- local r_i18n = '")\nwrite(translate("%1","%2"))\nwrite("'
- local r_i18n2 = '")\nwrite(translate("%1", ""))\nwrite("'
- local r_pexec = '")\nwrite(tostring(%s or ""))\nwrite("'
- local r_exec = '")\n%s\nwrite("'
-
- -- Parse the expressions
- for k,v in pairs(expr) do
- local p = v:sub(1, 1)
- v = v:gsub("%%", "%%%%")
- local re = nil
- if p == "+" then
- re = r_include:format(sanitize(string.sub(v, 2)))
- elseif p == ":" then
- if v:find(" ") then
- re = sanitize(v):gsub(":(.-) (.*)", r_i18n)
- else
- re = sanitize(v):gsub(":(.+)", r_i18n2)
- end
- elseif p == "=" then
- re = r_pexec:format(v:sub(2))
- elseif p == "#" then
- re = ""
- else
- re = r_exec:format(v)
- end
- template = template:gsub("<%%"..tostring(k).."%%>", re)
- end
-
- return loadstring(template)
-end
-