Для документации этого модуля может быть создана страница Модуль:DecadeMetaCat/doc

---*- 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 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)
    _, _, dec = mw.ustring.find(t, '([0-9]*0)-[ех] год')
    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
    d = dec
    if BC == 1 then
        -- 0-е годы до н.э. d=-10, 10-е до н.э. d=-20, 20-е до н.э. d=-30 и т.д.
        d = -dec-10
    end
    local wt = mw.html.create('table'):addClass('standard'):attr('align', 'center')
    local row = wt:tag('tr')
    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
        if i == 0 and i ~= dstart then -- разд. до н.э./н.э.
            row:tag('th'):wikitext('')
        end
        if i == d 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)
-- <десятилетие> - десятилетие числом (без окончания -е/-х)
-- <ключ> - ключ сортировки, н.э. - номер года,
-- до н.э. - отрицательное число начиная с -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], 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