local p = {}
local function getDecade(y)
return y - (y % 10)
end
local function toRoman(num)
local romanNumerals = {
{1000, "M"}, {900, "CM"}, {500, "D"}, {400, "CD"},
{100, "C"}, {90, "XC"}, {50, "L"}, {40, "XL"},
{10, "X"}, {9, "IX"}, {5, "V"}, {4, "IV"},
{1, "I"},
}
local res = {}
for _, rn in ipairs(romanNumerals) do
while num >= rn[1] do
table.insert(res, rn[2])
num = num - rn[1]
end
end
return table.concat(res)
end
local function getCentury(y)
local c = math.floor((y - 1) / 100) + 1
return toRoman(c)
end
function p.applyPatterns(patternTable, fullText, year, bcFlag, co)
if type(patternTable) ~= 'table' then
return ''
end
for patternKey, categoriesString in pairs(patternTable) do
local candidateName = patternKey
:gsub("{y}", tostring(year))
:gsub("{bc}", bcFlag and " до н. э." or "")
if co then
candidateName = candidateName:gsub("{co}", co)
end
if candidateName == fullText then
local decade = getDecade(year)
local century = getCentury(year)
local result = categoriesString
:gsub("{y}", tostring(year))
:gsub("{d}", tostring(decade))
:gsub("{c}", century)
if bcFlag then
result = result:gsub("{bc}", " до н. э.")
else
result = result:gsub("{bc}", "")
end
if co then
result = result:gsub("{co}", co)
end
return result
end
end
return ''
end
function p.getExtraCategories(fullText, year, bcFlag, co)
if not fullText or fullText == '' then
return ''
end
local firstLetter = mw.ustring.sub(fullText, 1, 1)
firstLetter = mw.ustring.upper(firstLetter)
if firstLetter:match("[%aА-Яа-я]") then
local subModuleName = 'Modul\':Категория по годам/список/' .. firstLetter
local ok, subModule = pcall(require, subModuleName)
if ok and type(subModule) == 'table' then
local cats = p.applyPatterns(subModule, fullText, year, bcFlag, co)
if cats and cats ~= '' then
return cats
end
end
end
local ok2, generalModule = pcall(require, 'Modul\':Категория по годам/список')
if not ok2 or type(generalModule) ~= 'table' then
return ''
end
return p.applyPatterns(generalModule, fullText, year, bcFlag, co)
end
local function makeYearLink(baseName, realY, suffix)
if realY == 0 then
return nil
elseif realY < 0 then
local posY = -realY
local bcSuffix = suffix
if not bcSuffix:find("до н%. э") then
bcSuffix = bcSuffix:gsub("%s*$", "") .. " до н. э."
end
return '[[:Kategorii:' .. baseName .. ' ' .. posY .. ' ' .. bcSuffix .. '|−' .. posY .. ']]'
else
local adSuffix = suffix:gsub("%s*до н%. э%.?", "")
return '[[:Kategorii:' .. baseName .. ' ' .. realY .. ' ' .. adSuffix .. '|' .. realY .. ']]'
end
end
local function generateOlderLinks(baseName, current, suffix, count)
local older = {}
local i = current - 1
while #older < count do
if i ~= 0 then
table.insert(older, makeYearLink(baseName, i, suffix))
end
i = i - 1
end
local reversed = {}
for j = #older, 1, -1 do
table.insert(reversed, older[j])
end
return reversed
end
local function generateNewerLinks(baseName, current, suffix, count)
local newer = {}
local i = current + 1
while #newer < count do
if i ~= 0 then
table.insert(newer, makeYearLink(baseName, i, suffix))
end
i = i + 1
end
return newer
end
function p._makeNavRow(baseName, year, suffix, bcFlag)
local realYear = bcFlag and -year or year
local older = generateOlderLinks(baseName, realYear, suffix, 5)
local newer = generateNewerLinks(baseName, realYear, suffix, 5)
local centerLink = makeYearLink(baseName, realYear, suffix)
local t = {}
table.insert(t, '{| class="standard" align="center"')
for _, val in ipairs(older) do
table.insert(t, '| ' .. val)
end
if centerLink then
if bcFlag then
table.insert(t, '! −' .. year)
else
table.insert(t, '! ' .. year)
end
end
for _, val in ipairs(newer) do
table.insert(t, '| ' .. val)
end
table.insert(t, '|}')
return table.concat(t, '\n')
end
function p.main(frame)
local title = mw.title.getCurrentTitle()
if title.namespace ~= 14 then
return "Модуль «Категория по годам» вызывается не в пространстве «Категория»."
end
local text = title.text
local baseName, year, suffix, co
local bcFlag = false
baseName, year, suffix, co = text:match('^(.-)%s+(%d+)%s+(году)%s+в%s+(.+)$')
if not (baseName and year) then
baseName, year, suffix = text:match('^(.-)%s+(%d+)%s+(года)$')
end
if not (baseName and year) then
baseName, year, suffix = text:match('^(.-)%s+(%d+)%s+(году)$')
end
if not (baseName and year) then
baseName, year, suffix = text:match('^(.-)%s+(%d+)%s+(года до н%. э%.)$')
if baseName and year then
bcFlag = true
end
end
if not (baseName and year) then
baseName, year, suffix = text:match('^(.-)%s+(%d+)%s+(году до н%. э%.)$')
if baseName and year then
bcFlag = true
end
end
if not (baseName and year) then
local y, after = text:match('^(%d+)%s+год%s+до н%. э%.%s*(.*)$')
if y then
bcFlag = true
year = y
if after ~= '' then
suffix = 'год до н. э. ' .. after
else
suffix = 'год до н. э.'
end
baseName = ''
else
y, after = text:match('^(%d+)%s+год%s*(.*)$')
if y then
year = y
if after ~= '' then
suffix = 'год ' .. after
else
suffix = 'год'
end
baseName = ''
end
end
end
if not (baseName and year) then
return ''
end
year = tonumber(year)
if not year then
return ''
end
if co then
suffix = suffix .. " в {co}"
end
local navRow = p._makeNavRow(baseName, year, suffix, bcFlag)
local extraCats
if co then
extraCats = p.getExtraCategories(text, year, bcFlag, co)
else
extraCats = p.getExtraCategories(text, year, bcFlag)
end
if co then
local countryModule = require("Modul':Категория по годам/список/страны")
local countryData = countryModule[co]
if countryData then
navRow = navRow:gsub("в%s+{co}", countryData.prep)
navRow = navRow:gsub("{co}", countryData.gen)
extraCats = extraCats:gsub("в%s+{co}", countryData.prep)
extraCats = extraCats:gsub("{co}", countryData.gen)
else
navRow = navRow:gsub("{co}", co)
extraCats = extraCats:gsub("{co}", co)
end
end
return navRow .. '\n' .. extraCats
end
return p