Documentation for this module may be created at Module:Main page feed/doc
-- Recent events and deaths for the Vector main page.
-- Reads "YYYY in India" (Events and Deaths). No JavaScript.
--
-- {{#invoke:Main page feed|events|5}}
-- {{#invoke:Main page feed|deaths|5}}
local p = {}
local months = {
'January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December'
}
local monthIndex = {}
for i, name in ipairs(months) do
monthIndex[name:lower()] = i
end
local function istNow()
-- Server clock is UTC. India is UTC+5:30.
return os.date('!*t', os.time() + 19800)
end
local function pageContent(year)
local title = mw.title.new(tostring(year) .. ' in India')
if not title or not title.exists then
return ''
end
return title:getContent() or ''
end
local function chapter(text, name)
local _, finish = text:find('==%s*' .. name .. '%s*==')
if not finish then
return ''
end
local rest = text:sub(finish + 1)
local nextHeading = rest:find('\n==[^=]')
if nextHeading then
rest = rest:sub(1, nextHeading - 1)
end
return rest
end
local function clean(text)
text = text:gsub('<ref[^>]-/>', '')
text = text:gsub('<ref.->.-</ref>', '')
text = text:gsub('{{[^{}]-}}', '')
text = text:gsub('%s+', ' ')
text = text:gsub('^%s+', ''):gsub('%s+$', '')
text = text:gsub('[%.%s]+$', '')
return text
end
local function parseDated(section, year)
local items = {}
local currentDay, currentMonth
for line in (section .. '\n'):gmatch('(.-)\n') do
local day, monthName, rest = line:match('^%*+%s*(%d%d?)%s+(%a+)%s*[–—%-]%s*(.*)$')
if day and monthIndex[monthName:lower()] then
currentDay = tonumber(day)
currentMonth = monthIndex[monthName:lower()]
rest = clean(rest or '')
if rest ~= '' then
table.insert(items, {
day = currentDay,
month = currentMonth,
year = year,
text = rest
})
end
elseif currentDay and line:match('^%*+%s*%S') then
local text = clean(line:gsub('^%*+%s*', ''))
if text ~= '' then
table.insert(items, {
day = currentDay,
month = currentMonth,
year = year,
text = text
})
end
end
end
return items
end
local function stamp(item)
return item.year * 10000 + item.month * 100 + item.day
end
local function collect(kind, limit)
local now = istNow()
local today = now.year * 10000 + now.month * 100 + now.day
local year = now.year
local text = pageContent(year)
local items = parseDated(chapter(text, kind), year)
local function keep(list)
local out = {}
for _, item in ipairs(list) do
if stamp(item) <= today then
table.insert(out, item)
end
end
return out
end
items = keep(items)
if #items < limit then
local prevMonth = now.month - 1
local prevYear = year
local prevText = text
if prevMonth < 1 then
prevMonth = 12
prevYear = year - 1
prevText = pageContent(prevYear)
end
local older = parseDated(chapter(prevText, kind), prevYear)
for _, item in ipairs(keep(older)) do
if item.month == prevMonth then
table.insert(items, item)
end
end
end
table.sort(items, function(a, b)
return stamp(a) > stamp(b)
end)
local out = {}
for i = 1, math.min(limit, #items) do
out[i] = items[i]
end
return out, year
end
local function render(items, empty)
if #items == 0 then
return empty
end
local lines = {}
for _, item in ipairs(items) do
table.insert(lines, string.format(
'* \'\'\'%d %s\'\'\' – %s',
item.day,
months[item.month],
item.text
))
end
return table.concat(lines, '\n')
end
function p.events(frame)
local limit = tonumber(frame.args[1]) or 5
local items = collect('Events', limit)
return render(items, '* No recent events listed.')
end
function p.deaths(frame)
local limit = tonumber(frame.args[1]) or 5
local items = collect('Deaths', limit)
return render(items, '* No recent deaths listed.')
end
return p