%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
% This is file 'pagerange.sty', version 0.3.                                %
%                                                                           %
% 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 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 2005/12/01 or later.        %
%                                                                           %
% The LPPL maintenance status of this software is 'author-maintained'.      %
%                                                                           %
% This software is provided 'as it is', without warranty of any kind,       %
% either expressed or implied, including, but not limited to, the           %
% implied warranties of merchantability and fitness for a particular        %
% purpose.                                                                  %
%                                                                           %
% Copyright (c) 2009 Ahmed Musa (a.musa@rocketmail.com).                    %
%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%

\ProvidesPackage{pagerange}%
  [2009/11/10 v0.3 Split page ranges intelligently (Ahmed Musa)]
\NeedsTeXFormat{LaTeX2e}[1996/12/01]
\def\prg@warn#1{\PackageWarningNoLine{pagerange}{#1}}
\def\prg@err#1{\PackageError{pagerange}{#1}{\@ehc}}
\@ifpackageloaded{lastpage}{}{\RequirePackage{lastpage}[1994/06/25]}
\@ifpackageloaded{xkeyval}{}{\RequirePackage{xkeyval}[2008/08/13]}
\ifcase0%
  \ifx\eTeXversion\@undefined 1\else\ifnum\eTeXversion<\tw@ 1\fi\fi
\else
  \prg@err{eTeX not loaded or old version.\MessageBreak
    This package requires eTeX version 2 or later.}
\fi
\def\prg@ifdef#1{\csname @\ifdefined#1\expandafter first\else
  \expandafter second\fi oftwo\endcsname
}
\def\prg@ifundef#1{%
  \prg@ifdef{#1}{\csname @\ifx#1\relax\expandafter first\else
    \expandafter second\fi oftwo\endcsname}{\@firstoftwo}%
}
\def\prg@ifcsundef#1{\expandafter\prg@ifundef\csname#1\endcsname}
\def\prg@check@ifdef#1{%
  \prg@ifcsundef{#1}{}{%
    \prg@err{\expandafter\noexpand\csname#1\endcsname already defined}}%
  \prg@check@ifdef
}
\prg@check@ifdef{pagerange}{pagestart}{pageend}{getpagenumber}%
  \iffalse\fi\fi\endcsname{}{}
\edef\prg@restorecodes{%
  \catcode45=\the\catcode45\relax % -
  \catcode38=\the\catcode38\relax % &
}
\AtEndOfPackage{\prg@restorecodes}
\catcode38=3\relax
\@makeother\-%
\long\gdef\prg@ifblank#1{% macro credit: ifmtarg.sty
  \prg@ifblank@aux#1&&\@secondoftwo\@firstoftwo:}
\long\gdef\prg@ifblank@aux#1#2&#3#4#5:{#4}
\long\def\prg@xifblank#1{\begingroup
  \protected@edef\x{\endgroup\noexpand\prg@ifblank{#1}}\x%
}
\chardef\active=13\relax
\def\prg@ifmacro#1{%
  \prg@ifdef{#1}\relax{\prg@err{\string#1 undefined}}%
  \begingroup
  \edef\x{\endgroup
    \noexpand\def\noexpand\getparameter####1\detokenize{macro}:####2&{%
      \noexpand\prg@ifblank{####2}{\noexpand\@secondoftwo}%
        {\noexpand\@firstoftwo}%
    }%
   \noexpand\expandafter\noexpand\getparameter%
    \noexpand\meaning\noexpand#1\detokenize{macro}:&%
  }\x
}
\def\prg@ismacro@err#1{%
  \prg@err{%
    Illegal tie '#1'.\MessageBreak
    Note that the 'tie' has been fully expanded \MessageBreak
    and may be different from what you submitted.\MessageBreak
    Perhaps you've used an active character as 'tie'
  }%
}
\define@boolkeys[KV]{pagerange}[prg@]{acceptempty}[true]
\define@cmdkey[KV]{pagerange}[prg@]{tie}[-]{%
  \edef\prg@tie{\prg@tie}%
  \expandafter\prg@ifmacro\prg@tie{\prg@ismacro@err\prg@tie}{}
}
\define@cmdkey[KV]{pagerange}[prg@]{defaultfirstpage}[1]{}
\define@cmdkey[KV]{pagerange}[prg@]{defaultlastpage}[\getpagenumber{LastPage}]{}
\DeclareOptionX*{\prg@warn{Unknown option '\CurrentOption' ignored}}
\ExecuteOptionsX<pagerange>{tie,defaultfirstpage,defaultlastpage}
\ProcessOptionsX*<pagerange>\relax
\gdef\pagerangeoptions#1{\setkeys[KV]{pagerange}{#1}}
\long\def\prg@forall#1#2\do#3{%
  #3{#1}%
  \ifx\\#2\\%
    \relax
  \else
    \prg@forall#2\do{#3}%
  \fi
}
\let\pagestart\@empty
\let\pageend\@empty
\newcount\prg@cntx\prg@cntx=\z@\relax
\long\def\prg@split@pagerange#1{%
  \def\reserved@a{#1}%
  \ifx\reserved@a\prg@tie
    \advance\prg@cntx\@ne\relax
  \fi
  \ifnum\prg@cntx=\z@
    \g@addto@macro\pagestart{#1}%
  \else\ifnum\prg@cntx=\@ne
    \ifx\reserved@a\prg@tie\else
      \g@addto@macro\pageend{#1}%
    \fi
  \else\ifnum\prg@cntx>\@ne
    \prg@err{Multiple ties in page range.\MessageBreak
      Please use only one tie}%
  \fi\fi\fi
}
\newcount\prg@cnta\prg@cnta=\z@\relax
\newcount\prg@cntb\prg@cntb=\z@\relax
\def\pagerange#1{%
  \let\pagestart\@empty
  \let\pageend\@empty
  \prg@cntx=\z@\relax
  \prg@xifblank{#1}{%
    \ifprg@acceptempty
      \prg@warn{Blank page range supplied:\MessageBreak
        I've therefore set the range as 1-1 and continued}
      \let\pagestart\prg@defaultfirstpage
      \let\pageend\prg@defaultlastpage
    \else
      \prg@err{Blank page range.\MessageBreak
        If you really mean blank pagerange,\MessageBreak
        then also use 'acceptempty' boolean option
      }%
    \fi
  }{%
    \begingroup\edef\@tempa{\endgroup%
      \noexpand\prg@forall#1\noexpand\do{\noexpand\prg@split@pagerange}}%
    \@tempa
  }%
  \ifx\@empty\pagestart
    \ifnum\prg@cntx=\@ne
      \let\pagestart\prg@defaultfirstpage
    \fi
  \fi
  \prg@cnta=\number\pagestart\relax
  \ifx\@empty\pageend
    \prg@cntb=\@M\relax
    \ifnum\prg@cntx=\@ne
      \let\pageend\prg@defaultlastpage
    \fi
  \else
    \prg@cntb=\number\pageend\relax
  \fi
  \ifnum\prg@cnta>\prg@cntb
    \prg@err{Inconsistent page range: Page \pageend\space > \pagestart}%
  \fi
}
\def\prg@carr#1#2#3\@nil{%
  \ifx\relax#3\relax\prg@err{Problem with page reference}\fi
  #2%
}
\def\getpagenumber#1{%
  \prg@ifcsundef{r@#1}{\prg@defaultfirstpage}{%
    \expandafter\expandafter\expandafter\prg@carr
    \csname r@#1\endcsname\prg@defaultfirstpage\@nil
  }%
}

\endinput 