Module:Timeline

From aquila
Revision as of 20:33, 23 October 2026 by Baseplate (talk | contribs)
Jump to navigation Jump to search

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