83 lines
2.6 KiB
Lua
83 lines
2.6 KiB
Lua
--[[
|
|
Copyright (C) 2023
|
|
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE
|
|
]]
|
|
|
|
local function read(fn)
|
|
local fd = io.open(fn, "r")
|
|
|
|
if not fd then return nil end
|
|
|
|
local ret = fd:read("*all")
|
|
fd:close()
|
|
return ret
|
|
end
|
|
|
|
local function compile(src, name)
|
|
local code = {"RETURN_STRINGS={} "}
|
|
|
|
name = name or "Lyre Render"
|
|
|
|
while true do
|
|
local startI = select(2, src:find("{[{%%]", 1, false))
|
|
local endI
|
|
local isstmt = false
|
|
|
|
if startI then
|
|
isstmt = src:byte(startI) == string.byte("%")
|
|
endI = select(2, src:find(isstmt and "%%}" or "}}", 1, false))
|
|
end
|
|
|
|
if startI and endI then
|
|
if endI < startI then
|
|
table.insert(code, ";RETURN_STRINGS[#RETURN_STRINGS+1]="..string.format("%q", src:sub(1, startI - 2)))
|
|
src = src:sub(startI - 1)
|
|
else
|
|
table.insert(code, ";RETURN_STRINGS[#RETURN_STRINGS+1]="..string.format("%q", src:sub(1, startI - 2)))
|
|
|
|
if isstmt then
|
|
table.insert(code, src:sub(startI + 1, endI - 2))
|
|
else
|
|
table.insert(code, "RETURN_STRINGS[#RETURN_STRINGS+1]=tostring("..src:sub(startI + 1, endI - 2)..")")
|
|
end
|
|
|
|
table.insert(code, ret)
|
|
|
|
src = src:sub(endI + 1)
|
|
end
|
|
else
|
|
table.insert(code, "RETURN_STRINGS[#RETURN_STRINGS+1]="..string.format("%q", src)..";return table.concat(RETURN_STRINGS)")
|
|
break
|
|
end
|
|
end
|
|
|
|
local env = setmetatable({table = table, tostring = tostring, tonumber = tonumber, pairs = pairs, ipairs = ipairs, string = string, math = math, RETURN_STRINGS = {}, type = type}, {})
|
|
|
|
local chu, err
|
|
if _ENV then
|
|
chu, err = load(table.concat(code), name, "t", env)
|
|
if err then error(err) end
|
|
else
|
|
chu, err = loadstring(table.concat(code), name)
|
|
if err then error(err) end
|
|
setfenv(chu, env)
|
|
end
|
|
|
|
return {chu = chu, env = env}
|
|
end
|
|
|
|
local function render(tmpl, envOverride, strongEnv)
|
|
local mt = getmetatable(tmpl.env)
|
|
mt.__index = envOverride
|
|
if strongEnv then mt.__newindex = envOverride end
|
|
return tmpl.chu()
|
|
end
|
|
|
|
return {
|
|
render = render,
|
|
compile = compile,
|
|
compilef = function(fn) return compile(read(fn), fn) end
|
|
}
|