#!/usr/local/bin/perl -w
my
(
$columns
,
$lang
,
$last
,
$example
,
$table_workaround
)
= ( 9,
'en'
, 400, 80218, 0);
GetOptions(
'columns=i'
=> \
$columns
,
'lang=s'
=> \
$lang
,
'example=s'
=> \
$example
,
'table-workaround'
=> \
$table_workaround
);
die
"At least 5 colmuns"
if
$columns
< 5;
die
"The number of columns must be a multiple of 4 plus 1 (e.g. 5, 9 or 13)"
unless
$columns
% 4 == 1;
binmode
STDOUT,
':utf8'
;
--
$columns
;
my
@parts
= (
'b'
,
'e'
);
my
@day_of_yearpart
;
my
%year_of_partday
;
foreach
my
$part
(
@parts
)
{ day_of_yearpart(
$_
,
$part
)
foreach
(1..
$last
) }
if
(DEBUG)
{
for
my
$year
(1 ..
$last
)
{
print
' '
, day_of_yearpart(
$year
,
$_
)
foreach
(
@parts
);
print
"\n"
if
$year
% 4 == 3;
}
print
"\n"
;
}
my
$next_letter
=
'a'
;
my
%letter_of_partday
= ();
foreach
my
$part
(
@parts
)
{
foreach
(
sort
{
$a
<=>
$b
}
keys
%{
$year_of_partday
{
$part
}})
{
$letter_of_partday
{
$part
}{
$_
} =
$next_letter
++;
++
$next_letter
if
$next_letter
eq
'i'
;
}
}
if
(DEBUG)
{
for
my
$year
(1 ..
$last
)
{
print
' '
,
$year
,
' '
, word_for_year(
$year
);
print
"\n"
if
$year
% 4 == 0
}
print
"\n"
;
}
my
%line_for_interval
;
my
%end_of_interval
;
build_intervals();
if
(DEBUG)
{
print
"$_ $end_of_interval{$_} $line_for_interval{$_}\n"
foreach
(
sort
{
$a
<=>
$b
}
keys
%line_for_interval
);
}
my
$ref_labels
;
if
(
$lang
eq
'fr'
)
{
$ref_labels
=
do
"$FindBin::Bin/labels_fr"
}
else
{
$ref_labels
=
do
"$FindBin::Bin/labels_en"
}
my
%labels
=
%$ref_labels
;
my
@fr_month
=
qw (Vendémiaire
Brumaire Frimaire Nivôse Pluviôse Ventôse
Germinal Floréal Prairial Messidor Thermidor Fructidor);
push
@fr_month
,
"Sans-Culottides<br>$labels{add_days}"
;
html_0(
$labels
{titler2g});
html_1(
$labels
{title1});
html_2(
$_
)
foreach
(
@parts
);
print
"<table><tr><td>\n"
if
$table_workaround
;
usage(
$example
);
print
"</td></tr></table>\n"
if
$table_workaround
;
print
"</body>\n</html>\n"
;
sub
day_of_yearpart {
my
(
$year
,
$part
) =
@_
;
return
$day_of_yearpart
[
$year
]{
$part
}
if
$day_of_yearpart
[
$year
]{
$part
};
my
$month
=
$part
eq
'b'
? 1 : 7;
my
$date
= DateTime->from_object(
object
=> DateTime::Calendar::FrenchRevolutionary->new(
year
=>
$year
,
month
=>
$month
));
my
$day
=
$date
->day();
$year_of_partday
{
$part
}{
$day
} =
$year
unless
$year_of_partday
{
$part
}{
$day
};
$day_of_yearpart
[
$year
]{
$part
} =
$day
;
}
sub
word_for_year {
my
(
$year
) =
@_
;
join
''
,
map
{ letter_of_yearpart(
$year
,
$_
) }
@parts
;
}
sub
letter_of_yearpart {
my
(
$year
,
$part
) =
@_
;
$letter_of_partday
{
$part
}{
$day_of_yearpart
[
$year
]{
$part
}};
}
sub
build_intervals {
my
$current_start
= 1;
%line_for_interval
= (
1
=>
' '
x
$columns
);
$end_of_interval
{1} = 4;
foreach
my
$year
(1..
$last
) {
my
$old_line
=
$line_for_interval
{
$current_start
};
my
$new_line
=
' '
x
$columns
;
substr
(
$new_line
,
$year
% 100 %
$columns
* 2, 2) = word_for_year(
$year
);
my
$intersection
=
$old_line
&
$new_line
;
$intersection
=~
tr
/ /./;
unless
(
$old_line
=~ m{
$intersection
} &&
$new_line
=~ m{
$intersection
}) {
$current_start
=
$year
;
$line_for_interval
{
$year
} =
$new_line
;
}
$line_for_interval
{
$current_start
} |=
$new_line
;
$end_of_interval
{
$current_start
} =
$year
;
}
}
sub
formulas {
my
(
$year
,
$month
) =
@_
;
my
@formulas
= ();
my
@month
=
qw(Sep Oct Nov Dec Jan Feb Mar Apr May Jun Jul Aug Sep)
;
my
$date
= DateTime->from_object(
object
=> DateTime::Calendar::FrenchRevolutionary->new(
year
=>
$year
,
month
=>
$month
));
my
$offset
=
$date
->day() - 1;
push
@formulas
,
"+$offset $labels{month3}[$date->month_0]"
;
if
(
$month
< 13)
{
$date
= DateTime->from_object(
object
=> DateTime::Calendar::FrenchRevolutionary->new(
year
=>
$year
,
month
=>
$month
,
day
=> 30));
$offset
= 30 -
$date
->day();
push
@formulas
,
"-$offset $labels{month3}[$date->month() - 1]"
;
}
@formulas
;
}
sub
html_0 {
my
(
$title
) =
@_
;
print
<<"EOF";
<html>
<head>
<title>$title</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>$title</h1>
EOF
}
sub
html_1 {
my
(
$title1
) =
@_
;
print
"<table border><tr><td></td><th align='center' colspan='$columns'>$title1</th></tr><tr align='right'><td></td>\n"
;
foreach
my
$n1
(0 ..
$columns
- 1)
{
printf
"<td>%2d"
,
$n1
;
for
(
my
$n0
=
$n1
+
$columns
;
$n0
<= 99;
$n0
+=
$columns
)
{
printf
"<br>%2d"
,
$n0
% 100 }
print
"<br> "
if
$n1
> 99 %
$columns
;
print
"</td>\n"
;
}
print
"</tr>\n"
;
foreach
my
$year1
(
sort
{
$a
<=>
$b
}
keys
%end_of_interval
)
{
print
"<tr align='center'><td>$year1 - $end_of_interval{$year1}"
;
my
$line
=
$line_for_interval
{
$year1
};
$line
=~ s=(..)=</td><td>$1=g;
print
"$line</td></tr>\n"
;
}
print
"</table>\n"
;
}
sub
html_2 {
my
(
$part
) =
@_
;
my
@days
=
sort
{
$a
<=>
$b
}
keys
%{
$letter_of_partday
{
$part
}};
my
$colspan
=
@days
+ 1;
print
"<p><table border><tr><th align='center' colspan='$colspan'>$labels{title2}{$part}</th></tr>\n"
;
if
(
$part
eq
'b'
)
{
html_2header(1791,
$part
);
html_two_formulas(
$part
,
$_
)
foreach
(1..3);
html_one_formula (
$part
, 4, 0);
html_2header(1792,
$part
);
html_one_formula (
$part
, 4, 1);
html_two_formulas(
$part
, 5);
html_one_formula (
$part
, 6, 0);
}
else
{
html_2header(1792,
$part
);
html_one_formula (
$part
, 6, 1);
html_two_formulas(
$part
,
$_
)
foreach
(7..12);
html_one_formula (
$part
, 13, 0);
}
print
"</table>\n"
;
}
sub
html_2header {
my
(
$offset
,
$part
) =
@_
;
my
@letters
=
sort
values
%{
$letter_of_partday
{
$part
}};
print
"<tr align='center'><th>"
,
join
(
'</th><th>'
,
"$labels{year_ttl} + $offset"
,
@letters
)
,
"</th></tr>\n"
;
}
sub
html_two_formulas {
my
(
$part
,
$month
) =
@_
;
my
@days
=
sort
{
$a
<=>
$b
}
keys
%{
$letter_of_partday
{
$part
}};
print
"<tr align='center'><td>$fr_month[$month - 1]</td>"
;
foreach
(
@days
)
{
my
$year
=
$year_of_partday
{
$part
}{
$_
};
my
@formulas
= formulas(
$year
,
$month
);
print
"<td>$formulas[0]<br>$formulas[1]</td>\n"
;
}
print
"</tr>\n"
;
}
sub
html_one_formula {
my
(
$part
,
$month
,
$nb
) =
@_
;
my
@days
=
sort
{
$a
<=>
$b
}
keys
%{
$letter_of_partday
{
$part
}};
print
"<tr align='center'><td>$fr_month[$month - 1]</td>"
;
foreach
(
@days
)
{
my
$year
=
$year_of_partday
{
$part
}{
$_
};
my
@formulas
= formulas(
$year
,
$month
);
print
"<td>$formulas[$nb]</td>\n"
;
}
print
"</tr>\n"
;
}
sub
usage {
my
(
$day
) =
@_
;
my
(
$y
,
$m
,
$d
) =
unpack
"A4A2A2"
,
sprintf
"%08d"
,
$day
;
$y
+= 0;
if
(
$m
== 6 ||
$m
== 13)
{
my
@m
=
qw(1 2 3 4 5 7 8 9 10 11 12)
;
$m
=
$m
[11 *
rand
];
}
my
$date_r
= DateTime::Calendar::FrenchRevolutionary->new(
year
=>
$y
,
month
=>
$m
,
day
=>
$d
);
my
$date_g
= DateTime->from_object(
object
=>
$date_r
);
my
$title_date
=
$date_r
->strftime(
"%d %B %EY"
);
my
$y2
=
sprintf
"%02d"
,
$y
% 100;
my
$part
=
$m
<= 6 ?
'b'
:
'e'
;
my
$offset
=
$part
eq
'e'
? 1792 : 1791;
my
$letter
= letter_of_yearpart(
$y
,
$part
);
my
$word
= word_for_year(
$y
);
my
@formulas
= formulas(
$y
,
$m
);
my
$limit
= $1
if
$formulas
[1] =~ /(\d+)/;
my
$formula
=
$formulas
[
$d
<=
$limit
? 0 : 1];
my
$gyear
=
$date_g
->year;
my
$gmonth
=
$date_g
->month;
my
$gday
=
$date_g
->day;
my
$begint
;
foreach
(
sort
{
$a
<=>
$b
}
keys
%end_of_interval
)
{
last
if
$y
<
$_
;
$begint
=
$_
;
}
my
$gr_date
= &{
$labels
{
format
}}(
$gyear
,
$gmonth
,
$gday
,
$lang
);
$_
=
eval
"qq($labels{usage3})"
;
print
;
print
"\n"
;
$date_r
= DateTime::Calendar::FrenchRevolutionary->new(
year
=>
$y
,
month
=> 6,
day
=>
$d
);
$date_g
= DateTime->from_object(
object
=>
$date_r
);
$title_date
=
$date_r
->strftime(
"%d %B %EY"
);
@formulas
= formulas(
$y
, 6);
my
$bletter
= letter_of_yearpart(
$y
,
'b'
);
my
$eletter
= letter_of_yearpart(
$y
,
'e'
);
$gyear
=
$date_g
->year;
$gmonth
=
$date_g
->month;
$gday
=
$date_g
->day;
$gr_date
= &{
$labels
{
format
}}(
$gyear
,
$gmonth
,
$gday
,
$lang
);
$limit
= $1
if
$formulas
[1] =~ /(\d+)/;
if
(
$d
<=
$limit
)
{
$formula
=
$formulas
[0];
$offset
= 1791 }
else
{
$formula
=
$formulas
[1];
$offset
= 1792 }
$_
=
eval
"qq($labels{usage4})"
;
print
;
}