<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">% \iffalse meta-comment
%
% Copyright (C) 2019 by Laurence R Taylor
% -----------------------------------
%
% This file may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3c 
% 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.3c or later is part of all distributions of LaTeX
% version 2005/12/01 or later.
%
% \fi
%
% \iffalse
%
%&lt;*driver&gt;
\documentclass{ltxdoc}
\usepackage{bubblesort}
\usepackage{graphicx}
\usepackage{hyperref}
\hypersetup{
    colorlinks=true,
    linkcolor=blue,
    filecolor=magenta,      
    urlcolor=cyan,
}
\DisableCrossrefs
\CodelineNumbered
\RecordChanges
\begin{document}
\DocInput{bubblesort.dtx} 
\end{document}
%&lt;/driver&gt;
% \fi
% 
% \CheckSum{293}
%
% \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     \&amp;
% Acute accent  \'    Left paren    \(     Right paren   \)
% Asterisk \*  Plus \+  Comma \,
% Minus \-  Point \.  Solidus   \/
% Colon \:  Semicolon  \;  Less than     \&lt;
% Equals \=  Greater than  \&gt;  Question mark \?
% Commercial at \@   Left bracket  \[   Backslash     \\
% Right bracket \]  Circumflex    \^  Underscore    \_
% Grave accent  \`    Left brace    \{     Vertical bar  \|  
% Right brace   \}     Tilde         \~}
% 
%
% \hfuzz=200pt
% \changes{v1.0}{?2019?/?07?/?17?}{Initial version} 
% \title{bubblesort}
% \author{Laurence R Taylor}
% \date{2020/06/24}
% \maketitle
% \begin{abstract}
% This package is a \LaTeX\ port of the sorting function \href{https://en.wikipedia.org/wiki/Bubble_sort}{bubble sort}. 
% Bubble sort is usually coded using arrays but it can be done without them and 
% since \LaTeX\ does not support arrays natively, bubble sort seemed like a good routine to port. 
% It's lack of speed is not really a problem with the data sizes likely to be encountered in most \LaTeX\ applications. 
%
% The objects to be sorted are either a stack or a list.
% A \emph{stack} is a sequence of legal \TeX\ code items enclosed in brace pairs, \vskip0pt%
% \begin{center}|{|\emph{item 1}|}{|\emph{item 2}|}|\dots|{|\emph{item n}|}|\end{center}
% while a \emph{list} is a macro which expands to a stack. Fragile commands in an \emph{item} may not work as expected. 
% To sort the items one needs a notion of when one \emph{item} is ``less than'' another. 
% 
% The macro |\bubblesort| does the bubble sort. It takes three arguments: |\bubblesort[#1]{#2}{#3}|. 
% The optional argument is a comparator macro telling when one item is smaller than another. 
% If empty it assumes the stack is a stack of integers or real numbers
% and sorts it using the usual $&lt;$. Argument |#2| is the stack or list to be sorted and 
% argument |#3| a macro which will contain the sorted list in increasing order. 
% 
% The only dependency is |etoolbox.sty|.
% \end{abstract}
% \section{Introduction}    
% \makeatletter
% \newcounter{LineAA}
% \def\Label#1{\hypertarget{@bubblesort@ref#1}\relax\setcounter{LineAA}{\value{CodelineNo}}\stepcounter{LineAA}
% {\immediate\write\@auxout{\string\gdef\string\@bubblesort@ref#1{\number\value{LineAA}}}}}
% \def\codeRef#1{\ifcsdef{@bubblesort@ref#1}{\hyperlink{@bubblesort@ref#1}{\csname @bubblesort@ref#1\endcsname}}{\textbf{??}}}
% \def\LabelLine#1{\Label{#1}\nointerlineskip\begin{macrocode}}
% \newbox\ff\setbox\ff=\hbox{\scalebox{0.75}{\hbox{\Large\tt doublebubblesort}}}
% \newbox\fff\setbox\fff=\hbox{\scalebox{0.75}{\hbox{\Large\tt doublebubblesortB}}}
% \newbox\mm\setbox\mm=\hbox{\rotatebox{114}{\vrule depth0.8pt height 0pt width 9pt}}
% \makeatother
% \newbox\ff\setbox\ff=\hbox{\scalebox{0.75}{\hbox{\Large\tt doublebubblesort}}}
% \newbox\fff\setbox\fff=\hbox{\scalebox{0.75}{\hbox{\Large\tt doublebubblesortB}}}
% \newbox\mm\setbox\mm=\hbox{\rotatebox{114}{\vrule depth0.8pt height 0pt width 9pt}}
% There are two macros provided which implement the standard bubble sort algorithms 
% on stacks or lists. See section \ref{SandL} for a discussion of stacks or lists.
% \subsection{\texorpdfstring{\copy\mm\tt bubblesort}{bubblesort}}
% |\bubblesort[#1]{#2}{#3}|: Argument |#2| is the stack or list to be sorted. Argument |#3| contains the sorted list 
% after evaluation. Argument |#2| can be the same as argument |#3|. Argument |#3| can also be blank in which 
% case the output string is inserted into the input stream. 
% Optional argument |#1| is a comparator macro. 
% \subsubsection{Comparator macros}
% A comparator macro can have any legal \TeX\ name. It must have two arguments. 
% When in use the comparator macro is evaluated on consecutive pairs of elements in the stack. 
% If argument |#2| is ``smaller'' than argument |#1| the macro sets |\bubblesortflag| to |1| and sets it 
% to |-1| otherwise. 
% Two examples are supplied: |\realSort| on line \codeRef{realSort}\ of the code below and
% |\alphSort| on line \codeRef{alphSort}.
%
% \subsection{\texorpdfstring{\copy\mm\tt doublebubblesort}{bubblesort}}|\doublebubblesort[#1]{#2}{#3}{#4}{#5}|:
% 
% The macro |\doublebubblesort| sorts two stack/lists. Arguments |#1|, |#2| and |#3| are identical to the corresponding 
% arguments for |\bubblesort|. Argument |#4| is another stack or list of the same length or longer than stack/list |#2|. 
% When expanded |\doublebubblesort| sorts |#2| just the same as |\bubblesort| would. However, every move made on 
% stack |#2| is also done on stack |#4|. Argument |#5| is the name for the output of the result of this ``sort'' on |#4|. 
% As usual |#5| can be blank or |#4| and |#5| can be the same macro. |#3| and |#5| can also be the same macro, in
% which case it contains the result of the sort on argument |#4|, \emph{except} if both |#3| and |#5| are blank, |#3| 
% is put into the input stream followed by |#5|. 
% 
% An example to keep in mind is the following. One way to mimic a hash in \LaTeX\ is to have a list of keys and a second 
% list of values with the value associated to a key being determined by position in the values list. If the key list is sorted it 
% will be necessary to do the same interchanges on the values list to maintain the correspondence. 
% See subsection \ref{permute} for another example using |\doublebubblsort|. 
% \section{Stacks and lists}\label{SandL}
% The lists here closely resemble Knuth's lists in the 
% \href{http://www.ctex.org/documents/shredder/src/texbook.pdf}{\TeX book}, page 378, Appendix D,
% except they lack Knuth's initial |\\| prepended to each item. As discussed by Knuth, the |\\| can be used to process 
% each item in the list.
% Sort algorithms require knowledge of pairs of items from the list 
% so macros which only know about one item are not needed. 
% 
% 
% Other implementations of lists use a reserved character as a separator. 
% Separators like commas or semicolons or whatever have the drawback that then the separator can not be used in the item text
% without additional coding. 
%
% \TeX's brace-pair mechanism is quite robust. It handles nested brace pairs just fine. One word of \textcolor{red}{warning}: 
% an empty brace pair |{}| is used as an end of list indicator. They are added to the stack/list arguments
% when needed and are not present at the end of lists produced by macros in this package so they rarely trouble the user.  
% It does mean that
% \textcolor{red}{there can be no empty (or even |{white space}|) brace pairs in the input list.} 
% Given how \TeX\ discards white space, |{white space}| is probably not what is wanted anyway. Using |{{white space}}| will probably  
% yield results closer to what was intended and this works. 
% \section{Examples}
% Here are a few examples if things that can be done with sorts.
% \subsection{\texorpdfstring{\copy\mm\tt refs}{refs}}
% Given a stack of references defined from |\label| such as |{ref 1}{ref 2}|\dots|{ref n}| which expand to integers or real numbers
% try to define 
% \begin{center}
% \color{red}|\def\refs#1{\bubblesort[\refSort]{#1}{\answers}}|\hskip1in\null \\where |\refSort#1#2{\realSort{\ref{#1}}{\ref{#2}}}|. \color{black}
% \end{center}
% The above does not work because |\ref| is protected and does not expand to just the number. 
% Instead, the package |refcount.sty| supplies |\getrefnumber| which is expandable and does what is needed. 
% Add |\usepackage{refcount}| to the preamble and define
% \begin{verbatim}
% \def\refSort#1#2{%
% \edef\aa{\getrefnumber{#1} pt}\edef\bb{\getrefnumber{#2} pt}%
% \ifdimless{\bb}{\aa}{\bubblesortflag=1}{\bubblesortflag=-1}%
% }
% \end{verbatim}
% Then|\def\refs#1{\bubblesort[\refSort]{#1}{\ans}}| sorts the numbers in increasing order and puts the answer in |\ans|. 
%
% \subsection{Use {\texorpdfstring{\copy\mm\tt refs}{refs}}\ twice}
% Since |\bubblesort| is a stable sorting algorithm, it can be usefully used more than once on the same data.
% Suppose |\refSort| is defined as above and there is a list |\def\LL{{ref 1}{ref 2}|\dots|{ref n}}|.
% Then |\bubblesort[\refSort]{\LL}{\LL}| sorts the numbers in increasing order. 
% 
% But some of them may be from definitions, others from theorems, or lemmas, etc. 
% Suppose |\refName#1| is a macro such that |\refName{ref k}| returns |Definition|, |Theorem|, |Lemma|, etc..
% Then
% \begin{center}
% |\bubblesort[\refSort]{\LL}{\LL} \bubblesort[\alphSort]{\LL}{\LL}|
% \end{center} 
% \noindent returns 
% |\def\LL{{ref k_1}{ref k_2}|\dots|{ref k_n}}|
% where the first set of references are |Definition|'s,  the second set of references are |Lemma|'s and
% the third set of references are |Theorem|'s. 
% The set of numbers for the |Definition|'s are increasing, 
% the set of numbers for the |Lemma|'s are increasing and
% the set of numbers for the |Theorem|'s are increasing.  
% With more complicated coding, the names can be added and the lists compactified to get something line
% |Theorems 1-3 and 5, Lemma 9 and Definitions 6, 8 and 12|. 
% 
% \subsection{\texorpdfstring{\copy\mm\tt permute}{permute}}\label{permute}
% Use |\doublebubblesort| to apply a permutation to a stack/list.
% A \emph{permutation} is an ordered stack/list of symbols which also has a natural order. 
% Popular symbol sets are positive integers and lowercase letters. The comparator macro needs 
% to sort a list of symbols with no repetitions back to its natural order. 
% A permutation $\pi$ can be given by listing the values of $\pi$ when applied to the symbols
% in their natural order. For example $\pi$|={{5}{1}{2}{3}{4}}| means $\pi$|(1)=5|, $\pi$|(2)=1|, $\pi$|(3)=2|, $\pi$|(4)=3|, $\pi$|(5)=4|.  
% 
% At the end of line 2 of the displayed code below, |\ott| contains the symbols in their natural order 
% so |\permute| does not need to be told the symbols in advance.
% At the end of line 3, |\ott| contains the inverse to the original permutation. 
% At the end of line 4, |#4| contains the permuted version of |#3|. 
%
% \null\hskip0.13\textwidth \vbox{\begin{verbatim}
% \newcommand{\permute}[4][\realSort]{%
% \bubblesort[#1]{#2}{\ott}%
% \doublebubblesort[#1]{#2}{\ott}{\ott}{\ott}%
% \doublebubblesort[#1]{\ott}{\ott}{#3}{#4}%
% }
% \end{verbatim}}
% If |\def\LL{{${a_1}$}{${a_2}$}{${a_3}$}{${a_4}$}{${a_5}$}}| then\\
% |\permute{{5}{1}{2}{3}{4}}{\LL}{}| yields
%
% {${\tt a}_5$}\, {${\tt a}_1$}\, {${\tt a}_2$}\, {${\tt a}_3$}\, {${\tt a}_4$}\ , which is 
% {${\tt a}_{\pi(1)}$}\, {${\tt a}_{\pi(2)}$}\, {${\tt a}_{\pi(3)}$}\, {${\tt a}_{\pi(4)}$}\, {${\tt a}_{\pi(5)}$}\  as desired. 
% \bigskip
%
% |\permute| can also be used to multiply permutations: 
% \begin{itemize}
% \item |\permute{\pi_1}{\pi_2}{\ans}| yields |\pi_2|$\circ$|\pi_1|  
% \item |\permute{\pi_2}{\pi_1}{\ans}| yields |\pi_1|$\circ$|\pi_2|. 
% \end{itemize}
% 
% \section{Implementation}\label{implementation}
% Line numbers refer to the line numbers printed next to the code beginning with |\NeedsTeXFormat| \hyperlink{NeedsTeXFormat}{here}.
% There are only four public macros, |\bubblesort| on line \codeRef{bubblesort}
% and |\doublebubblesort| on line \codeRef{doublebubblesort} and comparator macros |\realSort| on line \codeRef{realSort}\ and
% |\alphSort| on line \codeRef{alphSort}. 
% Private macros begin with |\@bubblesort@| to minimize the chance of name conflicts with other packages. 
% This makes reading the code somewhat tedious so 
% in the descriptions of the code below, the initial |\@bubblesort@| will be replaced by |*|. 
%
% \subsection{\texorpdfstring{\copy\mm\tt bubblesort}{bubblesort}}
% |\bubblesort[#1]{#2}{#3}|:
% The implementation of |\bubblesort| begins by defining an empty |*rightList| and putting the stack/list to be sorted, |#2|, into |*workingList|. 
% Note |#2| is now safe - unless |#2| equals |#3|, |#2| will never change. 
% Then |\bubblesort| removes the leftmost item in |*workingList| 
% and saves it in |*testItem|. Then it moves on to |\@bubblesort@S| which does the recursion.
%
% First, |\bubblesort@S| (line \codeRef{bubblesortS}) sets an |etoolbox| boolean, |did a flip|, to false and sets |*leftList| to empty. 
% Then the macro removes the leftmost element in |*workingList| and saves it in |*nextItem|. 
% Then it enters the |while| loop (line \codeRef{while}). 
% The exit condition is that |*nextItem| is empty. 
% Then the comparator macro is evaluated on the ordered pair $\bigl($|*testItem| , |*nextItem|$\bigr)$. 
% The smaller of the pair is append to |*leftList| on the right and the larger is set to |*testItem|. 
% The loop continues until |*workingList| is empty. At this point |*testItem| contains the largest element in the 
% original |*workingList| and it is added to |*rightList| at the left end. 
% Hence |*leftList| followed by |*rightList| is the original list. 
% Next |*leftList| is put into |*workingList| and then the leftmost element is removed and put into |*testItem|. 
% Finally the |while| loop is reentered. 
%
% After $k$ iterations of the |while| loop, |*rightList| has $k$ elements which are the $k$ largest elements in the original list in increasing order. 
% When the boolean |did a flip| is false, |*leftList| is also ordered so |*leftList| followed by |*rightList| is the original list sorted 
% and the |while| loop exits. 
% The sorted list and macro |#3| from |\bubblesort| are passed on to |\@bubblesort@output| which outputs the list as requested
% and |\bubblesort| is finished. 
%
% \noindent\textbf{Remark:} The reader who has worked through the discussion above will have noticed that this implementation of bubble sort 
% uses about four times  the storage as the |C| version which sorts the array in place. 
% Stacks used in \LaTeX, are probably small enough that this is not a problem. 
%
% Sorting a thousand item list of integers in reverse order (which is the worse case scenario) took less than sixty-five seconds running
% |TexShop| |4.44| on a Mac 2013 Powerbook using timing code from 
% \href{https://tex.stackexchange.com/questions/456316/what-is-the-latex-equivalent-of-context-testfeatureonce-to-benchmark-performanc/456322#456322}{tex.stackexchange}. It put no strain on \TeX's memory allocations. 
%
% \bigskip
% \subsection{\texorpdfstring{\copy\mm\tt doublebubblesort}{doublebubblesort}}
% |\doublebubblesort[#1]{#2}{#3}{#4}{#5}|:
% The |\doublebubblesort| (line \codeRef{doublebubblesort}), |\@doublebubblesort@S| (line \codeRef{doublebubblesortS}), 
% macros work much like |\bubblesort|, |\@bubblesort@S|. 
% The code in the |double|'d version contains the identical code from |\bubblesort|, |\@bubblesort@S| except that |A| is added
% to the end of each of the internal macros. There is also a parallel copy of macros with |B| added and everything done with the
% |A| variables is mimicked with the |B| variables.
%
% \bigskip
% \subsection{The remaining macros}
% The macro |\@bubblesort@output#1#2| (line \codeRef{output}) is just to shorten the code 
% since there are three places a stack or a list is output (lines \codeRef{outputA}, \codeRef{outputB} and \codeRef{outputC}). 
%
% The macro |\@bubblesort@EoS| is the End-of-Stack indicator. 
%
% The remaining macros do the removing items from a list and inserting items at either end of a list. 
% The shift macro is \\
% \null\hskip1in|\@bubblesort@shift#1#2\@bubblesort@EoS#3#4| (line \codeRef{shiftM})\\
% which is used as \\|\expandafter\@bubblesort@shift{stack/list}\@bubblesort@EoS{\itemA}{\itemB}| which 
% puts the leftmost item in the stack/list into |\itemA| and the rest of the stack/list into |\itemB|. 
%
% The macros |\@bubblesort@rightappendItem| (line \codeRef{rAi}) \\and 
% |\@bubblesort@lefttappendItem| (line \codeRef{lAi}) are identical to Knuth's 
% |\rightappenditem| and |\leftappenditem| except that there are no prepended |\\|'s.
%
% \StopEventually{}
% \color{white}
% \setcounter{CodelineNo}{15}
% \begin{macro}{blank}\color{black}\textbf{Start of code:}
% \hypertarget{NeedsTeXFormat}{}
% The rest of the file from the end of this paragraph onward is a copy of the file
% generated by \TeX ing the |bubblesort.ins| file except that the standard set of comments 
% at the start of an |ins| generated file are omitted. And of course the line numbers on the left here are
% not present in the |\bubblesort.sty| file.  
% The comments portion takes 15 lines. 
% Most editors show line numbers and allow line number navigation so it has been arranged that
% the line numbers in the typeset |bubblesort.dtx| file below match the line numbers 
% in the |ins|-generated |bubblesort.sty| file.
% \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}[2005/12/01]
\ProvidesPackage{bubblesort}
      [2020/07/01 v1.0 implements a bubble sort]

\RequirePackage{etoolbox}

\makeatletter

\newcount\bubblesortflag
\newbool{did a flip}
\def\@bubblesort@EoS{}% End-of-Stack indicator

%    \end{macrocode} \LabelLine{realSort}
\def\realSort#1#2{%
\ifdimless{#2 pt}{#1 pt}{\bubblesortflag=1}{\bubblesortflag=-1}}
%    \end{macrocode} \LabelLine{alphSort}
\def\alphSort#1#2{\ifnumequal{\pdfstrcmp{#1}{#2}}{1}%
{\bubblesortflag=1}{\bubblesortflag=-1}}
%    \end{macrocode} \LabelLine{bubblesort}
\newcommand{\bubblesort}[3][\realSort]{%
%% #1 comparator macro, #2 input stack/list, #3 answer list: #2=#3 OK
\def\@bubblesort@rightList{}%
\expandafter\@bubblesort@shiftOne#2{}{}{}\@bubblesort@EoS{%
\@bubblesort@testItem}{\@bubblesort@workingList}%
\expandafter\@bubblesort@S{#3}{#1}%
}
%    \end{macrocode} \LabelLine{bubblesortS}
\def\@bubblesort@S#1#2{% #1 is name for answer --- #2 is comparator macro
\boolfalse{did a flip}\def\@bubblesort@leftList{}%
\expandafter\@bubblesort@shiftOne\@bubblesort@workingList{}{}\@bubblesort@EoS{%
\@bubblesort@nextItem}{\@bubblesort@workingList}%
%    \end{macrocode} \Label{while}\nointerlineskip\begin{macrocode}
\whileboolexpr{not test{\ifdefvoid{\@bubblesort@nextItem}}}{%
#2{\@bubblesort@testItem}{\@bubblesort@nextItem}\relax%
\ifnumequal{\bubblesortflag}{1}{% flip
\booltrue{did a flip}%
\expandafter\@bubblesort@rightappendItem\expandafter{\@bubblesort@nextItem}%
\to\@bubblesort@leftList%
}{%
\expandafter\@bubblesort@rightappendItem\expandafter{\@bubblesort@testItem}%
\to\@bubblesort@leftList%
\expandafter\def\expandafter\@bubblesort@testItem\expandafter{\@bubblesort@nextItem}%
}%
\expandafter\@bubblesort@shiftOne\@bubblesort@workingList\@bubblesort@EoS{%
\@bubblesort@nextItem}{\@bubblesort@workingList}%
}%
\expandafter\leftappendItem\expandafter{\@bubblesort@testItem}\to\@bubblesort@rightList%
\ifbool{did a flip}{%
\expandafter\def\expandafter\@bubblesort@workingList\expandafter%
{\@bubblesort@leftList{}{}{}}%
\expandafter\@bubblesort@shiftOne\@bubblesort@workingList\@bubblesort@EoS{%
\@bubblesort@testItem}{\@bubblesort@workingList}%
\def\@bubblesort@leftList{}%
\@bubblesort@S{#1}{#2}}%
%    \end{macrocode} \Label{outputA}\nointerlineskip\begin{macrocode}
{\@bubblesort@output{#1}{\@bubblesort@leftList\@bubblesort@rightList}%
}}
%    \end{macrocode} \Label{output}\nointerlineskip\begin{macrocode}
\def\@bubblesort@output#1#2{% #1 name of output list or empty ---  #2 sorted stack
\ifstrempty{#1}%
{#2}{\expandafter\edef\expandafter#1\expandafter{#2}}%
}
%    \end{macrocode} \Label{doublebubblesort}\nointerlineskip\begin{macrocode}
\newcommand{\doublebubblesort}[5][\realSort]{%
%% #1 comparator macro
%% #2 input stack/list  --- #3 output for #2 stack/list; #2=#3 OK
%% #4 second stack/list --- #5 answer list for #4; #4=#5 OK
\def\@bubblesort@rightListA{}\def\@bubblesort@rightListB{}%
\expandafter\@bubblesort@shiftOne#2{}{}{}\@bubblesort@EoS{%
\@bubblesort@testItemA}{\@bubblesort@workingListA}%
\expandafter\@bubblesort@shiftOne#4{}{}{}\@bubblesort@EoS{%
\@bubblesort@testItemB}{\@bubblesort@workingListB}%
\expandafter\@doublebubblesort@S{#3}{#5}{#1}%
}
%    \end{macrocode} \Label{doublebubblesortS}\nointerlineskip\begin{macrocode}
\def\@doublebubblesort@S#1#2#3{%
%% #1 output for sorted stack/list --- #2 output for ``sorted'' stack/list 
%% #3 comparator macro
\boolfalse{did a flip}\def\@bubblesort@leftListA{}\def\@bubblesort@leftListB{}%
\expandafter\@bubblesort@shiftOne\@bubblesort@workingListA{}{}%
\@bubblesort@EoS{\@bubblesort@nextItemA}{\@bubblesort@workingListA}%
\expandafter\@bubblesort@shiftOne\@bubblesort@workingListB{}{}%
\@bubblesort@EoS{\@bubblesort@nextItemB}{\@bubblesort@workingListB}%
\whileboolexpr{not test{\ifdefvoid{\@bubblesort@nextItemA}}}{%
#3{\@bubblesort@testItemA}{\@bubblesort@nextItemA}\relax%
\ifnumequal{\bubblesortflag}{1}{% flip
\booltrue{did a flip}%
\expandafter\@bubblesort@rightappendItem\expandafter{%
\@bubblesort@nextItemA}\to\@bubblesort@leftListA%
\expandafter\@bubblesort@rightappendItem\expandafter{%
\@bubblesort@nextItemB}\to\@bubblesort@leftListB%
}{%
\expandafter\@bubblesort@rightappendItem\expandafter{%
\@bubblesort@testItemA}\to\@bubblesort@leftListA%
\expandafter\@bubblesort@rightappendItem\expandafter{%
\@bubblesort@testItemB}\to\@bubblesort@leftListB%
\expandafter\def\expandafter\@bubblesort@testItemA\expandafter{%
\@bubblesort@nextItemA}%
\expandafter\def\expandafter\@bubblesort@testItemB\expandafter{%
\@bubblesort@nextItemB}%
}%
\expandafter\@bubblesort@shiftOne\@bubblesort@workingListA\@bubblesort@EoS{%
\@bubblesort@nextItemA}{\@bubblesort@workingListA}%
\expandafter\@bubblesort@shiftOne\@bubblesort@workingListB\@bubblesort@EoS{%
\@bubblesort@nextItemB}{\@bubblesort@workingListB}%
}%
\expandafter\leftappendItem\expandafter{\@bubblesort@testItemA}\to%
\@bubblesort@rightListA%
\expandafter\leftappendItem\expandafter{\@bubblesort@testItemB}\to%
\@bubblesort@rightListB%
\ifbool{did a flip}{%
\expandafter\def\expandafter\@bubblesort@workingListA\expandafter{%
\@bubblesort@leftListA{}{}{}}%
\expandafter\def\expandafter\@bubblesort@workingListB\expandafter{%
\@bubblesort@leftListB{}{}{}}%
\expandafter\@bubblesort@shiftOne\@bubblesort@workingListA\@bubblesort@EoS{%
\@bubblesort@testItemA}{\@bubblesort@workingListA}%
\expandafter\@bubblesort@shiftOne\@bubblesort@workingListB\@bubblesort@EoS{%
\@bubblesort@testItemB}{\@bubblesort@workingListB}%
\def\@bubblesort@leftListA{}%
\def\@bubblesort@leftListB{}%
\expandafter\@doublebubblesort@S{#1}{#2}{#3}}%
%    \end{macrocode} \Label{outputB}\nointerlineskip\begin{macrocode}
{\@bubblesort@output{#1}{\@bubblesort@leftListA\@bubblesort@rightListA}%
%    \end{macrocode} \Label{outputC}\nointerlineskip\begin{macrocode}
\@bubblesort@output{#2}{\@bubblesort@leftListB\@bubblesort@rightListB}}%
}

%    \end{macrocode} \Label{shiftM}\nointerlineskip\begin{macrocode}
\def\@bubblesort@shiftOne#1#2\@bubblesort@EoS#3#4{%
\expandafter\gdef\expandafter#3\expandafter{#1}%
\expandafter\gdef\expandafter#4\expandafter{#2}%
}

\newtoks\ta\newtoks\tb
%    \end{macrocode} \Label{rAi}\nointerlineskip\begin{macrocode}
\long\def\@bubblesort@rightappendItem#1\to#2{\ta={{#1}}\tb=\expandafter{#2}%
\edef#2{\the\tb\the\ta}}
%    \end{macrocode} \Label{lAi}\nointerlineskip\begin{macrocode}
\long\def\leftappendItem#1\to#2{\ta={{#1}}\tb=\expandafter{#2}%
\edef#2{\the\ta\the\tb}}
\makeatother
\endinput
%    \end{macrocode} 
% \end{macro}
% \Finale
</pre></body></html>