Module:Timeline: Difference between revisions

From aquila
Jump to navigation Jump to search
No edit summary
No edit summary
Line 15: Line 15:
     for i = 1, 14 do events[i] = {} end
     for i = 1, 14 do events[i] = {} end


     -- Dynamically capture all events passed to the template
     -- Parse parameters, but ONLY keep them if they have actual text in them
     for k, v in pairs(frame.args) do
     for k, v in pairs(frame.args) do
         local day, index, field = string.match(k, "^Day(%d+)_(%d+)_(%w+)$")
         local day, index, field = string.match(k, "^Day(%d+)_(%d+)_(%w+)$")
Line 21: Line 21:
             day = tonumber(day)
             day = tonumber(day)
             index = tonumber(index)
             index = tonumber(index)
           
             if events[day][index] == nil then
             if events[day][index] == nil then
                 events[day][index] = {}
                 events[day][index] = {}
             end
             end
             events[day][index][field] = v
             events[day][index][field] = v
           
            -- If the Post is provided, consider this a valid event
            if field == "Post" and v ~= "" then
                events[day][index].isValid = true
            end
        end
    end
    -- Cleanup empty events and count valid ones
    local validCounts = {}
    for i = 1, 14 do
        validCounts[i] = 0
        for j = 1, 20 do
            if events[i][j] and events[i][j].isValid then
                validCounts[i] = validCounts[i] + 1
            else
                events[i][j] = nil
            end
         end
         end
     end
     end
Line 39: Line 58:
     table.insert(html, '|-')
     table.insert(html, '|-')


     local skipRows = 0
    -- This loop correctly handles grouping empty dates
    for i = 1, 14 do
     local i = 1
        if skipRows > 0 then
    while i <= 14 do
             skipRows = skipRows - 1
        if validCounts[i] == 0 then
            -- Find how many consecutive empty days there are
            local emptySpan = 1
            for j = i + 1, 14 do
                if validCounts[j] == 0 then
                    emptySpan = emptySpan + 1
                else
                    break
                end
            end
           
            local dateLabel = dayLabels[i]
             if emptySpan > 1 then
                dateLabel = dayLabels[i] .. " to<br>" .. dayLabels[i + emptySpan - 1]
            end
            dateLabel = dateLabel .. ", Year " .. year
           
            table.insert(html, '| ' .. dateLabel)
            table.insert(html, '| ')
            table.insert(html, '| ')
            table.insert(html, '| ')
            table.insert(html, '|-')
           
            -- Skip ahead by the number of empty days we just grouped
            i = i + emptySpan
         else
         else
             local eventCount = #events[i]
            -- There are events on this day
             local rowspanAttr = ''
            if validCounts[i] > 1 then
                rowspanAttr = ' rowspan="' .. validCounts[i] .. '" '
            end
              
              
             if eventCount == 0 then
             table.insert(html, '|' .. rowspanAttr .. '| ' .. dayLabels[i] .. ', Year ' .. year)
                local emptySpan = 1
           
                for j = i + 1, 14 do
            local rowPrinted = 0
                    if #events[j] == 0 then
            for j = 1, 20 do
                        emptySpan = emptySpan + 1
                local event = events[i][j]
                    else
                if event and event.isValid then
                        break
                     if rowPrinted > 0 then
                    end
                end
               
                local dateLabel = dayLabels[i]
                if emptySpan > 1 then
                    dateLabel = dayLabels[i] .. " to<br>" .. dayLabels[i + emptySpan - 1]
                end
                dateLabel = dateLabel .. ", Year " .. year
               
                table.insert(html, '| ' .. dateLabel)
                table.insert(html, '| ')
                table.insert(html, '| ')
                table.insert(html, '| ')
                table.insert(html, '|-')
               
                skipRows = emptySpan - 1
            else
                local rowspanAttr = ''
                if eventCount > 1 then
                    rowspanAttr = ' rowspan="' .. eventCount .. '" '
                end
               
                table.insert(html, '|' .. rowspanAttr .. '| ' .. dayLabels[i] .. ', Year ' .. year)
               
                for idx, event in ipairs(events[i]) do
                     if idx > 1 then
                         table.insert(html, '|-')
                         table.insert(html, '|-')
                     end
                     end
Line 103: Line 124:
                     table.insert(html, '| ' .. dateText)
                     table.insert(html, '| ' .. dateText)
                     table.insert(html, '|-')
                     table.insert(html, '|-')
                    rowPrinted = rowPrinted + 1
                 end
                 end
             end
             end
            i = i + 1
         end
         end
     end
     end

Revision as of 19:35, 23 October 2026

Documentation for this module may be created at Module:Timeline/doc

local p = {}

local dayLabels = {
    "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"
}

function p.renderTable(frame)
    local year = tonumber(frame.args["Year"])
    local category = frame.args["Category"]
    
    local events = {}
    for i = 1, 14 do events[i] = {} end

    -- Parse parameters, but ONLY keep them if they have actual text in them
    for k, v in pairs(frame.args) do
        local day, index, field = string.match(k, "^Day(%d+)_(%d+)_(%w+)$")
        if day and index and field then
            day = tonumber(day)
            index = tonumber(index)
            
            if events[day][index] == nil then
                events[day][index] = {}
            end
            events[day][index][field] = v
            
            -- If the Post is provided, consider this a valid event
            if field == "Post" and v ~= "" then
                events[day][index].isValid = true
            end
        end
    end

    -- Cleanup empty events and count valid ones
    local validCounts = {}
    for i = 1, 14 do
        validCounts[i] = 0
        for j = 1, 20 do 
            if events[i][j] and events[i][j].isValid then
                validCounts[i] = validCounts[i] + 1
            else
                events[i][j] = nil 
            end
        end
    end

    local html = {}
    table.insert(html, '{| class="wikitable mw-collapsible" style="width: 100%; margin-top: 10px; font-size: 85%; line-height: 1.4; border-collapse: collapse;"')
    table.insert(html, '|+ Era Nova, Year ' .. year .. ' — ' .. category .. ' Timeline')
    table.insert(html, '! In-Universe Date')
    table.insert(html, '! Post')
    table.insert(html, '! Character / Nation')
    table.insert(html, '! Real-World Date')
    table.insert(html, '|-')
    table.insert(html, '! colspan="4" style="background-color: #f1f5f9; color: #0b132b; text-align: center; font-weight: bold; padding: 6px;" | ' .. string.upper(category) .. ' NEWS')
    table.insert(html, '|-')

    -- This loop correctly handles grouping empty dates
    local i = 1
    while i <= 14 do
        if validCounts[i] == 0 then
            -- Find how many consecutive empty days there are
            local emptySpan = 1
            for j = i + 1, 14 do
                if validCounts[j] == 0 then
                    emptySpan = emptySpan + 1
                else
                    break
                end
            end
            
            local dateLabel = dayLabels[i]
            if emptySpan > 1 then
                dateLabel = dayLabels[i] .. " to<br>" .. dayLabels[i + emptySpan - 1]
            end
            dateLabel = dateLabel .. ", Year " .. year
            
            table.insert(html, '| ' .. dateLabel)
            table.insert(html, '| ')
            table.insert(html, '| ')
            table.insert(html, '| ')
            table.insert(html, '|-')
            
            -- Skip ahead by the number of empty days we just grouped
            i = i + emptySpan
        else
            -- There are events on this day
            local rowspanAttr = ''
            if validCounts[i] > 1 then
                rowspanAttr = ' rowspan="' .. validCounts[i] .. '" '
            end
            
            table.insert(html, '|' .. rowspanAttr .. '| ' .. dayLabels[i] .. ', Year ' .. year)
            
            local rowPrinted = 0
            for j = 1, 20 do
                local event = events[i][j]
                if event and event.isValid then
                    if rowPrinted > 0 then
                        table.insert(html, '|-')
                    end
                    
                    local postText = event.Post or ""
                    if postText ~= "" and not string.find(postText, "%[%[") then
                        postText = "[[" .. postText .. "]]"
                    end
                    
                    local charText = event.Char or ""
                    if charText ~= "" and not string.find(charText, "%[%[") then
                        charText = "[[" .. charText .. "]]"
                    end

                    local dateText = event.Date or ""
                    if dateText == "" then
                        local daysOffset = ((year - 1) * 14) + (i - 1)
                        local timestamp = os.time({year=2026, month=07, day=28, hour=12}) + (daysOffset * 86400)
                        dateText = os.date("%Y-%m-%d", timestamp)
                    end

                    table.insert(html, '| ' .. postText)
                    table.insert(html, '| ' .. charText)
                    table.insert(html, '| ' .. dateText)
                    table.insert(html, '|-')
                    rowPrinted = rowPrinted + 1
                end
            end
            i = i + 1
        end
    end

    table.insert(html, '|}')
    return table.concat(html, "\n")
end

return p