Модуль:Песочница/AlphaRho/years
< Модуль:Песочница | AlphaRho
Документация
---*- mode: lua; coding: utf-8; -*-
local p = {}
-- переменные
local year -- год, положительное число
local BC -- 0 == н.э. 1 == до н.э.
local templ -- строка-шаблон вида 'Мир в %s году%s'
local title = mw.title.getCurrentTitle().text
-- опции
local year_min = -40000 -- 0 == только н.э.
local year_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 gsub = mw.ustring.gsub
local function get_templ(s)
-- формируем строку-шаблон вида:
-- 'Мир в 99 году до н. э.' -> 'Мир в %s году%s'
-- определяем BC
local t
t, BC = gsub(s, '[0-9]+ (год[ау]?) до н%. э%.', '%%s %1%%s')
local n = BC
if BC ~= 1 then
t, n = gsub(s, '[0-9]+ (год[ау]?)', '%%s %1%%s')
end
if n ~= 1 then
-- не найдено или найдено больше одного
error('Год не найден')
end
-- в/во
templ = gsub(t, 'во %%s году', 'в %%s году')
end
local function get_year(t)
_, _, year = mw.ustring.find(t, '([0-9]+) год')
if not year then error('год не найден') end
year = tonumber(year)
end
local function format(y, wiki)
local bcs, t
if y < 1 then
y = 1 - y
bcs = ' до н. э.'
--t = tostring(c)..' до н. э.'
t = '-'..y
else
bcs = ''
t = y
end
local s
if wiki then
-- в/во
local tt = templ
if y == 2 then
tt = gsub(templ, 'в %%s году', 'во %%s году')
end
s = string.format(tt, y, bcs)
s = string.format('[[:К:%s|%s]]', s, t)
else
s = t
end
return s
end
local function navbox()
local y
y = year
if BC == 1 then
-- пропускаем 0
-- 1 до н.э. y == 0, 2 до н.э. y == -1 и т.д.
y = 1 - year
end
local wt = mw.html.create('table'):addClass('standard'):attr('align', 'center')
local row = wt:tag('tr')
local ystart
if year_min < 1 then
ystart = math.max(year_min+1, y - range)
else
ystart = math.max(year_min, y - range)
end
local yend = math.min(year_max, y + range) -- FIXME: до н.э.
for i = ystart, yend do
if i == 1 and i~= ystart then -- разд. до н.э./н.э.
row:tag('th'):wikitext('')
end
if i == y 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)
-- <год> - год без слова "год"
-- <ключ> - ключ сортировки, н.э. - номер года,
-- до н.э. - отрицательное число начиная с -99 (-99 == 1 год до н.э. -98 == 2 год до н.э. и т.д.)
-- <десятилетие> - десятилетие числом (без окончания -е/-х)
-- <век> - век римскими цифрами
local d = math.floor(year/10)*10 -- десятилетие
local c = toroman(math.floor((year-1)/100)+1) -- век
-- в/во
if c == 'II' then
s = gsub(s, ' в <век>', ' во <век>')
end
if BC == 1 then
s = gsub(s, '<год> (год[ау]?)', year..' %1 до н. э.')
s = gsub(s, '<ключ>', year-10000) -- ?
s = gsub(s, '<десятилетие>(-[ех] год[ыоа][вх]?)', d..'%1 до н. э.') -- годы/годов/годах
s = gsub(s, '<век> (век[еа]?)', c..' %1 до н. э.')
else
s = gsub(s, '<год>', year)
s = gsub(s, '<ключ>', year)
s = gsub(s, '<десятилетие>', d)
s = gsub(s, '<век>', c)
end
return s
end
local function cats(args)
local y, t
local ret = ''
for _, y in sparseIpairs(args) do
t = mw.text.split(y, '!', true)
-- в/во
local tt = t[1]
if year == 2 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
return do_expand(ret)
end
function p.main(frame)
local args = getArgs(frame)
title = args['title'] or title
-- разбор аргументов
range = tonumber(args['range'] or 5)
year_min = tonumber(args['min'] or -40000)
year_max = tonumber(args['max'] or 2100)
-- нахождение текушего года
get_year(title)
-- создание шаблона-строки
get_templ(title)
-- создание навбокса и категорий
return navbox(title) .. cats(args)
end
function p.expand(frame)
local args = getArgs(frame)
title = args['title'] or title
get_year(title)
BC = mw.ustring.find(title, '[0-9]+ год[ау]? до н%. э%.')
if BC then
BC = 1
else
BC = 0
end
-- в/во
local tt = args[1]
if year == 2 then
tt = mw.ustring.gsub(args[1], 'в <год> году', 'во <год> году')
end
return do_expand(tt)
end
function p.doc(frame)
local args = getArgs(frame)
title = args['title'] or title
local templ = string.gsub(title, '/doc$', '') -- rm /doc
local text = mw.title.new(templ,10):getContent()
text = string.gsub(text, '<noinclude>.-</noinclude>', '')
text = string.gsub(text, '<!--.--->', '')
ret = ';Добавляет категории:\n'
local cats = string.gsub(text, '.-{{#invoke:YearMetaCat2|main(.-)}}.*', '%1')
for _, c in ipairs(mw.text.split(cats, '|', true)) do
c = mw.text.trim(mw.text.split(c, '!', true)[1])
if c ~= '' and not string.find(c, '=') then
ret = ret..'* '..c..'\n'
end
end
local templs = ''
local n = 0
for t in string.gmatch(text, '{{[^#].-}}') do
t = mw.text.trim(string.sub(t, 3, -3))
t = string.gsub(t, '{{#invoke:YearMetaCat2|expand|', '')
n = n + 1
local i = string.find(t, '|')
if i then
local tn = string.sub(t, 0, i-1)
local a = string.sub(t, i)
templs = templs..string.format('* {{[[Ш:%s|%s]]%s}}\n', tn, tn, a)
else
templs = templs..string.format('* {{[[Ш:%s|%s]]}}\n', t, t)
end
end
if n == 1 then
ret = ret..';Добавляет шаблон:\n'..templs
elseif n > 1 then
ret = ret..';Добавляет шаблоны:\n'..templs
end
return ret
end
return p