Модуль:CenturyMetaCat
Модуль используется для навигиции и категоризации категорий по векам (для категорий с заголовком, включающим «<римские цифры> век/века/веке»).
- Определяет век и эру (до н.э / н.э.).
- Создаёт навигационную линейку по векам.
- Корректно работает с веками до нашей эры.
- Добавляет категории.
Использование
{{#invoke:CenturyMetaCat|main |Мир в <век> веке |Мир <тысячелетие>-го тысячелетия! <ключ> |Мир по векам! <ключ> }}
<век>
— век римскими цифрами без слова «век»<тысячелетие>
— тысячелетие числом (без окончания -е/-м/-го)<ключ>
— ключ сортировки, н. э. — номер века числом, до н. э. — отрицательное число начиная с -99 (-99 == I век до н. э. -98 == II век до н. э. и т. д.); нужен для корректной сортировки в категориях
Полная версия
{{#invoke:CenturyMetaCat|main |Категория 1![ключ сортировки]![диапазон веков от]![диапазон веков до] ... |Категория N[...] |min = до какого века рисовать линейку слева, по умолчанию -39 (0 — рисовать только века нашей эры) |max = до какого века рисовать линейку справа, по умолчанию 21 |range = сколько веков в линейке слева и справа, по умолчанию 5 |title = заголовок страницы, используемый вместо текущего (для тестов) }}
Категории
Категория состоит из 4-х полей, разделенных !
(восклицательным знаком):
- первое — название категории
- второе — ключ сортировки (необязательно)
- третье — начиная с какого века добавлять категорию (необязательно)
- четвертое — каким веком заканчивать добавление категории (необязательно)
Примеры:
|Мир по векам! <ключ>
— добавлять категорию «Мир по векам» с ключом сортировки <пробел><ключ>|Графы Средних веков!<ключ>!5!15
— добавлять категорию «Графы Средних веков» в категории с V по XV века|Книги в общественном достоянии!<ключ>!!19
— добавлять категорию «Книги в общественном достоянии» во все категории до XIX века включительно
Есть эмпирическое правило: в категории обязательно должен быть или <век> (в названии), или <ключ> (в ключе сортировки), но не оба.
Другие опции
|min = до какого века рисовать линейку слева, по умолчанию -39 (0 — рисовать только века нашей эры) |max = до какого века рисовать линейку справа, по умолчанию 21 |range = сколько веков в линейке слева и справа, по умолчанию 5 |title = заголовок страницы, используемый вместо текущего (для тестов)
Дополнительные функции
expand
- заменяет
<век>
на текущий, по необходимости добавив «до н. э.» - заменяет
<тысячелетие>
на текущее, по необходимости добавив «до н. э.» - заменяет
<ключ>
на ключ сортировки
Пример:
{{#invoke:CenturyMetaCat|expand|Мир в <век> веке}}
на странице «К:Земля I века до н. э.» вернёт:
Мир в I веке до н. э.
century_from_title
Возвращает век из заголовка числом, для веков до н.э. с минусом.
См. также
- Модуль:YearMetaCat — аналог для годов и десятилетий
- Модуль:YearMetaCat2 — аналог для годов
- Модуль:DecadeMetaCat — аналог для десятилетий
- Модуль:MetaCatDoc — для документирования шаблонов, использующих этот модуль
---*- mode: lua; coding: utf-8; -*- local p = {} -- константы local ROMAN = { I = 1, IV = 4, V = 5, IX = 9, X = 10, --XL = 40, --L = 50, } -- переменные local cent -- век, положительное число local roman_cent -- век римскими цифрами local BC -- 0 == н.э. 1 == до н.э. local templ -- строка-шаблон вида 'Мир в %s веке%s' local title = mw.title.getCurrentTitle().text -- опции local cent_min -- число, по умолчанию -39, 0 == только н.э. local cent_max -- число, по умолчанию 21 (XXI век) local range = 5 -- экспортируемые функции local getArgs = require('Module:Arguments').getArgs local sparseIpairs = require('Module:TableTools').sparseIpairs local toroman = require('Module:Roman').convert local gsub = mw.ustring.gsub function roman_to_int(s) local i = 1 local num = 0 while i <= s:len() do local c if i < s:len() then c = ROMAN[s:sub(i, i+1)] end if c then num = num + c i = i + 2 else num = num + ROMAN[s:sub(i, i)] i = i + 1 end end return num end local function get_templ(s) -- формируем строку-шаблон вида: -- 'Мир в XI веке до н. э.' -> 'Мир в %s веке%s' -- определяем BC local t t, BC = gsub(s, '[IVX]+ (век[еа]?) до н%. э%.', '%%s %1%%s') local n = BC if BC ~= 1 then t, n = gsub(s, '[IVX]+ (век[еа]?)', '%%s %1%%s') end if n ~= 1 then -- не найдено или найдено больше одного error('Век не найден') end -- в/во, о/об t = gsub(t, 'во %%s веке', 'в %%s веке') templ = gsub(t, 'об %%s веке', 'о %%s веке') end local function get_cent(t) _, _, roman_cent = mw.ustring.find(t, '([IVX]+) век') if not roman_cent then error('век не найден') end cent = roman_to_int(roman_cent) end local function format(c, wiki) local bcs, t if c < 1 then c = 1 - c bcs = ' до н. э.' --t = toroman(c)..' до н. э.' t = '-'..toroman(c) else bcs = '' t = toroman(c) end local s if wiki then -- в/во, о/об local tt = templ if c == 2 then tt = gsub(tt, 'в %%s веке', 'во %%s веке') end if c == 11 then tt = gsub(tt, 'о %%s веке', 'об %%s веке') end s = string.format(tt, toroman(c), bcs) s = string.format('[[:Категория:%s|%s]]', s, t) else s = t end return s end local function navbox() local c c = cent if BC == 1 then -- пропускаем 0 -- I до н.э. c == 0, II до н.э. c == -1 и т.д. c = 1 - cent end local wt = mw.html.create('table'):addClass('standard'):attr('align', 'center') local row = wt:tag('tr') local cstart if cent_min < 1 then cstart = math.max(cent_min+1, c - range) else cstart = math.max(cent_min, c - range) end local cend = math.min(cent_max, c + range) -- FIXME: до н.э. for i = cstart, cend do if i == 1 and i ~= cstart then row:tag('th'):wikitext('') end -- разд. до н.э./н.э. if i == c then row:tag('th'):wikitext(format(i, false)) else row:tag('td'):wikitext(format(i, true)) end end return tostring(wt) end local function do_expand(s) -- <век> - век римскими цифрами без слова "век" (XVII) -- <тысячелетие> - тысячелетие числом (без добавления -е/-м/-го) -- <ключ> - ключ сортировки, н.э. - номер века числом, -- до н.э. - отрицательное число начиная с -99 (-99 == I век до н.э. -98 == II век до н.э. и т.д.) local mil = math.floor((cent-1)/10)+1 -- тысячелетие -- в/во, о/об ? if mil == 2 then s = gsub(s, ' в <тысячелетие>', ' во <тысячелетие>') end if BC == 1 then s = gsub(s, '<век> (век[еа]?)', roman_cent .. ' %1 до н. э.') s = gsub(s, '<тысячелетие>(-[емг][о]? тысячелети[еия])', mil..'%1 до н. э.') -- 2-е/2-м/2-го s = gsub(s, '<ключ>', cent-100) else s = gsub(s, '<век>', roman_cent) s = gsub(s, '<тысячелетие>', mil) s = gsub(s, '<ключ>', cent) end return s end local function cats(args) local c, t local ret = '' for _, c in sparseIpairs(args) do t = mw.text.split(c, '!', true) -- диапазон веков для кат. local cmin = -99 if t[3] and t[3] ~= '' then cmin = tonumber(t[3]) end local cmax = 99 if t[4] and t[4] ~= '' then cmax = tonumber(t[4]) end local cc = cent if BC == 1 then cc = -cent end if cc >= cmin and cc <= cmax then -- в/во, о/об local tt = t[1] if cent == 2 then tt = gsub(tt, 'в <век> веке', 'во <век> веке') end if cent == 11 then tt = gsub(tt, 'о <век> веке', 'об <век> веке') end if t[2] and t[2] ~= '' then ret = ret .. string.format('[[Категория:%s|%s]]', tt, t[2]) else ret = ret .. string.format('[[Категория:%s]]', tt) end 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 5) cent_min = tonumber(args['min'] or -39) cent_max = tonumber(args['max'] or 21) -- нахождение текушего века get_cent(title) -- создание шаблона-строки get_templ(title) -- создание навбокса и категорий return navbox(title) .. cats(args) end function p.expand(frame) local args = getArgs(frame) title = args['title'] or title get_cent(title) BC = mw.ustring.find(title, '[IVX]+ век[еа]? до н%. э%.') if BC then BC = 1 else BC = 0 end -- в/во, о/об local tt = args[1] if cent == 2 then tt = gsub(args[1], 'в <век> веке', 'во <век> веке') end if cent == 11 then tt = gsub(tt, 'о <век> веке', 'об <век> веке') end return do_expand(tt) end function p.century_from_title(frame) local args = getArgs(frame) title = args['title'] or title BC = mw.ustring.find(title, '[IVX]+ век[еа]? до н%. э%.') get_cent(title) if BC then return -cent end return cent end return p