From 910f589664407d620dc2a30c7b1de1a10e715df1 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Fri, 19 May 2017 21:06:02 +0000 Subject: ran_toks (19may17) git-svn-id: svn://tug.org/texlive/trunk@44429 c570f23f-e606-0410-a88d-b1316a301751 --- .../texmf-dist/source/latex/ran_toks/ran_toks.dtx | 519 ++++++++++++++------- 1 file changed, 340 insertions(+), 179 deletions(-) (limited to 'Master/texmf-dist/source/latex/ran_toks') diff --git a/Master/texmf-dist/source/latex/ran_toks/ran_toks.dtx b/Master/texmf-dist/source/latex/ran_toks/ran_toks.dtx index be22614b340..0a36c48614f 100644 --- a/Master/texmf-dist/source/latex/ran_toks/ran_toks.dtx +++ b/Master/texmf-dist/source/latex/ran_toks/ran_toks.dtx @@ -1,36 +1,10 @@ -% \iffalse meta-comment -%<*internal> -\iffalse -% -%<*internal> -\fi -\def\nameofplainTeX{plain} -\ifx\fmtname\nameofplainTeX\else - \expandafter\begingroup -\fi -% -%<*install> -\input docstrip.tex -\keepsilent -\askforoverwritefalse -\preamble -\endpreamble -\ifx\fmtname\nameofplainTeX -\generate{ - \file{\jobname.sty}{\from{\jobname.dtx}{copyright,package}} -} -\fi -% -%\endbatchfile -%<*internal> -\ifx\fmtname\nameofplainTeX - \expandafter\endbatchfile\else - \expandafter\endgroup\fi -% +%\iffalse +% makeindex -s gglo.ist -o ran_toks.gls ran_toks.glo +% makeindex -s gind.ist -o ran_toks.ind ran_toks.idx %<*copyright> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% ran_toks.sty package, 2013/08/03 %% -%% Copyright (C) 2012 D. P. Story %% +%% Web package, %% +%% Copyright (C) 1999-2017 D. P. Story %% %% dpstory@uakron.edu %% %% %% %% This program can redistributed and/or modified under %% @@ -40,74 +14,97 @@ %% License, or (at your option) any later version. %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % -%\NeedsTeXFormat{LaTeX2e} +%\NeedsTeXFormat{LaTeX2e}[1997/12/01] %\ProvidesPackage{ran_toks} -% [2016/02/06 v1.0e Randomizing tokens] +% [2017/05/04 v1.1 Randomizing tokens (dps)] %<*driver> \documentclass{ltxdoc} -%\usepackage{\jobname} -%\usepackage[numbered]{hypdoc} -%\EnableCrossrefs -%\CodelineIndex -%\RecordChanges +\usepackage[colorlinks,hyperindex=false]{hyperref} +%\def\texorpdfstring#1#2{#1} +%\pdfstringdefDisableCommands{\let\\\textbackslash} +\OnlyDescription % comment out for implementation details +\EnableCrossrefs +\CodelineIndex +\RecordChanges +\bgroup\ttfamily +\gdef\brpr#1{\char123\relax#1\char125\relax}\egroup +\let\darg\brpr +\let\env\texttt +\let\opt\texttt +\let\app\textsf +\def\visispace{\symbol{32}} +\def\ameta#1{\ensuremath{\langle\textit{\texttt{#1}}\rangle}} +\def\meta#1{\textsl{\texttt{#1}}} +\def\SUB#1{\ensuremath{{}_{\mbox{\scriptsize\ttfamily#1}}}} +\def\cs#1{\texttt{\bslash#1}} +\InputIfFileExists{aebdocfmt.def}{\PackageInfo{ran_toks}{Inputting aebdocfmt.def}} + {\def\IndexOpt{\DescribeMacro}\def\IndexKey{\DescribeMacro}\let\setupFullwidth\relax + \PackageInfo{ran_toks}{aebdocfmt.def cannot be found}} \begin{document} - \DocInput{\jobname.dtx} +\def\CMD#1{\textbackslash#1} +\let\pkg\textsf +\let\opt\texttt +\addtolength{\marginparwidth}{3pt} + \GetFileInfo{ran_toks.sty} + \title{The \textsf{ran\_toks} Package} + \author{D. P. Story\\ + Email: \texttt{dpstory@uakron.edu}} + \date{processed \today} + \maketitle + \tableofcontents + \DocInput{ran_toks.dtx} +\IfFileExists{\jobname.ind}{\newpage\setupFullwidth\par\PrintIndex}{\paragraph*{Index} The index goes here.\\Execute + \texttt{makeindex -s gind.ist -o ran\_toks.ind ran\_toks.idx} on the command line and recompile + \texttt{ran\_toks.dtx}.} +\IfFileExists{\jobname.gls}{\PrintChanges}{\paragraph*{Change History} The list of changes goes here.\\Execute + \texttt{makeindex -s gglo.ist -o ran\_toks.gls ran\_toks.glo} on the command line and recompile + \texttt{ran\_toks.dtx}.} \end{document} % % \fi -% -%\GetFileInfo{\jobname.sty} -% -%\title{The \textsf{ran\_toks} Package} -%\author{D. P. Story} -%\date{Released \today} -% -%\maketitle -% -%\StopEventually{^^A -% \PrintChanges -% \PrintIndex -%} +% \MakeShortVerb{|} +% \InputIfFileExists{aebdonotindex.def}{\PackageInfo{ran_toks}{Inputting aebdonotindex.def}} +% {\PackageInfo{ran_toks}{cannot find aebdonotindex.def}} % % \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{} -% { -% {tok_1}{tok_2}...{tok_n} +% takes one argument, which is a list of tokens: +%\begin{quote}\ttfamily +% \string\ranToks\darg{\ameta{name}}\\ +% \darg{\\\null +% \qquad\darg{\ameta{tok\SUB1}}\darg{\ameta{tok\SUB2}}...\darg{\ameta{tok\SUB{n}}}\\ % } -%\end{verbatim} +%\end{quote} % 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} +%\begin{quote}\ttfamily +%\cs{useRanTok\darg{1}}, \cs{useRanTok\darg{2}},..., \cs{useRanTok\darg{n}} +%\end{quote} % 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{} -%\begin{rtVW} -% -%\end{rtVW} -%... -%... -%\begin{rtVW} -% -%\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} +%\begin{quote}\ttfamily +%\string\bRTVToks\darg{\ameta{name}}\\ +%\string\begin\darg{rtVW}\\ +%\null\qquad\ameta{some content}\\ +%\string\end\darg{rtVW}\\ +%...\\ +%...\\ +%\string\begin\darg{rtVW}\\ +%\null\qquad\ameta{some content}\\ +%\string\end\darg{rtVW}\\ +%\string\eRTVToks +%\end{quote} +% The contents of each of the \texttt{rtVW} environments are written to the computers hard drive, then input +% back in random order, using \cs{useRanTok}, eg, +%\begin{quote}\ttfamily +%\cs{useRanTok\darg{1}}, \cs{useRanTok\darg{2}},..., \cs{useRanTok\darg{n}} +%\end{quote} % Other details are left to the readers' imagination. % % \paragraph{Requirements.} As of this writing, we require only the \texttt{verbatim} package @@ -115,7 +112,7 @@ % \begin{macrocode} \RequirePackage{verbatim} % \end{macrocode} -% Input \texttt{random.tex} if now already input. +% \paragraph*{Input \texttt{random.tex}.} Input \texttt{random.tex} if not already input. %\changes{v1.0d}{2013/08/03}{Added conditional input of random.tex} % \begin{macrocode} \@ifundefined{nextrandom}{\input{random.tex}}{} @@ -132,7 +129,7 @@ \nextrandom \nextrandom \nextrandom % \end{macrocode} % Save the initial seed value to \cs{rtInitSeedValue}. -% \changes{v1.0c}{2013/08/03}{Save the initial seed value to \cs{rtInitSeedValue}.} +% \changes{v1.0c}{2013/08/03}{Save the initial seed value to \string\cs{rtInitSeedValue}.} % \begin{macrocode} \xdef\InitSeedValue{\the\randomi}% \fi @@ -229,51 +226,50 @@ % We write only if \cs{ifsaveseed} is true. % \begin{macrocode} \def\InitSeedValue{\the\randomi} -\def\rt@writeSeedData{% - \ifsaveseed - \@ifundefined{saveseedinfo}{\newwrite\saveseedinfo}{} - \immediate\openout \saveseedinfo \jobname_rt.sav - \let\verbatim@out\saveseedinfo - \def\rt@msgi{initializing seed value}% - \def\rt@msgii{last random number used}% - \uccode`c=`\%\uppercase{% - \rt@IWVO{\InitSeedValue\space c \rt@msgi}% - \rt@IWVO{\the\randomi\space c \rt@msgii}% - }\immediate\closeout\saveseedinfo - \fi -} +\def\rt@writeSeedData{\ifsaveseed + \@ifundefined{saveseedinfo}{\newwrite\saveseedinfo}{} + \immediate\openout \saveseedinfo \jobname_rt.sav + \let\verbatim@out\saveseedinfo + \def\rt@msgi{initializing seed value}% + \def\rt@msgii{last random number used}% + \uccode`c=`\%\uppercase{% + \rt@IWVO{\InitSeedValue\space c \rt@msgi}% + \rt@IWVO{\the\randomi\space c \rt@msgii}}\immediate + \closeout\saveseedinfo\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}, +% \DescribeMacro{\rt@populateList}\hskip-\marginparsep|{|\ameta{n}|}| is a utility command, +% its argument \ameta{n} is a positive integer, % 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 +\def\rt@populateList#1{\rt@listIn={}\rt@nCnt\z@ + \@whilenum\rt@nCnt<#1\do{\advance\rt@nCnt\@ne \edef\rt@listInHold{\the\rt@listIn\noexpand\\{\the\rt@nCnt}}% - \rt@listIn=\expandafter{\rt@listInHold}% - }% -} + \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 +% \DescribeMacro{\rt@RandomizeList}\hskip-\marginparsep\thinspace|{|\ameta{n}|}| +% is the command that gets the process of randomizing +% the input list going. The argument is the number \ameta{n} 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={}% +\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} +% Save the list out as \cs{rt@BaseName-List} for later retrieval. This is the randomized +% list of integers for this base name. +% \changes{v1.1}{2017/05/04}{Save out list for later use} +% \begin{macrocode} + \global\rt@nameedef{\rt@BaseName-List}{\the\rt@listOut}} % \end{macrocode} % \DescribeMacro{\rt@randomizeList} randomizes the list of consecutive integers, and leaves the % results, @@ -283,17 +279,16 @@ % 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 +\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 + \rt@nCnt\z@ \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@loopTest{\advance\rt@nMax\m@ne + \ifnum\rt@nMax>\z@ \def\rt@next{% \rt@listIn=\expandafter{\the\rt@newListIn}% \rt@newListIn={}\rt@randomizeList}% @@ -309,7 +304,7 @@ % 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 +\def\rt@processi#1{\advance\rt@nCnt\@ne \ifnum\rt@nCnt=\rt@getRanNum \edef\rt@listOutHold{\the\rt@listOut}% \global\rt@listOut=\expandafter{\rt@listOutHold\\{#1}}% @@ -322,52 +317,94 @@ \fi } % \end{macrocode} +% We perform modular arithmetic when the index of \cs{useRanTok} is too large. +% \DescribeMacro{\rt@modarith}\cs{rt@modarith} performs modular arithmetic on its arguments (\texttt{\#1 mod \#2}) +% and returns the result in the macro \cs{rt@mod}. +% \begin{macrocode} +\def\rt@modarith#1#2{\count\z@=#1\relax\count\tw@=#1\relax +% \end{macrocode} +% This macro uses \cs{dimen0} and +% \cs{dimen2}, so it should be called within a group. +% \begin{macrocode} + \advance\count\z@\m@ne\divide\count\z@ #2\relax + \multiply\count\z@ #2\relax + \advance\count\tw@-\count\z@ + \edef\rt@mod{\the\count\tw@}} +% \end{macrocode} +% Warning messages, these are \DescribeMacro{\rt@badIndex}\cs{rt@badIndex} and +% \cs{rt@badTokName}\DescribeMacro{\rt@badTokName}. +% \begin{macrocode} +\def\rt@badIndex#1#2{\PackageWarningNoLine{ran_toks} + {The argument of \string\useRanTok{#1} on line + \the\inputlineno\space is\MessageBreak + greater than \string\nToksFor{#2} (\nToksFor{#2}), + instead will use\MessageBreak + \string\useRanTok{\rt@mod}, obtained from modular + arithmetic.\MessageBreak + You might want to fix this} +} +\def\rt@badTokName#1{% + \PackageWarningNoLine{ran_toks} + {The token list `#1' on line \the\inputlineno\space + is undefined,\MessageBreak + possibly simply mispelled; check spelling.\MessageBreak + If undefined, use \string\ranToks\space or \string\bRTVToks/% + \string\eRTVToks\space\MessageBreak + to define a list with the name `#1'}% +} +\def\rt@warnTokName#1{% + \PackageWarningNoLine{ran_toks} + {The token list `#1' on line \the\inputlineno\space + is already defined,\MessageBreak + will overwrite this list}% +} +% \end{macrocode} % \section{The main commands} -% \DescribeMacro{\ranToks} takes one argument, a list of tokens. It randomizes them. +% \begin{macro}{\ranToks}\hskip-\marginparsep\,\texttt{\darg{\ameta{token-list}}} +% takes one argument, \texttt{\darg{\ameta{token-list}}}, 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 -} +\long\def\r@nToks#1{\rt@nMax\z@\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}). +% \end{macro} +% \begin{macro}{\useRTName}\hskip-\marginparsep\,\texttt{\darg{\ameta{name}}} +% 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 +% \end{macro} +% \begin{macro}{\bRTVToks}\hskip-\marginparsep\,\texttt{\darg{\ameta{name}}} +% \cs{bRTVToks} and \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}% -} +\newcommand{\bRTVToks}[1]{\rt@nCnt\z@\useRTName{#1}} % \end{macrocode} +% \end{macro} +% \begin{macro}{\eRTVToks} % 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}% -} +\newcommand{\eRTVToks}{\global + \rt@nameedef{\rt@BaseName Cnt}{\the\rt@nCnt}% + \expandafter\r@nVToks\expandafter{\rt@BaseName}} % \end{macrocode} +% \end{macro} % \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 +\newenvironment{rtVW}{\global\advance\rt@nCnt\@ne \immediate\openout\rt@Verb@write \jobname_\rt@BaseName\the\rt@nCnt.cut \let\verbatim@out\rt@Verb@write @@ -386,21 +423,18 @@ \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}% -} + \@whilenum\rt@nCnt<\rt@nMax\do{\advance\rt@nCnt\@ne + \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}. -% \changes{v1.0e}{2016/02/06}{Fixed a bug, when the first two tokens \texttt{\#1} are the same, +% \changes{v1.0e}{2016/02/06}{Fixed a bug, when the first two tokens \string\texttt{\#1} are the same, % we get an incorrect decision} % \begin{macrocode} \def\rt@PAR{\par} @@ -409,74 +443,201 @@ % If the current argument is \cs{par}, we skip it % \begin{macrocode} \ifx\rt@rgi\rt@PAR\def\rt@next{\r@ndToks}\else - \advance\rt@nMax1\relax + \advance\rt@nMax\@ne \global\@namedef{rtTok\the\rt@nMax\rt@BaseName}{#1}% \def\rt@next{\@ifnextchar\rt@NIL - {\rt@endToks\@gobble}{\r@ndToks}}% - \fi\rt@next -} + {\rt@endToks\@gobble}{\r@ndToks}}\fi\rt@next} +% \end{macrocode} +% \hskip-\marginparsep|{|\ameta{n}|}| The \DescribeMacro{\rt@performRanDefns}\cs{rt@performRanDefns} performs code that +% is repeated in several other macros: \cs{rt@endToks}, \cs{reorderRanToks}, and +% \cs{copyRanToks}. It randomizes the list {\cs{rt@RandomizeList}, then assignments +% the randomized list to the definitions. +% \begin{macrocode} +\def\rt@performRanDefns#1{% +% \end{macrocode} +% Now we randomize the order of the integers 1, 2,\dots \texttt{\#1}. +% \begin{macrocode} + \rt@RandomizeList{#1}\rt@nCnt\z@ % \end{macrocode} -% The final destination for \cs{r@ndToks}. +% Now we randomize the definitions. We \verb!\let\\=\rt@ssign!, then +% let loose the tokens! +% \begin{macrocode} + \let\\\rt@ssign\the\rt@listOut} +% \end{macrocode} +% The final destination for \DescribeMacro{\rt@endToks}\cs{r@ndToks}. % \begin{macrocode} -\def\rt@endToks{% +\def\rt@endToks{\global % \end{macrocode} % Save the number of tokens counted % \begin{macrocode} - \global\rt@nameedef{nMax4\rt@BaseName}{\the\rt@nMax}% + \rt@nameedef{nMax4\rt@BaseName}{\the\rt@nMax}% + \rt@performRanDefns{\the\rt@nMax}\endgroup} % \end{macrocode} -% Now we randomize the order of the integers 1, 2,\dots\cs{rt@nMax}. +% \begin{macro}{\reorderRanToks}\hskip-\marginparsep\,\texttt{\darg{\ameta{name}}} +% The \cs{reorderRanToks} command reorders (or re-indexes) +% the family with name \ameta{name} (\texttt{\#1}). % \begin{macrocode} - \rt@RandomizeList{\the\rt@nMax}% - \rt@nCnt=0 +\def\reorderRanToks#1{\begingroup\useRTName{#1}\expandafter + \ifx\csname nMax4#1\endcsname\relax % \end{macrocode} -% Now we randomized the definitions. We \verb!\let\\=\assignRanToks!, then -% let loose the tokens! +% Document author has not run \cs{ranToks} yet for this basename (\texttt{\#1}) % \begin{macrocode} - \let\\\assignRanToks - \the\rt@listOut - \endgroup -} + \rt@badTokName{#1}\else +% \end{macrocode} +% Good to go. We reorder this list. +% \begin{macrocode} + \rt@performRanDefns{\@nameuse{nMax4#1}}\fi +\endgroup} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\copyRanToks}\hskip-\marginparsep +% \texttt{\darg{\ameta{name1}}\darg{\ameta{name2}}} +% Use this command to copy \ameta{name1} to \ameta{name2}. This gives +% a randomization of the same list, without affecting the original order of \ameta{name1}. +% \begin{macrocode} +\newcommand\copyRanToks[2]{\begingroup\expandafter + \ifx\csname nMax4#1\endcsname\relax +% \end{macrocode} +% Source list is not defined +% \begin{macrocode} + \rt@badTokName{#1}% + \else\expandafter +% \end{macrocode} +% Source list is defined +% \begin{macrocode} + \ifx\csname nMax4#2\endcsname\relax +% \end{macrocode} +% Destination list is not defined, which is good in this instance. This is +% the case we copy the list. +% \begin{macrocode} + \useRTName{#2}\global + \rt@nameedef{nMax4#2}{\@nameuse{nMax4#1}}% + \rt@nCnt=\csname nMax4#2\endcsname\relax + \@whilenum\rt@nCnt>\z@\do{\global + \rt@nameedef{rtTok\the\rt@nCnt#2}% + {\noexpand\@nameuse{rtTok\the\rt@nCnt#1}}% + \advance\rt@nCnt\m@ne}% + \rt@performRanDefns{\@nameuse{nMax4#2}}\else +% \end{macrocode} +% Destination list is defined already, warn the user. +% \begin{macrocode} + \rt@warnTokName{#2}\fi + \fi +\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 +% \end{macro} +%\DescribeMacro{\rt@ssign}\hskip-\marginparsep\texttt{\darg{\ameta{name}}} makes the assignments that are expanded by \cs{useRanTok}. +% We \cs{let} the assignment \verb!\let\\=\rt@ssign! 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\@nameuse{rtTok#1\rt@BaseName}}% -% {\noexpand\rtTokByNum[\rt@BaseName]{#1}}% -} +\def\rt@ssign#1{\advance\rt@nCnt\@ne\global + \rt@nameedef{rtRanTok\the\rt@nCnt\rt@BaseName}{\noexpand + \@nameuse{rtTok#1\rt@BaseName}}} % \end{macrocode} % \subsection{Additional user access commands} -% \DescribeMacro{\nToksFor} expands the the number of tokens whose name is \texttt{\#1}. +% \DescribeMacro{\nToksFor}\hskip-\marginparsep\texttt{\darg{\ameta{name}}} +% expands the the number of tokens whose name is \ameta{name} (\texttt{\#1}). % \begin{macrocode} -\newcommand{\nToksFor}[1]{\@nameuse{nMax4#1}} +\newcommand{\nToksFor}[1]{\expandafter + \ifx\csname nMax4#1\endcsname\relax + \textbf{??}\rt@badTokName{#1}\else + \@nameuse{nMax4#1}\fi} % \end{macrocode} -% \DescribeMacro{\rtTokByNum} is an internal macro, but it can be used publicly. +% \DescribeMacro{\rtTokByNum}\hskip-\marginparsep\texttt{[\ameta{name}]\darg{\ameta{num}}} 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} +\newcommand{\rtTokByNum}[2][\rt@BaseName]{\expandafter + \ifx\csname nMax4#1\endcsname\relax + \textbf{??}\rt@badTokName{#1}\else + \@nameuse{rtTok#2#1}\expandafter\ignorespaces\fi} +% \end{macrocode} +%\DescribeMacro{\useRanTok}\hskip-\marginparsep\texttt{[\ameta{name}]\darg{\ameta{num}}} +% After \cs{ranToks} has been executed, the user has access to the +% randomized tokens through \cs{useRanTok}. The argument \ameta{num} is an integer 1 through max. +% \begin{macrocode} +\newcommand{\useRanTok}[2][\rt@BaseName]{\bgroup + \expandafter\ifx\csname nMax4#1\endcsname\relax + \rt@badTokName{#1}\else + \ifnum#2>\nToksFor{#1}\rt@modarith{#2}{\nToksFor{#1}}% % \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. +% If index (\texttt{\#2}) is greater than array length, use modular arithmetic to resolve +% the issue, and send a warning to the user. +% \changes{v1.1}{2017/05/04}{Add modular arithmetic to resolve case where index is greater than length} % \begin{macrocode} -\newcommand{\useRanTok}[2][\rt@BaseName]{\@nameuse{rtRanTok#2#1}} + \rt@badIndex{#2}{#1}\@nameuse{rtRanTok\rt@mod#1}\else + \@nameuse{rtRanTok#2#1}\fi\fi\egroup} % \end{macrocode} -% \DescribeMacro{\displayListRandomly} lists all items in the list as passed +% \DescribeMacro{\displayListRandomly}\hskip-\marginparsep\texttt{[\ameta{prior}][\ameta{post}]\darg{\ameta{name}}} +% lists all items in the list as passed % by the required argument. For expanding in a list environment, use \cs{item} as % the optional argument. Designed for listing all question in an eqexam % document in random order. -%\changes{v1.0b}{2013/07/29}{Added \cs{displayListRandomly}} -%\changes{v1.0e}{2016/02/06}{Added optional argument to \cs{displayListRandomly}} -% \begin{macrocode} -\newcommand{\displayListRandomly}[2][]{\rt@nCnt=0\relax - \@whilenum\rt@nCnt<\nToksFor{#2}\advance\rt@nCnt1\relax - \do{#1\useRanTok{\the\rt@nCnt}}% +%\changes{v1.0b}{2013/07/29}{Added \string\cs{displayListRandomly}} +%\changes{v1.0e}{2016/02/06}{Added optional argument to \string\cs{displayListRandomly}} +%\changes{v1.1}{2017/05/04}{Added second optional argument to \string\cs{displayListRandomly}} +% \begin{macrocode} +\newcommand{\displayListRandomly}[1][]{\bgroup\def\rt@prior{#1}% + \displ@yListRandomly} +\newcommand{\displ@yListRandomly}[2][]{\rt@nCnt\z@ + \expandafter\ifx\csname nMax4#2\endcsname\relax + \rt@rgi\space\textbf{??}\rt@badTokName{#2}#1% + \else +% \end{macrocode} +% Within the optional arguments, we define \DescribeMacro{\i}\cs{i}, +% \DescribeMacro{\first}\cs{first}, \DescribeMacro{\last}\cs{last}, and +% \DescribeMacro{\lessone}\cs{lessone} to do some logic on the arguments. +% These four macro are defined locally and not available outside the command +% \cs{displayListRandomly}. +% \begin{macrocode} + \def\rt@post{#1}\useRTName{#2}\let\i\rt@nCnt + \def\first{1}\edef\last{\@nameuse{nMax4#2}}% + \@tempcnta\last \advance\@tempcnta\m@ne + \edef\lessone{\the\@tempcnta}% + \@whilenum\rt@nCnt<\last\advance\rt@nCnt\@ne + \do{\rt@prior\useRanTok{\the\rt@nCnt}\rt@post}% + \fi\egroup } % \end{macrocode} +% \section{Commands that support a DB application} +% We begin with some utility commands to help parse the argument of \cs{useProbDBs}. +% \begin{macrocode} +\def\rt@gettonil#1\@nil{\def\to@nilarg{#1}} +\def\rt@ifspc{\ifx\@let@token\@sptoken + \let\rt@next\rt@xifspc\else + \let\rt@next\rt@gettonil\fi\rt@next} +\begingroup +\def\:{\rt@xifspc} +\expandafter\gdef\: {\futurelet\@let@token\rt@ifspc} +\endgroup +\def\rt@strpspcs{\futurelet\@let@token\rt@ifspc} +% \end{macrocode} +% \begin{macro}{\useTheseDBs}\hskip-\marginparsep\thinspace|{|\ameta{list}|}| +% Inputs any files included in the comma-delimited list. The base names need only be listed, +% as the extension is assumed to be \texttt{.tex}. The command \cs{useProbDBs} can only be used +% in the preamble. Refer to the demo file \texttt{mc\_db.tex} for an illustration of its intended use. +% \begin{macrocode} +\def\ProbDBWarningMsg#1{\filename@parse{#1} + \PackageWarning{ran_toks} + {The file \filename@area\filename@base.\ifx\filename@ext\relax + tex\else\filename@ext\fi\space cannot be found}} +\def\useTheseDBs#1{\def\rt@dblist{#1}\ifx\rt@dblist\@empty\else + \let\rt@DB@List\@empty + \edef\temp@expand{\noexpand\@for\noexpand\@@tmp:=\rt@dblist}% + \temp@expand\do{\ifx\@@tmp\@empty\else + \expandafter\rt@strpspcs\@@tmp\@nil\edef\@@tmp{\to@nilarg}% + \edef\rt@nextDB{\noexpand + \InputIfFileExists{\@@tmp}{}{\noexpand + \ProbDBWarningMsg{\@@tmp}}}% + \toks\tw@=\expandafter{\rt@DB@List}% + \toks@=\expandafter{\rt@nextDB}% + \edef\rt@DB@List{\the\toks\tw@\space\the\toks@}\fi + }\expandafter\rt@DB@List\fi} +\let\useProbDBs\useTheseDBs +% \end{macrocode} +% \end{macro} % \begin{macrocode} % % \end{macrocode} -%\Finale +% \Finale +\endinput -- cgit v1.2.3