Модуль:PersonMetaCat


ФункцииПравить

docПравить

Может быть использована отдельно для создания документации шаблона метакатегории. Её реализация также используется внутри других функций.

proffesionMetacatПравить

Реализация шаблона {{метакатегория профессии}}. В зависимости от пространства имён вызывает либо #category_desc, либо #doc.

category_descПравить

Создаёт страницу метакатегории и включает её в родительские категории с использованием аргументов страна, страны, век и века, которые заменяются в соответствии со словоформой.

ТестыПравить

При изменении модуля проверяйте, что все тесты выполняются.


local p = {}
local cc = nil --не вызывать раньше времени
local roman = nil --не вызывать раньше времени
local tt = nil --не вызывать раньше времени

local only_p = 'Единственный параметр'
local mdash = ' — '
local first_p = 'Первый параметр'
local second_p = 'второй'

local NS_TEMPLATE = 10
local NS_CATEGORY = 14
local COUNTRY = 'страна'
local CENTURY = 'век'

local params = {
	[COUNTRY] = 'название страны в именительном падеже',
	[CENTURY] = 'номер века арабскими цифрами'
}

local COUNTRY_NOM_PLACEHOLDER = '<страна>'
local CENTURY_NOM_PLACEHOLDER = '<век>'
local COUNTRY_GEN_PLACEHOLDER = '<страны>'
local CENTURY_GEN_PLACEHOLDER = '<века>'

local function error_string(s)
	return '<span class="error">' .. s .. '</span>'
end

local function param_name(p)
	return params[p] or error_string('Неизвестный параметр' .. mdash .. p)
end

local function expand(frame, tname, targs)
	return frame:expandTemplate({title = tname, args = targs})
end

local function cat_link(cat) 
	return '[[:К:' .. cat .. '|' .. cat .. ']]'
end

local function link(x)
	return '[[' .. x .. ']]'
end

local function _doc(first, second, cat, level)
	local ret = 'Шаблон для создания подкатегорий '
	if level and level == 2 then
		ret = ret .. 'второго уровня '
	end
	ret = ret .. 'категории '.. cat_link(cat) .. '‎. '
	if first == nil then
		ret = ret .. error_string('Необходимо перечислить параметры вызова')
	elseif second == nil then
		ret = ret .. only_p .. mdash .. param_name(first)
	else -- first ~= nil, second ~= nil
		ret = ret .. first_p .. mdash .. param_name(first) .. ', ' .. second_p .. mdash .. param_name(second)
	end
	return ret .. '.'
end

function p.doc(frame)
	getArgs = getArgs or require('Module:Arguments').getArgs
	local args = getArgs(frame)
	local level = args.level
	local cat = args.cat or '{{{cat}}}' --чтобы видеть сразу
	local first = args[1]
	local second = args[2]
	return _doc(first, second, cat, level)
end

local function get_roman_century(century)
	roman = roman or require('Module:Roman').convert
	return century and (roman(century) .. ' век') or error_string('Укажите век')
end

local function replace_placeholders(s, country, country_gen, century)
	local century_roman = nil
	local ret = s
	if ret:find(COUNTRY_NOM_PLACEHOLDER) then
		ret = mw.ustring.gsub(ret, COUNTRY_NOM_PLACEHOLDER, country)
	end
	if ret:find(COUNTRY_GEN_PLACEHOLDER) then
		ret = mw.ustring.gsub(ret, COUNTRY_GEN_PLACEHOLDER, country_gen)
	end
	if ret:find(CENTURY_NOM_PLACEHOLDER) then
		century_roman = get_roman_century(century)
		ret = mw.ustring.gsub(ret, CENTURY_NOM_PLACEHOLDER, century_roman)
	end
	if ret:find(CENTURY_GEN_PLACEHOLDER) then
		local century_roman_gen = (century_roman or get_roman_century(century)) .. 'а'
		ret = mw.ustring.gsub(ret, CENTURY_GEN_PLACEHOLDER, century_roman_gen)
	end
	return ret
end

function p.process_cat(cat_desc, country, country_gen, century)
	local split = mw.text.split(cat_desc, '!', true)
	if split == nil or #split == 0 then
		return ''
	elseif #split == 1 then
		return 'К:' .. replace_placeholders(split[1], country, country_gen, century)
	elseif #split >= 2 then
		return 'К:' .. replace_placeholders(split[1], country, country_gen, century) .. '|' .. replace_placeholders(split[2], country, country_gen, century)
	end
end

local function get_country_gen(frame, country)
	cc = cc or require('Module:CountryCases')
	return country and cc._genitive(frame, country) or error_string('Укажите страну')
end

function p.category_desc(frame, args, country, century)
	local country_gen = get_country_gen(frame, country)
	local ret = {expand(frame, 'метакатегория')}
	tt = tt or require('Module:TableTools')
	local n = tt.length(args)
	for i = 1, n do
		local s = p.process_cat(args[i], country, country_gen, century)
		if mw.ustring.len(s) > 0 then
			ret[#ret+1] = link(s)
		end
	end
	return table.concat(ret, '\n')
end

function p.single_category(frame)
	getArgs = getArgs or require('Module:Arguments').getArgs
	local args = getArgs(frame)
	local cat = args[1]
	local country = args[COUNTRY]
	local century = args[CENTURY]
	return p.process_cat(cat, country, get_country_gen(frame, country), century)
end

function p.proffesionMetacat(frame)
	getArgs = getArgs or require('Module:Arguments').getArgs
	local args = getArgs(frame)
	local ns = mw.title.getCurrentTitle().namespace
	if ns == NS_TEMPLATE then
		local ret = {}
		table.insert(ret, expand(frame, 'doc/begin', {'Шаблон:Метакатегория профессии'}))
		table.insert(ret, expand(frame, 'onLua', {'PersonMetaCat', 'proffesionMetacat'}))
		table.insert(ret, _doc(COUNTRY, nil, mw.text.split(args[1], '!')[1]))
		table.insert(ret, expand(frame, 'doc/end'))
		table.insert(ret, '[[К:Шаблоны:Для метакатегорий персоналий]]')
		return table.concat(ret, '\n')
	elseif ns == NS_CATEGORY then
		local country = args[COUNTRY]
		return p.category_desc(frame, args, country, nil)
	end
	return error_string('Шаблон предназначен для категорий')
end

return p