Модуль:Transclude: различия между версиями
Материал из ChronoWiki
Перейти к навигацииПерейти к поиску (По запросу У:Wikisaurus) |
(Изменять order в зависимости от from .. to в методе cycle. Вывод inline или newline в методе cycle.) |
||
Строка 117: | Строка 117: | ||
function M.cycle(f)-- Действует аналогично forall по числовой переменной, | function M.cycle(f)-- Действует аналогично forall по числовой переменной, | ||
-- изменяющейся (по умолчанию, от 1) до f.args[2]. | -- изменяющейся (по умолчанию, от 1) до f.args[2]. | ||
− | local tf,ac=f:getParent(),{}; | + | 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 | for p,k in pairs(f.args) do | ||
if type(p)=='number' then | if type(p)=='number' then | ||
Строка 127: | Строка 131: | ||
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 | ||
--[[Функция не пашет как можно ждать — пробелы отсекаются после передачи параметров в expandTemplate | --[[Функция не пашет как можно ждать — пробелы отсекаются после передачи параметров в expandTemplate |
Версия 06:19, 21 июня 2020
Для документации этого модуля может быть создана страница Модуль:Transclude/doc
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 function M.forall(frame)-- Итератор по нумерованным аргументам вызывающего шаблона. local template = frame.args[1] local separator = frame.args.separator or '' local conjunction = frame.args.conjunction or separator local results = {} for param, value in pairs(frame:getParent().args) do if type(param) == 'number' then results[param] = frame:expandTemplate{ title = template, args = {value} } end end return mw.text.listToText( results, separator, conjunction ) 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,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 --[[Функция не пашет как можно ждать — пробелы отсекаются после передачи параметров в 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