#!/v/guest/sw/bin/perl -w
###############################################################################
## ##
## Copyright (c) 2001 - 2009 by Steffen Beyer. ##
## All rights reserved. ##
## ##
## This program is free software; you can redistribute it ##
## and/or modify it under the same terms as Perl itself. ##
## ##
###############################################################################
#######################################
## ##
## See /calendar/ for a "live" ##
## example of this CGI script. ##
## ##
#######################################
BEGIN { eval { require bytes; }; }
use strict;
use Date::Calc qw(:all);
use Date::Calendar::Profiles qw($Profiles);
use Date::Calendar;
my $filler = '
';
my $RED = '';
my $PINK = '';
my $END = '';
my $language = 6;
my $country = 'NL';
my $select = 0;
my $dispyear = 0;
my $weekend = '';
my @DOW = ();
my @html = ();
my @start = ();
my @markwend = ();
my @marksele = ();
my @markyear = ();
my @language = ();
my @sortlang = ();
my @marklang = ();
my %profiles = ();
my %sortprof = ();
my %markprof = ();
my %weekend = ();
my %sdm = ();
&init_tables();
&process_profiles();
&process_query_string();
&set_defaults();
&print_page();
exit 0;
sub init_tables()
{
my $i;
local $_;
$html[0x00] = '';
$html[0x01] = '';
$html[0x02] = '';
$html[0x03] = '';
$html[0x04] = '';
$html[0x05] = '';
$html[0x06] = '';
$html[0x07] = '';
$html[0x08] = '';
# $html[0x09] = '';
# $html[0x0A] = '';
$html[0x0B] = '';
$html[0x0C] = '';
$html[0x0D] = '';
$html[0x0E] = '';
$html[0x0F] = '';
$html[0x10] = '';
$html[0x11] = '';
$html[0x12] = '';
$html[0x13] = '';
$html[0x14] = '';
$html[0x15] = '';
$html[0x16] = '';
$html[0x17] = '';
$html[0x18] = '';
$html[0x19] = '';
$html[0x1A] = '';
$html[0x1B] = '';
$html[0x1C] = '';
$html[0x1D] = '';
$html[0x1E] = '';
$html[0x1F] = '';
$html[0x22] = '"';
$html[0x26] = '&';
# $html[0x27] = ''';
$html[0x3C] = '<';
$html[0x3E] = '>';
$html[0x7F] = '';
$html[0x80] = '';
$html[0x81] = '';
$html[0x82] = '';
$html[0x83] = '';
$html[0x84] = '';
$html[0x85] = '';
$html[0x86] = '';
$html[0x87] = '';
$html[0x88] = '';
$html[0x89] = '';
$html[0x8A] = '';
$html[0x8B] = '';
$html[0x8C] = '';
$html[0x8D] = '';
$html[0x8E] = '';
$html[0x8F] = '';
$html[0x90] = '';
$html[0x91] = '';
$html[0x92] = '';
$html[0x93] = '';
$html[0x94] = '';
$html[0x95] = '';
$html[0x96] = '';
$html[0x97] = '';
$html[0x98] = '';
$html[0x99] = '';
$html[0x9A] = '';
$html[0x9B] = '';
$html[0x9C] = '';
$html[0x9D] = '';
$html[0x9E] = '';
$html[0x9F] = '';
$html[0xA0] = ' ';
$html[0xA1] = '¡';
$html[0xA2] = '¢';
$html[0xA3] = '£';
$html[0xA4] = '¤';
$html[0xA5] = '¥';
$html[0xA6] = '¦';
$html[0xA7] = '§';
$html[0xA8] = '¨';
$html[0xA9] = '©';
$html[0xAA] = 'ª';
$html[0xAB] = '«';
$html[0xAC] = '¬';
$html[0xAD] = '';
$html[0xAE] = '®';
$html[0xAF] = '¯';
$html[0xB0] = '°';
$html[0xB1] = '±';
$html[0xB2] = '²';
$html[0xB3] = '³';
$html[0xB4] = '´';
$html[0xB5] = 'µ';
$html[0xB6] = '¶';
$html[0xB7] = '·';
$html[0xB8] = '¸';
$html[0xB9] = '¹';
$html[0xBA] = 'º';
$html[0xBB] = '»';
$html[0xBC] = '¼';
$html[0xBD] = '½';
$html[0xBE] = '¾';
$html[0xBF] = '¿';
$html[0xC0] = 'À';
$html[0xC1] = 'Á';
$html[0xC2] = 'Â';
$html[0xC3] = 'Ã';
$html[0xC4] = 'Ä';
$html[0xC5] = 'Å';
$html[0xC6] = 'Æ';
$html[0xC7] = 'Ç';
$html[0xC8] = 'È';
$html[0xC9] = 'É';
$html[0xCA] = 'Ê';
$html[0xCB] = 'Ë';
$html[0xCC] = 'Ì';
$html[0xCD] = 'Í';
$html[0xCE] = 'Î';
$html[0xCF] = 'Ï';
$html[0xD0] = 'Ð';
$html[0xD1] = 'Ñ';
$html[0xD2] = 'Ò';
$html[0xD3] = 'Ó';
$html[0xD4] = 'Ô';
$html[0xD5] = 'Õ';
$html[0xD6] = 'Ö';
$html[0xD7] = '×';
$html[0xD8] = 'Ø';
$html[0xD9] = 'Ù';
$html[0xDA] = 'Ú';
$html[0xDB] = 'Û';
$html[0xDC] = 'Ü';
$html[0xDD] = 'Ý';
$html[0xDE] = 'Þ';
$html[0xDF] = 'ß';
$html[0xE0] = 'à';
$html[0xE1] = 'á';
$html[0xE2] = 'â';
$html[0xE3] = 'ã';
$html[0xE4] = 'ä';
$html[0xE5] = 'å';
$html[0xE6] = 'æ';
$html[0xE7] = 'ç';
$html[0xE8] = 'è';
$html[0xE9] = 'é';
$html[0xEA] = 'ê';
$html[0xEB] = 'ë';
$html[0xEC] = 'ì';
$html[0xED] = 'í';
$html[0xEE] = 'î';
$html[0xEF] = 'ï';
$html[0xF0] = 'ð';
$html[0xF1] = 'ñ';
$html[0xF2] = 'ò';
$html[0xF3] = 'ó';
$html[0xF4] = 'ô';
$html[0xF5] = 'õ';
$html[0xF6] = 'ö';
$html[0xF7] = '÷';
$html[0xF8] = 'ø';
$html[0xF9] = 'ù';
$html[0xFA] = 'ú';
$html[0xFB] = 'û';
$html[0xFC] = 'ü';
$html[0xFD] = 'ý';
$html[0xFE] = 'þ';
$html[0xFF] = 'ÿ';
$start[0] = [Today()];
$start[1] = [Week_of_Year(@{$start[0]})];
for ( $i = 1; $i <= Languages(); $i++ )
{
$_ = Language_to_Text($i);
$language[$i] = html($_);
$sortlang[$i] = iso_coll(iso_lc($_));
}
%sdm =
(
'BLN' => 'Berlin',
'BON' => 'Bonn',
'CGN' => 'Köln',
'DET' => 'Detroit (USA)',
'FFM' => 'Frankfurt a.M.',
'HAN' => 'Hannover',
'HH' => 'Hamburg',
'MUC' => 'München',
'RAT' => 'Ratingen (Düsseldorf)',
'STG' => 'Stuttgart',
'ZRH' => 'Zürich (Schweiz)'
);
%profiles = map { $_, $_ } keys(%{$Profiles});
}
sub process_profiles()
{
my $profile = $INC{'Date/Calendar/Profiles.pm'};
my($read,$cache,$line,$key);
$read = 1;
if (defined($profile) and $profile ne '' and -f $profile and -r $profile and -s $profile)
{
$cache = $0;
$cache =~ s!\.+[^/\\\.]*$!!;
$cache .= ".cache";
if (!(-f $cache and -s $cache) or ((stat($cache))[9] < (stat($profile))[9]))
{
if (open(PROFILE, "<$profile"))
{
if (open(CACHE, ">$cache"))
{
while (defined ($line = ))
{
if ($line =~ m!^\s*\$Profiles->{'([A-Za-z]+(?:-[A-Za-z]+)?)'}\s*=\s*\#\s*(.+?)\s*$!)
{
$profiles{$1} = $2;
}
}
foreach $key (keys %profiles)
{
if ($key =~ m!^([A-Za-z]+)-([A-Za-z]+)$! and defined $profiles{$1})
{
if ($1 eq 'sdm')
{
$profiles{$key} = $profiles{$1} . " - " . $sdm{$2};
}
else
{
$profiles{$key} = $profiles{$1} . " - " . $profiles{$key};
}
}
}
foreach $key (sort keys(%profiles))
{
printf(CACHE "%8s => %s\n", $key, $profiles{$key});
$read = 0;
}
close(CACHE);
}
close(PROFILE);
}
}
}
if ($read and -f $cache and -r $cache and -s $cache)
{
if (open(CACHE, "<$cache"))
{
while (defined ($line = ))
{
if ($line =~ m!^\s*([A-Za-z]+(?:-[A-Za-z]+)?)\s*=>\s*(.+?)\s*$!)
{
$profiles{$1} = $2;
}
}
close(CACHE);
}
}
foreach $key (keys(%profiles))
{
$line = $profiles{$key};
$profiles{$key} = html($line);
$sortprof{$key} = iso_coll(iso_lc($line));
}
}
sub process_query_string()
{
my $query = $ENV{'QUERY_STRING'} || $ENV{'REDIRECT_QUERY_STRING'} || 'weekend=6-7';
my @pairs = split(/&/, $query);
my($pair,$var,$val,$dow);
%weekend = ();
foreach $pair (@pairs)
{
($var,$val) = split(/=/,$pair,2);
if ($var =~ m!^[a-z]+$!)
{
if ($var eq 'select')
{
if ($val =~ m!^[0-9]+$!) { $select = $val ? 1 : 0; }
}
elsif ($var eq 'weekend')
{
if ($val =~ m!^[1-7]$!) { $weekend{$val} = 1; }
elsif ($val =~ m!^[1-7](?:-[1-7])+$!) { foreach $dow (split(/-/,$val)) { $weekend{$dow} = 1; } }
}
elsif ($var eq 'dispyear')
{
if ($val =~ m!^[0-9]+$! and $val >= 0 and $val <= 2) { $dispyear = $val; }
}
elsif ($var eq 'language')
{
if ($val =~ m!^[0-9]+$! and $val >= 1 and $val <= Languages()) { $language = $val; }
}
elsif ($var eq 'country')
{
if ($val =~ m!^[A-Za-z]+(?:-[A-Za-z]+)?$! and defined $profiles{$val}) { $country = $val; }
}
elsif ($var eq 'myear')
{
if ($val =~ m!^[0-9]+$! and $val >= 1583 and $val <= 2299) { $start[0][0] = $val; }
}
elsif ($var eq 'month')
{
if ($val =~ m!^[0-9]+$! and $val >= 1 and $val <= 12) { $start[0][1] = $val; }
}
elsif ($var eq 'week')
{
if ($val =~ m!^[0-9]+$! and $val >= 1 and $val <= 53) { $start[1][0] = $val; }
}
elsif ($var eq 'wyear')
{
if ($val =~ m!^[0-9]+$! and $val >= 1583 and $val <= 2299) { $start[1][1] = $val; }
}
}
}
$weekend{0} = 1 unless (scalar(keys(%weekend)));
$weekend = join('-',sort(keys(%weekend)));
}
sub set_defaults()
{
my $year;
local $_;
@markwend = ('') x 8;
@marksele = ('', '');
@markyear = ('', '', '');
@marklang = ('') x (Languages() + 1);
%markprof = map { $_, '' } keys(%profiles);
$markwend[$_] = ' CHECKED' foreach (keys %weekend);
$marksele[$select] = ' CHECKED';
$markyear[$dispyear] = ' CHECKED';
$marklang[$language] = ' SELECTED';
$markprof{$country} = ' SELECTED';
if ($dispyear > 0)
{
if ($select) { $year = $start[1][1]; }
else { $year = $start[0][0]; }
$start[0] = [$year,1,1];
$start[1] = [1,$year];
$start[2] = Days_in_Year($year,12);
$start[3] = [$year-1,1,1];
$start[4] = [1,$year-1];
$start[5] = [$year+1,1,1];
$start[6] = [1,$year+1];
}
else
{
if ($select)
{
$_ = Weeks_in_Year($start[1][1]);
$start[1][0] = $_ if ($start[1][0] > $_);
$start[0] = [Monday_of_Week(@{$start[1]})];
$start[2] = 28;
$start[3] = [Add_Delta_Days(@{$start[0]},-28)];
$start[4] = [Week_of_Year(@{$start[3]})];
$start[5] = [Add_Delta_Days(@{$start[0]},+28)];
$start[6] = [Week_of_Year(@{$start[5]})];
}
else
{
$start[0][2] = 1;
$start[1] = [Week_of_Year(@{$start[0]})];
$start[2] = Days_in_Month(@{$start[0]}[0,1]);
$start[3] = [Add_Delta_YM(@{$start[0]},0,-1)];
$start[4] = [Week_of_Year(@{$start[3]})];
$start[5] = [Add_Delta_YM(@{$start[0]},0,+1)];
$start[6] = [Week_of_Year(@{$start[5]})];
}
}
$DOW[$_] = html(Day_of_Week_Abbreviation($_,$language)) foreach (1..7);
}
sub print_page()
{
my($i,$key);
print <<"VERBATIM";
Content-type: text/html; charset="iso-8859-1"
Steffen Beyer's International Eternal Gregorian Calendar
Steffen Beyer's International Eternal Gregorian Calendar
VERBATIM
&print_calendar();
print <<"VERBATIM";
${RED}Please
report
any errors you find on this page!${END}
Download
the Perl software that does all this!
VERBATIM
}
sub print_calendar()
{
my $year = 0;
my $index = 0;
my $oyear = 0;
my $oweek = 0;
my $omonth = 0;
my($calendar,$full,$half,$C,$N,$cell,$week,$dow);
my(@date,$tags);
local $_;
$calendar = Date::Calendar->new( $Profiles->{$country}, Decode_Language("English"), keys(%weekend) );
print <<"VERBATIM";
$profiles{$country} |
Year |
Week Number |
Day of Week |
Month |
Day |
Name |
VERBATIM
@date = @{$start[0]};
while ($start[2] > 0 and $date[0] <= 2299)
{
if ($date[0] >= 1583)
{
if ($year != $date[0])
{
$year = $date[0];
$index = $calendar->date2index(@date);
$full = $calendar->year($year)->vec_full();
$half = $calendar->year($year)->vec_half();
}
if ( ($dispyear == 0) or
(($dispyear == 2) and (keys(%{$tags = $calendar->year($year)->tags($index)}))) or
(($dispyear == 1) and ($full->bit_test($index) or $half->bit_test($index)) and not exists($weekend{Day_of_Week(@date)})))
{
print "\n";
if ($full->bit_test($index)) { $C = $RED; $N = $END; }
elsif ($half->bit_test($index)) { $C = $PINK; $N = $END; }
else { $C = ''; $N = ''; }
if ($oyear != $date[0])
{
$oyear = $date[0];
$cell = "$oyear";
}
else { $cell = $filler; }
print qq($cell | \n); # Year
$week = Week_of_Year(@date);
if ($oweek != $week)
{
$oweek = $week;
$cell = "$week";
}
else { $cell = $filler; }
print qq($cell | \n); # Week Number
$tags = $calendar->year($year)->tags($index) unless ($dispyear == 2);
$dow = html(Day_of_Week_to_Text(Day_of_Week(@date),$language));
print qq($C$dow$N | \n); # Day of Week
if ($omonth != $date[1])
{
$omonth = $date[1];
$cell = "" . html(Month_to_Text($omonth,$language)) . "";
}
else { $cell = $filler; }
print qq($cell | \n); # Month
print qq($C$date[2]$N | \n); # Day
if (keys(%$tags))
{
print
qq(\n), # Name
join
(
" \n",
map
{
if ($tags->{$_} & 2) { $RED . html($_) . $END; }
elsif ($tags->{$_} & 1) { $PINK . html($_) . $END; }
else { html($_) }
}
keys(%$tags)
),
qq(\n | \n);
}
else
{
print qq($filler | \n); # Name
}
print "
\n";
}
}
if (--$start[2] > 0) { @date = Add_Delta_Days(@date,1); $index++; }
}
}
sub html($)
{
my $string = $_[0];
my $o;
$string =~ s!(.)!(defined $html[$o=ord($1)])?($html[$o]||"&\#$o;"):$1!eg;
$string;
}
sub iso_lc($)
{
my $string = $_[0];
$string =~ tr/\x41-\x5A\xC0-\xD6\xD8-\xDE\x8A\x8C\x9F/\x61-\x7A\xE0-\xF6\xF8-\xFE\x9A\x9C\xFF/;
$string;
}
sub iso_coll($)
{
my $string = $_[0];
$string =~ s/\xC4/Ae/g; # German
$string =~ s/\xE4/ae/g;
$string =~ s/\xD6/Oe/g;
$string =~ s/\xF6/oe/g;
$string =~ s/\xDC/Ue/g;
$string =~ s/\xFC/ue/g;
$string =~ s/\xDF/ss/g;
$string =~ s/\xC6/AE/g; # Scandinavian
$string =~ s/\xE6/ae/g;
# $string =~ s/\xD8/OE/g;
# $string =~ s/\xF8/oe/g;
$string =~ s/\xFF/ij/g; # Dutch
$string =~ s/\x9F/IJ/g; # Dutch (Non-Standard!)
$string =~ s/\x8C/OE/g; # French (Non-Standard!)
$string =~ s/\x9C/oe/g; # French (Non-Standard!)
$string =~ tr/\x20\x2D\x5F\x30-\x39A\xC0-\xC6a\xE0-\xE6BbC\xC7c\xE7DdE\xC8-\xCBe\xE8-\xEBFfGgHhI\xCC-\xCFi\xEC-\xEFJjKkLlMmNn\xD1\xF1O\xD2-\xD6\xD8\x8Co\xF2-\xF6\xF8\x9CPpQqRrS\x8As\x9A\xDFTtU\xD9-\xDCu\xF9-\xFCVvWwXxY\xDD\x9Fy\xFD\xFFZz\xD0\xF0\xDE\xFE\x21-\x2C\x2E\x2F\x3A-\x40\x5B-\x5E\x60\x7B-\x89\x8B\x8D-\x99\x9B\x9D\x9E\xA0-\xBF\xD7\xF7/\x20-\xFF/;
$string;
}
__END__