343 lines
8.5 KiB
Lua
343 lines
8.5 KiB
Lua
local pcall = pcall
|
|
local require = require
|
|
local getmetatable = getmetatable
|
|
|
|
--- Internal configuration of
|
|
--- Aspect Template Engine. Be careful.
|
|
--- @class aspect.config
|
|
local config = {}
|
|
|
|
--- JSON configuration
|
|
config.json = {
|
|
encode = nil,
|
|
decode = nil,
|
|
error = "JSON encode/decode no available. Please install `cjson` or `json` or configure `require('aspect.config').json` before using Aspect"
|
|
}
|
|
|
|
--- UTF8 configuration
|
|
config.utf8 = {
|
|
len = nil,
|
|
lower = nil,
|
|
upper = nil,
|
|
sub = nil,
|
|
match = nil,
|
|
}
|
|
|
|
config.env = {
|
|
|
|
}
|
|
|
|
--- escape filter settings (HTML strategy)
|
|
config.escape = {
|
|
pattern = "[}{\"><'&]",
|
|
replaces = {
|
|
["&"] = "&",
|
|
["<"] = "<",
|
|
[">"] = ">",
|
|
['"'] = """,
|
|
["'"] = "'"
|
|
}
|
|
}
|
|
|
|
--- condition aliases (also see bellow)
|
|
config.is_false = {
|
|
[""] = true,
|
|
[0] = true,
|
|
}
|
|
|
|
--- empty string variants (also see bellow)
|
|
config.is_empty_string = {
|
|
[""] = true,
|
|
}
|
|
|
|
config.is_n = {
|
|
}
|
|
|
|
--- dynamically configure config.is_false and config.is_empty_string
|
|
do
|
|
--- https://github.com/openresty/lua-nginx-module#core-constants
|
|
local ngx = ngx or {}
|
|
if ngx.null then
|
|
config.is_false[ngx.null] = true
|
|
config.is_empty_string[ngx.null] = true
|
|
end
|
|
|
|
--- https://luarocks.org/modules/openresty/lua-cjson
|
|
local has_cjson, cjson = pcall(require, "cjson.safe")
|
|
if has_cjson then
|
|
config.is_false[cjson.null] = true
|
|
config.is_empty_string[cjson.null] = true
|
|
config.json.encode = cjson.encode
|
|
config.json.decode = cjson.decode
|
|
else
|
|
local has_json, json = pcall(require, "json")
|
|
if has_json then
|
|
config.json.encode = json.encode
|
|
config.json.decode = json.decode
|
|
if json.null then
|
|
config.is_false[json.null] = true
|
|
config.is_empty_string[json.null] = true
|
|
end
|
|
if json.empty_array then
|
|
config.is_false[json.empty_array] = true
|
|
end
|
|
end
|
|
end
|
|
|
|
--- https://github.com/isage/lua-cbson
|
|
local has_cbson, cbson = pcall(require, "cbson")
|
|
if has_cbson then
|
|
config.is_false[getmetatable(cbson.null())] = true
|
|
config.is_false[getmetatable(cbson.array())] = true
|
|
config.is_empty_string[getmetatable(cbson.null())] = true
|
|
end
|
|
|
|
--- https://www.tarantool.io/ru/doc/1.10/reference/reference_lua/yaml/
|
|
local has_yaml, yaml = pcall(require, "yaml")
|
|
if has_yaml and yaml.NULL then
|
|
config.is_false[yaml.NULL] = true
|
|
config.is_empty_string[yaml.NULL] = true
|
|
end
|
|
|
|
--- https://github.com/gvvaughan/lyaml
|
|
local has_lyaml, lyaml = pcall(require, "lyaml")
|
|
if has_lyaml then
|
|
config.is_false[lyaml.null] = true
|
|
config.is_empty_string[lyaml.null] = true
|
|
end
|
|
|
|
--- https://www.tarantool.io/ru/doc/2.4/reference/reference_lua/msgpack/
|
|
local has_msgpack, msgpack = pcall(require, "msgpack")
|
|
if has_msgpack then
|
|
config.is_false[msgpack.NULL] = true
|
|
config.is_empty_string[msgpack.NULL] = true
|
|
end
|
|
|
|
--- https://www.tarantool.io/en/doc/2.4/reference/reference_lua/box_null/
|
|
if box and box.NULL then
|
|
config.is_false[box.NULL] = true
|
|
config.is_empty_string[box.NULL] = true
|
|
end
|
|
end
|
|
|
|
--- Detect UTF8 module
|
|
do
|
|
local utf8
|
|
for _, name in ipairs({"lua-utf8", "utf8", "lutf8"}) do
|
|
local ok, module = pcall(require, name)
|
|
if ok then
|
|
utf8 = module
|
|
break
|
|
end
|
|
end
|
|
if utf8 then
|
|
config.utf8.len = utf8.len or utf8.length
|
|
config.utf8.upper = utf8.upper
|
|
config.utf8.lower = utf8.lower
|
|
config.utf8.sub = utf8.sub
|
|
config.utf8.match = utf8.match
|
|
config.utf8.find = utf8.find
|
|
end
|
|
end
|
|
|
|
--- Compiler configuration
|
|
config.compiler = {
|
|
is_boolean = {
|
|
["true"] = true,
|
|
["false"] = true
|
|
},
|
|
special = {
|
|
["true"] = "true",
|
|
["false"] = "false",
|
|
["nil"] = "nil",
|
|
["null"] = "nil"
|
|
},
|
|
--- danger variables names
|
|
reserved_words = {
|
|
["and"] = true,
|
|
["break"] = true,
|
|
["do"] = true,
|
|
["else"] = true,
|
|
["elseif"] = true,
|
|
["end"] = true,
|
|
["false"] = true,
|
|
["for"] = true,
|
|
["function"] = true,
|
|
["if"] = true,
|
|
["in"] = true,
|
|
["local"] = true,
|
|
["nil"] = true,
|
|
["not"] = true,
|
|
["or"] = true,
|
|
["repeat"] = true,
|
|
["return"] = true,
|
|
["then"] = true,
|
|
["true"] = true,
|
|
["until"] = true,
|
|
["while"] = true,
|
|
},
|
|
--- correspondence table for math operators
|
|
math_ops = {
|
|
["+"] = "+",
|
|
["-"] = "-",
|
|
["/"] = "/",
|
|
["*"] = "*",
|
|
["%"] = "%",
|
|
["**"] = "^",
|
|
},
|
|
--- correspondence table for comparison operators
|
|
comparison_ops = {
|
|
["=="] = "==",
|
|
["!="] = "~=",
|
|
[">="] = ">=",
|
|
["<="] = "<=",
|
|
["<"] = "<",
|
|
[">"] = ">",
|
|
},
|
|
--- correspondence table for logic operators
|
|
logic_ops = {
|
|
["and"] = "and",
|
|
["or"] = "or"
|
|
},
|
|
other_ops = {
|
|
["~"] = true,
|
|
["|"] = true,
|
|
["."] = true,
|
|
["["] = true,
|
|
["]"] = true,
|
|
[","] = true
|
|
},
|
|
--- reserved variables names
|
|
reserved_vars = {
|
|
_self = true,
|
|
_context = true,
|
|
_charset = true,
|
|
__ = true
|
|
},
|
|
|
|
tag_type = {
|
|
EXPRESSION = 1,
|
|
CONTROL = 2,
|
|
COMMENT = 3,
|
|
},
|
|
|
|
strip = {
|
|
["-"] = "%s",
|
|
["~"] = "[ \t]"
|
|
}
|
|
}
|
|
|
|
config.tokenizer = {
|
|
patterns = {
|
|
NUMBER1 = '^[%+%-]?%d+%.?%d*[eE][%+%-]?%d+', -- 123.45e-32
|
|
NUMBER2 = '^[%+%-]?%d+%.?%d*', -- 123 or 123.456
|
|
NUMBER3 = '^0x[%da-fA-F]+', -- 0xDeadBEEF
|
|
NUMBER4 = '^%d+%.?%d*[eE][%+%-]?%d+',
|
|
NUMBER5 = '^%d+%.?%d*',
|
|
WORD = '^[%a_][%w_]*',
|
|
WSPACE = '^%s+',
|
|
STRING1 = "^(['\"])%1", -- empty string
|
|
STRING2 = [[^(['"])(\*)%2%1]],
|
|
STRING3 = [[^(['"]).-[^\](\*)%2%1]],
|
|
CHAR1 = "^''",
|
|
CHAR2 = [[^'(\*)%1']],
|
|
CHAR3 = [[^'.-[^\](\*)%1']],
|
|
PREPRO = '^#.-[^\\]\n',
|
|
}
|
|
}
|
|
|
|
config.loop = {
|
|
keys = {
|
|
parent = true,
|
|
iteration = true,
|
|
index = true,
|
|
index0 = true,
|
|
revindex = true,
|
|
revindex0 = true,
|
|
first = true,
|
|
last = true,
|
|
length = true,
|
|
prev_item = true,
|
|
next_item = true,
|
|
has_more = true,
|
|
|
|
--- trees
|
|
level = true,
|
|
level0 = true,
|
|
first_node = true,
|
|
last_node = true,
|
|
path = true
|
|
}
|
|
}
|
|
|
|
config.macro = {
|
|
import_type = {
|
|
GROUP = 1,
|
|
SINGLE = 2
|
|
}
|
|
}
|
|
|
|
config.escapers = {}
|
|
|
|
config.date = {
|
|
months = {
|
|
["jan"] = 1, ["january"] = 1,
|
|
["feb"] = 2, ["february"] = 2,
|
|
["mar"] = 3, ["march"] = 3,
|
|
["apr"] = 4, ["april"] = 4,
|
|
["may"] = 5, ["may"] = 5,
|
|
["jun"] = 6, ["june"] = 6,
|
|
["jul"] = 7, ["july"] = 7,
|
|
["aug"] = 8, ["august"] = 8,
|
|
["sep"] = 9, ["september"] = 9,
|
|
["oct"] = 10, ["october"] = 10,
|
|
["nov"] = 11, ["november"] = 11,
|
|
["dec"] = 12, ["december"] = 12,
|
|
},
|
|
months_locale = {
|
|
en = {
|
|
[1] = {"Jan", "January"},
|
|
[2] = {"Feb", "February"},
|
|
[3] = {"Mar", "March"},
|
|
[4] = {"Apr", "April"},
|
|
[5] = {"May", "May"},
|
|
[6] = {"Jun", "June"},
|
|
[7] = {"Jul", "July"},
|
|
[8] = {"Aug", "August"},
|
|
[9] = {"Sep", "September"},
|
|
[10] = {"Oct", "October"},
|
|
[11] = {"Nov", "November"},
|
|
[12] = {"Dec", "December"},
|
|
}
|
|
},
|
|
week = {
|
|
["mon"] = 1, ["monday"] = 1,
|
|
["tue"] = 2, ["tuesday"] = 2,
|
|
["wed"] = 3, ["wednesday"] = 3,
|
|
["thu"] = 4, ["thursday"] = 4,
|
|
["fri"] = 5, ["friday"] = 5,
|
|
["sat"] = 6, ["saturday"] = 6,
|
|
["sun"] = 7, ["sunday"] = 7,
|
|
},
|
|
week_locale = {
|
|
en = {
|
|
[1] = {"Mon", "Monday"},
|
|
[2] = {"Tue", "Tuesday"},
|
|
[3] = {"Wed", "Wednesday"},
|
|
[4] = {"Thu", "Thursday"},
|
|
[5] = {"Fri", "Friday"},
|
|
[6] = {"Sat", "Saturday"},
|
|
[7] = {"Sun", "Sunday"},
|
|
},
|
|
},
|
|
aliases = {
|
|
c = "%a %b %d %H:%m%s %Y",
|
|
r = "%I:%M:%S %p",
|
|
R = "%I:%M",
|
|
T = "%H:%M:%S",
|
|
D = "%m/%d/%y",
|
|
F = "%Y-%m-%d"
|
|
}
|
|
}
|
|
|
|
return config |