Модуль:Template call code/песочница: различия между версиями
(Новая страница: « Категория:Песочницы модулей») |
Нет описания правки |
||
(не показана 1 промежуточная версия этого же участника) | |||
Строка 1: | Строка 1: | ||
local getArgs = require('Module:Arguments').getArgs | |||
local ru = mw.language.new('ru') | |||
local p = {} | |||
-- Используется для того, чтобы можно было удалять элементы из таблицы | |||
local function copy(other) | |||
local res = {} | |||
for k, v in pairs(other) do | |||
res[k] = v | |||
end | |||
return res | |||
end | |||
[[Категория:Песочницы модулей] | local function makeInvokeFunc(funcName, flags) | ||
return function (frame) | |||
local args = copy(getArgs(frame, { | |||
trim = false, | |||
removeBlanks = false | |||
})) | |||
return p[funcName](args, flags) | |||
end | |||
end | |||
--предотвращает обработку вики-текста в отображении образца | |||
local function processText(str, nowiki) | |||
local res = str | |||
if nowiki then | |||
str = mw.text.unstripNoWiki(str) | |||
str = string.gsub(str, '%[', '[') | |||
str = string.gsub(str, '%]', ']') | |||
str = string.gsub(str, '<', '<') | |||
str = string.gsub(str, '>', '>') | |||
str = string.gsub(str, '{', '{') | |||
str = string.gsub(str, '|', '|') | |||
str = string.gsub(str, '}', '}') | |||
str = string.gsub(str, '\'', ''') | |||
str = string.gsub(str, '"', '"') | |||
str = string.gsub(str, '(://)', '<span>%1</span>') | |||
end | |||
return str | |||
end | |||
local function addParams(args, params) | |||
local text, equals_pos, param, value = '', 0, '', '' | |||
local function addPipe() | |||
if params.spaced then | |||
text = text .. ' ' | |||
end | |||
text = text .. '<span' | |||
if not params.black then | |||
text = text .. ' class="wp-templatelink"' | |||
end | |||
if not params.spaced then | |||
text = text .. ' style="margin:0 2px;"' | |||
end | |||
text = text .. '>|</span>' | |||
end | |||
for k, v in pairs(args) do | |||
if type(k) == 'number' then -- Неименованные параметры | |||
if k >= params.from then | |||
equals_pos = v:find('=') | |||
if equals_pos and v:find('{{=}}') == equals_pos - 2 then | |||
equals_pos = nil | |||
end | |||
if equals_pos then -- Содержащие «=» преобразуем в именованные | |||
param = v:sub(1, equals_pos - 1) | |||
value = v:sub(equals_pos + 1) | |||
addPipe() | |||
text = text .. processText(param, params.nowiki) .. '=' .. processText(value, params.nowiki) | |||
else -- Истинно неименованные | |||
addPipe() | |||
text = text .. processText(v, params.nowiki) | |||
end | |||
end | |||
elseif not k:find('^_') then -- Именованные параметры, исключая модификаторы внешнего вида | |||
addPipe() | |||
text = text .. processText(k, params.nowiki) .. '=' .. processText(v, params.nowiki) | |||
end | |||
end | |||
return text | |||
end | |||
function p._main(args, flags) | |||
local name = args[1] | |||
table.remove(args, 1) | |||
-- Вещи типа «=» в первом параметре | |||
if not name then | |||
for k, v in pairs(args) do | |||
if not k:find('^_') then | |||
name = k .. '=' .. v | |||
args[k] = nil | |||
break | |||
end | |||
end | |||
end | |||
local optpText | |||
if not flags.withoutParams then | |||
if name then | |||
local spanOffset = mw.ustring.find(name, '<span') -- След использования шаблона optp | |||
if spanOffset then | |||
optpText = mw.ustring.sub(name, spanOffset) | |||
name = mw.ustring.sub(name, 1, spanOffset - 1) | |||
end | |||
end | |||
end | |||
local yesno = require('Module:Yesno') | |||
local nolink, subst, podst, global, nav, noRedirect, ucFirst, black, nobr | |||
local tag, style, comment, lang, sister, global, textInPlaceOfName, | |||
namePrefix, prefix, postfix, nowiki | |||
local spaced, from | |||
if flags.withoutParams then | |||
for i, v in ipairs(args) do | |||
if v == 'nl' or v == 'nolink' then | |||
noLink = true | |||
elseif v == 's' then | |||
subst = true | |||
elseif v == 'п' then | |||
podst = true | |||
elseif v == 'g' then | |||
global = true | |||
elseif v == 'nav' then | |||
nav = true | |||
elseif v == 'noredir' then | |||
noRedirect = true | |||
elseif v == 'u' then | |||
ucFirst = true | |||
elseif v == 'b' then | |||
black = true | |||
elseif v == 'nobr' then | |||
nobr = true | |||
end | |||
end | |||
tag = args.tag or 'span' | |||
style = args.style | |||
comment = args.comment | |||
lang = args.lang | |||
sister = args.sister | |||
textInPlaceOfName = args.text | |||
namePrefix = args.nameprefix | |||
prefix = args.prefix | |||
postfix = args.postfix | |||
nowiki = args.nowiki | |||
else | |||
noLink = yesno(args._nolink or args._nl, false) or not yesno(args._link, false) | |||
subst = yesno(args._s, false) | |||
podst = yesno(args['_п'], false) | |||
global = yesno(args._g, false) | |||
nav = yesno(args._nav, false) | |||
noRedirect = yesno(args._noredir, false) | |||
ucFirst = yesno(args._u, false) | |||
black = yesno(args._b, false) | |||
nobr = yesno(args._nobr, false) | |||
tag = args._tag or 'span' | |||
style = args._style | |||
comment = args._comment | |||
lang = args._lang | |||
sister = args._sister | |||
textInPlaceOfName = args._text | |||
namePrefix = args._nameprefix | |||
prefix = args._prefix | |||
postfix = args._postfix | |||
nowiki = args._nowiki | |||
spaced = yesno(args._spaced, false) | |||
from = (tonumber(args._from) or 2) - 1 | |||
end | |||
global = global or name and mw.ustring.sub(name, 1, 1) == ':' | |||
black = black or tag ~= 'span' | |||
if textInPlaceOfName == '' then | |||
textInPlaceOfName = nil | |||
end | |||
if comment == '' then | |||
comment = nil | |||
end | |||
if lang == '' then | |||
lang = nil | |||
end | |||
if sister == '' then | |||
sister = nil | |||
end | |||
if namePrefix == '' then | |||
namePrefix = nil | |||
end | |||
if name then | |||
local trimmedName = mw.text.trim(name) | |||
if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'subst:' then | |||
subst = true | |||
name = mw.ustring.sub(trimmedName, 7) | |||
end | |||
if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'подст:' then | |||
podst = true | |||
name = mw.ustring.sub(trimmedName, 7) | |||
end | |||
end | |||
if subst then | |||
namePrefix = 'subst:' | |||
elseif podst then | |||
namePrefix = 'подст:' | |||
end | |||
local currentTitle = mw.title.getCurrentTitle() | |||
-- При опущенном первом параметре берём имя шаблона из названия страницы | |||
if name == '' or not name then | |||
local currentTitleRoot = currentTitle.rootText | |||
if not ucFirst and | |||
((ru:uc(currentTitleRoot) ~= currentTitleRoot and | |||
-- Книга:Литературное наследство, TranslateDate | |||
not mw.ustring.match(currentTitleRoot, '^[А-Яа-яA-Za-z]+:?[А-ЯA-Z]') | |||
) or | |||
#currentTitleRoot == 1 | |||
) | |||
then | |||
name = ru:lcfirst(currentTitleRoot) | |||
else | |||
name = currentTitleRoot | |||
end | |||
end | |||
-- Начинаем собирать код | |||
local linkBody, titleObject, linkBegin, linkDivider, linkEnd | |||
local prefixes = {} | |||
if lang then | |||
table.insert(prefixes, lang) | |||
end | |||
if sister then | |||
table.insert(prefixes, sister) | |||
end | |||
linkBody = table.concat(prefixes, ':') | |||
if #linkBody ~= 0 then | |||
linkBody = ':' .. linkBody | |||
end | |||
if mw.ustring.sub(name, 1, 1) ~= ':' then | |||
linkBody = linkBody .. ':' | |||
end | |||
if not global then | |||
linkBody = linkBody .. 'Template:' | |||
end | |||
linkBody = linkBody .. name | |||
titleObject = mw.title.new(linkBody) | |||
local noLink = noLink or currentTitle == titleObject | |||
local takeBracketsInLink = not noLink and | |||
mw.ustring.len(name) == 1 and | |||
not black and | |||
not namePrefix | |||
if not noLink then | |||
if not noRedirect or ( | |||
noRedirect and | |||
not lang and | |||
not sister and | |||
not titleObject.exists | |||
) then | |||
linkBegin = '[[' | |||
linkEnd = ']]' | |||
linkDivider = '|' | |||
else | |||
linkBegin = '[' | |||
linkEnd = ']' | |||
linkDivider = ' ' | |||
linkBody = titleObject:fullUrl('redirect=no') | |||
end | |||
end | |||
local text = '' | |||
if tag then | |||
text = text .. '<' .. tag .. ' class="templateCallCode' | |||
if nobr then | |||
text = text .. ' nowrap' | |||
end | |||
text = text .. '"' | |||
if style then | |||
text = text .. ' style="' .. style .. '"' | |||
end | |||
text = text .. '>' | |||
end | |||
if prefix then | |||
text = text .. processText(prefix, nowiki) | |||
end | |||
if not black then | |||
text = text .. '<span class="wp-templatelink">' | |||
end | |||
text = text .. '{' | |||
if not takeBracketsInLink then | |||
text = text .. '{' | |||
end | |||
if namePrefix then | |||
text = text .. namePrefix | |||
end | |||
if not black then | |||
text = text .. '</span>' | |||
end | |||
if nav and currentTitle == titleObject then | |||
text = text .. '\'\'\'' | |||
end | |||
text = text .. '<span data-navboxnavigation-link="0">' | |||
local commentedLabel | |||
if comment then | |||
-- https://phabricator.wikimedia.org/T200704 | |||
-- commentedLabel = mw.getCurrentFrame():expandTemplate({title = 'comment', args = {(textInPlaceOfName or name), comment}}) | |||
commentedLabel = '<span class="commentedText" title="' .. comment .. '" style="border-bottom: 1px dotted; cursor: help;">' .. | |||
(textInPlaceOfName or name) .. | |||
'</span>' | |||
end | |||
local label = (commentedLabel or textInPlaceOfName or name) | |||
if not noLink then | |||
if noRedirect then | |||
text = text .. '<span class="plainlinks">' | |||
end | |||
text = text .. linkBegin .. linkBody .. linkDivider | |||
if not noLink and takeBracketsInLink then | |||
text = text .. '<span class="wp-templatelink">{</span>' | |||
end | |||
text = text .. label | |||
if not noLink and takeBracketsInLink then | |||
text = text .. '<span class="wp-templatelink">}</span>' | |||
end | |||
text = text .. linkEnd | |||
if noRedirect then | |||
text = text .. '</span>' | |||
end | |||
else | |||
text = text .. label | |||
end | |||
text = text .. '</span>' | |||
if nav and currentTitle == titleObject then | |||
text = text .. '\'\'\'' | |||
end | |||
if not flags.withoutParams then | |||
if optpText then | |||
text = text .. optpText | |||
end | |||
text = text .. addParams(args, { | |||
spaced = spaced, | |||
black = black, | |||
nowiki = nowiki, | |||
from = from | |||
}) | |||
if spaced then | |||
text = text .. ' ' | |||
end | |||
end | |||
if not black then | |||
text = text .. '<span class="wp-templatelink">' | |||
end | |||
text = text .. '}' | |||
if not takeBracketsInLink then | |||
text = text .. '}' | |||
end | |||
if not black then | |||
text = text .. '</span>' | |||
end | |||
if postfix then | |||
text = text .. processText(postfix, nowiki) | |||
end | |||
if tag then | |||
text = text .. '</' .. tag .. '>' | |||
end | |||
return text | |||
end | |||
function p._onlyParams(args) | |||
local span = mw.html.create('span') | |||
span:css( 'color', mw.getCurrentFrame():expandTemplate({ title = 'optp/color' }) ) | |||
local yesno = require('Module:Yesno') | |||
span:wikitext(addParams(args, { | |||
spaced = yesno(args._spaced, false), | |||
black = true, | |||
nowiki = yesno(args._nowiki, false), | |||
from = 1 | |||
})) | |||
return tostring(span) | |||
end | |||
p.withoutParams = makeInvokeFunc('_main', {withoutParams = true}) | |||
p.withParams = makeInvokeFunc('_main', {withoutParams = false}) | |||
p.onlyParams = makeInvokeFunc('_onlyParams') | |||
return p | |||
[[Категория: Песочницы модулей]] |
Текущая версия от 19:47, 12 июля 2022
local getArgs = require('Module:Arguments').getArgs local ru = mw.language.new('ru')
local p = {}
-- Используется для того, чтобы можно было удалять элементы из таблицы local function copy(other) local res = {} for k, v in pairs(other) do res[k] = v end return res end
local function makeInvokeFunc(funcName, flags) return function (frame) local args = copy(getArgs(frame, { trim = false, removeBlanks = false })) return p[funcName](args, flags) end end
--предотвращает обработку вики-текста в отображении образца local function processText(str, nowiki) local res = str if nowiki then str = mw.text.unstripNoWiki(str) str = string.gsub(str, '%[', '[') str = string.gsub(str, '%]', ']') str = string.gsub(str, '<', '<') str = string.gsub(str, '>', '>') str = string.gsub(str, '{', '{') str = string.gsub(str, '|', '|') str = string.gsub(str, '}', '}') str = string.gsub(str, '\, ''') str = string.gsub(str, '"', '"') str = string.gsub(str, '(://)', '%1') end return str end
local function addParams(args, params) local text, equals_pos, param, value = , 0, ,
local function addPipe() if params.spaced then text = text .. ' ' end text = text .. '<span' if not params.black then text = text .. ' class="wp-templatelink"' end if not params.spaced then text = text .. ' style="margin:0 2px;"' end text = text .. '>|' end
for k, v in pairs(args) do if type(k) == 'number' then -- Неименованные параметры if k >= params.from then equals_pos = v:find('=') if equals_pos and v:find('=') == equals_pos - 2 then equals_pos = nil end if equals_pos then -- Содержащие «=» преобразуем в именованные param = v:sub(1, equals_pos - 1) value = v:sub(equals_pos + 1) addPipe() text = text .. processText(param, params.nowiki) .. '=' .. processText(value, params.nowiki) else -- Истинно неименованные addPipe() text = text .. processText(v, params.nowiki) end end elseif not k:find('^_') then -- Именованные параметры, исключая модификаторы внешнего вида addPipe() text = text .. processText(k, params.nowiki) .. '=' .. processText(v, params.nowiki) end end
return text end
function p._main(args, flags) local name = args[1] table.remove(args, 1)
-- Вещи типа «=» в первом параметре if not name then for k, v in pairs(args) do if not k:find('^_') then name = k .. '=' .. v args[k] = nil break end end end
local optpText if not flags.withoutParams then if name then local spanOffset = mw.ustring.find(name, '<span') -- След использования шаблона optp if spanOffset then optpText = mw.ustring.sub(name, spanOffset) name = mw.ustring.sub(name, 1, spanOffset - 1) end end end
local yesno = require('Module:Yesno')
local nolink, subst, podst, global, nav, noRedirect, ucFirst, black, nobr local tag, style, comment, lang, sister, global, textInPlaceOfName, namePrefix, prefix, postfix, nowiki local spaced, from
if flags.withoutParams then for i, v in ipairs(args) do if v == 'nl' or v == 'nolink' then noLink = true elseif v == 's' then subst = true elseif v == 'п' then podst = true elseif v == 'g' then global = true elseif v == 'nav' then nav = true elseif v == 'noredir' then noRedirect = true elseif v == 'u' then ucFirst = true elseif v == 'b' then black = true elseif v == 'nobr' then nobr = true end end
tag = args.tag or 'span' style = args.style comment = args.comment lang = args.lang sister = args.sister textInPlaceOfName = args.text namePrefix = args.nameprefix prefix = args.prefix postfix = args.postfix nowiki = args.nowiki else noLink = yesno(args._nolink or args._nl, false) or not yesno(args._link, false) subst = yesno(args._s, false) podst = yesno(args['_п'], false) global = yesno(args._g, false) nav = yesno(args._nav, false) noRedirect = yesno(args._noredir, false) ucFirst = yesno(args._u, false) black = yesno(args._b, false) nobr = yesno(args._nobr, false)
tag = args._tag or 'span' style = args._style comment = args._comment lang = args._lang sister = args._sister textInPlaceOfName = args._text namePrefix = args._nameprefix prefix = args._prefix postfix = args._postfix nowiki = args._nowiki
spaced = yesno(args._spaced, false) from = (tonumber(args._from) or 2) - 1
end
global = global or name and mw.ustring.sub(name, 1, 1) == ':' black = black or tag ~= 'span'
if textInPlaceOfName == then textInPlaceOfName = nil end if comment == then comment = nil end if lang == then lang = nil end if sister == then sister = nil end if namePrefix == then namePrefix = nil end
if name then local trimmedName = mw.text.trim(name) if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'subst:' then subst = true name = mw.ustring.sub(trimmedName, 7) end if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'подст:' then podst = true name = mw.ustring.sub(trimmedName, 7) end end
if subst then namePrefix = 'subst:' elseif podst then namePrefix = 'подст:' end
local currentTitle = mw.title.getCurrentTitle() -- При опущенном первом параметре берём имя шаблона из названия страницы if name == or not name then local currentTitleRoot = currentTitle.rootText if not ucFirst and ((ru:uc(currentTitleRoot) ~= currentTitleRoot and -- Книга:Литературное наследство, TranslateDate not mw.ustring.match(currentTitleRoot, '^[А-Яа-яA-Za-z]+:?[А-ЯA-Z]') ) or #currentTitleRoot == 1 ) then name = ru:lcfirst(currentTitleRoot) else name = currentTitleRoot end end
-- Начинаем собирать код local linkBody, titleObject, linkBegin, linkDivider, linkEnd
local prefixes = {} if lang then table.insert(prefixes, lang) end if sister then table.insert(prefixes, sister) end linkBody = table.concat(prefixes, ':')
if #linkBody ~= 0 then linkBody = ':' .. linkBody end if mw.ustring.sub(name, 1, 1) ~= ':' then linkBody = linkBody .. ':' end if not global then linkBody = linkBody .. 'Template:' end linkBody = linkBody .. name titleObject = mw.title.new(linkBody)
local noLink = noLink or currentTitle == titleObject local takeBracketsInLink = not noLink and mw.ustring.len(name) == 1 and not black and not namePrefix
if not noLink then if not noRedirect or ( noRedirect and not lang and not sister and not titleObject.exists ) then linkBegin = '[[' linkEnd = ']]' linkDivider = '|' else linkBegin = '[' linkEnd = ']' linkDivider = ' ' linkBody = titleObject:fullUrl('redirect=no') end end
local text = if tag then text = text .. '<' .. tag .. ' class="templateCallCode' if nobr then text = text .. ' nowrap' end text = text .. '"' if style then text = text .. ' style="' .. style .. '"' end text = text .. '>' end if prefix then text = text .. processText(prefix, nowiki) end
if not black then text = text .. '' end text = text .. '{' if not takeBracketsInLink then text = text .. '{' end if namePrefix then text = text .. namePrefix end if not black then text = text .. '' end
if nav and currentTitle == titleObject then text = text .. '\'\'\ end
text = text .. ''
local commentedLabel if comment then -- https://phabricator.wikimedia.org/T200704 -- commentedLabel = mw.getCurrentFrame():expandTemplate({title = 'comment', args = {(textInPlaceOfName or name), comment}}) commentedLabel = '' .. (textInPlaceOfName or name) .. '' end local label = (commentedLabel or textInPlaceOfName or name) if not noLink then if noRedirect then text = text .. '' end text = text .. linkBegin .. linkBody .. linkDivider if not noLink and takeBracketsInLink then text = text .. '{' end text = text .. label if not noLink and takeBracketsInLink then text = text .. '}' end text = text .. linkEnd if noRedirect then text = text .. '' end else text = text .. label end
text = text .. ''
if nav and currentTitle == titleObject then text = text .. '\'\'\ end
if not flags.withoutParams then if optpText then text = text .. optpText end
text = text .. addParams(args, { spaced = spaced, black = black, nowiki = nowiki, from = from })
if spaced then text = text .. ' ' end end
if not black then text = text .. '' end text = text .. '}' if not takeBracketsInLink then text = text .. '}' end if not black then text = text .. '' end
if postfix then text = text .. processText(postfix, nowiki) end if tag then text = text .. '</' .. tag .. '>' end
return text end
function p._onlyParams(args) local span = mw.html.create('span') span:css( 'color', mw.getCurrentFrame():expandTemplate({ title = 'optp/color' }) )
local yesno = require('Module:Yesno')
span:wikitext(addParams(args, { spaced = yesno(args._spaced, false), black = true, nowiki = yesno(args._nowiki, false), from = 1 }))
return tostring(span) end
p.withoutParams = makeInvokeFunc('_main', {withoutParams = true}) p.withParams = makeInvokeFunc('_main', {withoutParams = false}) p.onlyParams = makeInvokeFunc('_onlyParams')
return p