% unipersian-numerals.def
%
% UniPersian: Persian language support for LaTeX.
%
% Copyright (C) 2026 Amer Amikhteh
%
% This file is part of the UniPersian package.
%
% This work is free software: you may redistribute it and/or modify
% it under the terms of the LaTeX Project Public License as published
% by the LaTeX Project, either version 1.3c of the License, or
% (at your option) any later version.
%
% This work is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
%
% The full license text is available at:
% https://www.latex-project.org/lppl/
%
% This work is "maintained" by Amer Amikhteh.
%
% The current maintainer of this work is Amer Amikhteh.

\ProvidesFile{unipersian-numerals.def}
[2026/09/08 v0.1.0 Persian numeral definitions]


\makeatletter

% ------------------------------------------------
% Raw numeric Arabic counters
% ------------------------------------------------

\let\uper@arabic\arabic
\def\arabic#1{\number\value{#1}}

% -------------------------------------------------
% Abjad simple, 1..28
% -------------------------------------------------


\def\@Abjad#1{%
  \ifcase#1%
  \or آ\or ب\or ج\or د%
  \or ه\or و\or ز\or ح\or ط%
  \or ی\or ک\or ل\or م\or ن%
  \or س\or ع\or ف\or ص%
  \or ق\or ر\or ش\or ت\or ث%
  \or خ\or ذ\or ض\or ظ\or غ%
  \else
    \@ctrerr
  \fi
}

\def\Abjad#1{%
  \expandafter\@Abjad\csname c@#1\endcsname
}

\let\Abjadnumeral\@Abjad

% -------------------------------------------------
% Harfi, Persian alphabetic, 1..32
% -------------------------------------------------

\def\@harfi#1{%
  \ifcase#1%
  \or آ\or ب\or پ\or ت\or ث%
  \or ج\or چ\or ح\or خ\or د%
  \or ذ\or ر\or ز\or ژ\or س%
  \or ش\or ص\or ض\or ط\or ظ%
  \or ع\or غ\or ف\or ق\or ک%
  \or گ\or ل\or م\or ن\or و%
  \or ه\or ی%
  \else
    \@ctrerr
  \fi
}

\def\harfi#1{%
  \expandafter\@harfi\csname c@#1\endcsname
}

\let\harfinumeral\@harfi

% -------------------------------------------------
% Adadi, full Persian words
% -------------------------------------------------

\newcommand{\adadi}[1]{%
  \expandafter\@adadi\csname c@#1\endcsname
}

\newcommand{\@adadi}[1]{%
  \uper@numberstring{#1}\uper@yekanii{صفر}{}%
}

\let\adadinumeral\@adadi

\def\uper@numberoutofrange#1#2{%
  \PackageError{unipersian}%
  {The number `#1' is too large to be formatted using persian}%
  {The largest possible number is 999,999,999.}%
}

\def\uper@numberstring#1#2#3#4{%
  \ifnum\number#1<\@ne
    #3%
  \else
    \ifnum\number#1<1000000000 %
      \expandafter\uper@adadi\expandafter{\number#1}#2%
    \else
      \uper@numberoutofrange{#1}{#4}%
    \fi
  \fi
}

\def\uper@adadi#1#2{%
  \expandafter\uper@@adadi
  \ifcase
    \ifnum#1<10 1%
    \else
      \ifnum#1<100 2%
      \else
        \ifnum#1<\@m 3%
        \else
          \ifnum#1<\@M 4%
          \else
            \ifnum#1<100000 5%
            \else
              \ifnum#1<1000000 6%
              \else
                \ifnum#1<10000000 7%
                \else
                  \ifnum#1<100000000 8%
                  \else
                    9%
                  \fi
                \fi
              \fi
            \fi
          \fi
        \fi
      \fi
    \fi
  \or 00000000#1%
  \or 0000000#1%
  \or 000000#1%
  \or 00000#1%
  \or 0000#1%
  \or 000#1%
  \or 00#1%
  \or 0#1%
  \or #1%
  \or
    \@nil#2%
  \fi
}

\def\uper@@adadi#1#2#3#4#5#6#7\or#8\@nil#9{%
  \ifnum#1#2#3>\z@
    \uper@milyoongan#1#2#3%
    \ifnum#7>\z@
      \ifnum#4#5#6>\z@
        \ و %
      \else
        \ و %
      \fi
    \else
      \ifnum#4#5#6>\z@
        \ و %
      \fi
    \fi
  \fi
  \ifnum#4#5#6>\z@
    \uper@sadgan#4#5#6{#1#2#3}{#4#5}\uper@yekani
    \ifnum#4#5#6>\@ne
      ‌%
    \fi
    هزار%
    \ifnum#7>\z@
      \ و %
    \fi
  \fi
  \uper@sadgan#7{#4#5#6}1#9%
}

\def\uper@milyoongan#1#2#3{%
  \ifnum#1#2#3=\@ne
    \uper@sadgan#1#2#301\uper@yekaniii
    ‌%
    میلیون%
  \else
    \uper@sadgan#1#2#301\uper@yekanii
    ‌%
    میلیون%
  \fi
}

\def\uper@sadgan#1#2#3#4#5#6{%
  \ifnum#1>\z@
    \ifnum#4#1>\@ne
      \uper@yekaniv#1%
    \fi
    صد%
    \ifnum#2#3>\z@
      \ و %
    \fi
  \fi
  \ifnum#2#3<20
    \ifnum#5#2#3>\@ne
      #6{#2#3}%
    \fi
  \else
    \uper@dahgan#2%
    \ifnum#3>\z@
      \ و \uper@yekani#3%
    \fi
    #60%
  \fi
}

\def\uper@yekani#1{%
  \ifcase#1%
    \@empty
  \or یک%
  \or دو%
  \or سه%
  \or چهار%
  \or پنج%
  \or شش%
  \or هفت%
  \or هشت%
  \or نه%
  \or ده%
  \or یازده%
  \or دوازده%
  \or سیزده%
  \or چهارده%
  \or پانزده%
  \or شانزده%
  \or هفده%
  \or هجده%
  \or نوزده%
  \fi
}

\def\uper@yekanii#1{%
  \ifcase#1%
    \@empty
  \or یک%
  \else
    \uper@yekani{#1}%
  \fi
}

\def\uper@yekaniii#1{%
  \ifcase#1%
    \@empty
  \or یک%
  \else
    \uper@yekani{#1}%
  \fi
}

\def\uper@yekaniv#1{%
  \ifcase#1%
    \@empty
  \or
  \or دوی%
  \or سی%
  \or چهار%
  \or پان%
  \or شش%
  \or هفت%
  \or هشت%
  \or نه%
  \fi
}

\def\uper@dahgan#1{%
  \ifcase#1%
  \or
  \or بیست%
  \or سی%
  \or چهل%
  \or پنجاه%
  \or شصت%
  \or هفتاد%
  \or هشتاد%
  \or نود%
  \fi
}

% -------------------------------------------------
% Tartibi, full Persian ordinal words
% -------------------------------------------------

\newcommand{\tartibi}[1]{%
  \expandafter\@tartibi\csname c@#1\endcsname
}

\newcommand{\@tartibi}[1]{%
  \uper@numberstring@tartibi{#1}\uper@tartibi{صفرم}{م}%
}

\let\tartibinumeral\@tartibi

\def\uper@numberstring@tartibi#1#2#3#4{%
  \ifnum\number#1<\@ne
    #3%
  \else
    \ifnum\number#1<1000000000 %
      \expandafter\uper@adadi@tartibi\expandafter{\number#1}#2%
    \else
      \uper@numberoutofrange{#1}{#4}%
    \fi
  \fi
}

\def\uper@adadi@tartibi#1#2{%
  \expandafter\uper@@adadi@tartibi
  \ifcase
    \ifnum#1<10 1%
    \else
      \ifnum#1<100 2%
      \else
        \ifnum#1<\@m 3%
        \else
          \ifnum#1<\@M 4%
          \else
            \ifnum#1<100000 5%
            \else
              \ifnum#1<1000000 6%
              \else
                \ifnum#1<10000000 7%
                \else
                  \ifnum#1<100000000 8%
                  \else
                    9%
                  \fi
                \fi
              \fi
            \fi
          \fi
        \fi
      \fi
    \fi
  \or 00000000#1%
  \or 0000000#1%
  \or 000000#1%
  \or 00000#1%
  \or 0000#1%
  \or 000#1%
  \or 00#1%
  \or 0#1%
  \or #1%
  \or
    \@nil#2%
  \fi
}

\def\uper@@adadi@tartibi#1#2#3#4#5#6#7\or#8\@nil#9{%
  \ifnum#1#2#3>\z@
    \uper@milyoongan@tartibi#1#2#3%
    \ifnum#7>\z@
      \ifnum#4#5#6>\z@
        \ و %
      \else
        \ و %
      \fi
    \else
      \ifnum#4#5#6>\z@
        \ و %
      \fi
    \fi
  \fi
  \ifnum#4#5#6>\z@
    \uper@sadgan#4#5#6{#1#2#3}{#4#5}\uper@yekani
    \ifnum#4#5#6>\@ne
      ‌%
    \fi
    هزار%
    \ifnum#7>\z@
      \ و %
    \fi
  \fi
  \uper@sadgan@tartibi#7{#4#5#6}1#9%
}

\def\uper@milyoongan@tartibi#1#2#3{%
  \ifnum#1#2#3=\@ne
    \uper@sadgan@tartibi#1#2#301\uper@yekaniii
    ‌%
    میلیون%
  \else
    \uper@sadgan#1#2#301\uper@yekanii
    ‌%
    میلیون%
  \fi
}

\def\uper@sadgan@tartibi#1#2#3#4#5#6{%
  \ifnum#1>\z@
    \ifnum#4#1>\@ne
      \uper@yekaniv#1%
    \fi
    صد%
    \ifnum#2#3>\z@
      \ و %
    \fi
  \fi
  \ifnum#2#3<20
    \ifnum#5#2#3>\@ne
      \ifnum#1#2#3#4#5=10001 %
        اول%
      \else
        #6{#2#3}%
      \fi
    \fi
  \else
    \ifnum#2#3=30
      \uper@dahgan@tartibi#2%
    \else
      \uper@dahgan#2%
    \fi
    \ifnum#3>\z@
      \ و \uper@yekanv#3%
    \fi
    #60%
  \fi
}

\def\uper@dahgan@tartibi#1{%
  \ifcase#1%
  \or
  \or بیست%
  \or سی‌ا%
  \or چهل%
  \or پنجاه%
  \or شصت%
  \or هفتاد%
  \or هشتاد%
  \or نود%
  \fi
}

\def\uper@tartibi#1{%
  \ifcase#1%
    م%
  \or یکم%
  \or دوم%
  \or سوم%
  \or چهارم%
  \or پنجم%
  \or ششم%
  \or هفتم%
  \or هشتم%
  \or نهم%
  \or دهم%
  \or یازدهم%
  \or دوازدهم%
  \or سیزدهم%
  \or چهاردهم%
  \or پانزدهم%
  \or شانزدهم%
  \or هفدهم%
  \or هجدهم%
  \or نوزدهم%
  \fi
}

\def\uper@yekanv#1{%
  \ifcase#1%
    \@empty
  \or یک%
  \or دو%
  \or سو%
  \or چهار%
  \or پنج%
  \or شش%
  \or هفت%
  \or هشت%
  \or نه%
  \or ده%
  \or یازده%
  \or دوازده%
  \or سیزده%
  \or چهارده%
  \or پانزده%
  \or شانزده%
  \or هفده%
  \or هجده%
  \or نوزده%
  \fi
}

% -------------------------------------------------
% enumitem integration
%
% This makes labels such as \tartibi* valid in
% enumitem optional arguments.
% -------------------------------------------------

\newif\ifuper@enumitem@counters@registered

\def\uper@register@enumitem@counters{%
  \ifuper@enumitem@counters@registered
  \else
    \@ifundefined{AddEnumerateCounter}{}{%
      \AddEnumerateCounter{\tartibi}{\@tartibi}{نودونهم}%
      \uper@enumitem@counters@registeredtrue
    }%
  \fi
}

\AtBeginDocument{%
  \uper@register@enumitem@counters
}



% -------------------------------------------------
% Classical abjad, 1..1999
% -------------------------------------------------

\providecommand*{\uper@warning}[1]{%
  \PackageWarning{unipersian}{#1}%
}

\def\@abjad#1{%
  \ifnum#1>1999 %
    \uper@warning{Illegal value (#1) for abjad numeral}%
    #1%
  \else
    \ifnum#1<\z@
      \space
      \uper@warning{Illegal value (#1) for abjad numeral}%
    \else
      \ifnum#1<10 %
        \expandafter\abj@num@i\number#1%
      \else
        \ifnum#1<100 %
          \expandafter\abj@num@ii\number#1%
        \else
          \ifnum#1<\@m %
            \expandafter\abj@num@iii\number#1%
          \else
            \ifnum#1<\@M %
              \expandafter\abj@num@iv\number#1%
            \fi
          \fi
        \fi
      \fi
    \fi
  \fi
}

\def\abjad#1{%
  \expandafter\@abjad\csname c@#1\endcsname
}

\let\abjadnumeral\@abjad

\def\abjad@zero{}

\def\abj@num@i#1{%
  \ifcase#1%
  \or آ%
  \or ب%
  \or ج%
  \or د%
  \or ه%
  \or و%
  \or ز%
  \or ح%
  \or ط%
  \fi
  \ifnum#1=\z@
    \abjad@zero
  \fi
}

\def\abj@num@ii#1{%
  \ifcase#1%
  \or ی%
  \or ک%
  \or ل%
  \or م%
  \or ن%
  \or س%
  \or ع%
  \or ف%
  \or ص%
  \fi
  \ifnum#1=\z@
  \fi
  \abj@num@i
}

\def\abj@num@iii#1{%
  \ifcase#1%
  \or ق%
  \or ر%
  \or ش%
  \or ت%
  \or ث%
  \or خ%
  \or ذ%
  \or ض%
  \or ظ%
  \fi
  \ifnum#1=\z@
  \fi
  \abj@num@ii
}

\def\abj@num@iv#1{%
  \ifcase#1%
  \or غ%
  \fi
  \ifnum#1=\z@
  \fi
  \abj@num@iii
}

% -------------------------------------------------
% Latin alphabet switching, as in xepersian
% -------------------------------------------------

\let\@latinalph\@alph
\let\@latinAlph\@Alph

\def\LatinAlphs{%
  \let\@alph\@latinalph
  \let\@Alph\@latinAlph
}

\def\PersianAlphs{%
  \let\@alph\@abjad
  \let\@Alph\@Abjad
}

\def\thempfootnote{%
  {\itshape\@latinalph\c@mpfootnote}%
}

% -------------------------------------------------
% Language alphabet switching, as in xepersian
% -------------------------------------------------

\newif\ifuper@alph@hooks@registered

\def\uper@register@alph@hooks{%
  \ifuper@alph@hooks@registered
  \else
    \@ifundefined{extraspersian}{}{%
      \addto\extraspersian{%
        \PersianAlphs
      }%
    }%
    \@ifundefined{extrasfarsi}{}{%
      \addto\extrasfarsi{%
        \PersianAlphs
      }%
    }%
    \@ifundefined{extrasenglish}{}{%
      \addto\extrasenglish{%
        \LatinAlphs
      }%
    }%
    \uper@alph@hooks@registeredtrue
  \fi
}

\AtBeginDocument{%
  \uper@register@alph@hooks
  \PersianAlphs
}






\makeatother

\endinput
