Модуль:Template call code: различия между версиями

Материал из Буквицы
Перейти к навигации Перейти к поиску
м (Karaby переименовал страницу Модуль:Template call code&action=edit в Модуль:Template call code без оставления перенаправления)
м (1 версия импортирована)
 
(не показана 1 промежуточная версия 1 участника)
Строка 13: Строка 13:
end
end


local function makeInvokeFunc(funcName)
local function makeInvokeFunc(funcName, flags)
return function (frame)
return function (frame)
local args = copy(getArgs(frame, {
local args = copy(getArgs(frame, {
Строка 19: Строка 19:
removeBlanks = false
removeBlanks = false
}))
}))
return p[funcName](args)
return p[funcName](args, flags)
end
end
end
end


p.withoutParams = makeInvokeFunc('_withoutParams')
--предотвращает обработку вики-текста в отображении образца
 
local function processText(str, nowiki)
function p._withoutParams(args)
local res = str
local name = args[1]
if nowiki then
table.remove(args, 1)
str = mw.text.unstripNoWiki(str)
str = string.gsub(str, '%[', '[')
-- Вещи типа «=» в первом параметре
str = string.gsub(str, '%]', ']')
if not name then
str = string.gsub(str, '<', '&lt;')
for k, v in pairs(args) do
str = string.gsub(str, '>', '&gt;')
if not k:find('^_') then
str = string.gsub(str, '{', '&#123;')
name = k .. '=' .. v
str = string.gsub(str, '|', '&#124;')
args[k] = nil
str = string.gsub(str, '}', '&#125;')
break
str = string.gsub(str, '\'', '&#39;')
end
str = string.gsub(str, '"', '&quot;')
end
str = string.gsub(str, '(://)', '<span>%1</span>')
end
local flags = {}
for i, v in ipairs(args) do
if v == 'nl' or v == 'nolink' then
flags.noLink = true
elseif v == 's' then
flags.subst = true
elseif v == 'п' then
flags.podst = true
elseif v == 'g' then
flags.global = true
elseif v == 'nav' then
flags.nav = true
elseif v == 'noredir' then
flags.noRedirect = true
elseif v == 'u' then
flags.ucFirst = true
elseif v == 'b' then
flags.black = true
end
end
if name then
local trimmedName = mw.text.trim(name)
if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'subst:' then
flags.subst = true
name = mw.ustring.sub(trimmedName, 7)
end
if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'подст:' then
flags.podst = true
name = mw.ustring.sub(trimmedName, 7)
end
end
end
return str
if args.text == '' then
args.text = nil
end
if args.comment == '' then
args.comment = nil
end
if args.lang == '' then
args.lang = nil
end
if args.sister == '' then
args.sister = nil
end
local currentTitle = mw.title.getCurrentTitle()
-- При опущенном первом параметре берём имя шаблона из названия страницы
if name == '' or not name then
local currentTitleRoot = currentTitle.rootText
if not flags.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 global = flags.global or mw.ustring.sub(name, 1, 1) == ':'
-- Начинаем собирать код
local linkBody, titleObject, linkBegin, linkDivider, linkEnd
local prefixes = {}
if args.lang then
table.insert(prefixes, args.lang)
end
if args.sister then
table.insert(prefixes, args.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 = flags.noLink or currentTitle == titleObject
local takeBracketsInLink = not noLink and
mw.ustring.len(name) == 1 and
not flags.black and
not flags.subst and
not flags.podst
if not noLink then
if not flags.noRedirect or (
flags.noRedirect and
not args.lang and
not args.sister and
not titleObject.exists
) then
linkBegin = '[['
linkEnd = ']]'
linkDivider = '|'
else
linkBegin = '['
linkEnd = ']'
linkDivider = ' '
linkBody = titleObject:fullUrl('redirect=no')
end
end
local text = ''
if flags.nav and currentTitle == titleObject then
text = text .. '\'\'\''
end
if not flags.black then
text = text .. '<span class="wp-templatelink">'
end
text = text .. '{'
if not takeBracketsInLink then
text = text .. '{'
end
if flags.subst then
text = text .. 'subst:'
elseif flags.podst then
text = text .. 'подст:'
end
if not flags.black then
text = text .. '</span>'
end
text = text .. '<span data-navboxnavigation-link="0">'
local commentedLabel
if args.comment then
-- https://phabricator.wikimedia.org/T200704
-- commentedLabel = mw.getCurrentFrame():expandTemplate({title = 'comment', args = {(args.text or name), args.comment}})
commentedLabel = '<span class="commentedText" title="' .. args.comment .. '" style="border-bottom: 1px dotted; cursor: help;">' ..
(args.text or name) ..
'</span>'
end
local label = (commentedLabel or args.text or name)
if not noLink then
if flags.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 flags.noRedirect then
text = text .. '</span>'
end
else
text = text .. label
end
text = text .. '</span>'
if not flags.black then
text = text .. '<span class="wp-templatelink">'
end
text = text .. '}'
if not takeBracketsInLink then
text = text .. '}'
end
if not flags.black then
text = text .. '</span>'
end
if flags.nav and currentTitle == titleObject then
text = text .. '\'\'\''
end
return text
end
end


function addParams(args, params)
local function addParams(args, params)
local text, equals_pos, param, value = '', 0, '', ''
local text, equals_pos, param, value = '', 0, '', ''
function addPipe()
local function addPipe()
if params.spaced then
if params.spaced then
text = text .. ' '
text = text .. ' '
end
end
text = text .. '<span'
text = text .. '<span class="'
if not params.spaced then
text = text .. ' ts-templateCallCode-pipe'
end
if not params.black then
if not params.black then
text = text .. ' class="wp-templatelink"'
text = text .. ' ts-templateCallCode-weak'
end
if not params.spaced then
text = text .. ' style="margin:0 2px;"'
end
end
text = text .. '>&#124;</span>'
-- &#124;, чтобы не трактовалось как разделитель ячеек в таблицах
text = text .. '">&#124;</span>'
end
end
local beforeParam = '<span class="ts-templateCallCode-param">'
local afterParam = '</span>'
for k, v in pairs(args) do
for k, v in pairs(args) do
if type(k) == 'number' then  -- Неименованные параметры
if type(k) == 'number' then  -- Неименованные параметры
equals_pos = v:find('=')
if k >= params.from then
if equals_pos and v:find('{{=}}') == equals_pos - 2 then
equals_pos = v:find('=')
equals_pos = nil
if equals_pos and v:find('{{=}}') == equals_pos - 2 then
end
equals_pos = nil
if equals_pos then  -- Содержащие «=» преобразуем в именованные
end
param = v:sub(1, equals_pos - 1)
if equals_pos then  -- Содержащие «=» преобразуем в именованные
value = v:sub(equals_pos + 1)
param = v:sub(1, equals_pos - 1)
addPipe()
value = v:sub(equals_pos + 1)
text = text .. param .. '=' .. value
addPipe()
else  -- Истинно неименованные
text = text .. beforeParam .. processText(param, params.nowiki) .. '=' .. processText(value, params.nowiki) .. afterParam
addPipe()
else  -- Истинно неименованные
text = text .. v
addPipe()
local paramValue = processText(v, params.nowiki)
if #paramValue ~= 0 then
text = text .. beforeParam .. paramValue .. afterParam
end
end
end
end
elseif not k:find('^_') then  -- Именованные параметры, исключая модификаторы внешнего вида
elseif not k:find('^_') then  -- Именованные параметры, исключая модификаторы внешнего вида
addPipe()
addPipe()
text = text .. k .. '=' .. v
text = text .. beforeParam .. processText(k, params.nowiki) .. '=' .. processText(v, params.nowiki) .. afterParam
end
end
end
end
Строка 266: Строка 93:
end
end


p.withParams = makeInvokeFunc('_withParams')
function p._main(args, flags)
 
function p._withParams(args)
local name = args[1]
local name = args[1]
table.remove(args, 1)
table.remove(args, 1)
Строка 284: Строка 109:
local optpText
local optpText
if name then
if not flags.withoutParams then
local spanOffset = mw.ustring.find(name, '<span')  -- След использования шаблона optp
if name then
if spanOffset then
local spanOffset = mw.ustring.find(name, '<span')  -- След использования шаблона optp
optpText = mw.ustring.sub(name, spanOffset)
if spanOffset then
name = mw.ustring.sub(name, 1, spanOffset - 1)
optpText = mw.ustring.sub(name, spanOffset)
name = mw.ustring.sub(name, 1, spanOffset - 1)
end
end
end
end
end
Строка 294: Строка 121:
local yesno = require('Module:Yesno')
local yesno = require('Module:Yesno')
local nobr = yesno(args._nobr, false)
local nolink, subst, podst, global, nav, noRedirect, ucFirst, black, nobr
local tag = args._tag or 'span'
local tag, style, comment, lang, sister, global, textInPlaceOfName,
local style = args._style
namePrefix, prefix, postfix, nowiki
local spaced = yesno(args._spaced, false)
local spaced, from
local subst = yesno(args._s, false)
local podst = yesno(args['_п'], false)
if flags.withoutParams then
local global = yesno(args._g, false) or name and mw.ustring.sub(name, 1, 1) == ':'
for i, v in ipairs(args) do
local lang = args._lang
if v == 'nl' or v == 'nolink' then
local sister = args._sister
noLink = true
local nav = yesno(args._nav, false)
elseif v == 's' then
local ucFirst = yesno(args._u, false)
subst = true
local black = yesno(args._b, false) or tag ~= 'span'
elseif v == 'п' then
local noLink = yesno(args._nolink or args._nl, false) or not yesno(args._link, false)
podst = true
local textInPlaceOfName = args._text
elseif v == 'g' then
local comment = args._comment
global = true
local noRedirect = yesno(args._noredir, false)
elseif v == 'nav' then
local prefix = args._prefix
nav = true
local postfix = args._postfix
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
if textInPlaceOfName == '' then
Строка 324: Строка 200:
if sister == '' then
if sister == '' then
sister = nil
sister = nil
end
if namePrefix == '' then
namePrefix = nil
end
end
Строка 336: Строка 215:
name = mw.ustring.sub(trimmedName, 7)
name = mw.ustring.sub(trimmedName, 7)
end
end
end
if subst then
namePrefix = 'subst:'
elseif podst then
namePrefix = 'подст:'
end
end
Строка 343: Строка 228:
local currentTitleRoot = currentTitle.rootText
local currentTitleRoot = currentTitle.rootText
if not ucFirst and
if not ucFirst and
((ru:uc(currentTitleRoot) ~= currentTitleRoot and
(
-- Книга:Литературное наследство, TranslateDate
(
not mw.ustring.match(currentTitleRoot, '^[А-Яа-яA-Za-z]+:?[А-ЯA-Z]')
ru:uc(currentTitleRoot) ~= currentTitleRoot and
) or
-- Книга:Литературное наследство, TranslateDate
not mw.ustring.match(currentTitleRoot, '^[А-Яа-яA-Za-z]+:?[А-ЯA-Z]')
) or
#currentTitleRoot == 1
#currentTitleRoot == 1
)
)
Строка 381: Строка 268:
local noLink = noLink or currentTitle == titleObject
local noLink = noLink or currentTitle == titleObject
local takeBracketsInLink = not noLink and
 
mw.ustring.len(name) == 1 and
not black and
not subst and
not podst
if not noLink then
if not noLink then
if not noRedirect or (
if not noRedirect or (
Строка 407: Строка 289:
local text = ''
local text = ''
if tag then
if tag then
text = text .. '<' .. tag .. ' class="templateCallCode'
text = text .. '<' .. tag .. ' class="ts-templateCallCode'
if nobr then
if nobr then
text = text .. ' nowrap'
text = text .. ' nowrap'
Строка 418: Строка 300:
end
end
if prefix then
if prefix then
text = text .. prefix
text = text .. processText(prefix, nowiki)
end
end
text = text .. '<span class="'
if not spaced then
text = text .. ' ts-templateCallCode-opening'
end
if not black then
if not black then
text = text .. '<span class="wp-templatelink">'
text = text .. ' ts-templateCallCode-weak'
end
end
text = text .. '{{'
text = text .. '">{{'
if subst then
if namePrefix then
text = text .. 'subst:'
text = text .. namePrefix
elseif podst then
text = text .. 'подст:'
end
if not black then
text = text .. '</span>'
end
end
text = text .. '</span>'
if nav and currentTitle == titleObject then
if nav and currentTitle == titleObject then
text = text .. '\'\'\''
text = text .. '\'\'\''
end
end
text = text .. '<span class="ts-templateCallCode-templateName" data-navboxnavigation-link="0">'
local commentedLabel
local commentedLabel
if comment then
if comment then
-- https://phabricator.wikimedia.org/T200704
-- https://phabricator.wikimedia.org/T200704
-- commentedLabel = mw.getCurrentFrame():expandTemplate({title = 'comment', args = {(text or name), comment}})
-- commentedLabel = mw.getCurrentFrame():expandTemplate({title = 'comment', args = {(textInPlaceOfName or name), comment}})
commentedLabel = '<span class="commentedText" title="' .. comment .. '" style="border-bottom: 1px dotted; cursor: help;">' ..
commentedLabel = '<span class="commentedText" title="' .. comment .. '" style="border-bottom: 1px dotted; cursor: help;">' ..
(textInPlaceOfName or name) ..
(textInPlaceOfName or name) ..
Строка 458: Строка 342:
text = text .. label
text = text .. label
end
end
text = text .. '</span>'
if nav and currentTitle == titleObject then
if nav and currentTitle == titleObject then
Строка 463: Строка 349:
end
end
if optpText then
if not flags.withoutParams then
text = text .. optpText
if optpText then
end
text = text .. optpText
end
text = text .. addParams(args, {
spaced = spaced,
text = text .. addParams(args, {
black = black,
spaced = spaced,
})
black = black,
nowiki = nowiki,
if spaced then
from = from
text = text .. ' '
})
if spaced then
text = text .. ' '
end
end
end
if not black then
text = text .. '<span class="'
text = text .. '<span class="wp-templatelink">'
if not spaced then
text = text .. ' ts-templateCallCode-closing'
end
end
text = text .. '}}'
if not black then
if not black then
text = text .. '</span>'
text = text .. ' ts-templateCallCode-weak'
end
end
text = text .. '">}}</span>'
if postfix then
if postfix then
text = text .. postfix
text = text .. processText(postfix, nowiki)
end
end
if tag then
if tag then
Строка 491: Строка 382:
end
end
return text
local ts = mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = { src = 'Модуль:Template call code/styles.css' } }
return ts .. text
end
end
p.onlyParams = makeInvokeFunc('_onlyParams')


function p._onlyParams(args)
function p._onlyParams(args)
local span = mw.html.create('span')
span:css( 'color', mw.getCurrentFrame():expandTemplate({ title = 'optp/color' }) )
local yesno = require('Module:Yesno')
local yesno = require('Module:Yesno')
span:wikitext(addParams(args, {
return addParams(args, {
spaced = yesno(args._spaced, false),
spaced = yesno(args._spaced, false),
black = true,
black = true,
}))
nowiki = yesno(args._nowiki, false),
from = 1
})
end


return tostring(span)
p.withoutParams = makeInvokeFunc('_main', {withoutParams = true})
end
p.withParams = makeInvokeFunc('_main', {withoutParams = false})
p.onlyParams = makeInvokeFunc('_onlyParams')


return p
return p

Текущая версия от 09:30, 24 декабря 2021

Модуль используется в:

  • шаблоне {{tl}} (функция withoutParams());
  • шаблонах {{tlp}}, {{tc}}, {{tpre}}, {{*tpre}}, {{tcl}}, {{tcls}}, {{tls}}, {{шсп}}, {{tlu}} (функция withParams());
  • шаблоне {{optp}} (функция onlyParams()).

См. также


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, '%[', '&#91;')
		str = string.gsub(str, '%]', '&#93;')
		str = string.gsub(str, '<', '&lt;')
		str = string.gsub(str, '>', '&gt;')
		str = string.gsub(str, '{', '&#123;')
		str = string.gsub(str, '|', '&#124;')
		str = string.gsub(str, '}', '&#125;')
		str = string.gsub(str, '\'', '&#39;')
		str = string.gsub(str, '"', '&quot;')
		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
		
		-- &#124;, чтобы не трактовалось как разделитель ячеек в таблицах
		text = text .. '">&#124;</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