모듈:template utilities
보이기
이 모듈에 대한 설명문서는 모듈:template utilities/설명문서에서 만들 수 있습니다
local export = {}
export.brackets_temp = { ['{{'] = '}}' }
export.brackets_temp_and_link = { ['{{'] = '}}', ['%[%['] = ']]' }
function export.find_bracket(str, brackets, p_start)
local function find_left(pos_start)
local p1_result, cap_result, right_result = str:len() + 1
local cap_this
for k, v in pairs(brackets) do
cap_this = {str:find(k, pos_start)}
if cap_this[1] and cap_this[1] < p1_result then
p1_result, cap_result, right_result = cap_this[1], cap_this, v
end
end
if not cap_result then return nil end
local p2_result = cap_result[2]
cap_result[2] = str:sub(p1_result, p2_result)
local t = type(right_result)
if t == 'string' then
return p1_result, p2_result, right_result:gsub('%%(.)', function(m1)
if m1:match'%d' then
return cap_result[m1 + 2]
else return m1 end
end)
end
local repl
if t == 'function' then
cap_result[3] = cap_result[3] or cap_result[2]
repl = right_result(select(3, unpack(cap_result)))
elseif t == 'table' then
repl = right_result[cap_result[3] or cap_result[2]]
else error('bad right bracket type: ' .. t) end
if not repl then repl = cap_result[2]
elseif type(repl) == 'number' then repl = tostring(repl) end
return p1_result, p2_result, repl
end
local p_init, p0, str_brac = find_left(p_start)
if p_init == nil then return nil end
local nest = {str_brac}
local p1, p2, p3, p4
repeat
p0 = p0 + 1
p1, p2 = str:find(str_brac, p0)
if p1 == nil then return nil end
if p1 > p2 then error'Any bracket must not have zero length.' end
p3, p4, str_brac = find_left(p0)
if p3 == nil then
local n = #nest - 1
while n > 0 do
p1, p2 = str:find(nest[n], p2 + 1)
if p1 == nil then return nil end
n = n - 1
end
p0 = p2
break
else
if p3 > p4 then error'Any bracket must not have zero length.' end
if p3 < p1 then
table.insert(nest, str_brac)
p0 = p4
else
table.remove(nest)
str_brac = nest[#nest]
p0 = p2
end
end
until #nest == 0
return p_init, p0, str:sub(p_init, p0)
end
function export.gfind_bracket(str, brackets)
local p0 = 0
return function()
p0 = p0 + 1
local p1, p2, text_b = export.find_bracket(str, brackets, p0)
p0 = p2
return p1, p2, text_b
end
end
function export.find_ignoring_brackets(str, brackets, pat, init, ...)
local find_result = {str:find(pat, init, ...)}
local p1, p2 = find_result[1], find_result[2]
if p1 == nil then return nil end
local p3, p4 = export.find_bracket(str, brackets)
while p4 and p4 <= p2 do p3, p4 = export.find_bracket(str, brackets, p4 + 1) end
while p3 and p3 <= p2 do
find_result = {str:find(pat, p4 + 1, ...)}
p1, p2 = find_result[1], find_result[2]
if p1 == nil then return nil end
while p4 and p4 <= p2 do p3, p4 = export.find_bracket(str, brackets, p4 + 1) end
end
return unpack(find_result)
end
function export.gsplit_ignoring_brackets(str, brackets, sep)
local p0 = 0
local empty = 0
return function()
if p0 == nil then return nil end
p0 = p0 + empty
if p0 > str:len() then return nil end
p0 = p0 + 1
local p1, p2 = export.find_ignoring_brackets(str, brackets, sep, p0)
p0, p2 = p2, p0 - empty
if p1 then
empty = p1 > p0 and 1 or 0
return str:sub(p2, p1 - 1)
else return str:sub(p2) end
end
end
function export.parse_temp(str)
if str:sub(1, 2) ~= '{{' or str:sub(-2) ~= '}}' then return nil end
str = str:sub(3, -3)
local p_title_end = export.find_ignoring_brackets(str, export.brackets_temp_and_link, '|')
if not p_title_end then return { title = str, args = {} }
end
local args = {}
local count = 0
for arg in export.gsplit_ignoring_brackets(str:sub(p_title_end + 1), export.brackets_temp_and_link, '|') do
local p_eqsign = export.find_ignoring_brackets(arg, export.brackets_temp_and_link, '=')
if p_eqsign then
local arg_name = arg:sub(1, p_eqsign - 1)
local arg_name_num = tonumber(arg_name)
if arg_name_num and arg_name_num > 0 and arg_name_num == math.floor(arg_name_num) then
arg_name = arg_name_num
else
arg_name = arg_name:match'^%s*(%S-)%s*$'
end
args[arg_name] = arg:sub(p_eqsign + 1):match'^%s*(%S-)%s*$'
else
count = count + 1
args[count] = arg
end
end
return { title = str:sub(1, p_title_end - 1), args = args }
end
function export.iter_num(t)
local i = 0
local index_max = 0
for k, _ in pairs(t.args) do
if type(k) == 'number' and index_max < k then
index_max = k
end
end
return function()
local v
repeat
i = i + 1
if i > index_max then return nil end
v = t.args[i]
until v
return i, v
end
end
function export.glue_temp(t)
local content = { t.title }
for i, v in export.iter_num(t) do
if i == #content then
table.insert(content, v)
else
table.insert(content, i .. '=' .. v)
end
end
for k, v in pairs(t.args) do
if type(k) == 'string' then
table.insert(content, k .. '=' .. v)
end
end
return '{{' .. table.concat(content, '|') .. '}}'
end
return export