%% texsort.sty
%% Copyright 2000-2002 Sigitas Tolu\v sis
%% VTeX Ltd., Akademijos 4, Vilnius, Lithuania
%% e-mail sigitas@vtex.lt
%% http://www.vtex.lt/tex/download/macros/
%%
% This program can redistributed and/or modified under the terms
% of the LaTeX Project Public License Distributed from CTAN
% archives in directory macros/latex/base/lppl.txt; either
% version 1 of the License, or (at your option) any later version.
%
% PURPOSE:   Sort/compress numerical lists
%
% SHORT DESCRIPTION:
%
% \initarray#1#2
% --------------
%   Converts list #2 to array #1
%
% \outarray#1\sep#2
% -----------------
%   Outputs array #1 elements separated by #2
%
% \getarrayitem#1#2\to#3
% ----------------------
%   Gets #2'th element from array #1 to \csname#3\endcsname
%
% \setarrayitem#1#2#3
% -------------------
%   Sets #2'th element from array #1 to numeric value #3
%
% \getarraylenght#1
% -----------------
%   Gets array #1 elements count
%
% \setarraylenght#1
% -----------------
%   Sets array #1 elements count to value #2
%
% \upheap#1#2; \insertheapelem#1#2; \downheap#1#2; \removetop#1\to#2
% ------------------------------------------------------------------
%   Internal macros of sort algorithm
%
% \g@addto@macrobeg#1#2
% ---------------------
%   Adds defs #2 to macro #1 begining
%
% \add@zero#1
% -----------
%   Adds 0 before #1
%
% \sortlistarray#1\to#2
% ---------------------
%   Sorts array #1 to array #2
%
% \sortlist#1\to#2\sep#3
% ----------------------
%   Sorts list #1 and puts to macro #2; elements separated by #3
%
% \sortdotlist#1\to#2\sep#3
% ----------------------
%   Sorts list(1.1 etc.) #1 and puts to macro #2; elements separated by #3
%
% \compresslist#1\to#2\sep#3#4
% ----------------------------
%   Compress list #1 and puts to macro #2; 
%   single elements separated by #3, multi by #4
%
% Changes:
%  \changes{2000/06/06}{alfa version}
%  \changes{2000/06/08}{added compression}
%  \changes{2002/06/11}{added new command sortdotlist}
%
\def\get@CVSdate#1Id: #2,v #3 #4 #5 #6 #7${#4}%$
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{texsort}[\get@CVSdate$Id: texsort.sty,v 1.2 2002/06/11 15:18:10 sigitas Exp $]
%
\newcount\t@mp@r@a
\newcount\t@mp@r@b
\newcount\t@mp@r@c

\def\initarray#1#2{%
  \bgroup
    \@tempcnta=\z@
    \@for\@@refb:=#2\do{%
      \advance\@tempcnta by\@ne
      \bgroup
      \setbox0\hbox{\expandafter\global\expandafter\t@mp@r@a\expandafter\add@zero\@@refb\relax}%
      \ifdim\wd0>\z@\relax\@latex@warning{Negrynas skaicius \@@refb!}\fi
      \expandafter\edef\csname @a@\endcsname{\expandafter\xdef\expandafter
        \noexpand\csname#1@\the\@tempcnta\endcsname{\the\t@mp@r@a}}\@a@
      \egroup
    }%
    \expandafter\xdef\csname #1@lenght\endcsname{\the\@tempcnta}%
  \egroup
}
\def\outarray#1\sep#2{%
  \bgroup
    \@tempcnta=\z@\relax
    \@tempcntb=\getarraylenght{#1}%
    \loop
    \ifnum\@tempcnta<\@tempcntb 
      \advance\@tempcnta by1\relax
      \ifnum\@tempcnta>1\relax#2\fi\csname#1@\the\@tempcnta\endcsname
    \repeat
  \egroup
}
\def\add@zero#1{0#1}
\def\getarrayitem#1#2\to#3{\expandafter\xdef\csname#3\endcsname{\csname#1@#2\endcsname}}
\def\setarrayitem#1#2#3{%
  \bgroup
    \setbox0\hbox{\expandafter\global\expandafter\t@mp@r@a\expandafter\add@zero#3\relax}%
    \ifdim\wd0>\z@\relax\@latex@warning{Negrynas skaicius #3!}\fi
    \expandafter\edef\csname @a@\endcsname{\expandafter\xdef\expandafter
      \noexpand\csname#1@#2\endcsname{\the\t@mp@r@a}}\@a@
  \egroup
}
\def\getarraylenght#1{\@ifundefined{#1@lenght}{0}{\csname #1@lenght\endcsname}}
\def\setarraylenght#1#2{\expandafter\xdef\csname #1@lenght\endcsname{#2}}

%#1 - masyvas, #2 - elemento nr.
\def\upheap#1#2{%
  \bgroup
    \getarrayitem{#1}{#2}\to{vara}%
    \@namedef{#1@0}{\maxdimen}%
    \@tempcntb=#2\relax
    \loop
    \@tempcnta=\@tempcntb
    \divide\@tempcnta by2\getarrayitem{#1}{\the\@tempcnta}\to{varb}%
    \ifnum\varb>\vara\relax\else
      \getarrayitem{#1}{\the\@tempcnta}\to{varb}%
      \setarrayitem{#1}{\the\@tempcntb}{\varb}%
      \divide\@tempcntb by2\relax
    \repeat
    \setarrayitem{#1}{\the\@tempcntb}{\vara}%
  \egroup
}

%#1 - masyvas, #2 - dedama reiksme
\def\insertheapelem#1#2{%
  \bgroup 
    \@tempcnta=\getarraylenght{#1}\relax
    \advance\@tempcnta by1\relax
    \setarraylenght{#1}{\the\@tempcnta}\relax
    \setarrayitem{#1}{\the\@tempcnta}{#2}%
    \upheap{#1}{\the\@tempcnta}%
  \egroup
}

%#1 - masyvas, #2 - elemento nr.
\newcount\@tempcntd
\def\downheap#1#2{%
  \bgroup
    \getarrayitem{#1}{#2}\to{vara}%
    \@tempcntb=\getarraylenght{#1}%
    \t@mp@r@c=\@tempcntb\relax
    \divide\@tempcntb by2\relax
    \t@mp@r@b=\@tempcntb\relax
    \@tempcntb=#2\relax
    \ifnum\@tempcntb>\t@mp@r@b\relax\else 
      \loop
      \@tempcnta=\@tempcntb\advance\@tempcnta by\@tempcntb\relax
      \@tempcntd=\@tempcnta \advance\@tempcntd by1\relax
      \ifnum\@tempcnta<\t@mp@r@c\relax
        \getarrayitem{#1}{\the\@tempcnta}\to{temp@@a}%
        \getarrayitem{#1}{\the\@tempcntd}\to{temp@@b}%
        \ifnum\temp@@a<\temp@@b\relax
          \@tempcnta=\@tempcntd
        \fi
      \fi
      \getarrayitem{#1}{\the\@tempcnta}\to{temp@@a}%
      \ifnum\vara>\temp@@a\relax
        \t@mp@r@b=-1\relax
      \else
        \getarrayitem{#1}{\the\@tempcnta}\to{temp@@a}%
        \setarrayitem{#1}{\the\@tempcntb}{\temp@@a}%
        \@tempcntb=\@tempcnta
      \fi
      \ifnum\@tempcntb>\t@mp@r@b\relax
      \else
      \repeat
    \fi
    \setarrayitem{#1}{\the\@tempcntb}{\vara}%
  \egroup
}

\def\removetop#1\to#2{%
  \bgroup
    \getarrayitem{#1}{1}\to{temp@@c}%
    \expandafter\xdef\csname #2\endcsname{\temp@@c}%
    \@tempcnta=\getarraylenght{#1}%
    \getarrayitem{#1}{\the\@tempcnta}\to{temp@@a}%
    \setarrayitem{#1}{1}{\temp@@a}%
    \setarrayitem{#1}{\the\@tempcnta}{}%
    \advance\@tempcnta by-1\relax
    \setarraylenght{#1}{\the\@tempcnta}%
    \downheap{#1}{1}%
  \egroup
}
\long\def\g@addto@macrobeg#1#2{%
  \begingroup
    \def\@a@{#2}%
    \toks@\expandafter\expandafter\expandafter{\expandafter\@a@#1}%
    \xdef#1{\the\toks@}%
  \endgroup}

\def\sortlistarray#1\to#2{%
  \bgroup
    \@for\@@refb:=#1\do{%
      \insertheapelem{@tempa@}{\@@refb}%
    }%
    \@tempcntb=\getarraylenght{@tempa@}%
    \setarraylenght{#2}{\the\@tempcntb}%
    \@for\@@refb:=#1\do{%
      \removetop{@tempa@}\to{aka}%
      \setarrayitem{#2}{\the\@tempcntb}{\aka}%
      \advance\@tempcntb by-1\relax
    }%
  \egroup
}
\def\sortlist#1\to#2\sep#3{%
  \bgroup
    \@for\@@refb:=#1\do{%
      \insertheapelem{@tempa@}{\@@refb}%
    }%
    \@tempcntb=\getarraylenght{@tempa@}%
    \expandafter\def\csname#2\endcsname{}%
    \expandafter\def\expandafter\@a@\expandafter{\csname#2\endcsname}%
    \@for\@@refb:=#1\do{%
      \removetop{@tempa@}\to{aka}%
      \advance\@tempcntb by-1\relax
      \expandafter\expandafter\expandafter\g@addto@macrobeg\expandafter\@a@\expandafter{\aka}%
      \ifnum\@tempcntb>0\relax
        \expandafter\expandafter\expandafter\g@addto@macrobeg\expandafter\@a@\expandafter{#3}%
      \fi
    }%
  \egroup
}
\def\get@sep@dot.#1\relax{\global\t@mp@r@b=#1\relax}
\def\sortdotlist#1\to#2\sep#3{%
  \bgroup
    \@for\@@refb:=#1\do{%
      \xdef\cur@refb{\global\t@mp@r@a0\@@refb}\relax
      \afterassignment\get@sep@dot\cur@refb\relax
      \multiply\t@mp@r@a1000\advance\t@mp@r@a by \t@mp@r@b
      \expandafter\edef\csname @a@\endcsname{\expandafter\edef\expandafter
      \noexpand\csname @@refb\endcsname{\the\t@mp@r@a}}\@a@
      \insertheapelem{@tempa@}{\@@refb}%
    }%
    \@tempcntb=\getarraylenght{@tempa@}%
    \expandafter\def\csname#2\endcsname{}%
    \expandafter\def\expandafter\@a@\expandafter{\csname#2\endcsname}%
    \@for\@@refb:=#1\do{%
      \removetop{@tempa@}\to{aka}%
      \t@mp@r@b=\number\aka\relax
      \@tempcnta=\t@mp@r@b\relax
      \divide\@tempcnta by1000\relax
      \t@mp@r@a=\@tempcnta\relax
      \multiply\@tempcnta by1000\relax
      \advance\t@mp@r@b by-\@tempcnta
      \expandafter\edef\csname @a@\endcsname{\expandafter\edef\expandafter
      \noexpand\csname aka\endcsname{\the\t@mp@r@a.\the\t@mp@r@b}}\@a@
      \advance\@tempcntb by-1\relax
      \expandafter\expandafter\expandafter\g@addto@macrobeg\expandafter\@a@\expandafter{\aka}%
      \ifnum\@tempcntb>0\relax
        \expandafter\expandafter\expandafter\g@addto@macrobeg\expandafter\@a@\expandafter{#3}%
      \fi
    }%
  \egroup
}
\def\compresslist#1\to#2\sep#3#4{%
  \bgroup
    \expandafter\def\csname#2\endcsname{}%
    \expandafter\def\expandafter\@a@\expandafter{\csname#2\endcsname}%
    \t@mp@r@a=-1\relax
    \@tempcnta=-2\relax
    \expandafter\@for\expandafter\@@refb\expandafter:\expandafter=#1\do{%
       \ifnum\t@mp@r@a=-1\relax
         \t@mp@r@a=\@@refb\relax
         \t@mp@r@b=\@@refb\relax
         \t@mp@r@c=\@@refb\relax
         \expandafter\expandafter\expandafter\g@addto@macro\expandafter\@a@\expandafter{\the\t@mp@r@a}%
       \else
         \t@mp@r@c=\@@refb\relax
         \ifnum\t@mp@r@c=\t@mp@r@a\relax
           \expandafter\expandafter\expandafter\g@addto@macro\expandafter\@a@\expandafter{#3}%
           \expandafter\expandafter\expandafter\g@addto@macro\expandafter\@a@\expandafter{\the\t@mp@r@c}%
           \t@mp@r@b=\t@mp@r@c\relax
         \else
           \@tempcnta=\t@mp@r@b\relax
           \advance\@tempcnta by1\relax
           \ifnum\@tempcnta=\t@mp@r@c\relax
             \t@mp@r@b=\t@mp@r@c\relax
           \else
             \@tempcnta=\t@mp@r@a\relax
             \advance\@tempcnta by-\t@mp@r@b\relax
             \ifnum\@tempcnta<-1\relax
               \expandafter\expandafter\expandafter\g@addto@macro\expandafter\@a@\expandafter{#4}%
               \expandafter\expandafter\expandafter\g@addto@macro\expandafter\@a@\expandafter{\the\t@mp@r@b}%
               \expandafter\expandafter\expandafter\g@addto@macro\expandafter\@a@\expandafter{#3}%
               \expandafter\expandafter\expandafter\g@addto@macro\expandafter\@a@\expandafter{\the\t@mp@r@c}%
             \else
               \ifnum\t@mp@r@a<\t@mp@r@b
                 \expandafter\expandafter\expandafter\g@addto@macro\expandafter\@a@\expandafter{#3}%
                 \expandafter\expandafter\expandafter\g@addto@macro\expandafter\@a@\expandafter{\the\t@mp@r@b}%
               \fi
               \expandafter\expandafter\expandafter\g@addto@macro\expandafter\@a@\expandafter{#3}%
               \expandafter\expandafter\expandafter\g@addto@macro\expandafter\@a@\expandafter{\the\t@mp@r@c}%
             \fi
             \t@mp@r@a=\t@mp@r@c\relax
             \t@mp@r@b=\t@mp@r@c\relax
           \fi
         \fi
       \fi
    }%
    \ifnum\t@mp@r@a<\t@mp@r@c\relax
      \advance\t@mp@r@a by-\t@mp@r@c\relax
      \ifnum\t@mp@r@a<-1\relax
        \expandafter\expandafter\expandafter\g@addto@macro\expandafter\@a@\expandafter{#4}%
      \else
        \expandafter\expandafter\expandafter\g@addto@macro\expandafter\@a@\expandafter{#3}%
      \fi
      \expandafter\expandafter\expandafter\g@addto@macro\expandafter\@a@\expandafter{\the\t@mp@r@c}%
    \fi
  \egroup
}
\endinput
