The editors' meeting has been canceled for technical reasons.

Module:ScheduleList

From NeuroWiki
Jump to navigation Jump to search

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

local p = {}

-- Utility function: Check if a year is a leap year
local function is_leap_year(year)
    return (year % 4 == 0 and year % 100 ~= 0) or (year % 400 == 0)
end

-- Utility function: Calculate the number of days in a month
local function days_in_month(month, leap_year)
    local days = {31, leap_year and 29 or 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
    return days[month]
end

-- Utility function: Convert `mmdd` input to `Month Day` format
local function format_date(mmdd)
    local months = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}
    local month = tonumber(string.sub(mmdd, 1, 2)) -- First two digits are the month
    local day = tonumber(string.sub(mmdd, 3, 4))   -- Last two digits are the day
    return string.format("%s %d", months[month], day)
end

-- Utility function: Calculate the next date
local function get_next_date(mmdd, leap_year)
    local month = tonumber(string.sub(mmdd, 1, 2))
    local day = tonumber(string.sub(mmdd, 3, 4))
    
    local days_in_current_month = days_in_month(month, leap_year)
    if day == days_in_current_month then
        day = 1
        month = month + 1
        if month > 12 then
            month = 1
        end
    else
        day = day + 1
    end
    
    return string.format("%02d%02d", month, day) -- Return in mmdd format
end

-- Utility function: Get the weekday in common English abbreviations
local function get_weekday(weekday)
    local weekdays = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}
    return weekdays[(weekday - 1) % 7 + 1]
end

-- Format date line
local function format_date_line(frame, date, time, week, title, css_class)
    local formatted_date = format_date(date)

    -- Set default title to "OFFLINE" if the title is empty
    if not title or title == "" then
        title = "OFFLINE"
    end

    local schedule_output
    if title == "OFFLINE" then
        css_class = (css_class and css_class .. " " or "") .. "offline" -- Add "offline" class if title is OFFLINE
        schedule_output = frame:expandTemplate{
            title = "ScheduleList/date",
            args = {formatted_date, "", week, title} -- Time empty, title as "OFFLINE"
        }
    else
        css_class = (css_class and css_class .. " " or "") .. "online" -- Add "online" class if title exists
        time = time or "19:00" -- Default time is "19:00"
        schedule_output = frame:expandTemplate{
            title = "ScheduleList/date",
            args = {formatted_date, time .. " (GMT)", week, title} -- Time and title displayed normally
        }
    end

    -- Build HTML output
    return string.format(
        '<li class="%s" style="display: flex;">' ..
        '<div class="datetime">%s</div>' ..
        '</li>',
        css_class, schedule_output
    )
end

-- Main function
function p.main(frame)
    local args = frame:getParent().args

    -- Get initial parameters
    local date = args.date -- Input date in `mmdd` format
    local week = tonumber(args.week) -- Input weekday (1~7)
    local leap_year = args.leap_year == "yes" -- Leap year check

    -- Return error messages if required parameters are missing
    if not date then return "Please provide an initial date (date parameter in mmdd format)!" end
    if not week or week < 1 or week > 7 then return "Please provide a valid initial weekday (week parameter, 1~7)!" end

    -- Initialize result table
    local result = {}
    local current_date = date
    local current_weekday = week

    -- Generate 7 rows in a loop
    for i = 1, 7 do
        local title = args["title" .. i] -- Title for each row
        local time = args["time" .. i] -- Time for each row (optional)
        local css_class = args["class" .. i] -- CSS class for each row
        local week_day = get_weekday(current_weekday) -- Calculate weekday

        -- Format each row
        table.insert(result, format_date_line(frame, current_date, time, week_day, title, css_class))

        -- Update date and weekday
        current_date = get_next_date(current_date, leap_year)
        current_weekday = current_weekday + 1
    end

    -- Wrap in <ul> and return as the result
    return '<ul class="schedule-list">' .. table.concat(result, "\n") .. '</ul>'
end

return p