%% ordinalref.sty
%% Copyright 2005 Glad Deschrijver
%%
%% ordinalref - A LaTeX package for using ordinal numbers in references
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
% of this license or (at your option) any later version.
% The latest version of this license is in
%   http://www.latex-project.org/lppl.txt
% and version 1.3 or later is part of all distributions of LaTeX
% version 2003/12/01 or later.
%
% This work consists of the files ordinalref.sty and ordinalrefdoc.tex.
%
% -----------------------------------------------------------------------
%
% The package provides the commands:
% \ordinal
%    replaces a string representing a number into its ordinal counterpart
%    (ordinal numbers not greater than 10 are written in full, other
%    numbers are abbreviated)
%    e.g. \ordinal{2} gives second, \ordinal{23} gives 23rd
% \ordinalshort
%    same as above, but abbreviates always
%    e.g. \ordinal{2} gives 2nd
% \ordinalref
%    gives an ordinal version of the reference (unabbreviated if the
%    number is not greater than 10, abbreviated otherwise)
%    e.g. if \ref{foo} would give 2, then \ordinalref{foo} gives second
%         if \ref{foo} would give (xi), then \ordinalref{foo} gives sixth
% \ordinalshortref
%    same as above, but abbreviates always
%
% The package is compatible with the package babel.  If babel is not
% loaded, then ordinalref will use internal \iflanguage and
% \selectlanguage commands.  If no optional argument is given, then
% ordinalref uses the language that is used with babel if it is loaded,
% otherwise ordinalref uses english.  If both are loaded, then any
% optional arguments given to ordinalref must also be given to babel.
% Any subsequent \selectlanguage will also change the language of
% ordinalref.
% Currently only english, french, dutch, spanish and italian are supported.
%
% When using french, you can give an optional argument which determines
% the gender of the ordinal number.  If the corresponding substantive is
% feminine, then you should use \ordinal{...}[f], when the corresponding
% substantive is masculine, then use \ordinal{...}[m]
%    e.g. le \ordinal{1}[m] livre gives: le premier livre
%         la \ordinalref{firstsection}[f] section gives: la premi\`ere section
% Similarly, for spanish the following options exist:
%   f: female singular (to obtain plural, use e.g. "las \ordinal{1}[f]s")
%   m: male singular
%   bm: male singular ordinal number put before the noun; this can be
%       used to obtain "el primer libro" instead of "el primero libro".
% For italian, the following options are available:
%   f: female singular
%   m: male singular
%   fp: female plural
%   mp: male plural
%
% Warning: in order to let \ordinalref and \ordinalshortref work, the
% commands \@newl@bel, \label and \refstepcounter are redefined.  This
% may lead to incompatibilities with other packages.

% History:
% 0.1: original version
% 0.2: - ordinalref can be used without babel
%      - added spanish and italian language support

\ProvidesPackage{ordinalref}[2005/08/01 v0.2 Use ordinal numbers in references]

\def\languagename{english}
\DeclareOption{english}{\AtBeginDocument{\selectlanguage{english}}}
\DeclareOption{dutch}{\AtBeginDocument{\selectlanguage{dutch}}}
\DeclareOption{french}{\AtBeginDocument{\selectlanguage{french}}}
\DeclareOption{spanish}{\AtBeginDocument{\selectlanguage{spanish}}}
\DeclareOption{italian}{\AtBeginDocument{\selectlanguage{italian}}}
\ProcessOptions

\@ifpackageloaded{babel}{}{%
  \gdef\iflanguage#1{%
    \def\ordinal@test@lang{#1}%
    \ifx\languagename\ordinal@test@lang%
      \expandafter\@firstoftwo
    \else%
      \expandafter\@secondoftwo
    \fi%
  }
  \gdef\selectlanguage#1{\gdef\languagename{#1}}
}

\newcounter{ordinal@tempnuma}
\newcounter{ordinal@tempnumb}
\def\lastdigit#1{%
  \setcounter{ordinal@tempnuma}{#1}%
  \setcounter{ordinal@tempnumb}{#1}%
  \ifnum\c@ordinal@tempnumb>10%
    \divide\c@ordinal@tempnumb 10%
    \multiply\c@ordinal@tempnumb 10%
    \advance\c@ordinal@tempnuma-\c@ordinal@tempnumb%
  \fi%
  \gdef\@last@digit{\theordinal@tempnuma}%
}

\def\ordinal#1{\csname ordinal@\languagename\endcsname{#1}}
\def\ordinalshort#1{\csname ordinalshort@\languagename\endcsname{#1}}

% English
\def\ordinalshort@english#1{%
  \lastdigit{#1}%
  #1%
  \ifcase\@last@digit th\or st\or nd\or rd\else th\fi%
}
\def\ordinal@english#1{\ifcase#1 zeroth\or first\or second\or third%
  \or fourth\or fifth\or sixth\or seventh\or eighth%
  \or ninth\or tenth\else\ordinalshort@english{#1}\fi%
}
% Dutch
\def\ordinalshort@dutch#1{#1e}
\def\ordinal@dutch#1{\ifcase#1 nulde\or eerste\or tweede\or derde%
  \or vierde\or vijfde\or zesde\or zevende\or achtste%
  \or negende\or tiende\else #1e\fi%
}
% French
\def\ordinal@gender@f{f}%
\def\ordinal@gender@m{m}%
\def\ordinalshort@french#1{%
  \@ifnextchar[{\ordinalshort@frenchb{#1}}{\ordinalshort@frenchb{#1}[f] }}
\def\ordinal@french#1{%
  \@ifnextchar[{\ordinal@frenchb{#1}}{\ordinal@frenchb{#1}[f] }}
\def\ordinalshort@frenchb#1[#2]{%
  \def\ordinal@opt@arg{#2}%
  \ifcase#1 nulli\`eme%
  \or \ifx \ordinal@opt@arg\ordinal@gender@m 1er\else 1re\fi%
  \else #1e\fi%
}
\def\ordinal@frenchb#1[#2]{%
  \def\ordinal@opt@arg{#2}%
  \ifcase#1 nulli\`eme%
  \or \ifx \ordinal@opt@arg\ordinal@gender@m premier\else premi\`ere\fi%
  \or deuxi\`eme\or troisi\`eme\or quatri\`eme\or cinqui\`eme\or sixi\`eme%
  \or septi\`eme\or huiti\`eme\or neuvi\`eme\or dixi\`eme\else #1e\fi%
}
% Spanish
\def\ordinal@gender@f{f}%
\def\ordinal@gender@m{m}%
\def\ordinal@gender@bm{bm}%
\def\ordinalshort@spanish#1{%
  \@ifnextchar[{\ordinalshort@spanishb{#1}}{\ordinalshort@spanishb{#1}[f] }}
\def\ordinal@spanish#1{%
  \@ifnextchar[{\ordinal@spanishb{#1}}{\ordinal@spanishb{#1}[f] }}
\def\ordinalshort@spanishb#1[#2]{%
  \def\ordinal@opt@arg{#2}%
  \ifx\ordinal@opt@arg\ordinal@gender@f #1a\else #1o\fi%
}
\def\ordinal@spanish@root#1{\ifcase#1 \or primer\or segund\or tercer%
  \or cuart\or quint\or sext\or s\'eptim\or octav%
  \or noven\or d\'ecim\else #1\fi%
}
\def\ordinal@spanishb#1[#2]{%
  \def\ordinal@opt@arg{#2}%
  \ifx\ordinal@opt@arg\ordinal@gender@f%
    \ordinal@spanish@root{#1}a%
  \else%
    \ordinal@spanish@root{#1}%
    \ifx\ordinal@opt@arg\ordinal@gender@bm%
      \ifcase#1\or\or o\or\else o\fi%
    \else%
      o%
    \fi%
  \fi%
}
% Italian
\def\ordinal@gender@f{f}%
\def\ordinal@gender@m{m}%
\def\ordinal@gender@fp{fp}%
\def\ordinal@gender@mp{mp}%
\def\ordinalshort@italian#1{%
  \@ifnextchar[{\ordinalshort@italianb{#1}}{\ordinalshort@italianb{#1}[f] }}
\def\ordinal@italian#1{%
  \@ifnextchar[{\ordinal@italianb{#1}}{\ordinal@italianb{#1}[f] }}
\def\ordinalshort@italianb#1[#2]{%
  \def\ordinal@opt@arg{#2}%
  \ifx\ordinal@opt@arg\ordinal@gender@f #1a\else%
    \ifx\ordinal@opt@arg\ordinal@gender@m #1o\else%
      \ifx\ordinal@opt@arg\ordinal@gender@fp #1e\else%
        #1i\fi\fi\fi%
}
\def\ordinal@italian@root#1{\ifcase#1 \or prim\or second\or terz%
  \or quart\or quint\or sest\or settim\or ottav%
  \or non\or decim\else #1\fi%
}
\def\ordinal@italianb#1[#2]{%
  \def\ordinal@opt@arg{#2}%
  \ordinal@italian@root{#1}%
  \ifx\ordinal@opt@arg\ordinal@gender@f a\else%
    \ifx\ordinal@opt@arg\ordinal@gender@m o\else%
      \ifx\ordinal@opt@arg\ordinal@gender@fp e\else%
        i\fi\fi\fi%
}

% Hack some known commands so that we can use ordinal numbers for
% references too
\def\@currentcount{}
\def\@newl@bel#1#2#3{%
  \@ifnextchar[{\@newl@belbis{#1}{#2}{#3}}{\@newl@belbis{#1}{#2}{#3}[]}}
\def\@newl@belbis#1#2#3[#4]{{%
  \@ifundefined{#1@#2}%
    \relax
    {\gdef \@multiplelabels {%
       \@latex@warning@no@line{There were multiply-defined labels}}%
     \@latex@warning@no@line{Label `#2' multiply defined}}%
  \global\@namedef{#1@#2}{#3}}%
  \global\@namedef{or@#2}{#4}%
}
\def\label#1{\@bsphack
  \protected@write\@auxout{}%
         {\string\newlabel{#1}{{\@currentlabel}{\thepage}}[\@currentcount]}%
  \@esphack%
}
\def\refstepcounter#1{\stepcounter{#1}%
    \protected@edef\@currentlabel
       {\csname p@#1\endcsname\csname the#1\endcsname}%
    \protected@edef\@currentcount
       {\number\csname c@#1\endcsname}%
}

% Here are the references
\def\ordinalref#1{%
  \@ifundefined{or@#1}%
    \relax%
    \ordinal{\csname or@#1\endcsname}%
}
\def\ordinalshortref#1{%
  \@ifundefined{or@#1}%
    \relax%
    \ordinalshort{\csname or@#1\endcsname}%
}

