# $Id: calendar.rb,v 1.2 2000/12/15 14:53:00 not Exp $
# 2000.1.?? 一歩 修正
=begin
calendar_x.rb
nDiary Plug-in カレンダーの作成
各(過去)日付へのリンク付きのカレンダーを作成します。
option:
lang=en 月名、曜日を英語表記にします。
lang=en2 曜日を2文字英語表記にします。
head=string 月別ファイル名に冒頭部文字列stringを足します。
dayhead=string 日付アンカーに冒頭部文字列stringを足します。
(xhtml対策。ndiary-versionによる互換性は考えない)
width=num 日付配列の幅を指定します。1〜31。
width=max 日付配列の幅を日数丁度にします。
width=over 日付配列の幅を日数以上で週で割れる数にします。
height=num 日付配列の高さを指定します。
title=on/off タイトル行をつけます/消します。
titlelink=on/off タイトル行に先月/来月へのリンクを加えます/消します。
week=on/off 曜日行をつけます/消します。
(widthが週で割れず、一列でない時はつけれません)
weekcolor=on/off 曜日に色をつけます/消します。
weekbgcolor=on/off 曜日に背景色をつけます/消します。
exsample:
<!--plug=calendar_x?height=2?lang=en2-->
=end
def plug(opt)
require 'date2'
#各変数の初期化
width = 14 #幅
height = -1 #高さ
title = 'on' #タイトル行
titlelink = 'on' #タイトル行前後月リンク
week = 'on' #曜日行
weekcolor = 'on' #曜日色
weekbgcolor = 'on' #曜日背景色
lang = 'en2' #タイトル、曜日文字列セット
classflag = 'off' #CSS除去対策。本来なら classflag = 'on'
tab = '' #TAB除去対策。本来なら tab = "\t"
part = '' #月内ファイル分割対策、「a,b,c」など。未対応
#各変数の読込
head = opt['head'] if opt['head'] =~ /.+/ #入力があれば
dayhead = opt['dayhead'] if opt['dayhead'] =~ /.+/ #入力があれば
width = opt['width'].to_i if opt['width'] =~ /^\d+$/ #数字なら
width_option = opt['width'] if opt['width'] =~ /^\D+$/ #非数字なら
height = opt['height'].to_i if opt['height'] =~ /^\d+$/ #数字なら
week = opt['week'] if opt['week'] =~ /.+/
weekcolor = opt['weekcolor'] if opt['weekcolor'] =~ /.+/
weekbgcolor = opt['weekbgcolor'] if opt['weekbgcolor'] =~ /.+/
title = opt['title'] if opt['title'] =~ /.+/
titlelink = opt['titlelink'] if opt['titlelink'] =~ /.+/
lang = opt['lang'] if opt['lang'] =~ /.+/
#何かの入力があれば、というのは、「!~ nil」では判定しないらしい
#nullが入力されて初期値がリセットされてしまう。ので、「=~ /.+/」に変更
width_option = 'max' if width == 0 #幅0の処理
width_option = 'max' if height == 0 #高さ0の処理
width = 7 if width_option == 'over' #後処理の都合で仮入力
#年月日情報処理###
#年情報、月情報
if self.kind_of?(LastDiary) then
thismonth = @diarys[0][0..5]
elsif self.kind_of?(PastDiary) then
thismonth = @targetMonth
else
return
end
y = thismonth[0..3].to_i #今年情報
m = thismonth[4..5].to_i #今月情報
ny = y
nm = m + 1
if nm > 12 then
ny += 1
nm = 1
end
nextmonth = sprintf("%04d%02d", ny, nm) #来月情報
nextfile = @outputDirectory + head + nextmonth + part + '.html'
nexturl = head + nextmonth + part + '.html'
py = y
pm = m - 1
if pm < 1 then
py -= 1
pm = 12
end
prevmonth = sprintf("%04d%02d", py, pm) #先月情報
prevfile = @outputDirectory + head + prevmonth + part + '.html'
prevurl = head + prevmonth + part + '.html'
#曜日情報
if lang == 'en' then #英語三文字曜日
wdayname = %w(Sun Mon Tue Wed Thu Fri Sat)
mo = Time::local(y,m).strftime("%Y/%m")
prevtext = "<<"
nexttext = ">>"
elsif lang == 'en2' then #英語二文字曜日
wdayname = %w(Sn Mn Te We Th Fr St)
mo = Time::local(y,m).strftime2("%Y.%m")
prevtext = "<-"
nexttext = "->"
else #漢字一文字曜日
wdayname = %w(日 月 火 水 木 金 土)
mo = Time::local(y,m).strftime2("%Y年%m月")
prevtext = "先月"
nexttext = "来月"
end
if weekcolor == 'on' then #曜日文字色つけ
wdayname[0] = '<font color="#ff0000">' + wdayname[0] + '</font>'
wdayname[1] = '<font color="#550011">' + wdayname[1] + '</font>'
wdayname[2] = '<font color="#440022">' + wdayname[2] + '</font>'
wdayname[3] = '<font color="#330033">' + wdayname[3] + '</font>'
wdayname[4] = '<font color="#220044">' + wdayname[4] + '</font>'
wdayname[5] = '<font color="#110055">' + wdayname[5] + '</font>'
wdayname[6] = '<font color="#0000ff">' + wdayname[6] + '</font>'
end
wdaybg = ['', '', '', '', '', '', '']
if weekbgcolor == 'on' then #曜日文字背景色つけ
wdaybg[0] = ' bgcolor="#ffcccc"'
wdaybg[1] = ''
wdaybg[2] = ''
wdaybg[3] = ''
wdaybg[4] = ''
wdaybg[5] = ''
wdaybg[6] = ' bgcolor="#ccccff"'
end
#日情報
day = (1..28).to_a.concat((29..31).to_a.delete_if{ |d|
!Date::exist?(y, m, d)
}).collect!{ |d|
d.to_s
} #よく判らないが、これで毎月の日数判定が
#できて、日付情報が入るらしい
len = day.size #日数情報
if height != -1 then
if week == 'on' then
width = 7
else
width = day.size / height
end
end #高さからの幅逆算,曜日付の時は保留,下で処理
#ここで問題。整数演算で「切り上げ」をするにはどうすればいいのでしょう
#rubyはデフォルトでは切り下げらしい
wday = 0 #曜日順序調整情報
if width_option == 'max' then #一列で日数丁度型,
#あれ、大文字小文字関係なしマッチって
#どうするんだっけ?
width = len
wday = Time::local(y,m,1).wday
elsif (width % 7) == 0 then #通常
1.upto(Time::local(y,m,1).wday){
day.unshift(" ")
}
5.downto(Time::local(y,m,day[-1]).wday){
day.push(" ")
} #よく判らないが週割ができるようにシフトらしい
width = day.size if width_option == 'over'
if height != -1 then
width = (((day.size / 7) + 1) / height) * 7
end #高さからの幅逆算
end
while (day.size % width) != 0
day.push(" ")
end #1週以上シフトの後ろの空白追加
height = day.size / width
week = 'off' if ((width % 7) != 0) && (height > 1)
#出力情報処理###
#始端情報
str = "<table"
str << "class=\"calendar\"" if classflag == 'on'
str << ">\n"
#タイトル情報
if title == 'on' then
str << "#{tab}<tr>\n"
str << "#{tab}#{tab}<th colspan=\"#{len}\">"
if titlelink == 'on' then
if File::readable?(prevfile) then
str << "<a href=\"#{prevurl}\">#{prevtext}</a> "
# else
# str << "#{prevtext} " #お好みによってはリンクなしで文字列のみ表記
end
end
str << "#{mo}"
if titlelink == 'on' then
if File::readable?(nextfile) then
str << " <a href=\"#{nexturl}\">#{nexttext}</a>"
# else
# str << " #{nexttext}" #お好みによってはリンクなしで文字列のみ表記
end
end
str << "</th>\n"
str << "#{tab}</tr>\n"
end
#来月リンクはテストしていない(過去日記にカレンダー埋めれないバグ)
#曜日情報
if week == 'on' then
str << "#{tab}<tr align=\"center\">\n"
for i in 0..(width - 1)
str << "#{tab}#{tab}<th#{wdaybg[(i + wday) % 7]}>"
str << "#{wdayname[(i + wday) % 7]}</th>\n"
end
str << "#{tab}</tr>\n"
end
#日付情報
while day.size != 0
str << "#{tab}<tr align=\"center\">\n"
for i in 0..(width - 1)
d = day.shift
dd = sprintf("%02d", d.to_i)
str << "#{tab}#{tab}<td"
if d =~ /\d+/ then
di = Time::local(y,m,d.to_i).wday
str << "#{wdaybg[di]}"
end
if @allDiarys.key?(thismonth + dd) then
str << "><a href=\"#{head}#{thismonth}#{@monthPartNames[dd.to_i]}.html##{dayhead}#{dd}\">#{d}</a></td>\n"
else
str << ">#{d}</td>\n"
end
end
str << "#{tab}</tr>\n"
end
str << "</table>\n"
return str
#debug - flag-message
#$stderr.puts "\n** check:#{width} #{height} #{title} #{titlelink} #{week} #{weekcolor} #{weekbgcolor}"
end
|