The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

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