% \iffalse meta-comment/*% \end{macrocode}*/ % % Copyright (C) 2021 by Sigitas Tolu\v{s}is % --------------------------------------------------------------------------- % 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 2005/12/01 or later. % % This work has the LPPL maintenance status `maintained'. % % The Current Maintainer of this work is Sigitas Tolu\v{s}is. % % This work consists of the files texsort.dtx and texsort.ins % and the derived filebase texsort.sty. % % \fi % % \iffalse %<*internal> \begingroup % %<*batchfile> \input docstrip.tex \keepsilent\askforoverwritefalse \preamble %% %% This is file `texsort.sty', %% generated with the docstrip utility. %% %% The original source files were: %% %% texsort.dtx (with options: `package') %% \endpreamble \generate{\file{texsort.sty}{\from{texsort.dtx}{package}}} % %\endbatchfile %<*internal> \generate{\file{texsort.ins}{\from{texsort.dtx}{batchfile}}} \endgroup % %<*driver> \ProvidesFile{texsort.dtx} % %<*package> %% Copyright (C) 2000-2021 by Sigitas Tolu\v{s}is %% UAB VTeX, Mokslininkų 2A, LT-08412 Vilnius, Lithuania %% -------------------------------------------------------------------------- %% 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 2005/12/01 or later. %% %% PURPOSE: Sort/compress numerical lists %% % %\NeedsTeXFormat{LaTeX2e}[1999/12/01] %\ProvidesPackage{texsort} %<*package> [2012/05/29 v1.1 Sort/compress alphanumerical list] % % %<*driver> \documentclass{ltxdoc} \usepackage{texsort}[2012/05/29] %%\EnableCrossrefs %%\CodelineIndex %%\RecordChanges \begin{document} \DocInput{texsort.dtx} %%\PrintChanges %%\PrintIndex \end{document} % % \fi % % \CheckSum{629} % % \CharacterTable % {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z % Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z % Digits \0\1\2\3\4\5\6\7\8\9 % Exclamation \! Double quote \" Hash (number) \# % Dollar \$ Percent \% Ampersand \& % Acute accent \' Left paren \( Right paren \) % Asterisk \* Plus \+ Comma \, % Minus \- Point \. Solidus \/ % Colon \: Semicolon \; Less than \< % Equals \= Greater than \> Question mark \? % Commercial at \@ Left bracket \[ Backslash \\ % Right bracket \] Circumflex \^ Underscore \_ % Grave accent \` Left brace \{ Vertical bar \| % Right brace \} Tilde \~} % % % \changes{v0.1a}{2000/06/06}{Created alfa version} % \changes{v1.0}{2000/06/08}{Added compression} % \changes{v1.1}{2012/05/29}{Converted to DTX file} % % \DoNotIndex{\newcommand,\newenvironment} % % \providecommand*{\url}{\texttt} % \GetFileInfo{texsort.dtx} % \title{The \textsf{texsort} package} % \author{Sigitas Tolu\v{s}is \\ \url{sigitas@vtex.lt}} % \date{\fileversion~from \filedate} % % \maketitle % % \section{Introduction} % % Purpose: sort/compress numerical lists. % % \section{Usage} % % \DescribeMacro{\sortlist} % % \leftline{Sort list:} % % \verb|\sortlist{1,5,20,6,23,2,1,4000,4}\to{mylist}\sep{,}| % % \medskip % \leftline{Result:} % % \sortlist{1,5,20,6,23,2,1,4000,4}\to{mylist}\sep{,} % \verb|\mylist->|\mylist % % \bigskip % \DescribeMacro{\compresslist} % % \leftline{Compress list:} % % \verb|\compresslist{\mylist}\to{clist}\sep{,}{-}| % % \medskip % \leftline{Result:} % \compresslist{\mylist}\to{clist}\sep{,}{-}% % \verb|\clist->|\clist % % \StopEventually{} % % \section{Implementation} % % \iffalse %<*package> % \fi % % \begin{macrocode} \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{texsort}[2012/05/29] % \end{macrocode} % % \begin{macrocode} \newcount\t@mp@r@a \newcount\t@mp@r@b \newcount\t@mp@r@c % \end{macrocode} % % \begin{macro}{\initarray} % \marg{list}\marg{array} % % \medskip % Converts \meta{list} to \meta{array}. % \medskip % \begin{macrocode} \def\initarray#1#2{% \bgroup \@tempcnta=\z@ \@for\@@refb:=#2\do{% \advance\@tempcnta by\@ne \bgroup \setbox\z@\hbox{% \expandafter\global\expandafter\t@mp@r@a\expandafter\add@zero\@@refb\relax }% \ifdim\wd0>\z@\relax \@latex@warning{Not number \@@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 } % \end{macrocode} % \end{macro} % % % \begin{macro}{\outarray} % \marg{array}\marg{sep} % % \medskip % Outputs \meta{array} elements separated by \meta{sep}. % \medskip % \begin{macrocode} \def\outarray#1\sep#2{% \bgroup \@tempcnta=\z@\relax \@tempcntb=\getarraylenght{#1}% \loop \ifnum\@tempcnta<\@tempcntb \advance\@tempcnta by\@ne\relax \ifnum\@tempcnta>\@ne\relax#2\fi \csname#1@\the\@tempcnta\endcsname \repeat \egroup } % \end{macrocode} % \end{macro} % % % \begin{macro}{\add@zero} % \marg{arg} % % \medskip % Adds 0 before \meta{arg}. % \medskip % \begin{macrocode} \def\add@zero#1{0#1} % \end{macrocode} % \end{macro} % % % \begin{macro}{\getarrayitem} % \marg{array}\marg{index}\verb|\to|\marg{command} % % \medskip % Gets \meta{array} element by \meta{index} to \verb|\|\meta{command}. % \medskip % \begin{macrocode} \def\getarrayitem#1#2\to#3{\expandafter\xdef\csname#3\endcsname{\csname#1@#2\endcsname}} % \end{macrocode} % \end{macro} % % % \begin{macro}{\setarrayitem} % \marg{array}\marg{index}\marg{value} % % \medskip % Sets \meta{array} element by \meta{index} to \meta{value}. % \medskip % \begin{macrocode} \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{Not number #3!}% \fi \expandafter\xdef\csname#1@#2\endcsname{\the\t@mp@r@a}% \egroup } % \end{macrocode} % \end{macro} % % % \begin{macro}{\getarraylenght} % \marg{array} % % \medskip % Gets \meta{array} elements count. % \medskip % \begin{macrocode} \def\getarraylenght#1{\@ifundefined{#1@lenght}{0}{\csname #1@lenght\endcsname}} % \end{macrocode} % \end{macro} % % % \begin{macro}{\setarraylenght} % \marg{array}\marg{value} % % \medskip % Sets \meta{array} elements count to \meta{value}. % \medskip % \begin{macrocode} \def\setarraylenght#1#2{\expandafter\xdef\csname #1@lenght\endcsname{#2}} % \end{macrocode} % \end{macro} % % % \begin{macro}{\upheap} % \marg{array}\marg{index} % % \medskip % Internal macro of sort algorithm. % \medskip % \begin{macrocode} \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 } % \end{macrocode} % \end{macro} % % % \begin{macro}{\insertheapelem} % \marg{array}\marg{value} % % \medskip % Internal macro of sort algorithm. % \medskip % \begin{macrocode} \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 } % \end{macrocode} % \end{macro} % % \begin{macrocode} \newcount\@tempcntd % \end{macrocode} % % \begin{macro}{\downheap} % \marg{array}\marg{index} % % \medskip % Internal macro of sort algorithm. % \medskip % \begin{macrocode} \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 } % \end{macrocode} % \end{macro} % % \begin{macrocode} % \end{macrocode} % % \begin{macro}{\removetop} % \marg{array}\verb|\to|\marg{command} % % \medskip % Internal macro of sort algorithm. % \medskip % \begin{macrocode} \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 } % \end{macrocode} % \end{macro} % % % \begin{macro}{\g@addto@macrobeg} % \marg{macro}\marg{definition} % % \medskip % Adds some more \meta{definition} to \meta{macro} begining. % \medskip % \begin{macrocode} \long\def\g@addto@macrobeg#1#2{% \begingroup \def\@a@{#2}% \toks@\expandafter\expandafter\expandafter{\expandafter\@a@#1}% \xdef#1{\the\toks@}% \endgroup } % \end{macrocode} % \end{macro} % % % \begin{macro}{\sortlistarray} % \marg{array}\marg{sorted array} % % \medskip % Sorts \meta{array} and puts result to \meta{sorted array}. % \begin{macrocode} \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 } % \end{macrocode} % \end{macro} % % % \begin{macro}{\sortlist} % \marg{list}\verb|\to|\marg{macro}\verb|\sep|\marg{sep} % % \medskip % Sorts \meta{list} and puts elements separated by \meta{sep} to \meta{macro}. % \medskip % \begin{macrocode} \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 } % \end{macrocode} % \end{macro} % % % \begin{macro}{\compresslist} % \marg{list}\verb|\to|\marg{macro}\verb|\sep|\marg{single}\marg{multi} % % \medskip % Compress \meta{list} and puts result to \marg{macro}; % single elements separated by \meta{single}, multi by \meta{multi}. % \medskip % \begin{macrocode} \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 } % \end{macrocode} % \end{macro} % % \begin{macrocode} %\endinput % \end{macrocode} % % \iffalse % % \fi % % \Finale