Модуль:Transclude

Материал из ultracity
Перейти к навигации Перейти к поиску

local M={}


-- Функции для работы с параметрами вызвавшего шаблона --


function M.uni(f)-- Унификация имён параметров; псевдонимы.

   local tf, cs=f:getParent(), {};
   local findcs=function(a) cs[a]=f.args[a] end;
   (f.args['|фиксрег'] or f.args['|fixreg'] or ):gmatch(' *([^%n]+) *', findcs);
   -- |фиксрег = список разделённых новыми строками аргументов, регистр которых не менять
   local args,am={};
   for a,v in pairs(tf.args) do
       am = a:lower():gsub('[_ ]+',' ');
       args[ cs[a] and a  or  ( f.args[am] or am ) ] = v
   end
   return tf:expandTemplate{title=f.args[1]; args=args}

end

M['forall'] = function(f)-- Итератор по аргументам вызывающего шаблона.

   -- f.args[1] — имя вызываемого шаблона.
    local tf,ac,res,tln,sep,gl=f:getParent(),{},{},f.args[1]:match('^%s*([^#]-)%s*#(.*)$'),tonumber(f.args[2]) or 1;
    if not tln then tln,sep=f.args[1]:match('^%s*(.-)%s*$'), end
    for p,k in pairs(f.args) do if type(p)=='string' then ac[p]=k end end
    local ans,i,ablk={},1;
    while tf.args[i] do
        if gl==1 then
            ans[i] = tf:expandTemplate{ title=tln; args={tf.args[i], unpack(ac)} }
        else
            ablk={}; for j = 0, gl-1 do ablk[j] = tf.args[i*gl+j] end;
            for k,v in pairs(ac) do ablk[k]=v end;
            ans[i] = tf:expandTemplate{ title=tln; args=ablk }
        end
        i = i+1
    end
    return table.concat(ans,sep)

end

function M.escapeparams(f)-- Нормализация -- (обезопасивание) значений параметров.

   local i,ac,acn=0,{},{};
   local function repl(s)
       return s:gsub('{{','Шаблон:Х'):gsub('',"Шаблон:ЪЪ"):gsub('{{Х','Шаблон:ХХ')--: --замена фигурных скобок
          :gsub('=','='):gsub('|','|') 
   end
   for k,v in pairs(f:getParent().args) do
       if type(k)=='number' then ac[k]=repl(v); i=i+1
       else acn[repl(k)]=repl(v)end
   end
   if i ~= #ac-1 then --нумерованные параметры не сплошные
       for k,v in pairs(ac) do
           if k>i then acn[tostring(k)] = v; ac[k]=nil end-- удалять в pairs можно
       end
   end
   for k,v in pairs(acn) do
       table.insert(ac, table.concat(f.args[2] or "\n ", k, f.args[3] or ' = ', v, f.args[4] or ) )
   end
   return table.concat(ac,'|')

end

function M.npc(f)-- Итератор по именованно-нумерованным параметрам.

   local tf, ac, ns = f:getParent(), {}, {};
   for k,v in pairs(tf.args) do
       local b,n = string.match(k,"^(.-)%s*(%d*)$");
       n = tonumber(n);
       if n then
           if f.args[b] then
               if not ac[n] then
                   ac[n] = mw.clone(f.args)
                   setmetatable( ac[n], nil ) -- metatable ломает expandTemplate
                   table.insert(ns,n)
               end
               ac[n][b] = v
           end--if f.args[b]
       end--if n
   end--for
   table.sort(ns);
   local tmod = #f.args-1
   for n,i in ipairs(ns) do
       ns[n]=tf:expandTemplate{ title=f.args[n % tmod+1]; args=ac[i] }
   end
   return table.concat(ns)

end

function M.call(f)-- Просто вызывает шаблон с аргументами вызывающего.

   return f:getParent():expandTemplate{ title=f.args[1]; args=f:getParent().args }

end

function M.join(f)-- Версия forall с разделителем вместо шаблона.

   -- f.args[1] — разделитель.
   local t, tf, i = {}, f:getParent(), tonumber(f.args.from) or 1
   local k,j,m = tonumber(f.args.to),i,f.args[3]
   while k and i<=k or tf.args[i] do
   	if (
   		({
   			['_']=function(s)return s~=end;
   			['s']=function(s)return not tostring(s):match("^%s*$")end
   		})[m] or function() return true end
   	)(tf.args[i]) then
   		t[j]=tf.args[i];
   		j=j+1
   	end;
   	i=i+1
   end
   return mw.text.listToText(t,f.args[1],f.args[2] or f.args[1])

end


-- Функции для работы с параметрами шаблона в invoke --


--[[ function M.split(f)-- Разрезает строку f.args[3] -- указанным в f.args[2](?) разделителем

   -- и передаёт куски шаблону f.args[1].
   local tf, ac, oldi, i, e =f:getParent(), {}, 1, f.args[3]:find(f.args[1],1,true)
   -- «f.args[1]» в строке выше — точно не ошибка? --Incnis Mrsi
   while i do
       table.insert( ac,  f.args[3]:sub(oldi, i-1) ); oldi=e+1
   end
   table.insert( ac, f.args[3]:sub(oldi, #f.args[3]-1) )
   return f:getParent():expandTemplate{ title=f.args[1]; args=ac }

end ]]

function M.cycle(f)-- Действует аналогично forall по числовой переменной,

   -- изменяющейся (по умолчанию, от 1) до f.args[2].
   local tf,ac=f:getParent(),{};
   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*$');
   local acr={};
   if not tonumber(s) then error('Начало цикла «'..s..'» — не число') end
   local function dc()
           local r=tf:expandTemplate{ title=f.args[1]; args={s,unpack(ac)} }
           s=s+1;
           if r~= then table.insert(acr,r); return r end
   end
   if type(fh)=='number' then 
       while s<fh do dc() end
   elseif fh~= then
       while tf:expandTemplate{ title=fh; args={s,unpack(ac)} } do dc() end
   else
       while dc() do end
   end
   return table.concat(acr)

end --[[Функция не пашет как можно ждать — пробелы отсекаются после передачи параметров в expandTemplate function M.pass(f)-- Передаёт шаблону параметры без подрезки.

   local ac,i={},1;
   while f.args[2*i] do ac[ tonumber(f.args[2*i]) or f.args[2*i] ] = f.args[2*i+1]; i=i+1 end;
   return  f:getParent():expandTemplate{ title=f.args[1]; args=ac }

end ]] return M