Модуль:DecadeMetaCat

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
Документация

Модуль используется для навигации и категоризации категорий по десятилетиям (для категорий с заголовком, включающим «<число кратное 10>-е/-х годы/годов/годах»).

  • Определяет десятилетие и эру (до н.э. / н.э.).
  • Создаёт навигационную линейку по десятилетиям.
  • Корректно работает с десятилетиями до нашей эры.
  • Добавляет категории.

Использование[править код]

{{#invoke:DecadeMetaCat|main
|Мир <десятилетие>-х годов
|Мир <век> века!<ключ>
|Мир по десятилетиям!<ключ>
}}
  • <десятилетие> — десятилетие числом (без окончания -е/-х)
  • <век> — век римскими цифрами без слова «век»
  • <ключ> — ключ сортировки, н. э. — год, до н. э. — отрицательное число начиная с -10000 (-10000 == 0-е годы до н. э. -9990 == 10-е годы до н. э. и т. д.); нужен для корректной сортировки в категориях

Полная версия

{{#invoke:DecadeMetaCat|main
|Категория 1![ключ сортировки]
...
|Категория N[...]
|min = до какого года рисовать линейку слева, по умолчанию -40000 (0 — рисовать только года нашей эры)
|max = до какого года рисовать линейку справа, по умолчанию 2100
|range = сколько десятилетий в линейке слева и справа, по умолчанию 5
|title = заголовок страницы, используемый вместо текущего (для тестов)
}}

Категория состоит из 2-х полей, разделённых ! (восклицательным знаком):

Примеры:

  • |Мир по десятилетиям!<ключ> — добавлять категорию «Мир по десятилетиям» с ключом сортировки <ключ>

Дополнительные функции[править код]

Функция expand

  • заменяет <десятилетие> на текущее, по необходимости добавив «до н. э.»
  • заменяет <век> на текущий, по необходимости добавив «до н. э.»
  • заменяет <ключ> на ключ сортировки

Пример:

{{#invoke:DecadeMetaCat|expand|Мир <десятилетие>-х годов}}

на странице «К:Земля в 100-е годы до н. э.» вернёт:

Мир 100-х годов до н. э.

См. также[править код]

---*- mode: lua; coding: utf-8; -*-

local p = {}

-- переменные
local dec -- десятилетие, положительное число
local BC   -- 0 == н.э. 1 == до н.э.
local templ -- строка-шаблон вида 'Мир в %s-е годы%s'
local title = mw.title.getCurrentTitle().text

-- опции
local dec_min = -40000 -- 0 == только н.э.
local dec_max = 2100 -- XXI
local range = 5

-- экспортируемые функции
local getArgs = require('Module:Arguments').getArgs
local sparseIpairs = require('Module:TableTools').sparseIpairs
--local toroman = require('Module:Math').Roman
local toroman = require('Module:Roman').convert
local getStyles = require('Модуль:Индекс категории').getStyles
local gsub = mw.ustring.gsub

local function get_templ(s)
	-- формируем строку-шаблон вида:
	-- 'Мир в 90-е годы до н. э.' -> 'Мир в %s-е годы%s'
	-- определяем BC
	local t
	t, BC = gsub(s, '[0-9]*0(-[ех] год[ыоа][вх]?) до н. э.', '%%s%1%%s') -- годы/годов/годах
	local n = BC
	if BC ~= 1 then
		t, n = gsub(s, '[0-9]*0(-[ех] год[ыоа][вх]?)', '%%s%1%%s')
	end
	if n ~= 1 then
		-- не найдено или найдено больше одного
		error('десятилетие не найдено')
	end
	templ = t
end

local function get_dec(t)
	local _, _, d = mw.ustring.find(t, '([0-9]*0)-[ех] год')
	dec = d
	if not dec then error('десятилетие не найдено') end
	dec = tonumber(dec)
end

local function format(d, wiki)
	local bcs, t
	if d < 0 then
		d = -d-10
		bcs = ' до н. э.'
		--t = tostring(d)..' до н. э.'
		t = '-'..d
	else
		bcs = ''
		t = d
	end
	local s
	if wiki then
		s = string.format(templ, d, bcs)
		s = string.format('[[:К:%s|%s]]', s, t)
	else
		s = t
	end
	return s
end

local function navbox()
	local d = dec
	if BC == 1 then
		-- 0-е годы до н.э. d=-10, 10-е до н.э. d=-20, 20-е до н.э. d=-30 и т.д.
		d = -dec-10
	end
	local wt = mw.html.create('div')
		:addClass('ts-module-Индекс_категории hlist')
	local row = wt:tag('ul')
	local dstart
	if dec_min < 0 then
		dstart = math.max(dec_min-10, d - range*10)
	else
		dstart = math.max(dec_min, d - range*10)
	end
	local dend = math.min(dec_max, d + range*10) -- FIXME: до н.э.
	for i = dstart, dend, 10 do
		row:tag('li'):wikitext(format(i, true))
	end
	return getStyles() .. tostring(wt)
end

local function do_expand(s)
-- <десятилетие> - десятилетие числом (без окончания -е/-х)
-- <ключ> - ключ сортировки, н.э. - номер года,
-- до н.э. - отрицательное число начиная с -10000 (-10000 == 0-е годы до н.э. -9990 == 10-е годы до н.э. -9980 == 20-е годы до н.э. и т.д.)
-- <век> - век римскими цифрами
	local c = toroman(math.floor(dec/100)+1) -- век
	-- в/во
	if c == 'II' then
		s = gsub(s, ' в <век>', ' во <век>')
	end
	if BC == 1 then
		s = gsub(s, '<десятилетие>(-[ех] год[ыоа][вх]?)', dec..'%1 до н. э.') -- годы/годов/годах
		s = gsub(s, '<ключ>', dec-10000) -- ?
		s = gsub(s, '<век> (век[еа]?)', c..' %1 до н. э.')
	else
		s = gsub(s, '<десятилетие>', dec)
		s = gsub(s, '<ключ>', dec)
		s = gsub(s, '<век>', c)
	end
	return s
end

local function cats(args)
	local s, t
	local ret = ''
	for _, s in sparseIpairs(args) do
		t = mw.text.split(s, '!', true)
		if t[2] and t[2] ~= '' then
			ret = ret .. string.format('[[Категория:%s|%s]]', t[1], mw.text.trim(t[2]))
		else
			ret = ret .. string.format('[[Категория:%s]]', t[1])
		end
	end
	return do_expand(ret)
end

function p.main(frame)
	local args = getArgs(frame)
	title = args['title'] or title
	-- разбор аргументов
	range = tonumber(args['range'] or range)
	dec_min = tonumber(args['min'] or dec_min)
	dec_max = tonumber(args['max'] or dec_max)
	-- нахождение текушего года
	get_dec(title)
	-- создание шаблона-строки
	get_templ(title)
	-- создание навбокса и категорий
	return navbox(title) .. cats(args)
end

function p.expand(frame)
	local args = getArgs(frame)
	title = args['title'] or title
	get_dec(title)
	BC = mw.ustring.find(title, '[0-9]*0-[ех] год[ыоа][вх]? до н%. э%.')
	if BC then
		BC = 1
	else
		BC = 0
	end
	return do_expand(args[1])
end

return p