Mine sisu juurde

Modul':Transclude

Мегавики-späi

local p={}

-- Вызывает внутренний шаблон с аргументами объемлющего шаблона function p.call(frame) local template = frame.args[1] local args = frame:getParent().args

   return frame:expandTemplate{ title=template, args=args }

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

-- Вызывает внутренний шаблон, передавая ему нумерованные параметры объемлющего шаблона по-одному 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

-- Берёт нумерованные аргументы объемлющего шаблона и склеивает их в единую строку 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

-- Служебная функция: удаляет дубликаты из отсортированного массива с нумерованными индексами 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

-- Вызывает внутренний шаблон несколько раз, передавая в него блоки аргументов объемлющего шаблона 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 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

-- Действует аналогично 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';
   end
   for p,k in pairs(f.args) do
       if type(p)=='number' then
           if p>2 then ac[p-1]=k end
       else ac[p]=k
       end
   end
   local s,fh = f.args[2]:match('^%s*(%-?%d+)%s*%.%.') or 1,
       f.args[2]:match('%.%.%s*(%S.*)%s*$') or f.args[2] or ;
   fh=tonumber(fh) or fh:match('^%s*(.-)%s*$');

s=tonumber(s);

   local acr={};
   if not s then error('Начало цикла «'..s..'» — не число') end
   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
   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
       while tf:expandTemplate{ title=fh; args={s,unpack(ac)} } do dc('asc') end
   else
       while dc('asc') do end
   end
   return table.concat(acr, sep)

end

return p