Module:Sandbox/Tokoko/Calendar Explained

require('strict')

local p = local root =

local function addRow(row) table.insert(root, row)end

local function isLeapYear(year) return year % 4

0 and (year % 100 ~= 0 or year % 400

0)end

local function getDaysInMonth(month, year) return month

2 and isLeapYear(year) and 29 or ("\31\28\31\30\31\30\31\31\30\31\30\31"):byte(month)end

local function getMonthNumber(m) if tonumber(m) ~= nil then return tonumber(m) elseif m

"current" then return tonumber(os.date("%m")) elseif m

"next" then return tonumber(os.date("%m")) % 12 + 1 elseif m

"last" then return (tonumber(os.date("%m")) - 2) % 12 + 1 else return 1 endend

local function applyDefaultValue(inputValue, defaultValue) return (inputValue and inputValue ~= "") and inputValue or defaultValueend

local function getWeekdays(format) if format

"Mon1st" then return elseif format

"iso" then return else return endend

local function getIsoWeekNumber(year, month, day) local daysFromStart = os.difftime(os.time, os.time) / 86400 local daysUntilEnd = os.difftime(os.time, os.time) / 86400 local firstWeekday = tonumber(os.date("%w",os.time)) local nextFirstWeekday = tonumber(os.date("%w",os.time)) if daysUntilEnd < 4 and nextFirstWeekday >= 4 then return 1 end local daysFromFirstMonday = daysFromStart - (8 - firstWeekday) local iso = math.floor(daysFromFirstMonday / 7) + 2 - (firstWeekday > 5 and 1 or 0) return iso

0 and getIsoWeekNumber(year - 1, 12, 26) or isoend

local function make_link(text, flag, pref, suff) return flag and "" .. text .. "" or textend

local function format_date(date) return date < 10 and " " .. date or dateend

local function _calendar(frame, _monthNumber, full_mode, float) local monthNumber = _monthNumber local year = tonumber(applyDefaultValue(frame.args.year,os.date("%Y"))) local month = os.date("%B", os.time) local show_year = applyDefaultValue(frame.args.show_year,"on") local format = applyDefaultValue(frame.args.format,"Sun1st") --format = "iso" local colspan = (format

"iso" and 8 or 7) local prevnext = applyDefaultValue(frame.args.prevnext

"on", false) local end_note = applyDefaultValue(frame.args.EndNote, "") local colour = frame.args.colour local title_colour = applyDefaultValue(colour,frame.args.title_colour) local week_colour = applyDefaultValue(colour,frame.args.week_colour) local wknum_colour = frame.args.wknum_colour local lk = applyDefaultValue(frame.args.lk, "") local show_link_year = string.match(lk, "y") local show_link_month = string.match(lk, "m") local show_link_day = string.match(lk, "d") local lk_pref = frame.args.lk_pref local lk_suff = frame.args.lk_suff local lk_pref_d = applyDefaultValue(lk_pref,frame.args.lk_pref_d) local lk_suff_d = applyDefaultValue(lk_suff,frame.args.lk_suff_d) local lk_pref_m = applyDefaultValue(lk_pref,frame.args.lk_pref_m) local lk_suff_m = applyDefaultValue(lk_suff,frame.args.lk_suff_m) local lk_pref_mnext = frame.args.lk_pref_mnext local lk_pref_mprev = frame.args.lk_pref_mprev local lk_suff_mnext = frame.args.lk_suff_mnext local lk_suff_mprev = frame.args.lk_suff_mprev if full_mode and show_year

"on" then show_year = "with month" end -- calculate helper variables local prevMonth = os.date("%B", os.time) local nextMonth = os.date("%B", os.time) local firstWeekday = tonumber(os.date("%w",os.time)) local daysInMonth = getDaysInMonth(monthNumber, year)

-- constuct title addRow("

- class=\"navbox-title\"" .. " style=\"background:" .. title_colour .. ";\"\n") local title_colspan = (prevnext and colspan - 2 or colspan) local title = make_link(month .. (show_year

"with month" and " " .. year or ""), show_link_month, lk_pref_m, lk_suff_m) local title_row = "

" .. title .. "\n" if prevnext then addRow("<<\n" .. title_row .. ">>\n") else addRow(title_row) end

-- construct weekdays addRow("

- class=\"navbox-title\"" .. " style=\"background:" .. week_colour .. ";\"\n") for i, wd in ipairs(getWeekdays(format)) do addRow("" .. wd .. "\n") end addRow("-\n")

-- construct dates local daysToMiss = firstWeekday - ((format

"Mon1st" or format

"iso") and 1 or 0) local date = - daysToMiss + 1 local num_rows = full_mode and 6 or math.ceil((daysInMonth + daysToMiss) / 7) for i = 1, num_rows * colspan do local lastColumn = i % colspan

0 local firstColumn = i % colspan

1 if format

"iso" and firstColumn then addRow("

class=\"navbox-abovebelow\" style=\"background:" .. wknum_colour .. ";\"" .. getIsoWeekNumber(year, monthNumber, date) .. "\n") elseif date > 0 and date <= daysInMonth then addRow("" .. make_link(format_date(date), show_link_day, lk_pref_d .. month .. " ", lk_suff_d) .. "\n") date = date + 1 else addRow(" \n") date = date + 1 end if(lastColumn) then addRow("-\n") end end if end_note ~= "" then addRow("- class=\"navbox-title\" \n") addRow("" .. end_note .. "\n") end if show_year

"on" then addRow("

- class=\"navbox-title\"" .. " style=\"background:" .. title_colour .. ";\"\n") addRow("" .. make_link(year, show_link_year, "", "") .. "\n") end addRow("
")end

function p.main(frame)

local _month = frame.args.month local full_calendar = not (_month and _month ~= "") local year = tonumber(applyDefaultValue(frame.args.year,os.date("%Y"))) local title = applyDefaultValue(frame.args.title,"") local col = applyDefaultValue(frame.args.col,4) local row = frame.args.row local float = "float" .. applyDefaultValue(frame.args.float,"left") if full_calendar then addRow("

" .. title .. " " .. year .. "\n") for i=1, 12 do if (i - 1) % col

0 then addRow("

- style=\"vertical-align: top;\"\n") end addRow("\n") _calendar(frame, i, true, "") addRow("\n") end addRow("
") else _calendar(frame, getMonthNumber(frame.args.month), false, float) end

--return "" .. table.concat(root) .. " \n" .. return table.concat(root)end

return p