Модуль:Template call code
Для документации этого модуля может быть создана страница Модуль:Template call code/doc
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 class="'
if not params.spaced then
text = text .. ' ts-templateCallCode-pipe'
end
if not params.black then
text = text .. ' ts-templateCallCode-weak'
end
-- |, чтобы не трактовалось как разделитель ячеек в таблицах
text = text .. '">|</span>'
end
local beforeParam = '<span class="ts-templateCallCode-param">'
local afterParam = '</span>'
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 .. beforeParam .. processText(param, params.nowiki) .. '=' .. processText(value, params.nowiki) .. afterParam
else -- Истинно неименованные
addPipe()
local paramValue = processText(v, params.nowiki)
if #paramValue ~= 0 then
text = text .. beforeParam .. paramValue .. afterParam
end
end
end
elseif not k:find('^_') then -- Именованные параметры, исключая модификаторы внешнего вида
addPipe()
text = text .. beforeParam .. processText(k, params.nowiki) .. '=' .. processText(v, params.nowiki) .. afterParam
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
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="ts-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
text = text .. '<span class="'
if not spaced then
text = text .. ' ts-templateCallCode-opening'
end
if not black then
text = text .. ' ts-templateCallCode-weak'
end
text = text .. '">{{'
if namePrefix then
text = text .. namePrefix
end
text = text .. '</span>'
if nav and currentTitle == titleObject then
text = text .. '\'\'\''
end
text = text .. '<span class="ts-templateCallCode-templateName" 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 .. label .. 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
text = text .. '<span class="'
if not spaced then
text = text .. ' ts-templateCallCode-closing'
end
if not black then
text = text .. ' ts-templateCallCode-weak'
end
text = text .. '">}}</span>'
if postfix then
text = text .. processText(postfix, nowiki)
end
if tag then
text = text .. '</' .. tag .. '>'
end
local ts = mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = { src = 'Модуль:Template call code/styles.css' } }
return ts .. text
end
function p._onlyParams(args)
local yesno = require('Module:Yesno')
return addParams(args, {
spaced = yesno(args._spaced, false),
black = true,
nowiki = yesno(args._nowiki, false),
from = 1
})
end
p.withoutParams = makeInvokeFunc('_main', {withoutParams = true})
p.withParams = makeInvokeFunc('_main', {withoutParams = false})
p.onlyParams = makeInvokeFunc('_onlyParams')
return p