% Author: Alexey Shipunov, dactylorhiza@gmail.com
% Russian encoding below: Windows-1251

\ProvidesPackage{numerus}%
        [2019/10/03 v1.21 Spell numbers in Russian words]

% 20191003: "numeral" -> "numerus"

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                      %
% Синтаксис: \propis[необязательный_аргумент]{<число>}                 %
%            \Propis[необязательный_аргумент]{<число>}                 %
%            \PROpis[необязательный_аргумент]{<число>}                 %
%                                                                      %
% Необязательный_аргумент: k (по умолчанию, количественное             %
%                             числительное)                            %
%                          z (порядковое числительное женского рода    %
%                             в именительном падеже)                   %
%                          m (порядковое числительное мужского рода    %
%                             в именительном падеже)                   %
%                                                                      %
% <Число>: цифра < 999 для порядковых числительных и < 999999 для      %
%          количественных, или счетчик, принимающий аналогичные        %
%          значения                                                    %
% ВНИМАНИЕ: пакет не работает с оглавлениями и                         %
%           с более чем однобайтовыми кодировками                      %
%           порядковые номера больше 999 не поддерживаются             %
%                                                                      %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                      %
% Простой пример: \propis{99} дает `девяносто девять'                  %
%                                                                      %
% Сложный пример: сначала                                              %
% \renewcommand*{\thechapter}{\PROpis[z]{\c@chapter}},                 %
% потом (если \c@chapter=99) \textsl{\uppercase{Глава} \thechapter}    %
% дает текст `ГЛАВА ДЕВЯНОСТО ДЕВЯТАЯ' наклонным шрифтом               %
%                                                                      %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newif\ifKol@
\newif\ifPor@Zen
\newcount\Vrem@A

% Все буквы маленькие (`девяносто девять')
\newcommand*{\propis}[2][k]{%
        \let\V@\relax
        \Delat@Propis{#1}{#2}}

% Первая буква большая (`Девяносто девять')
\newcommand*{\Propis}[2][k]{%
        \let\V@\Perv@B
        \let\B@=B%
        \Delat@Propis{#1}{#2}}

\def\Verh@#1{\uppercase{#1}}
\def\Perv@B#1{\if B\B@ \Verh@ #1\else
        #1\fi
        \let\B@\relax}

% Все буквы большие (`ДЕВЯНОСТО ДЕВЯТЬ') ---
% \uppercase{\propis{...}} не работает
\newcommand*{\PROpis}[2][k]{%
        \let\V@\uppercase
        \Delat@Propis{#1}{#2}}

% Основная команда
\def\Delat@Propis#1#2{{%
        \if k#1\Kol@true\else
        \if z#1\Por@Zentrue\else
        \if m#1\relax\else
        \Oshibka@Arg
\fi\fi\fi\Test@Propis{#2}}}

% Проверка ошибок и разветвление
\def\Test@Propis#1{%
        \ifnum #1<0\Oshibka@Otr\else
        \ifnum #1<10\Delat@Ed#1\else
        \ifnum #1<20\expandafter\expandafter\expandafter
                \Nadz@\expandafter\number#1\else
        \ifnum #1<100\expandafter\expandafter\expandafter
                \Delat@Des\expandafter\number#1\else
        \ifnum #1<1000\expandafter\expandafter\expandafter
                \Delat@Sot\expandafter\number#1\else
        \ifnum #1<1000000\ifKol@\Vrem@A#1\advance\Vrem@A1000000
                        \expandafter\expandafter\expandafter
                        \Delat@Tys\expandafter\number\Vrem@A\else
                \Oshibka@Tys\fi\else
                \Oshibka@Mill
\fi\fi\fi\fi\fi\fi}

% Ошибки
\def\Oshibka@Arg{\PackageWarning{numerus}{%
`propis' got wrong mandatory argument!^^J%
Command did not executed}}

\def\Oshibka@Otr{\PackageWarning{numerus}{%
`propis' got argument < 0!^^J%
Command did not executed}}

\def\Oshibka@Tys{\PackageWarning{numerus}{%
Ordinal numeruss > 999 not supported :(^^J%
Command did not executed}}

\def\Ошибка@Mill{\PackageWarning{numerus}{%
`propis' got argument > 999 999!^^J%
Command did not executed}}

% Единицы (0...10)
\def\Delat@Ed#1{\ifKol@\Kol@Ed#1\else
        \Por@Ed#1\fi}

\def\Kol@Ed#1{\ifcase#1\V@{ноль}\or\V@{один}\or\V@{два}\or
\V@{три}\or\V@{четыре}\or\V@{пять}\or\V@{шесть}\or\V@{семь}\or
\V@{восемь}\or\V@{девять}\or\V@{десять}\fi}

\def\Por@Ed#1{\ifcase#1\V@{нулев}\or\V@{перв}\or\V@{втор}\or
\V@{трет}\or\V@{четверт}\or\V@{пят}\or\V@{шест}\or\V@{седьм}\or
\V@{восьм}\or\V@{девят}\or\V@{десят}\fi\Ok@Ed#1}

\def\Ok@Ed#1{\ifKol@\relax\else
        \ifPor@Zen\ifcase#1\V@{ая}\or\V@{ая}\or\V@{ая}\or
        \V@{ья}\else\V@{ая}\fi\else
                \ifcase#1\V@{ой}\or\V@{ый}\or\V@{ой}\or
                \V@{ий}\or\V@{ый}%
                        \or\V@{ый}\or\V@{ой}\or\V@{ой}\or
                        \V@{ой}\or\V@{ый}%
\fi\fi\fi}

% От 10 до 19
\def\Nadz@#1#2{\ifcase#2\V@{десят}\or\V@{одиннадцат}\or
\V@{двенадцат}\or\V@{тринадцат}\or\V@{четырнадцат}\or
\V@{пятнадцат}\or\V@{шестнадцат}\or\V@{семнадцат}\or
\V@{восемнадцат}\or\V@{девятнадцат}\fi\Ok@Nadz}

\def\Ok@Nadz{\ifKol@\V@{ь}\else
        \ifPor@Zen\V@{ая}\else\V@{ый}%
\fi\fi}

% 20--99
\def\Delat@Des#1#2{\ifKol@\Kol@Des#1%
        \ifnum #2=0\relax\else
                \ \Kol@Ed#2\fi\else
        \ifnum #2=0\Por@Des#1\else
                \Kol@Des#1\ \Por@Ed#2%
\fi\fi}

\def\Kol@Des#1{\ifcase#1\or\or\V@{двадцать}\or\V@{тридцать}\or
\V@{сорок}\or\V@{пятьдесят}\or\V@{шестьдесят}\or
\V@{семьдесят}\or\V@{восемьдесят}\or\V@{девяносто}\fi}

\def\Por@Des#1{\ifcase#1\or\or\V@{двадцат}\or\V@{тридцат}\or
\V@{сороков}\or\V@{пятидесят}\or\V@{шестидесят}\or
\V@{семидесят}\or\V@{восьмидесят}\or\V@{девяност}\fi\Ok@Des#1}

\def\Ok@Des#1{\ifKol@\relax\else
        \ifPor@Zen\V@{ая}\else
                \ifcase#1\or\or\V@{ый}\or\V@{ый}\or\V@{ой}\else
                \V@{ый}\fi
\fi\fi}

% 100--999
\def\Delat@Sot#1#2#3{%
\ifnum #2=0%
        \ifnum #3=0%
                \ifKol@\Kol@Sot#1\else\Por@Sot#1\fi\else
        \Kol@Sot#1\ \Delat@Ed#3\fi\else
\Delat@Ост@Sot#1#2#3\fi}

\def\Delat@Ост@Sot#1#2#3{\Kol@Sot#1\ \ifnum#2=1\Nadz@#2#3\else
        \Delat@Des#2#3\fi}

\def\Kol@Sot#1{\ifcase#1\or\V@{сто}\or\V@{двести}\or
\V@{триста}\or\V@{четыреста}\or\V@{пятьсот}\or\V@{шестьсот}\or
\V@{семьсот}\or\V@{восемьсот}\or\V@{девятьсот}\fi}

\def\Por@Sot#1{\ifcase#1\or\V@{сот}\or\V@{двухсот}\or
\V@{трехсот}\or\V@{четырехсот}\or\V@{пятисот}\or\V@{шестисот}\or
\V@{семисот}\or\V@{восьмисот}\or\V@{девятисот}\fi\Ok@Nadz}

% 1000--999999 (только для количественных числительных)
\def\Delat@Tys1#1#2#3#4#5#6{%
        \Delat@P@Tys{#1}{#2}{#3}%
\Delat@V@Tys{#4}{#5}{#6}}

% Первые три цифры
\def\Delat@P@Tys#1#2#3{%
\ifnum #1=0%
        \ifnum #2=0%
                \ifnum #3=1\V@{тысяча}\else
                        \ifnum #3=2\V@{две тысячи}\else
        \Delat@Ed#3\ \V@{тысяч}%
\ifcase#3\or\or\or\V@{и}\or\V@{и}\else\relax\fi\fi\fi\else
        \ifnum #2=1\Nadz@#2#3\ \V@{тысяч}\else
                \ifnum #3=1\Delat@Des{#2}{0}\V@{одна тысяча}\else
                        \ifnum #3=2\Delat@Des{#2}{0}\V@{две тысячи}\else
        \Delat@Des#2#3\ \V@{тысяч}%
\ifcase#3\or\or\or\V@{и}\or\V@{и}\else\relax\fi\fi\fi\fi\fi\else
                \ifnum #3=1\Delat@Sot{#1}{#2}{0}\V@{одна тысяча}\else
                        \ifnum #3=2\Delat@Sot{#1}{#2}{0}\V@{две тысячи}\else
\Delat@Sot#1#2#3\ \V@{тысяч}\ifnum #2=1\relax\else
\ifcase#3\or\or\or\V@{и}\or\V@{и}\else\relax\fi\fi\fi\fi\fi}

% Вторые три цифры
\def\Delat@V@Tys#1#2#3{%
\ifnum #1=0%
        \ifnum #2=0%
                \ifnum #3=0\relax\else
                \ \Delat@Ed#3\fi\else
        \ifnum #2=1\ \Nadz@#2#3\else
        \ \Delat@Des#2#3\fi\fi\else
\ \Delat@Sot#1#2#3\fi}

\endinput
