モジュール:サンドボックス/とうねこ/Module:Calendar

モジュールの解説[作成]
local p = {}

local function ymd2mjd(y, m, d, mode)
	return require('Module:MJD').ymd2mjd({y, m, d, mode=mode})
end

local function mjd2ymd(mjd, mode)
	return require('Module:MJD').mjd2ymd({mjd, mode=mode})
end

local function holiday(ymd)
	return require('Module:IsHoliday').main(ymd)
end

local function formatdate(mjd, format)
	return require('Module:Date').main({mjd=mjd, format=format})
end

local function cell(mjd, y, m, d, link, anchor, opacity, design, mode)
	local ymd = mjd2ymd(mjd, mode)
	local holiday = holiday(ymd)
	local t = ''
	local span_sty = 'color:black;'
	local td_sty = ''
	
	if mjd % 7 == 4 then -- 日曜日なら改行、赤文字
		t = t..'</tr><tr>'
		span_sty = 'color:red;'
	end
	if mjd % 7 == 3 then -- 土曜日なら青文字
		span_sty = 'color:blue;'
	end
	if holiday ~= '' then -- 祝日なら赤文字
		span_sty = 'color:red;'
	end
	if ymd[1] == y and ymd[2] == m and ymd[3] == d then 
		td_sty = td_sty..'background-color:#9f9;'
	elseif design[ymd[3]] == 1 then 
		td_sty = td_sty..'background-color:#ee0;'
	end
	if design[ymd[3]] == 1 then 
		td_sty = td_sty..'font-weight:bold;'
	end
	if opacity ~= 1 then
		td_sty = td_sty..'opacity:'..opacity..';'
	end
	if td_sty ~= '' then
		td_sty = ' style="'..td_sty..'"'
	end
	if link ~= nil then
		link = formatdate(mjd, link)
	else
		link = ymd[2]..'月'..ymd[3]..'日'
	end
	if anchor ~= nil then
		anchor = '#'..formatdate(mjd, anchor)
	else
		anchor = ''
	end
	
	t = t..'<td'..td_sty..'>[['..link..anchor..'|<span style="'..span_sty..'">'..ymd[3]..'</span>]]</td>'
	return t
end


function p.main(frame)
	local args = require('Module:Arguments').getArgs(frame, {wrappers = 'Template:Calendar', removeBlanks = false})
	local mode = args['mode']
	local curymd = require('Module:MJD').curymd({mode = mode}) -- 現在時刻をローカル時刻で取得
	
	local y = tonumber(args['年']) or curymd[1]
	local m = tonumber(args['月']) or curymd[2]
	local d = tonumber(args['日']) -- 日付未指定時は、今年の今月が表示されている場合のみ今日の表示を追加
	if y == curymd[1] and m == curymd[2] and d == nil then
		d = curymd[3]
	end
	
	local link = args['link']
	local anchor = args['anchor']
	local opacity = args['opacity'] or 0.3
	local float = ''
	local designs = args['指定日'] or ''
	local design = {}
	for n in designs:gmatch("%d*") do
		design[tonumber(n) or ''] = 1
	end
	
	if args['配置'] == 'center' then
		float = 'margin:0 auto;'
	elseif args['配置'] == 'left' then
		float = 'float:left; clear:left;'
	elseif args['配置'] == 'right' then
		float = 'float:right; clear:right;'
	else
		float = 'display:inline-table;'
	end
	
	float = args['float']
	
	-- カレンダー生成はすべて修正ユリウス日(MJD)で連番管理
	local beginmjd = ymd2mjd(y, m, 1, mode) -- 開始日のMJD
	local endmjd = ymd2mjd(y, m+1, 0, mode) -- 終了日のMJD
	-- 曜日はMJDを7で割った余り0(水)~6(火)で求められるので、数字を適当にずらして空欄の数を求める
	-- ただし、空欄の数は引数「前後範囲」以上とする(初期値は0)
	local premargin = tonumber(args['前範囲']) or tonumber(args['前後範囲']) or 0
	local postmargin = tonumber(args['後範囲']) or tonumber(args['前後範囲']) or 0
	local pre = (3 + beginmjd - premargin) % 7 + premargin -- 月初までの空欄の数
	local post = (3 - endmjd - postmargin) % 7 + postmargin -- 月末からの空欄の数
	
	local title = args['タイトル'] or '[['..y..'年]][['..m..'月]]'
	local t = '<table style="border:1px solid black; text-align:center; background:white; box-shadow: 0 0 1em rgba(0, 0, 0, 0.25);  '..float..'">'..
		'<caption style="font-weight:bold;">'..title..'</caption><tr>'..
		'<th>[[日曜日|<span style="color:red">日</span>]]</th>'..
		'<th>[[月曜日|<span style="color:black">月</span>]]</th>'..
		'<th>[[火曜日|<span style="color:black">火</span>]]</th>'..
		'<th>[[水曜日|<span style="color:black">水</span>]]</th>'..
		'<th>[[木曜日|<span style="color:black">木</span>]]</th>'..
		'<th>[[金曜日|<span style="color:black">金</span>]]</th>'..
		'<th>[[土曜日|<span style="color:blue">土</span>]]</th>'
	
	local mjd = beginmjd - pre
	while mjd < beginmjd do
		t = t..cell(mjd, y, m, d, link, anchor, opacity, design, mode)
		mjd = mjd + 1
	end
	while mjd <= endmjd do
		t = t..cell(mjd, y, m, d, link, anchor, 1, design, mode)
		mjd = mjd + 1
	end
	while mjd <= endmjd + post do
		t = t..cell(mjd, y, m, d, link, anchor, opacity, design, mode)
		mjd = mjd + 1
	end
	t = t..'</tr></table>'
	return t
end

return p