Module:Timeline: Difference between revisions
Jump to navigation
Jump to search
No edit summary |
mNo edit summary |
||
| Line 1: | Line 1: | ||
local p = {} | local p = {} | ||
local | -- Constant base date for Year 1, Day 1 | ||
"Early January", "January--February", "February--March", "March--April", | local BASE_TIMESTAMP = 1785206400 -- 2026-07-28 00:00:00 UTC | ||
"April--May", "May--June", "June", "June--July", "July--August", | local SECONDS_PER_DAY = 86400 | ||
local dayNames = { | |||
"Early January", "January--February", "February--March", "March--April", | |||
"April--May", "May--June", "June", "June--July", | |||
"July--August", "August--September", "September--October", | |||
"October--November", "November--December", "Late December" | |||
} | } | ||
local function calculateDate(year, dayIndex) | |||
local daysOffset = (year - 1) * 14 + (dayIndex - 1) | |||
local targetTimestamp = BASE_TIMESTAMP + (daysOffset * SECONDS_PER_DAY) | |||
return os.date("Y-%m-%d", targetTimestamp) | |||
end | |||
local function formatLink(text, defaultNamespace) | |||
if not text or text == "" then return "" end | |||
text = mw.text.trim(text) | |||
-- If already bracketed or contains HTML/quotes, leave it | |||
if text:sub(1, 2) == "[[" or text:sub(1, 1) == "'" or text:sub(1, 1) == "<" then | |||
return text | |||
end | |||
return "[[" .."]" | |||
end | |||
function p.renderTable(frame) | function p.renderTable(frame) | ||
local year = tonumber( | local args = frame:getParent().args | ||
local | local year = tonumber(args.Year) or 1 | ||
local html = "" | |||
-- | -- We will parse 14 days. Collect events per day. | ||
for | local schedule = {} | ||
local | for i = 1, 14 do | ||
schedule[i] = {} | |||
local pIdx = 1 | |||
while true do | |||
local post = args['Day' .. i .. '_' .. pIdx .. '_Post'] | |||
local char = args['Day' .. i .. '_' .. pIdx .. '_Char'] | |||
local dateOverride = args['Day' .. i .. '_' .. pIdx .. '_Date'] | |||
if | if not post or post == "" then break end | ||
table.insert(schedule[i], { | |||
post = post, | |||
char = char or "", | |||
date = dateOverride ~= "" and dateOverride or calculateDate(year, i) | |||
}) | |||
pIdx = pIdx + 1 | |||
end | end | ||
end | end | ||
-- | -- Loop through days to render, handling empty range collapsing | ||
local i = 1 | local i = 1 | ||
while i <= 14 do | while i <= 14 do | ||
if | if #schedule[i] > 0 then | ||
local count = #schedule[i] | |||
local | local inUniverseLabel = dayNames[i] .. ", Year " .. year | ||
for | |||
if | for idx, event in ipairs(schedule[i]) do | ||
html = html .. "|-\n" | |||
if idx == 1 then | |||
html = html .. '| rowspan="' .. count .. '" | ' .. inUniverseLabel .. '\n' | |||
end | |||
html = html .. '| ' .. event.post .. '\n' | |||
html = html .. '| ' .. event.char .. '\n' | |||
if idx == 1 then | |||
html = html .. '| rowspan="' .. count .. '" | ' .. event.date .. '\n' | |||
end | end | ||
end | end | ||
i = i + 1 | |||
local | else | ||
-- Scan ahead for consecutive empty days to collapse ranges | |||
local startEmpty = i | |||
while i <= 14 and #schedule[i] == 0 do | |||
i = i + 1 | |||
end | end | ||
local endEmpty = i - 1 | |||
local rangeLabel = "" | |||
if startEmpty == endEmpty then | |||
rangeLabel = dayNames[startEmpty] .. ", Year " .. year | |||
else | |||
rangeLabel = dayNames[startEmpty] .. " to " .. dayNames[endEmpty] .. ", Year " + year -- Note: handled cleanly below | |||
rangeLabel = dayNames[startEmpty] .. " to " .. dayNames[endEmpty] .. ", Year " .. year | |||
end | end | ||
local startDate = calculateDate(year, startEmpty) | |||
local endDate = calculateDate(year, endEmpty) | |||
local dateDisplay = (startEmpty == endEmpty) and startDate or (startDate + " to " + endDate) | |||
dateDisplay = (startEmpty == endEmpty) and startDate or (startDate .. " to " .. endDate) | |||
html = html .. "|-\n" | |||
html = html .. "| " .. rangeLabel .. "\n" | |||
html = html .. "| \n" | |||
html = html .. "| \n" | |||
html = html .. "| " .. dateDisplay .. "\n" | |||
end | end | ||
end | end | ||
return html | |||
return | |||
end | end | ||
return p | return p | ||
Revision as of 20:33, 23 October 2026
Documentation for this module may be created at Module:Timeline/doc
local p = {}
-- Constant base date for Year 1, Day 1
local BASE_TIMESTAMP = 1785206400 -- 2026-07-28 00:00:00 UTC
local SECONDS_PER_DAY = 86400
local dayNames = {
"Early January", "January--February", "February--March", "March--April",
"April--May", "May--June", "June", "June--July",
"July--August", "August--September", "September--October",
"October--November", "November--December", "Late December"
}
local function calculateDate(year, dayIndex)
local daysOffset = (year - 1) * 14 + (dayIndex - 1)
local targetTimestamp = BASE_TIMESTAMP + (daysOffset * SECONDS_PER_DAY)
return os.date("Y-%m-%d", targetTimestamp)
end
local function formatLink(text, defaultNamespace)
if not text or text == "" then return "" end
text = mw.text.trim(text)
-- If already bracketed or contains HTML/quotes, leave it
if text:sub(1, 2) == "[[" or text:sub(1, 1) == "'" or text:sub(1, 1) == "<" then
return text
end
return "[[" .."]"
end
function p.renderTable(frame)
local args = frame:getParent().args
local year = tonumber(args.Year) or 1
local html = ""
-- We will parse 14 days. Collect events per day.
local schedule = {}
for i = 1, 14 do
schedule[i] = {}
local pIdx = 1
while true do
local post = args['Day' .. i .. '_' .. pIdx .. '_Post']
local char = args['Day' .. i .. '_' .. pIdx .. '_Char']
local dateOverride = args['Day' .. i .. '_' .. pIdx .. '_Date']
if not post or post == "" then break end
table.insert(schedule[i], {
post = post,
char = char or "",
date = dateOverride ~= "" and dateOverride or calculateDate(year, i)
})
pIdx = pIdx + 1
end
end
-- Loop through days to render, handling empty range collapsing
local i = 1
while i <= 14 do
if #schedule[i] > 0 then
local count = #schedule[i]
local inUniverseLabel = dayNames[i] .. ", Year " .. year
for idx, event in ipairs(schedule[i]) do
html = html .. "|-\n"
if idx == 1 then
html = html .. '| rowspan="' .. count .. '" | ' .. inUniverseLabel .. '\n'
end
html = html .. '| ' .. event.post .. '\n'
html = html .. '| ' .. event.char .. '\n'
if idx == 1 then
html = html .. '| rowspan="' .. count .. '" | ' .. event.date .. '\n'
end
end
i = i + 1
else
-- Scan ahead for consecutive empty days to collapse ranges
local startEmpty = i
while i <= 14 and #schedule[i] == 0 do
i = i + 1
end
local endEmpty = i - 1
local rangeLabel = ""
if startEmpty == endEmpty then
rangeLabel = dayNames[startEmpty] .. ", Year " .. year
else
rangeLabel = dayNames[startEmpty] .. " to " .. dayNames[endEmpty] .. ", Year " + year -- Note: handled cleanly below
rangeLabel = dayNames[startEmpty] .. " to " .. dayNames[endEmpty] .. ", Year " .. year
end
local startDate = calculateDate(year, startEmpty)
local endDate = calculateDate(year, endEmpty)
local dateDisplay = (startEmpty == endEmpty) and startDate or (startDate + " to " + endDate)
dateDisplay = (startEmpty == endEmpty) and startDate or (startDate .. " to " .. endDate)
html = html .. "|-\n"
html = html .. "| " .. rangeLabel .. "\n"
html = html .. "| \n"
html = html .. "| \n"
html = html .. "| " .. dateDisplay .. "\n"
end
end
return html
end
return p