14.599
redaktə
(Səhifəni 'local M={} --------------------------------------------------------- -- Функции для работы с параметрами вызвавшего шаблона --...' ilə yarat) |
Redaktənin izahı yoxdur |
||
Sətir 1: | Sətir 1: | ||
local | local p={} | ||
-- | -- Вызывает внутренний шаблон с аргументами объемлющего шаблона | ||
function p.call(frame) | |||
function | local template = frame.args[1] | ||
local args = frame:getParent().args | |||
return frame:expandTemplate{ title=template, args=args } | |||
return | |||
end | end | ||
-- Общая реализация для forall и call | |||
local function forallImpl(args, separator, conjunction, func) | |||
-- нумерованные ключи из args | |||
local keys = {} | |||
-- перебор в произвольном порядке, даже для нумерованных ключей | |||
for key, value in pairs(args) do | |||
if type(key) == 'number' and value and value ~= '' then | |||
table.insert(keys, key) | |||
end | |||
end | |||
table.sort(keys) | |||
local results = {} | |||
for _, key in ipairs(keys) do | |||
local value = func(args[key]) | |||
table.insert(results, value) | |||
end | |||
return mw.text.listToText(results, separator, conjunction) | |||
end | end | ||
function | -- Вызывает внутренний шаблон, передавая ему нумерованные параметры объемлющего шаблона по-одному | ||
function p.forall(frame) | |||
local template = frame.args[1] | |||
local separator = frame.args.separator or '' | |||
local conjunction = frame.args.conjunction or separator | |||
local args = frame:getParent().args | |||
local func = function(value) | |||
return frame:expandTemplate{ title = template, args = {value} } -- или другой frame? | |||
end | |||
return forallImpl(args, separator, conjunction, func) | |||
end | end | ||
-- Берёт нумерованные аргументы объемлющего шаблона и склеивает их в единую строку | |||
function p.join(frame) | |||
local separator = frame.args[1] or '' | |||
local conjunction = frame.args[2] or separator | |||
local args = frame:getParent().args | |||
local func = function(value) | |||
return value | |||
end | |||
return forallImpl(args, separator, conjunction, func) | |||
end | end | ||
-- Служебная функция: удаляет дубликаты из отсортированного массива с нумерованными индексами | |||
local function deleteDuplicates(args) | |||
local res = {} | |||
for key, value in pairs(args) do | |||
if args[key+1] ~= value then | |||
table.insert(res, value) | |||
end | |||
end | |||
return res | |||
end | end | ||
function | -- Вызывает внутренний шаблон несколько раз, передавая в него блоки аргументов объемлющего шаблона | ||
function p.npc(frame) | |||
local args = frame:getParent().args | |||
local templateFrame = frame:getParent() | |||
local template = frame.args[1] | |||
-- определение, блоки аргументов с какими номерами нужны: | |||
-- если в объемлющем шаблоне есть "параметр12" и в вызове модуля есть "параметр", то вызывается 12-й блок | |||
local nums = {} | |||
for key, _ in pairs(args) do | |||
local main, num = string.match(key, '^(.-)%s*(%d*)$') | |||
num = tonumber(num) | |||
-- учитывать "параметр12", только если задано "параметр" | |||
if num and frame.args[main] then | |||
table.insert(nums, num) | |||
end | |||
return | end | ||
table.sort(nums) | |||
nums = deleteDuplicates(nums) | |||
-- проходить по нужным номерам блоков по возрастанию и однократно | |||
-- подставлять в шаблон: | |||
-- 1. общие аргументы данного модуля | |||
-- 2. аргументы объемлющего шаблона вида "параметр12" как "параметр" в 12-й блок | |||
local results = {} | |||
for _, blockNum in ipairs(nums) do | |||
-- общие аргументы модуля, которые передаются в каждый блок | |||
local blockArgs = mw.clone(frame.args) | |||
-- metatable ломает expandTemplate | |||
setmetatable(blockArgs, nil) | |||
for key, value in pairs(args) do | |||
local main, num = string.match(key, '^(.-)%s*(%d*)$') | |||
num = tonumber(num) | |||
-- передавать "параметр12" как "параметр" в 12-й блок, только если есть "параметр" в вызове модуля | |||
if blockNum == num and frame.args[main] then | |||
blockArgs[main] = value | |||
end | |||
end | |||
local blockText = templateFrame:expandTemplate{ title=template; args=blockArgs } | |||
table.insert(results, blockText) | |||
end | |||
return table.concat(results) | |||
end | end | ||
-- | -- Действует аналогично forall по числовой переменной, изменяющейся (по умолчанию, от 1) до f.args[2]. | ||
function p.cycle(f) | |||
local tf,ac,op=f:getParent(), {}, f.args.output or 'inline'; | |||
local sep=''; | |||
if op == 'newline' then | |||
sep='\n'; | |||
local tf, ac, | |||
end | end | ||
for p,k in pairs(f.args) do | for p,k in pairs(f.args) do | ||
if type(p)=='number' then | if type(p)=='number' then | ||
Sətir 132: | Sətir 126: | ||
f.args[2]:match('%.%.%s*(%S.*)%s*$') or f.args[2] or ''; | f.args[2]:match('%.%.%s*(%S.*)%s*$') or f.args[2] or ''; | ||
fh=tonumber(fh) or fh:match('^%s*(.-)%s*$'); | fh=tonumber(fh) or fh:match('^%s*(.-)%s*$'); | ||
s=tonumber(s); | |||
local acr={}; | local acr={}; | ||
if not | if not s then error('Начало цикла «'..s..'» — не число') end | ||
local function dc() | local function dc(order) | ||
local r=tf:expandTemplate{ title=f.args[1]; args={s,unpack(ac)} } | |||
if order == 'desc' then | |||
s=s-1; | |||
else | |||
s=s+1; | |||
end | |||
if r~='' then table.insert(acr,r); return r end | |||
end | end | ||
if type(fh)=='number' then | if type(fh)=='number' then | ||
if fh > s then | |||
while s<=fh do dc('asc') end | |||
else | |||
while s>=fh do dc('desc') end | |||
end | |||
elseif fh~='' then | elseif fh~='' then | ||
while tf:expandTemplate{ title=fh; args={s,unpack(ac)} } do dc() end | while tf:expandTemplate{ title=fh; args={s,unpack(ac)} } do dc('asc') end | ||
else | else | ||
while dc() do end | while dc('asc') do end | ||
end | end | ||
return table.concat(acr) | return table.concat(acr, sep) | ||
end | end | ||
return p | |||
return |