% \iffalse meta-comment
%<*internal>
\iffalse
%</internal>
%<*internal>
\fi
\def\nameofplainTeX{plain}
\ifx\fmtname\nameofplainTeX\else
  \expandafter\begingroup
\fi
%</internal>
%<*install>
\input docstrip.tex
\keepsilent
\askforoverwritefalse
\preamble
\endpreamble
\ifx\fmtname\nameofplainTeX
\generate{
  \file{\jobname.sty}{\from{\jobname.dtx}{copyright,package}}
}
\fi
%</install>
%<install>\endbatchfile
%<*internal>
\ifx\fmtname\nameofplainTeX
  \expandafter\endbatchfile\else
  \expandafter\endgroup\fi
%</internal>
%<*copyright>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% ran_toks.sty package,           2012/10/29           %%
%% Copyright (C) 2012  D. P. Story                      %%
%%   dpstory@uakron.edu                                 %%
%%                                                      %%
%% 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.      %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%</copyright>
%<package>\NeedsTeXFormat{LaTeX2e}
%<package>\ProvidesPackage{ran_toks}
%<package> [2012/11/18 v1.0a Randomizing tokens]
%<*driver>
\documentclass{ltxdoc}
%\usepackage{\jobname}
%\usepackage[numbered]{hypdoc}
%\EnableCrossrefs
%\CodelineIndex
%\RecordChanges
\begin{document}
  \DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
%
%\GetFileInfo{\jobname.sty}
%
%\title{The  \textsf{ran\_toks} Package}
%\author{D. P. Story}
%\date{Released \today}
%
%\maketitle
%
%\StopEventually{^^A
%  \PrintChanges
%  \PrintIndex
%}
%
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
% \paragraph*{Description.}
% This short package randomizes a list of tokens. The command, \cs{ranToks},
% takes one argument, which is, in turn, a list of tokens:
%\begin{verbatim}
%   \ranToks{<name>}
%   {
%       {tok_1}{tok_2}...{tok_n}
%   }
%\end{verbatim}
% The command defines a series of $n$ internal commands, one for each of the tokens.
% The definitions are essentially randomized. The randomized tokens are accessed through
% the command \cs{useRanTok}. For example
%\begin{verbatim}
%       \useRanTok{1}, \useRanTok{2},..., \useRanTok{n}
%\end{verbatim}
% gives a random listing of the $n$ tokens. These can be arranged on the page
% as desired.
%
% There is a second construct, designed for more elaborate randomization.
%\begin{verbatim}
%\bRTVToks{<name>}
%\begin{rtVW}
% <some content>
%\end{rtVW}
%...
%...
%\begin{rtVW}
%<some content>
%\end{rtVW}
%\eRTVToks
%\end{verbatim}
% The contents of each of the \texttt{rtVW} environments are written to disk, then input
% back in in random order, using \cs{useRanTok}, eg,
%\begin{verbatim}
%       \useRanTok{1}, \useRanTok{2},..., \useRanTok{n}
%\end{verbatim}
% Other details are left to the readers' imagination.
%
% \paragraph{Requirements.} As of this writing, we require only the \texttt{verbatim} package
% and \texttt{random.tex}, the package was written by Donald Arseneau.
%    \begin{macrocode}
\RequirePackage{verbatim}
\input{random.tex}
%    \end{macrocode}
% We redefine \cs{nextrandom} from \texttt{random.tex} to save the initializing seed.
%    \begin{macrocode}
\def\nextrandom{\begingroup
 \ifnum\randomi<\@ne % then initialize with time
    \global\randomi\time
    \global\multiply\randomi388 \global\advance\randomi\year
    \global\multiply\randomi31 \global\advance\randomi\day
    \global\multiply\randomi97 \global\advance\randomi\month
    \message{Randomizer initialized to \the\randomi.}%
    \nextrandom \nextrandom \nextrandom
%    \end{macrocode}
% Save the initial seed value to \cs{rtInitSeedValue}.
%    \begin{macrocode}
    \xdef\rtInitSeedValue{\the\randomi}%
 \fi
 \count@ii\randomi
 \divide\count@ii 127773 % modulus = multiplier * 127773 + 2836
 \count@\count@ii
 \multiply\count@ii 127773
 \global\advance\randomi-\count@ii % random mod 127773
 \global\multiply\randomi 16807
 \multiply\count@ 2836
 \global\advance\randomi-\count@
 \ifnum\randomi<\z@ \global\advance\randomi 2147483647\relax\fi
 \endgroup
}
%    \end{macrocode}
% The code for this package was taken from the \textsf{dps} package, and modified
% suitably. We use several token registers and count registers. This can probably
% be optimized.
%    \begin{macrocode}
\newtoks\rt@listIn \rt@listIn={}
\newtoks\rt@newListIn \rt@newListIn={}
\newtoks\rt@listOut \rt@listOut={}
\newcount\rt@nMax
\newcount\rt@nCnt
\newcount\rt@getRanNum
\newif\ifrtdebug \rtdebugfalse
\newif\ifwerandomize \werandomizetrue
\newif\ifsaveseed\saveseedtrue
\newwrite\rt@Verb@write
%    \end{macrocode}
%    \begin{macrocode}
\def\rt@nameedef#1{\expandafter\edef\csname #1\endcsname}
%    \end{macrocode}
%
% \section{Commands for controlling the process}
%
% \DescribeMacro{\ranToksOn}\DescribeMacro{\ranToksOff} These two turn on and turn off
% randomization.
%    \begin{macrocode}
\def\ranToksOn{\werandomizetrue}
\def\ranToksOff{\werandomizefalse}
%    \end{macrocode}
% \DescribeMacro{\useThisSeed} initializes the random number generator. Use this to reproduce
% the same sequence of pseudo-random numbers from an earlier run. We also set
% \cs{saveseedfalse} so we do not write the initial seed to the disk.
%    \begin{macrocode}
\def\useThisSeed#1{\saveseedfalse\randomi=#1}
\@onlypreamble\useThisSeed
%    \end{macrocode}
% \DescribeMacro{\useLastAsSeed} initializes the random number generator using the
% last random seed. If the file \cs{jobname\_rt.sav} does not exist, the generator will be
% initialized using time and date data.
%    \begin{macrocode}
\def\useLastAsSeed{\IfFileExists{\jobname_rt.sav}%
    {%
        \PackageInfo{ran_toks}{Inputting \jobname_rt.sav}%
        \newread\readsavfile
        \openin\readsavfile=\jobname_rt.sav
        \read\readsavfile to \rtInitSeedValue
        \read\readsavfile to \lastRandomNum
        \closein\readsavfile
        \randomi=\lastRandomNum
    }{%
        \PackageInfo{ran_toks}{\jobname_rt.sav cannot
        be found, \MessageBreak
        using the random initializer}%
    }%
}
\@onlypreamble\useLastAsSeed
%    \end{macrocode}
%
% \section{Utility commands}
%
% A standard \cs{verbatim} write used in exerquiz and other package in the AeB family.
%    \begin{macrocode}
\def\verbatimwrite{\@bsphack
    \let\do\@makeother\dospecials
    \catcode`\^^M\active \catcode`\^^I=12
    \def\verbatim@processline{%
        \immediate\write\verbatim@out
        {\the\verbatim@line}}%
    \verbatim@start}
\def\endverbatimwrite{\@esphack}
\def\rt@IWVO{\immediate\write\verbatim@out}
%    \end{macrocode}
% We write only if \cs{ifsaveseed} is true.
%    \begin{macrocode}
\def\rtInitSeedValue{\the\randomi}
\def\rt@writeSeedData{%
    \ifsaveseed
    \newwrite\rt@savedata
        \immediate\openout \rt@savedata \jobname_rt.sav
        \let\verbatim@out\rt@savedata
        \def\rt@msgi{initializing seed value}%
        \def\rt@msgii{last random number used}%
        \uccode`c=`\%\uppercase{%
        \rt@IWVO{\rtInitSeedValue\space c \rt@msgi}%
        \rt@IWVO{\the\randomi\space c \rt@msgii}%
        }%
    \fi
}
%    \end{macrocode}
% Save the initial seed value to hard drive.
%    \begin{macrocode}
\AtEndDocument{\rt@writeSeedData}%
%    \end{macrocode}
% \DescribeMacro{\rt@populateList} is a utility command, its argument is a positive integer, \texttt{n},
% and it generates a list of the form \verb!\\{1}\\{2}...\\{n}! and is held in the
% token register \cs{rt@listIn}  This listing is later
% randomly permuted by \cs{rt@RandomizeList}.
%    \begin{macrocode}
\def\rt@populateList#1{%
    \rt@listIn={}%
    \rt@nCnt=0
    \@whilenum\rt@nCnt<#1\do{%
        \advance\rt@nCnt1
        \edef\rt@listInHold{\the\rt@listIn\noexpand\\{\the\rt@nCnt}}%
        \rt@listIn=\expandafter{\rt@listInHold}%
    }%
}
%    \end{macrocode}
% \DescribeMacro{\rt@RandomizeList} is the command that gets the process of randomizing
% the input list going. The argument is the number of tokens. If
% \cs{werandomize} is false, it just returns the input list; otherwise, it
% calls \cs{rt@randomizeList} to actually do the work.
%    \begin{macrocode}
\def\rt@RandomizeList#1{%
    \global\rt@listIn={}\global\rt@newListIn={}\global\rt@listOut={}%
    \rt@nMax=#1\relax\rt@populateList{\the\rt@nMax}%
    \ifwerandomize
        \expandafter\rt@randomizeList\else
        \global\rt@listOut=\expandafter{\the\rt@listIn}\fi
}
%    \end{macrocode}
% \DescribeMacro{\rt@randomizeList} randomizes the list of consecutive integers, and leaves the
% results,
%\begin{verbatim}
%    \\{k_1}\\{k_2}...\\{k_n}
%\end{verbatim}
% in the token register \cs{rt@listOut}.
% \cs{rt@randomizeList} is a loop, looping between itself and \cs{rt@loopTest}.
%    \begin{macrocode}
\def\rt@randomizeList{%
    \let\\=\rt@processi
    \setrannum{\rt@getRanNum}{1}{\the\rt@nMax}%
\ifrtdebug\typeout{\string\rt@getRanNum=\the\rt@getRanNum}\fi
    \rt@nCnt=0\relax
\ifrtdebug\typeout{LISTING: \the\rt@listIn}\fi
    \the\rt@listIn
    \rt@loopTest
}
\def\rt@loopTest{\advance\rt@nMax-1\relax
    \ifnum\rt@nMax>0\relax
        \def\rt@next{%
            \rt@listIn=\expandafter{\the\rt@newListIn}%
            \rt@newListIn={}\rt@randomizeList}%
    \else
        \let\rt@next\relax
        \global\rt@listOut=\expandafter{\the\rt@listOut}%
\ifrtdebug\typeout{Final Result: \string\rt@listOut=\the\rt@listOut}\fi
    \fi
    \rt@next
}
%    \end{macrocode}
% In \cs{rt@randomizeList}, we \verb~\let\\=\rt@processi~ before dumping the
% contents of \cs{rt@listIn}. We then go into a loop \cs{rt@loopTest}. \cs{rt@getRanNum}
% is the random integer between 1 and \cs{rt@nMax}.
%    \begin{macrocode}
\def\rt@processi#1{\advance\rt@nCnt1
    \ifnum\rt@nCnt=\rt@getRanNum
        \edef\rt@listOutHold{\the\rt@listOut}%
        \global\rt@listOut=\expandafter{\rt@listOutHold\\{#1}}%
\ifrtdebug\typeout{Found it: \string\\{#1}}%
\typeout{New \string\rt@listOut: \the\rt@listOut}\fi
    \else
        \edef\rt@listInHold{\the\rt@newListIn}%
        \rt@newListIn=\expandafter{\rt@listInHold\\{#1}}%
\ifrtdebug\typeout{\string\rt@newListIn: \the\rt@newListIn}\fi
    \fi
}
%    \end{macrocode}
% \section{The main commands}
% \DescribeMacro{\ranToks} takes one argument, a list of tokens. It randomizes them.
% The randomized listing can be accessed using \cs{useRanTok}.
%    \begin{macrocode}
\def\ranToks#1{\begingroup
    \useRTName{#1}%
    \r@nToks
}
\long\def\r@nToks#1{%
    \rt@nMax=0
    \r@ndToks#1\rt@NIL
}
\def\rt@NIL{@nil}
%    \end{macrocode}
% \DescribeMacro{\useRTName} sets the base name (use prior to the use of \cs{useRanTok}).
%    \begin{macrocode}
\newcommand{\useRTName}[1]{\gdef\rt@BaseName{#1}}%
\let\rt@BaseName\@empty
%    \end{macrocode}
% \DescribeMacro{\bRTVToks}\cs{bRTVToks} and \DescribeMacro{\eRTVToks}\cs{eRTVToks} enclose a series
% of \texttt{rtVW} environments. The single argument is the name of this set of
% verbatim write ``tokens''.
%    \begin{macrocode}
\newcommand{\bRTVToks}[1]{%
    \rt@nCnt=0
    \useRTName{#1}%
}
%    \end{macrocode}
% At the end of the \texttt{rtVW} environments, initiated by \cs{bRTVToks}, the
% \cs{eRTVToks} command saves the number of tokens counted, and randomizes the
% access to the contents of the \texttt{rtVW} environments, this done by
% \cs{r@nVToks}.
%    \begin{macrocode}
\newcommand{\eRTVToks}{%
    \global\rt@nameedef{\rt@BaseName Cnt}{\the\rt@nCnt}%
    \expandafter\r@nVToks\expandafter{\rt@BaseName}%
}
%    \end{macrocode}
%    \begin{environment}{rtVW}
% \cs{rtVW} is a verbatim write environment. It saves its contents to the file
% \verb!\jobname_\rt@BaseName\the\rt@nCnt.cut!. The file is later input back into
% the source file in a random way.
%    \begin{macrocode}
\def\reVerbEnd{\ifhmode\unskip\fi}
\newenvironment{rtVW}{%
    \global\advance\rt@nCnt1
    \immediate\openout\rt@Verb@write
        \jobname_\rt@BaseName\the\rt@nCnt.cut
    \let\verbatim@out\rt@Verb@write
    \verbatimwrite
}{%
    \endverbatimwrite
    \immediate\write\rt@Verb@write{\string\reVerbEnd}%
    \immediate\closeout\rt@Verb@write
}
%    \end{macrocode}
%    \end{environment}
% \DescribeMacro{\r@nVToks} randomizes the contents of the \texttt{rtVW}
% environment.
%    \begin{macrocode}
\def\r@nVToks#1{\begingroup
    \gdef\rt@BaseName{#1}%
    \expandafter\rt@nMax\@nameuse{#1Cnt}%
    \rt@listIn={}\rt@nCnt=0\relax\let\rt@listInHold\@empty
    \@whilenum\rt@nCnt<\rt@nMax\do{%
    \advance\rt@nCnt1
    \edef\rt@listInHold{%
        \the\rt@listIn{\noexpand\rt@inputVerb{#1\the\rt@nCnt}}}%
    \rt@listIn=\expandafter{\rt@listInHold}%
    }%
\ifrtdebug\typeout{\string\r@nVToks: \the\rt@listIn}\fi
    \expandafter\r@nToks\expandafter{\the\rt@listIn}%
}
\def\rt@inputVerb#1{\input{\jobname_#1.cut}}
%    \end{macrocode}
% \DescribeMacro{\r@ndToks} is main looping command for \cs{ranToks}
% and \cs{eRTVToks} (through \cs{r@nVToks}).  If the ending token \cs{rt@NIL} is detected, we
% break off and go to \cs{rt@endToks}.
%    \begin{macrocode}
\long\def\r@ndToks#1{%
%    \end{macrocode}
% If the current argument is \cs{par}, we skip it
%    \begin{macrocode}
    \ifx#1\par\def\rt@next{\r@ndToks}\else
        \advance\rt@nMax1
        \global\@namedef{rtTok\the\rt@nMax\rt@BaseName}{#1}%
        \def\rt@next{\@ifnextchar\rt@NIL
            {\rt@endToks\@gobble}{\r@ndToks}}%
    \fi\rt@next
}
%    \end{macrocode}
% The final destination for \cs{r@ndToks}.
%    \begin{macrocode}
\def\rt@endToks{%
%    \end{macrocode}
% Save the number of tokens counted
%    \begin{macrocode}
    \global\rt@nameedef{nMax4\rt@BaseName}{\the\rt@nMax}%
%    \end{macrocode}
% Now we randomize the order of the integers 1, 2,\dots\cs{rt@nMax}.
%    \begin{macrocode}
    \rt@RandomizeList{\the\rt@nMax}%
    \rt@nCnt=0
%    \end{macrocode}
% Now we randomized the definitions. We \verb!\let\\=\assignRanToks!, then
% let loose the tokens!
%    \begin{macrocode}
    \let\\\assignRanToks
    \the\rt@listOut
    \endgroup
}
%    \end{macrocode}
%\DescribeMacro{\assignRanToks} makes the assignments that are expanded by \cs{useRanTok}.
% We \cs{let} the assignment \verb!\let\\=\assignRanToks! in \cs{rt@endToks}, just before we dump out the
% contents of \verb!\the\rt@listOut!.
%    \begin{macrocode}
\def\assignRanToks#1{\advance\rt@nCnt1
    \global\rt@nameedef{rtRanTok\the\rt@nCnt\rt@BaseName}%
        {\noexpand\rtTokByNum[\rt@BaseName]{#1}}%
}
%    \end{macrocode}
% \subsection{Additional user access commands}
% \DescribeMacro{\nToksFor} expands the the number of tokens whose name is \texttt{\#1}.
%    \begin{macrocode}
\newcommand{\nToksFor}[1]{\@nameuse{nMax4#1}}
%    \end{macrocode}
% \DescribeMacro{\rtTokByNum} is an internal macro, but it can be used publicly.
% The argument of it is an integer, eg, \verb!\rtTokByNum{3}! is the third token, as listed in the order
% given in the argument of \cs{ranToks}.
%    \begin{macrocode}
\newcommand{\rtTokByNum}[2][\rt@BaseName]{\@nameuse{rtTok#2#1}\ignorespaces}
%    \end{macrocode}
%\DescribeMacro{\useRanTok} After \cs{ranToks} has been executed, the user has access to the
% randomized tokens through \cs{useRanTok}. The argument is an integer 1 through max.
%    \begin{macrocode}
\newcommand{\useRanTok}[2][\rt@BaseName]{\@nameuse{rtRanTok#2#1}}
%    \end{macrocode}
%    \begin{macrocode}
%</package>
%    \end{macrocode}
%\Finale
