\NeedsTeXFormat{LaTeX2e}
\ProvidesFile{calxxxx-yyyy.tex}%
  [2023/01/01 v20.23a Print a calendar for a group of years (HMM)]
%
% Copyright © 2010 - 2023 H.-Martin Münch (Martin dot Muench at Uni-Bonn dot de)
% Portions of code copyrighted by Slobodan Janković.
% This file was invented in 1999 by Slobodan Janković.
% I was not able to reach him at slobodan@archimed.filfak.ni.ac.yu
% (not surprisingly with a .yu address).
% Thanks to the translators (see below) and the reporter of a bug: Koloskov Gleb.
% Languages/Translations:
%  - English: Slobodan Janković
%  - German (Deutsch): Martin Münch
%  - Danish (Dansk): Michael Lodahl
%
% I updated Janković's file, so that it is possible to print the calendars
% for different years and to use different languages (and therefore also use weeks
% running from Monday to Sunday instead of Sunday to Saturday).
%
% Hint: Gernerally \newcommand would be better than \def, but because this is
% no style file and the original code used \def, I did not want to change it.
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License (LPPL),
% either version 1.3c of this license or (at your option) any later version.
% This version of this license is in
%   https://www.latex-project.org/lppl/lppl-1-3c.txt
% and the latest version of this license is in
%   https://www.latex-project.org/lppl.txt
% and version 1.3c or later is part of all distributions of
% LaTeX version 2005/12/01 or later.
%
% This work has the LPPL maintenance status "maintained".
%
% The Current Maintainer of this work is H.-Martin Münch.
%
% This work consists of the main source files
%   calxxxx-yyyy.tex, README, and calxxxx-yyyy-doc.tex,
% and the derived files
%   calxxxx-yyyy-doc.pdf, cal2023-2040_DE.pdf, cal2023-2040_DK.pdf,
%   and cal2023-2040_EN.pdf.
%
% In memoriam
%  Claudia Simone Barth + 1996/01/30
%  Tommy Münch + 2014/01/02
%  Hans-Klaus Münch + 2014/08/24
%
\documentclass[12pt,a4paper,danish,german,english]{report}[2022/07/02]% v1.4n
% In the options you need to place the desired language at the last position.
% Sorry for the inconvenience.
\usepackage{babel}[2022/12/26]% v3.84
\selectlanguage{english}% Also possible: 'english', 'german', or 'danish'
\usepackage[a4paper,textwidth=\paperwidth,textheight=\paperheight]{geometry}[2020/01/02]% v5.9
\usepackage{array}[2022/09/04]% v2.5g
\listfiles
\thispagestyle{empty}

% Counters, logical, and lengths
% year, month, day of the week:
\newcount\y
\y=0\relax
\newcount\m
\m=0\relax
\newcount\x
\x=0\relax
% temporary counters:
\newcount\p
\p=0\relax
\newcount\q
\q=0\relax
\newif\ifleap     % if leap year
\newif\ifJulian   % if Julian calendar
\newif\ifZeroExist% if 0th year exist
\newif\ifCmRule   % cm rule at right
\newlength{\Wd}   % the widest name of days
\setlength{\Wd}{0pt}
\newlength{\Wdx}  % temporary dim
\setlength{\Wdx}{0pt}

%========== Start of Safe Modifications =============
% The following definitions are safe to change

% Fonts for Year, Months and Days
\def\yearfont{\normalsize\bfseries}
\def\monthfont{\scriptsize\scshape}
\def\dayfont{\tiny}

% Language Dependent Definitions (B.C., A.D., months, and days)
% Default language: English
\def\BC{\ B.\,C.}\def\AD{}% 'B.C.' after a negative year, nothing after a positive

\def\Jan{January}  \def\Feb{February}\def\Mar{March}   \def\Apr{April}
\def\May{May}      \def\Jun{June}    \def\Jul{July}    \def\Aug{August}
\def\Sep{September}\def\Oct{October} \def\Nov{November}\def\Dec{December}

\def\Sun{\textbf{S}} \def\Mon{\textbf{M}} \def\Tue{\textbf{T}} \def\Wen{\textbf{W}}
\def\Thr{\textbf{T}} \def\Fri{\textbf{F}} \def\Sat{\textbf{S}}

\iflanguage{english}{% English, which is already the default language. Nothing to be done.
\typeout{Language \languagename ^^J}
}{\iflanguage{german}{% Deutsch
 \typeout{Language \languagename ^^J}
 \def\BC{~v.~Chr.}\def\AD{}% '~v.~Chr.' after a negative year, nothing after a positive

 \def\Jan{Januar}   \def\Feb{Februar}\def\Mar{März}\def\Apr{April}
 \def\May{Mai}      \def\Jun{Juni}   \def\Jul{Juli}    \def\Aug{August}
 \def\Sep{September}\def\Oct{Oktober}\def\Nov{November}\def\Dec{Dezember}

 \def\Mon{\textbf{Mo}} \def\Tue{\textbf{Di}} \def\Wen{\textbf{Mi}}
 \def\Thr{\textbf{Do}} \def\Fri{\textbf{Fr}} \def\Sat{\textbf{Sa}} \def\Sun{\textbf{So}}
 }{\iflanguage{danish}{% Danish
  \typeout{Language \languagename ^^J}
  \def\BC{~f.~Kr.}\def\AD{}% '~f.~Kr.' after a negative year, nothing after a positive

  \def\Jan{Januar}   \def\Feb{Februar}\def\Mar{Marts}   \def\Apr{April}
  \def\May{Maj}      \def\Jun{Juni}   \def\Jul{Juli}    \def\Aug{August}
  \def\Sep{September}\def\Oct{Oktober}\def\Nov{November}\def\Dec{December}

  \def\Mon{\textbf{Ma}} \def\Tue{\textbf{Ti}} \def\Wen{\textbf{On}}
  \def\Thr{\textbf{To}} \def\Fri{\textbf{Fr}} \def\Sat{\textbf{L{\o}}} \def\Sun{\textbf{S{\o}}}
  }{% Not English, Danish or German. Place your translation here!
    % Further down there is another place in the code which needs the "translation"
    % for further languages, search for "Place your translation here!".
    \typeout{Language \languagename\space not supported. Keeping the default: English.}
   }
  }
 }

% Margins and Spaces
\setlength{\topmargin}{-1in}\setlength{\oddsidemargin}{-1in}% no margins
\def\sm{\hspace{2pt}}% space between months

% Select Gregorian/Julian calendar and zero/nonzero (default are both false)
\Julianfalse   % do not use Julian, use Gregorian calendar
\ZeroExistfalse% zero year does not exist (before 1st is -1st year)
%\Juliantrue   % use Julian, do not use Gregorian calendar
%\ZeroExisttrue% zero year exists (before 1st is 0th year)

% Do you wish a cm rule? (default is false)
\CmRulefalse% do not print the cm rule
%\CmRuletrue% print the cm rule

%========== End of Safe Modifications =============
% It is not recommended to change anything below this line!

% Set \x=the day of the week (0=Sunday, 1=Monday,...)
\def\dayofweek#1{\m=#1 \x=\y%              x:=y;
\ifnum \x>0\else%                          if x<=0 then
  \ifZeroExist \else \advance\x by 1 \fi%  begin if not ZeroExist x:=y+1;
  \q=\x \divide\q by 2800 \advance\q by -1%  q:=x; q:=(q div 2800-1)*2800;
  \multiply\q by 2800 \advance\x by -\q%     x:=x-q
\fi%                                       end;
\p=\x%                                     p:=x;
\q=\m \multiply \q by 3%                   q=m*31;
\advance \x by \q \advance \x by 4%        x:=x+q+4;
\ifnum \m<3 \advance \p by -1 \else%       if m<3 then p:=p-1 else
  \q=\m \multiply\q by 4 \advance\q by 23% begin q:=(4*m+23) div 10;
  \divide\q by 10 \advance\x by -\q%         x:=x-q
\fi%                                       end;
\q=\p \divide\q by 4 \advance\x by \q%     q:=p div 4; x:=x+q;
\ifJulian \else%                           if not Julian then
  \divide\p by 100 \advance\p by 1%        begin p:=p div 100+1;
  \multiply\p by 3 \divide\p by 4%           p:=p*3 div 4;
  \advance\x by -\p%                         x:=x-p
\fi%                                       end;
\p=\x \divide\p by 7 \multiply\p by 7%     p:=(x div 7)*7;
\advance \x by -\p}%                       x:=x-p;

%Is \y a leap year?
\def\setleap{\leapfalse \x=\y%                 leap:=false; x:=y;
\ifnum \x<0%                                 if x<0 then
  \ifZeroExist \else \advance\x by 1 \fi%    begin if not ZeroExist else x:=x+1
\fi%                                         end;
\p=\x \divide\p by 4 \multiply\p by 4%       p:=(x div 4)*4;
\message{}%
\ifnum \x=\p%                                if x=p then
  \q=\x \divide\q by 100 \multiply\q by 100% begin q:=(x div 100)*100;
  \ifnum \x=\q%                                if x=q then
    \q=\x \divide\q by 400 \multiply\q by 400% begin q:=(x div 400)*400;
    \ifnum \x=\q \leaptrue \fi%                   if x=q then leap:=true
  \else \leaptrue%                              end else leap:=true
\fi\fi}%                                      end end

% Defines all kind of rows
\def\rows{%
\def\rone{&1&8&15&22&29&}% rows for a month with 31 days
\def\rtwo{&2&9&16&23&30&}\def\btwo{&&2&9&16&23&30}%
\def\rthree{&3&10&17&24&31&}\def\bthree{&&3&10&17&24&31}%
\def\rfour{&4&11&18&25&&}\def\bfour{&&4&11&18&25&}%
\def\rfive{&5&12&19&26&&}\def\bfive{&&5&12&19&26&}%
\def\rsix{&6&13&20&27&&}\def\bsix{&&6&13&20&27&}%
\def\rseven{&7&14&21&28&&}\def\bseven{&&7&14&21&28&}%
\ifnum\m=2%                  if February...
  \ifleap\else\def\rone{&1&8&15&22&&}\fi% if it is no leap year
  \def\rtwo{&2&9&16&23&&}\def\btwo{&&2&9&16&23&}%
  \def\rthree{&3&10&17&24&&}\def\bthree{&&3&10&17&24&}%
\else%                       if other month with <=30 days ...
  \ifnum\m=1\else\ifnum\m=3\else\ifnum\m=5\else\ifnum\m=7\else\ifnum\m=8\else
  \ifnum\m=10\else\ifnum\m=12\else
  \def\rthree{&3&10&17&24&&}\def\bthree{&&3&10&17&24&}%
\fi\fi\fi\fi\fi\fi\fi\fi}

% Calendar of a month

\def\Month#1{% #1=month
\setleap\dayofweek{#1}\rows% set leap, set \x=day of the week, and define all rows
\setlength{\tabcolsep}{0pt}
\begin{tabular*}{7em}{|>{\centering}p{\Wd}|@{\extracolsep{\fill}}rrrrrr|}
\multicolumn{7}{l}{\sm\monthfont% print name of a month \m
  \ifcase\m \or\Jan\or\Feb\or\Mar\or\Apr\or\May\or\Jun\or\Jul\or\Aug\or\Sep\or\Oct\or\Nov\or\Dec \fi}\\
\hline
\ifcase\x
  \Sun\rone\\ \Mon\rtwo\\ \Tue\rthree\\ \Wen\rfour\\ \Thr\rfive\\ \Fri\rsix\\ \Sat\rseven\\ \or% if Sunday
  \Sun\bseven\\ \Mon\rone\\ \Tue\rtwo\\ \Wen\rthree\\ \Thr\rfour\\ \Fri\rfive\\ \Sat\rsix\\ \or% if Monday
  \Sun\bsix\\ \Mon\bseven\\ \Tue\rone\\ \Wen\rtwo\\ \Thr\rthree\\ \Fri\rfour\\ \Sat\rfive\\ \or% if Tuesday
  \Sun\bfive\\ \Mon\bsix\\ \Tue\bseven\\ \Wen\rone\\ \Thr\rtwo\\ \Fri\rthree\\ \Sat\rfour\\ \or% if Wednesday
  \Sun\bfour\\ \Mon\bfive\\ \Tue\bsix\\ \Wen\bseven\\ \Thr\rone\\ \Fri\rtwo\\ \Sat\rthree\\ \or% if Thursday
  \Sun\bthree\\ \Mon\bfour\\ \Tue\bfive\\ \Wen\bsix\\ \Thr\bseven\\ \Fri\rone\\ \Sat\rtwo\\ \or% if Friday
  \Sun\btwo\\ \Mon\bthree\\ \Tue\bfour\\ \Wen\bfive\\ \Thr\bsix\\ \Fri\bseven\\ \Sat\rone\\ \fi% if Saturday
\hline
\end{tabular*}}

\iflanguage{english}{% English, which is already the default language. Nothing to be done.
}{\iflanguage{german}{% Deutsch
\def\Month#1{% #1=month
\setleap\dayofweek{#1}\rows% set leap, set \x=day of the week, and define all rows
\setlength{\tabcolsep}{0pt}
\begin{tabular*}{7em}{|>{\centering}p{\Wd}|@{\extracolsep{\fill}}rrrrrr|}
\multicolumn{7}{l}{\sm\monthfont% print name of a month \m
  \ifcase\m \or\Jan\or\Feb\or\Mar\or\Apr\or\May\or\Jun\or\Jul\or\Aug\or\Sep\or\Oct\or\Nov\or\Dec \fi}\\
\hline
\ifcase\x
  \Mon\btwo\\   \Tue\bthree\\ \Wen\bfour\\  \Thr\bfive\\  \Fri\bsix\\   \Sat\bseven\\ \Sun\rone\\   \or%
  \Mon\rone\\   \Tue\rtwo\\   \Wen\rthree\\ \Thr\rfour\\  \Fri\rfive\\  \Sat\rsix\\   \Sun\rseven\\ \or%
  \Mon\bseven\\ \Tue\rone\\   \Wen\rtwo\\   \Thr\rthree\\ \Fri\rfour\\  \Sat\rfive\\  \Sun\rsix\\   \or%
  \Mon\bsix\\   \Tue\bseven\\ \Wen\rone\\   \Thr\rtwo\\   \Fri\rthree\\ \Sat\rfour\\  \Sun\rfive\\  \or%
  \Mon\bfive\\  \Tue\bsix\\   \Wen\bseven\\ \Thr\rone\\   \Fri\rtwo\\   \Sat\rthree\\ \Sun\rfour\\  \or%
  \Mon\bfour\\  \Tue\bfive\\  \Wen\bsix\\   \Thr\bseven\\ \Fri\rone\\   \Sat\rtwo\\   \Sun\rthree\\ \or%
  \Mon\bthree\\ \Tue\bfour\\  \Wen\bfive\\  \Thr\bsix\\   \Fri\bseven\\ \Sat\rone\\   \Sun\rtwo\\   \fi%
 \hline
 \end{tabular*}}%
 }{\iflanguage{danish}{% Danish
  \renewcommand{\Month}[1]{% #1=month
  \setleap\dayofweek{#1}\rows% set leap, set \x=day of the week, and define all rows
  \setlength{\tabcolsep}{0pt}
  \begin{tabular*}{7em}{|>{\centering}p{\Wd}|@{\extracolsep{\fill}}rrrrrr|}
  \multicolumn{7}{l}{\sm\monthfont% print name of a month \m
    \ifcase\m \or\Jan\or\Feb\or\Mar\or\Apr\or\May\or\Jun\or\Jul\or\Aug\or\Sep\or\Oct\or\Nov\or\Dec \fi}\\
  \hline
  \ifcase\x
    \Mon\btwo\\   \Tue\bthree\\ \Wen\bfour\\  \Thr\bfive\\  \Fri\bsix\\   \Sat\bseven\\ \Sun\rone\\   \or%
    \Mon\rone\\   \Tue\rtwo\\   \Wen\rthree\\ \Thr\rfour\\  \Fri\rfive\\  \Sat\rsix\\   \Sun\rseven\\ \or%
    \Mon\bseven\\ \Tue\rone\\   \Wen\rtwo\\   \Thr\rthree\\ \Fri\rfour\\  \Sat\rfive\\  \Sun\rsix\\   \or%
    \Mon\bsix\\   \Tue\bseven\\ \Wen\rone\\   \Thr\rtwo\\   \Fri\rthree\\ \Sat\rfour\\  \Sun\rfive\\  \or%
    \Mon\bfive\\  \Tue\bsix\\   \Wen\bseven\\ \Thr\rone\\   \Fri\rtwo\\   \Sat\rthree\\ \Sun\rfour\\  \or%
    \Mon\bfour\\  \Tue\bfive\\  \Wen\bsix\\   \Thr\bseven\\ \Fri\rone\\   \Sat\rtwo\\   \Sun\rthree\\ \or%
    \Mon\bthree\\ \Tue\bfour\\  \Wen\bfive\\  \Thr\bsix\\   \Fri\bseven\\ \Sat\rone\\   \Sun\rtwo\\   \fi%
  \hline
  \end{tabular*}}%
  }{% Neither English nor German nor Danish. Place your translation here!
   \typeout{Language \languagename \space not supported. Keeping the default: English.}
   }
  }
 }

% Enter the years. Well, could be sensitive to language, too...
\def\enteryear{\typeout{}
\typeout{Enter the year (negative for B.C., 0th year does\ifZeroExist\else\space not\fi\space exist),}
\typeout{with which to start the calendar!}\typeout{}
\typeout{For the current year, \number\year, just press the ENTER key!}
\loop
  \typein[\Year]{}
  \ifx \Year\empty \gdef\Year{\year} \fi
  \y=\Year%
  \leapfalse \ifnum \y=0 \ifZeroExist \else \leaptrue \fi\fi
\ifleap \typeout{}\typeout{0th year doesn't exist! Maybe you want the year -1.} \repeat
\typeout{}%
\typeout{Enter the year (negative for B.C., 0th year does\ifZeroExist\else\space not\fi\space exist),}%
\typeout{with which to end the calendar!}\typeout{}%
\typeout{For the current year, \number\year , just press the ENTER key!}%
\typeout{(More than 85 years will probably exceed TeX's memory.)}%
\loop
  \typein[\YearZ]{}
  \ifx \YearZ\empty \gdef\YearZ{\year} \fi
  \leapfalse \ifnum \y=0 \ifZeroExist \else \leaptrue \fi\fi
  \ifnum\YearZ<\Year \typeout{}\typeout{Error: (Start-)Year must be before (End-)Year!} \gdef\YearZ{\Year} \fi
  \ifleap \typeout{}\typeout{0th year does not exist! Maybe you want the year -1.} \repeat
\typeout{}%
\typeout{\ifJulian Julian\else Gregorian\fi\space Calendar for the years \number\y -\number\YearZ.}%
\typeout{(Leap years are starred * .)}%
\typeout{}}

% Set \Wd to the widest name of the days
\def\SetWidth{%
\settowidth{\Wd} {\dayfont\Sun}% Wd:=width(Sun);
\settowidth{\Wdx}{\dayfont\Mon}\ifdim\Wd<\Wdx \Wd=\Wdx \fi% if Wd<width(Mon) then Wd:=width(Mon);
\settowidth{\Wdx}{\dayfont\Tue}\ifdim\Wd<\Wdx \Wd=\Wdx \fi% etc.
\settowidth{\Wdx}{\dayfont\Wen}\ifdim\Wd<\Wdx \Wd=\Wdx \fi
\settowidth{\Wdx}{\dayfont\Thr}\ifdim\Wd<\Wdx \Wd=\Wdx \fi
\settowidth{\Wdx}{\dayfont\Fri}\ifdim\Wd<\Wdx \Wd=\Wdx \fi
\settowidth{\Wdx}{\dayfont\Sat}\ifdim\Wd<\Wdx \Wd=\Wdx \fi}

% Print the calendar for the given year
\newcommand{\printyear}[1]{%
\y=#1%
\setleap%
\ifleap\message{\the\y* ^^J}%
\else\message{\the\y\space}%
\fi%
\begin{minipage}{.3\paperwidth}\dayfont% set font for the days
{\sm \yearfont
  \ifnum\y>0 \number\y\AD \else \ifZeroExist \the\y \else \p=-\y \number\p\BC\fi\fi
  \ifJulian \ (Julian)\fi}\\[.5ex]% print year
\SetWidth
\Month{1}\sm\Month{2}\sm\Month{3}\\%  print all months
\Month{4}\sm\Month{5}\sm\Month{6}\\
\Month{7}\sm\Month{8}\sm\Month{9}\\
\Month{10}\sm\Month{11}\sm\Month{12}\par
\end{minipage}}

% Print cm scale at right
\def\cmscale(#1,#2){\setlength{\unitlength}{1mm}
\begin{picture}(0,0)(#1,#2)\scriptsize
  \newcounter{cms}\put(-.3,71){cm}
  \multiput(2,70)(0,-1){70}{\line(1,0){1}} \multiput(1,65)(0,-10){7}{\line(1,0){2}}
  \multiput(0,70)(0,-10){8}{\line(1,0){3}}
  \multiput(1,60.5)(0,-10){7}{\makebox(0,0)[b]{\addtocounter{cms}{1}\arabic{cms}}}
\end{picture}}

\newcounter{year}

\begin{document}
\noindent \enteryear
\setcounter{year}{\y}
\loop
\printyear{\value{year}}
  \ifnum \value{year}<\YearZ
    \stepcounter{year}
    \indent
\repeat
\message{^^J}\message{^^J}%
\newline%
\tiny{\indent Original calxxxx.\TeX{} \copyright{} 1999-12-19 Slobodan Jankovi\'{c}; %
these calendars produced with calxxxx-yyyy 2023-01-01 v20.23a by \texttt{Martin.Muench@Uni-Bonn.de};%
\newline\indent%
\iflanguage{english}{English by Slobodan Jankovi\'{c}.}{%
 \iflanguage{german}{Deutsch von H.-Martin M\"{u}nch.}{%
  \iflanguage{danish}{Dansk af Michael Lodahl.}{%
    (Unknown language/translator.)%
   }
  }
 }
}

\ifCmRule\cmscale(8,35)\fi% print cm rule
\end{document}