\ProvidesPackage{hebrewcal}
        [2022/07/18 v2.8 %
         Hebrew calendar for polyglossia (adapted from hebcal.sty in Babel)]

\RequirePackage{iftex}
\ifluatex
  \RequirePackage{luabidi}
\else
  \RequirePackage{bidi}
\fi

%% TODO rewrite this on the basis of Reingold & Dershowitz 
%%      on the model of hijrical (using calc)

\@ifundefined{@Remainder}{\input{cal-util.def}}{}

%
% OPTIONS
%
\RequirePackage{xkeyval}

% marcheshvan=true|false
\define@boolkey{hebrewcal}[@xpg@hebrew@]{marcheshvan}[true]{}

% fullyear=true|false
\define@boolkey{hebrewcal}[@xpg@hebrew@]{fullyear}[true]{}

% transliteration=academy|alt
\newif\if@hebrewcal@academytrans
\@hebrewcal@academytransfalse
\define@choicekey*+{hebrewcal}{transliteration}[\hcal@val\hcal@nr]{academy,alt}[alt]{%
   \ifcase\hcal@nr\relax
      % academy:
     \@hebrewcal@academytranstrue
   \or
      % alt:
      \@hebrewcal@academytransfalse
   \fi
   \PackageInfo{hebrewcal}{Setting transliteration=\hcal@val}%
}{%
  \PackageWarning{hebrewcal}{Unknown transliteration option `#1'}%
}

% Process
\ProcessOptionsX*<hebrewcal>
%%
%% END OPTIONS

\newcount\hebrewday  \newcount\hebrewmonth \newcount\hebrewyear
\def\hebrewdate#1#2#3{%
    \HebrewFromGregorian{#1}{#2}{#3}%
                        {\hebrewday}{\hebrewmonth}{\hebrewyear}%
    \if@RTL
      \@FormatForHebrew{\hebrewday}{\hebrewmonth}{\hebrewyear}%
    \else
      \@FormatForEnglish{\hebrewday}{\hebrewmonth}{\hebrewyear}%
    \fi}
\def\hebrewtoday{\hebrewdate{\day}{\month}{\year}}
% The command name is capitalised in the doc, and this is consistent
% with other names such as \Hijritoday and \Jalalitoday.
\let\Hebrewtoday=\hebrewtoday
\def\hebrewsetreg{%
    \HebrewFromGregorian{\day}{\month}{\year}%
                        {\hebrewday}{\hebrewmonth}{\hebrewyear}}
\def\HebrewYearName#1{{%
   \@tempcnta=#1\divide\@tempcnta by 1000\multiply\@tempcnta by 1000
   \ifnum#1=\@tempcnta\relax % divisible by 1000: disambiguate
     \Hebrewnumeral{#1}\ (לפ"ג)%
   \else % not divisible by 1000
     \ifnum#1<1000\relax     % first millennium: disambiguate
       \Hebrewnumeral{#1}\ (לפ"ג)%
     \else 
       \ifnum#1<5000
         \Hebrewnumeral{#1}%
       \else
         \ifnum#1<6000 % current millennium, print without thousands
           \@tempcnta=#1\relax
           \if@xpg@hebrew@fullyear\else\advance\@tempcnta by -5000\fi
           \Hebrewnumeral{\@tempcnta}%
         \else % #1>6000
           \Hebrewnumeral{#1}%
         \fi
       \fi
     \fi
   \fi}}
\def\HebrewMonthName#1#2{%
    \ifnum #1 = 7 
    \@CheckLeapHebrewYear{#2}%
        \if@HebrewLeap אדר\ ב'%
           \else אדר%
        \fi
    \else
        \ifcase#1
           % nothing for 0
           \or תשרי%
           \or\if@xpg@hebrew@marcheshvan מרחשון\else חשון\fi
           \or כסלו%
           \or טבת%
           \or שבט%
           \or אדר\ א'%
           \or אדר\ ב'%
           \or ניסן%
           \or אייר%
           \or סיון%
           \or תמוז%
           \or אב%
           \or אלול%
        \fi
    \fi}
\def\@FormatForHebrew#1#2#3{%
  \Hebrewnumeral{#1}~ב\HebrewMonthName{#2}{#3}~%
  \HebrewYearName{#3}}
\def\HebrewMonthNameInEnglish#1#2{%
    \ifnum #1 = 7
    \@CheckLeapHebrewYear{#2}%
        \if@HebrewLeap Adar II\else Adar\fi
    \else
        \ifcase #1
            % nothing for 0
            \or \if@hebrewcal@academytrans Tishri \else Tishrei \fi
            \or
              \if@hebrewcal@academytrans%
                 \if@xpg@hebrew@marcheshvan Marẖeshvan\else Heshvan\fi
              \else
                 \if@xpg@hebrew@marcheshvan Marcheshvan\else Heshvan\fi
              \fi
            \or Kislev
            \or \if@hebrewcal@academytrans Tevet \else Tebeth \fi
            \or \if@hebrewcal@academytrans Shvat \else Shebat \fi
            \or Adar I%
            \or Adar II%
            \or Nisan%
            \or \if@hebrewcal@academytrans Iyyar \else Iyar \fi
            \or Sivan%
            \or Tammuz%
            \or \if@hebrewcal@academytrans Av \else Ab \fi
            \or Elul%
        \fi
    \fi}
\def\@FormatForEnglish#1#2#3{%
    \HebrewMonthNameInEnglish{#2}{#3} \number#1,\ \number#3}
\newcount\@common
\newif\if@HebrewLeap
\def\@CheckLeapHebrewYear#1{%
    {%
        \countdef\tmpa = 0       % \tmpa==\count0
        \countdef\tmpb = 1       % \tmpb==\count1
        \tmpa = #1
        \multiply \tmpa by 7
        \advance \tmpa by 1
        \@Remainder{\tmpa}{19}{\tmpb}%
        \ifnum \tmpb < 7         % \tmpb = (7*year+1)%19
            \global\@HebrewLeaptrue
        \else
            \global\@HebrewLeapfalse
        \fi}}
\def\@HebrewElapsedMonths#1#2{%
    {%
        \countdef\tmpa = 0       % \tmpa==\count0
        \countdef\tmpb = 1       % \tmpb==\count1
        \countdef\tmpc = 2       % \tmpc==\count2
        \tmpa = #1
        \advance \tmpa by -1
        #2 = \tmpa               % #2 = \tmpa = year-1
        \divide #2 by 19         % Number of complete Meton cycles
        \multiply #2 by 235      % #2 = 235*((year-1)/19)
        \@Remainder{\tmpa}{19}{\tmpb}% \tmpa = years%19-years this cycle
        \tmpc = \tmpb
        \multiply \tmpb by 12
        \advance #2 by \tmpb     % add regular months this cycle
        \multiply \tmpc by 7
        \advance \tmpc by 1
        \divide \tmpc by 19      % \tmpc = (1+7*((year-1)%19))/19 -
        \advance #2 by \tmpc     %  add leap months
        \global\@common = #2}%
    #2 = \@common}
\def\@HebrewElapsedDays#1#2{%
    {%
        \countdef\tmpa = 0       % \tmpa==\count0
        \countdef\tmpb = 1       % \tmpb==\count1
        \countdef\tmpc = 2       % \tmpc==\count2
        \@HebrewElapsedMonths{#1}{#2}%
        \tmpa = #2
        \multiply \tmpa by 13753
        \advance \tmpa by 5604   % \tmpa=MonthsElapsed*13758 + 5604
        \@Remainder{\tmpa}{25920}{\tmpc}% \tmpc == ConjunctionParts
        \divide \tmpa by 25920
        \multiply #2 by 29
        \advance #2 by 1
        \advance #2 by \tmpa     %  #2 = 1 + MonthsElapsed*29 +
        \@Remainder{#2}{7}{\tmpa}% %  \tmpa == DayOfWeek
        \ifnum \tmpc < 19440
            \ifnum \tmpc < 9924
            \else                % New moon at 9 h. 204 p. or later
                \ifnum \tmpa = 2 % on Tuesday ...
                    \@CheckLeapHebrewYear{#1}% of a common year
                    \if@HebrewLeap
                    \else
                        \advance #2 by 1
                    \fi
                \fi
            \fi
            \ifnum \tmpc < 16789
            \else                 % New moon at 15 h. 589 p. or later
                \ifnum \tmpa = 1  % on Monday ...
                    \advance #1 by -1
                    \@CheckLeapHebrewYear{#1}% at the end of leap year
                    \if@HebrewLeap
                        \advance #2 by 1
                    \fi
                \fi
            \fi
        \else
            \advance #2 by 1      %  new moon at or after midday
        \fi
        \@Remainder{#2}{7}{\tmpa}%  %  \tmpa == DayOfWeek
        \ifnum \tmpa = 0          %  if Sunday ...
            \advance #2 by 1
        \else                     %
            \ifnum \tmpa = 3      %  Wednesday ...
                \advance #2 by 1
            \else
                \ifnum \tmpa = 5  %  or Friday
                     \advance #2 by 1
                \fi
            \fi
        \fi
        \global\@common = #2}%
    #2 = \@common}
\def\@DaysInHebrewYear#1#2{%
    {%
        \countdef\tmpe = 12   % \tmpe==\count12
        \@HebrewElapsedDays{#1}{\tmpe}%
        \advance #1 by 1
        \@HebrewElapsedDays{#1}{#2}%
        \advance #2 by -\tmpe
        \global\@common = #2}%
    #2 = \@common}
\def\@HebrewDaysInPriorMonths#1#2#3{%
    {%
        \countdef\tmpf= 14    % \tmpf==\count14
        #3 = \ifcase #1       % Days in prior month of regular year
               0 \or          % no month number 0
               0 \or          % Tishri
              30 \or          % Heshvan
              59 \or          % Kislev
              89 \or          % Tevet
             118 \or          % Shvat
             148 \or          % Adar I
             148 \or          % Adar II
             177 \or          % Nisan
             207 \or          % Iyyar
             236 \or          % Sivan
             266 \or          % Tammuz
             295 \or          % Av
             325 \or          % Elul
             400              % Dummy
        \fi
        \@CheckLeapHebrewYear{#2}%
        \if@HebrewLeap            % in leap year
            \ifnum #1 > 6         % if month after Adar I
                \advance #3 by 30 % add  30 days
            \fi
        \fi
        \@DaysInHebrewYear{#2}{\tmpf}%
        \ifnum #1 > 3
            \ifnum \tmpf = 353
                \advance #3 by -1
            \fi                   %  Short Kislev
            \ifnum \tmpf = 383
                \advance #3 by -1
            \fi
        \fi
        \ifnum #1 > 2
            \ifnum \tmpf = 355
                \advance #3 by 1
            \fi                   %  Long Heshvan
            \ifnum \tmpf = 385
                \advance #3 by 1
            \fi
        \fi
        \global\@common = #3}%
    #3 = \@common}
\def\@FixedFromHebrew#1#2#3#4{%
    {%
        #4 = #1
        \@HebrewDaysInPriorMonths{#2}{#3}{#1}%
        \advance #4 by #1         % Add days in prior months this year
        \@HebrewElapsedDays{#3}{#1}%
        \advance #4 by #1         % Add days in prior years
        \advance #4 by -1373429   % Subtract days before Gregorian
        \global\@common = #4}%     %   01.01.0001
    #4 = \@common}
\def\@GregorianDaysInPriorMonths#1#2#3{%
    {%
        #3 = \ifcase #1
               0 \or             % no month number 0
               0 \or
              31 \or
              59 \or
              90 \or
             120 \or
             151 \or
             181 \or
             212 \or
             243 \or
             273 \or
             304 \or
             334
        \fi
        \@CheckIfGregorianLeap{#2}%
        \if@GregorianLeap
            \ifnum #1 > 2        % if month after February
                \advance #3 by 1 % add leap day
            \fi
        \fi
        \global\@common = #3}%
    #3 = \@common}
\def\@GregorianDaysInPriorYears#1#2{%
     {%
         \countdef\tmpc = 4      % \tmpc==\count4
         \countdef\tmpb = 2      % \tmpb==\count2
         \tmpb = #1
         \advance \tmpb by -1
         \tmpc = \tmpb           % \tmpc = \tmpb = year-1
         \multiply \tmpc by 365  % Days in prior years =
         #2 = \tmpc              % = 365*(year-1) ...
         \tmpc = \tmpb
         \divide \tmpc by 4      % \tmpc = (year-1)/4
         \advance #2 by \tmpc    % ... plus Julian leap days ...
         \tmpc = \tmpb
         \divide \tmpc by 100    % \tmpc = (year-1)/100
         \advance #2 by -\tmpc   % ... minus century years ...
         \tmpc = \tmpb
         \divide \tmpc by 400    % \tmpc = (year-1)/400
         \advance #2 by \tmpc    % ... plus 4-century years.
         \global\@common = #2}%
    #2 = \@common}
\def\@AbsoluteFromGregorian#1#2#3#4{%
    {%
        \countdef\tmpd = 0       % \tmpd==\count0
        #4 = #1                  % days so far this month
        \@GregorianDaysInPriorMonths{#2}{#3}{\tmpd}%
        \advance #4 by \tmpd     % add days in prior months
        \@GregorianDaysInPriorYears{#3}{\tmpd}%
        \advance #4 by \tmpd     % add days in prior years
        \global\@common = #4}%
    #4 = \@common}
\def\HebrewFromGregorian#1#2#3#4#5#6{%
    {%
        \countdef\tmpx= 17        % \tmpx==\count17
        \countdef\tmpy= 18        % \tmpy==\count18
        \countdef\tmpz= 19        % \tmpz==\count19
        #6 = #3
        \global\advance #6 by 3761 %  approximation from above
        \@AbsoluteFromGregorian{#1}{#2}{#3}{#4}%
        \tmpz = 1  \tmpy = 1
        \@FixedFromHebrew{\tmpz}{\tmpy}{#6}{\tmpx}%
        \ifnum \tmpx > #4
            \global\advance #6 by -1 % Hyear = Gyear + 3760
            \@FixedFromHebrew{\tmpz}{\tmpy}{#6}{\tmpx}%
        \fi
        \advance #4 by -\tmpx     % Days in this year
        \advance #4 by 1
        #5 = #4
        \divide #5 by 30          % Approximation for month from below
        \loop                     % Search for month
            \@HebrewDaysInPriorMonths{#5}{#6}{\tmpx}%
            \ifnum \tmpx < #4
                \advance #5 by 1
                \tmpy = \tmpx
        \repeat
        \global\advance #5 by -1
        \global\advance #4 by -\tmpy
   }%
}

\endinput
