Module:Calendar widget: Difference between revisions

Content deleted Content added
No edit summary
No edit summary
 
(6 intermediate revisions by 3 users not shown)
Line 3:
 
--]]
require('Module:No globalsstrict');
local getArgs = require ('Module:Arguments').getArgs;
 
Line 30:
end
 
 
local function is_leap(year)
--[[--------------------------< I S _ L E A P >----------------------------------------------------------------
 
returns true when <year> is a leapyear
 
]]
 
local function is_leap (year)
return '1' == lang_obj:formatDate ('L', tostring(year));
end
 
 
--[[
--[[--------------------------< D A Y _ O F _ W E E K >--------------------------------------------------------
 
returns 1 to 7; 1 == Sunday; 1 == Monday when iso true
 
--]]
 
local function day_of_week (year, month, day, iso)
return
iso and lang_obj:formatDate ('N', year .. '-' .. month .. '-' .. day) or -- ISO: 1 = monday
lang_obj:formatDate ('w', year .. '-' .. month .. '-' .. day) + 1; -- 1 = sunday
end
 
-- year and month both numeric:
local function monthstart(year, month, iso)
return day_of_week(year, month, 1, iso)
end
 
Line 91 ⟶ 96:
local function get_display_year (props)
local year_text = props.year;
local lk_prefix = props.lk_pref_y or props.lk_pref;
local lk_suffix = props.lk_suff_y or props.lk_suff;
 
if props.lk_y then -- if to be linked
if props.lk_pref_ylk_prefix or props.lk_suff_ylk_suffix then -- when prefix or suffix, [[prefix .. link .. suffix|label]]
year_text = make_wikilink ((props.lk_pref_ylk_prefix or '') .. year_text .. (props.lk_suff_ylk_suffix or ''), year_text);
else
year_text = make_wikilink (year_text); -- just year
Line 115 ⟶ 122:
local month_text = mnum or props.month_num;
month_text = monthname[month_text];
 
local lk_prefix = props.lk_pref_m or props.lk_pref;
local lk_suffix = props.lk_suff_m or props.lk_suff;
 
if props['lk_m&y'] then -- stand-alone month calendars only
Line 121 ⟶ 131:
 
if props.lk_m or props['lk_m&y'] then
if props.lk_pref_mlk_prefix or props.lk_suff_mlk_suffix then -- when prefix or suffix, [[prefix .. link .. suffix|label]]
month_text = make_wikilink ((props.lk_pref_mlk_prefix or '') .. month_text .. (props.lk_suff_mlk_suffix or ''), month_text);
else
month_text = make_wikilink (month_text); -- just month name or composite month/year
end
end
Line 139 ⟶ 149:
 
local function get_display_day (day_text, mnum, props)
local lk_prefix = props.lk_pref_d or props.lk_pref;
local lk_suffix = props.lk_suff_d or props.lk_suff;
 
if props.lk_d then
local link_text = (props.lk_pref_dlk_prefix or '') .. monthname[mnum] .. ' ' .. day_text .. (props.lk_suff_dlk_suffix or '');
day_text = make_wikilink (link_text, day_text);
end
Line 170 ⟶ 183:
:attr (opt_attr)
:css (css_opts)
:wikitext (item) -- getthe aitem calendarto forbe monthwrapped numberin mnum<tag>...</tag>
:done() -- close <td>
table.insert (tags, tostring (repeat_tag)); -- make a string of this object
Line 191 ⟶ 204:
local result = {};
local hilite;
local hilite_two;
for col = 1, 7 do
Line 212 ⟶ 226:
if (props.year == props.this_ynum) and (mnum == props.this_mnum) and (dom == props.this_dnum) then
hilite = col;
end
end
if props.aday then -- highlight arbitrary date when displayed
if (props.year == props.this_ynum) and (mnum == props.this_mnum) and (dom == props.this_dnum) then
hilite_two = col;
end
end
Line 222 ⟶ 241:
table.insert (result, repeat_tags ('td', {td_item}, {['class']='mcal', ['css'] = {['background-color'] = props.today_color or '#cfc'}}));
else
if i == hilite_two then
table.insert (result, repeat_tags ('td', {td_item}, {['class']='mcal', ['css'] = {['background-color'] = props.aday_color or '#cfc'}}));
end
table.insert (result, repeat_tags ('td', {td_item}, options));
end
Line 240 ⟶ 262:
local css_opts = props.week_color and {['background'] = props.week_color} or {}
 
if props.iso_wk or props.iso then
if props.iso_wk then
table.insert (headers, repeat_tags ('th', {'Wk'}, {['class']='mcal', ['attr']={['title'] = 'ISO week number'}, ['css'] = css_opts})); -- iso week header
table.insert (headers, repeat_tags ('th', {'Wk'}, {['class']='mcal', ['attr']={['title'] = 'ISO week number'}, ['css'] = css_opts})); -- iso week header
end
for i, abbr in ipairs (iso_dayabbr) do
table.insert (headers, repeat_tags ('th', {iso_dayabbr[i]}, {['class']='mcal', ['attr']={['title'] = iso_dayname[i]}, ['css'] = css_opts}));
Line 434 ⟶ 458:
--[[--------------------------< _ C A L E N D A R >------------------------------------------------------------
 
module entry point. args is the parent frame args table
]]
 
local function _calendar (props)
if props.month_num then
return display_month (props.month_num, props);
else
return display_year (props)
end
end
 
--------------------------------------------------
--[[
Sakamoto's method: ISO date
returns day name or nil if bad arguments
 
iso here refers to the yyyy-mm-dd date format, not to iso day of week where 1 = monday
 
TODO: this function not used by the calendar widget; delete?
TODO: if kept, error check inputs
 
--]]
local function dayofweek (frame)
local isodate = mw.text.trim(frame.args[1] or "")
local y, m, d = isodate:match("(%d+)%p(%d+)%p(%d+)")
local dow = day_of_week(y, m, d)
if not dow then return "" end
return dayname[dow]
end
 
--[[
isleap returns "leap" if passed a leap year
otherwise returns nothing
 
TODO: this function not used by the calendar widget; delete?
 
]]
local function isleap (frame)
if is_leap(frame.args[1]) then return "leap" end
return ""
end
 
local function _calendar (args)
--[[
local props = {}; -- separate calendar properties table to preserve arguments as originally provided
Main entry point for widget
--]]
local function calendar(frame)
local args=getArgs (frame);
local cal_props = {}; -- separate calendar properties table to preserve arguments as originally provided
local this_year_num = tonumber (lang_obj:formatDate ('Y'));
local this_month_num = tonumber (lang_obj:formatDate ('n'));
 
cal_propsprops.this_ynum = this_year_num; -- for highlighting 'today' in a calendar display
cal_propsprops.this_mnum = this_month_num;
cal_propsprops.this_dnum = tonumber (lang_obj:formatDate ('j'));
 
cal_propsprops.year = args.year and tonumber(args.year) or this_year_num;
if (1583 > props.year) or (1582 == props.year and 10 > props.month_num) then -- gregorian calendar only (1583 for yearly calendar because gregorian started in October of 1582)
cal_props.leap = is_leap (cal_props.year)
props.year = this_year_num; -- so use this year
end
 
props.leap = is_leap (props.year)
cal_propsprops.title = args.title; -- year calendar title
 
cal_propsprops.cols = tonumber(args.cols or 4); -- yearly calendar number of columns
if 1 > cal_propsprops.cols or 12 < cal_propsprops.cols then
cal_propsprops.cols = 4;
end
Line 502 ⟶ 489:
if not mnum then -- month provided as some sort of text string
if args.month == "current" then
cal_propsprops.month_num = this_month_num
cal_propsprops.year = this_year_num
elseif args.month == "last" then
mnum = this_month_num - 1
if mnum == 0 then
cal_propsprops.month_num = 12 -- december last year
cal_propsprops.year = this_year_num - 1 -- last year
else
cal_propsprops.month_num = mnum; -- previous month
end
elseif args.month == "next" then
mnum = this_month_num + 1
if mnum == 13 then
cal_propsprops.month_num = 1 -- january next year
cal_propsprops.year = this_year_num + 1 -- next year
else
cal_propsprops.month_num = mnum; -- next month
end
else
local good
good, cal_propsprops.month_num = pcall (lang_obj.formatDate, lang_obj, 'n', args.month);
if not good then
cal_propsprops.month_num = this_month_num
else
cal_propsprops.month_num = tonumber (cal_propsprops.month_num)
end
end
else
cal_propsprops.month_num = (13 > mnum and 0 < mnum) and mnum or this_month_num; -- month provided as a number
end
 
cal_propsprops.prevnext = 'yes' == (args.prevnext and args.prevnext:lower()); -- show previous / next links in month header only in single month calendars
 
if args.lk_pref_mprev or args.lk_suff_mprev then
cal_propsprops.lk_pref_mprev = args.lk_pref_mprev;
cal_propsprops.lk_suff_mprev = args.lk_suff_mprev;
cal_propsprops.prevnext = true;
end
 
if args.lk_pref_mnext or args.lk_suff_mnext then
cal_propsprops.lk_pref_mnext = args.lk_pref_mnext;
cal_propsprops.lk_suff_mnext = args.lk_suff_mnext;
cal_propsprops.prevnext = true;
end
 
cal_propsprops.m_center = 'center' == (args.float and args.float:lower()); -- month calendar positions; default is left
cal_propsprops.m_float_r = 'right' == (args.float and args.float:lower());
end
cal_propsprops.iso_wk = 'yes' == (args['iso-wk'].iso_wk and args['iso-wk'].iso_wk:lower()); -- show iso format with week numbers when true
cal_propsprops.iso = 'yes' == (args.iso and args.iso:lower()) or cal_propsprops.iso_wk; -- iso format without week number unless cal_propsprops.iso_wk true; always true when cal_propsprops.iso_wk true
args.lk = args.lk and args.lk:lower();
if args.lk and ({['yes']=1, ['m&y']=1, ['dm&y']=1, ['dm']=1, ['my']=1, ['dy']=1, ['d']=1, ['m']=1, ['y']=1})[args.lk] then -- if valid keywords
if 'yes' == args.lk then -- all date components are individually linked
cal_propsprops.lk_d = true;
cal_propsprops.lk_m = true;
cal_propsprops.lk_y = true;
elseif 'm&y' == args.lk and cal_propsprops.month_num then -- stand-alone month calendars only; month and year as a single composite link
cal_propsprops['lk_m&y'] = true;
elseif 'dm&y' == args.lk and cal_propsprops.month_num then -- stand-alone month calendars only; month and year as a single composite link
cal_propsprops['lk_m&y'] = true;
cal_propsprops.lk_d = true;
else
cal_propsprops.lk_d = 'd' == args.lk:match ('d'); -- decode the keywords to know which components are to be linked
cal_propsprops.lk_m = 'm' == args.lk:match ('m');
cal_propsprops.lk_y = 'y' == args.lk:match ('y');
end
end
 
if not (cal_propsprops.title or cal_propsprops.lk_y or cal_propsprops['lk_m&y']) then
cal_propsprops.hide_year = ('yes' == args.hide_year) or ('off' == args.show_year); -- year normally displayed; this hides year display but not when linked or replaced with title
end
 
-- TODO: implement these two
cal_propsprops.lk_pref = args.lk_pref; -- prefix for all links except previous and next
cal_propsprops.lk_suff = args.lk_suff; -- suffix for all links except previous and next
 
for _, v in ipairs ({'y', 'm', 'd'}) do -- loop through calendar parts for link prefix and suffix parameters
cal_propsprops['lk_pref_' .. v] = args['lk_pref_' .. v] or args.lk_pref; -- set prefix values
cal_propsprops['lk_suff_' .. v] = args['lk_suff_' .. v] or args.lk_suff; -- set suffix values
if cal_propsprops['lk_pref_' .. v] or cal_propsprops['lk_suff_' .. v] then -- set the calendar link flags as necessary
cal_propsprops['lk_' .. v] = true;
end
end
if not (cal_propsprops.m_center or cal_propsprops.m_float_r) then -- these may aleady be set for stand-alone month calendar
cal_propsprops.y_center = 'center' == (args.float and args.float:lower());
cal_propsprops.y_float_r = 'right' == (args.float and args.float:lower());
end
 
--TODO: underscore instead of hyphen
cal_propsprops.today = 'yes' == (args['show-today'].show_today and args['show-today'].show_today:lower()); -- highlight today's date in calendars where it is displayed
cal_propsprops.today_color = args.today_color or args.today_colour;
props.aday = 'yes' == (args.show_a_day and args.show_a_day:lower()); -- highlight arbitrary date in calendars where it is displayed
cal_props.title_color = args.title_color or args.title_colour or args.color or args.colour;
cal_propsprops.week_coloraday_color = args.week_colora_day_color or args.week_colour or args.color or args.coloura_day_colour;
cal_props.wknum_color = args.wknum_color or args.wknum_colour;
props.title_color = args.title_color or args.title_colour or args.color or args.colour;
-- TODO: add all other args{} from template or invoke to cal_props{} modified as appropriate
props.week_color = args.week_color or args.week_colour or args.color or args.colour;
return _calendar (cal_props);
props.wknum_color = args.wknum_color or args.wknum_colour;
-- TODO: add all other args{} from template or invoke to props{} modified as appropriate
 
if props.month_num then -- set only when rendering stand-alone month calendar
return display_month (props.month_num, props);
else
return display_year (props);
end
end
 
 
--[[--------------------------< C A L E N D A R >--------------------------------------------------------------
 
template entry point. All parameters are template parameters; there are no special invoke parameters
 
]]
 
local function calendar (frame)
local args=getArgs (frame);
return _calendar (args);
end
 
Line 610 ⟶ 617:
return {
calendar = calendar,
dayofweek = dayofweek,
isleap = isleap,
}