diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/ran_toks |
Initial commit
Diffstat (limited to 'macros/latex/contrib/ran_toks')
-rw-r--r-- | macros/latex/contrib/ran_toks/README.md | 52 | ||||
-rw-r--r-- | macros/latex/contrib/ran_toks/doc/rantoks_man.pdf | bin | 0 -> 224675 bytes | |||
-rw-r--r-- | macros/latex/contrib/ran_toks/doc/rantoks_man.tex | 683 | ||||
-rw-r--r-- | macros/latex/contrib/ran_toks/examples/db1.tex | 76 | ||||
-rw-r--r-- | macros/latex/contrib/ran_toks/examples/db2.tex | 65 | ||||
-rw-r--r-- | macros/latex/contrib/ran_toks/examples/db3.tex | 65 | ||||
-rw-r--r-- | macros/latex/contrib/ran_toks/examples/db4.tex | 65 | ||||
-rw-r--r-- | macros/latex/contrib/ran_toks/examples/mc-db.tex | 75 | ||||
-rw-r--r-- | macros/latex/contrib/ran_toks/examples/mytext.verb | 1 | ||||
-rw-r--r-- | macros/latex/contrib/ran_toks/examples/ran_toks.tex | 95 | ||||
-rw-r--r-- | macros/latex/contrib/ran_toks/examples/random_tst.tex | 103 | ||||
-rw-r--r-- | macros/latex/contrib/ran_toks/examples/random_tst_qz.tex | 115 | ||||
-rw-r--r-- | macros/latex/contrib/ran_toks/ran_toks.dtx | 643 | ||||
-rw-r--r-- | macros/latex/contrib/ran_toks/ran_toks.sty | 302 |
14 files changed, 2340 insertions, 0 deletions
diff --git a/macros/latex/contrib/ran_toks/README.md b/macros/latex/contrib/ran_toks/README.md new file mode 100644 index 0000000000..6e47bf5109 --- /dev/null +++ b/macros/latex/contrib/ran_toks/README.md @@ -0,0 +1,52 @@ +The ran_toks Package +Author: D. P. Story +Dated: 2017/05/04 + +This short package, with minimal requirements, defines macros for +randomizing a list of tokens. There are two approaches: + + 1. \ranToks{myList}{ {One}{Two}{Three}{Four}{Five} }: Here the token + list occurs as the argument of the \ranToks command. myList is the + name of this list. The tokens can be anything that \TeX accepts as + a macro argument, this excludes \verb, for example. + + 2. Another construct writes verbatim to the disk, so the tokens can + be of arbitrary size, and include \verb and the verbatim + environment, for example, + + \bRTVToks{myStuff} + \begin{rtVW} + The inline answer is \verb!x^3! + \end{rtVW} + \begin{rtVW} + This is my stuff, leave it alone! + \end{rtVW} + ... + \begin{rtVW} + The verbatim listing is + \begin{verbatim} + \bRTVToks{myStuff} + ... (missing stuff) + \eRTVToks + \end{verbatim} + \end{rtVW} + \eRTVToks + +To actually see the randomized list, use the \useRanTok{num} command: For +myList, we would write \useRanTok{1}, \useRanTok{2}, \useRanTok{3}, +\useRanTok{4}, and {\useRanTok{5}} to obtain a random listing of the +tokens in the myList list. + +For users of AeB or eqexam, the latter structure can be used to randomize +the order of the questions on a quiz or exam. + +What's new in v1.1: Added the convenience command \useTheseDBs to input files for +an application to constructing exams (using eqexam) from a series of DB files. Refer to the +new demo file mc-db.tex. + +Enjoy! + +Now, I must get back to my retirement. + +dps + diff --git a/macros/latex/contrib/ran_toks/doc/rantoks_man.pdf b/macros/latex/contrib/ran_toks/doc/rantoks_man.pdf Binary files differnew file mode 100644 index 0000000000..66c8f3cbfd --- /dev/null +++ b/macros/latex/contrib/ran_toks/doc/rantoks_man.pdf diff --git a/macros/latex/contrib/ran_toks/doc/rantoks_man.tex b/macros/latex/contrib/ran_toks/doc/rantoks_man.tex new file mode 100644 index 0000000000..2776e3863d --- /dev/null +++ b/macros/latex/contrib/ran_toks/doc/rantoks_man.tex @@ -0,0 +1,683 @@ +\documentclass{article} +\usepackage[fleqn]{amsmath} +\usepackage[ + web={centertitlepage,designv,forcolorpaper, + latextoc,pro}, %tight, + eforms,aebxmp +]{aeb_pro} +\usepackage{ran_toks} + +\useThisSeed{1441984427} +%\useLastAsSeed +%\useThisSeed{2001383846} + +%2001383846 % initializing seed value +%1629639958 % last random number used + +\let\pkg\textsf +\let\env\texttt + +%\rtdebugtrue +%\ranToksOn +%\ranToksOff + + +%\usepackage{myriadpro} +\usepackage[altbullet]{lucidbry} + +%\usepackage{makeidx} +%\makeindex +\usepackage{acroman} + +\makeatletter +\def\eq@fititin#1{\noindent\unskip\nobreak\hfill\penalty50 + \hskip2em\hbox{}\nobreak\hfill#1} +\def\fitit{\eq@fititin{\exrtnlabelformat}} +\@mparswitchfalse\reversemarginpar +\renewcommand{\paragraph} + {\@startsection{paragraph}{4}{0pt}{6pt}{-3pt} + {\normalfont\normalsize\bfseries}} +\renewcommand{\subparagraph} + {\@startsection{subparagraph}{5}{\parindent}{6pt}{-3pt}% + {\normalfont\normalsize\bfseries}} +\makeatother + +\def\anglemeta#1{$\langle\textit{\texttt{#1}}\rangle$} +\let\ameta\anglemeta +\def\meta#1{\textit{\texttt{#1}}} +\def\darg#1{\texttt{\{#1\}}} +\def\takeMeasure{\bgroup\obeyspaces\takeMeasurei} +\def\takeMeasurei#1{\global\setbox\webtempboxi\hbox{\ttfamily#1}\egroup} +\def\bxSize{\wd\webtempboxi+2\fboxsep+2\fboxrule} + +\usepackage[active]{srcltx} + +\let\amtIndent\leftmargini +\def\SUB#1{${}_{\text{#1}}$} + +\newdimen\aebdimen \aebdimen\topsep +\newcommand\bVerb[1][]{\begingroup#1\vskip\aebdimen\parindent0pt}% +\def\eVerb{\vskip\aebdimen\endgroup\noindent} + + +\urlstyle{rm} + +\DeclareDocInfo +{ + university={\AcroTeX.Net}, + title={\texorpdfstring{The \textsf{ran\_toks}}{The manual for the ran\_toks} + Package\texorpdfstring{\\[6pt]\large}{: } + Randomizing the order of tokens}, + author={D. P. Story}, + email={dpstory@acrotex.net}, + subject=Documentation for the ran\_toks package, + talksite={\url{www.acrotex.net}}, + version={1.1}, + Keywords={LaTeX,PDF,random, tokens, JavaScript,Adobe Acrobat}, + copyrightStatus=True, + copyrightNotice={Copyright (C) \the\year, D. P. Story}, + copyrightInfoURL={http://www.acrotex.net} +} +\DeclareInitView{windowoptions={showtitle}} + + +\def\dps{$\hbox{$\mathfrak D$\kern-.3em\hbox{$\mathfrak P$}% + \kern-.6em \hbox{$\mathcal S$}}$} + +\universityLayout{fontsize=Large} +\titleLayout{fontsize=LARGE} +\authorLayout{fontsize=Large} +\tocLayout{fontsize=Large,color=aeb} +\sectionLayout{indent=-62.5pt,fontsize=large,color=aeb} +\subsectionLayout{indent=-31.25pt,color=aeb} +\subsubsectionLayout{indent=0pt,color=aeb} +\subsubDefaultDing{\texorpdfstring{$\bullet$}{\textrm\textbullet}} + +\def\exSrc{\makebox[0pt][r]{\large{\Pisymbol{webd}{157}}\enspace}} + +%\pagestyle{empty} +%\parindent0pt\parskip\medskipamount + +\chngDocObjectTo{\newDO}{doc} +\begin{docassembly} +var titleOfManual="The ran_toks Package"; +var manualfilename="Manual_BG_Print_rt.pdf"; +var manualtemplate="Manual_BG_Brown.pdf"; // Blue, Green, Brown +var _pathToBlank="C:/Users/Public/Documents/ManualBGs/"+manualtemplate; +var doc; +var buildIt=false; +if ( buildIt ) { + console.println("Creating new " + manualfilename + " file."); + doc = \appopenDoc({cPath: _pathToBlank, bHidden: true}); + var _path=this.path; + var pos=_path.lastIndexOf("/"); + _path=_path.substring(0,pos)+"/"+manualfilename; + \docSaveAs\newDO ({ cPath: _path }); + doc.closeDoc(); + doc = \appopenDoc({cPath: manualfilename, oDoc:this, bHidden: true}); + f=doc.getField("ManualTitle"); + f.value=titleOfManual; + doc.flattenPages(); + \docSaveAs\newDO({ cPath: manualfilename }); + doc.closeDoc(); +} else { + console.println("Using the current "+manualfilename+" file."); +} +var _path=this.path; +var pos=_path.lastIndexOf("/"); +_path=_path.substring(0,pos)+"/"+manualfilename; +\addWatermarkFromFile({ + bOnTop:false, + bOnPrint:false, + cDIPath:_path +}); +\executeSave(); +\end{docassembly} + +%\definePath\bgPath{"C:/Users/Public/Documents/% +% ManualBGs/Manual_BG_Print_AeB.pdf"} +%\begin{docassembly} +%\addWatermarkFromFile({% +% bOnTop: false, +% cDIPath: \bgPath +%}) +%\executeSave() +%\end{docassembly} + +\begin{document} + +\maketitle + +\selectColors{linkColor=black} +\tableofcontents +\selectColors{linkColor=webgreen} + +\section{Introduction} + +This is a short package for randomizing the order of tokens. The package +is long overdue; users of \textbf{AeB} and of \textsf{eqexam} have long asked for a way to +randomize the order of the problems in a test or quiz, or anything for +that matter. + +\newtopic\noindent\exSrc The \texttt{examples} folder contains three demonstration files: +\begin{enumerate} + \item \texttt{ran\_toks.tex} reproduces the sample code of this manual. + \item \texttt{random\_tst.tex} shows how to use \pkg{ran\_toks} to + randomize the \emph{questions} of an exam document created by the + \pkg{eqexam} package. + \item \texttt{random\_tst\_qz.tex} shows how to randomize choices of a + multiple choice field in a \env{quiz} environment of the + \pkg{exerquiz} package, when the choices contain verbatim text. + \item \texttt{mc-db.tex} is an \pkg{eqexam} file that draws from the + database files \texttt{db1.tex}, \texttt{db2.tex}, + \texttt{db3.tex}, and \texttt{db4.tex}, to construct the questions + of the exam. The questions are drawn at random from the DB files. Refer + to \hyperref[s:DBConcept]{Section~\ref*{s:DBConcept}} for a few more details. + +\end{enumerate} + +\section{The Preamble and Package Options} + +The preamble for this package is +\bVerb\takeMeasure{\string\usepackage\darg{ran\_toks}}% +\begin{minipage}{\bxSize}\kern0pt +\begin{Verbatim}[frame=single] +\usepackage{ran_toks} +\end{Verbatim} +\end{minipage}\eVerb +The package itself has no options. + +The requirements for \textsf{ran\_toks} are the \textsf{verbatim} package +(part of the standard {\LaTeX} distribution, and the macro file +\texttt{random.tex} by Donald Arseneau. + + +\section{The main commands and environments}\label{rtmain} + +There are two styles for defining a series of tokens to be randomized, +using either the \cs{ranToks} command or the \cs{bRTVToks}/\cs{eRTVToks} +pair. Each of these is discussed in the next two subsections. + +\subsection{The \texorpdfstring{\protect\cs{ranToks}}{\CMD{ranToks}} command} + +The \cs{ranToks} command was the original concept; declare a series of +tokens to be randomized. +\bVerb\takeMeasure{\string\ranToks\darg{\meta{name}}\{\%\enspace}% +\begin{minipage}{\bxSize}\kern0pt +\begin{Verbatim}[frame=single,commandchars=!()] +\ranToks{!meta(name)}{% + {!meta(token!SUB(1))} + {!meta(token!SUB(2))} + ... + {!meta(token!SUB(n))} +} +\end{Verbatim} +\end{minipage}\eVerb +were \meta{token\SUB{k}} is any non-verbatim content;\footnote{Any token that +can be in the argument of a command.} each token is enclosed in braces +(\darg{}), this is required. The \meta{name} parameter is required, and +must be unique for the document; it is used to build the names of internal +macros. Of course several such \cs{ranToks} can be used in the document, +either in the preamble or in the body of the document. Multiple +\cs{ranToks} commands must have a different \meta{name} parameter. + +\emph{After} a \cs{ranToks} command has been executed, the number of tokens +counted is accessible through the \cs{nToksFor} command, +\bVerb\takeMeasure{\string\nToksFor\darg{\meta{name}}}% +\begin{minipage}{\bxSize}\kern0pt +\begin{Verbatim}[frame=single,commandchars=!()] +\nToksFor{!meta(name)} +\end{Verbatim} +\end{minipage}\eVerb +The one argument is \meta{name}, and will expand to the total number +of tokens listing as argument in the \cs{ranToks} command by the same +name. + +The \cs{ranToks} command does not display the randomized tokens, for that +the command \cs{useRanTok} is used. +\bVerb\takeMeasure{\string\useRTName\darg{\meta{name}}}% +\begin{minipage}{\bxSize} +\begin{Verbatim}[frame=single,commandchars=!()] +\useRanTok{!meta(num)} +\useRTName{!meta(name)} +\end{Verbatim} +\end{minipage}\eVerb +The argument of \cs{useRanTok} is a positive integer between 1 and +\cs{nToksFor\darg{\meta{name}}}, the number of tokens declared by +\cs{ranToks}, inclusive. There is no space created following the +\cs{useRanTok} command, so if these are to be used ``inline'', enclose them +in braces (\darg{}), for example, \darg{\cs{useRanTok\darg{1}}}. The use of +\cs{useRTName} is optional unless the listing of the \cs{useRanTok} commands +is separated from the \cs{ranToks} command that defined them by another +\cs{ranToks} command of a different name. That should be clear! + +Consider this example. + +\begin{Verbatim}[xleftmargin=\amtIndent] +\ranToks{myPals}{% + {Jim}{Richard}{Don} + {Alex}{Tom}{J\"{u}rgen} +} +\end{Verbatim} +\ranToks{myPals}{% + {Jim}{Richard}{Don} + {Alex}{Tom}{J\"{u}rgen} +} +I have {\nToksFor{myPals}} pals, they are \useRanTok{1}, \useRanTok{2}, +\useRanTok{3}, \useRanTok{4}, {\useRanTok{5}} and \useRanTok{6}. (Listed +in the order of best friend to least best friend.) +The verbatim listing is, +\begin{Verbatim}[xleftmargin=\amtIndent] +I have {\nToksFor{myPals}} pals, they are \useRanTok{1}, +\useRanTok{2}, \useRanTok{3}, \useRanTok{4}, {\useRanTok{5}} +and \useRanTok{6}. +\end{Verbatim} +Notice that \cs{useRanToks} are not enclosed in braces for 1--4 because +they are each followed by a comma; the fifth token, \texttt{\darg{\cs{useRanTok\darg{5}}}}, is +enclosed in braces to generate a space following the insertion of the text. + +Repeating the sentence yields, ``I have {\nToksFor{myPals}} pals, they are +\useRanTok{1}, \useRanTok{2}, \useRanTok{3}, \useRanTok{4}, +{\useRanTok{5}} and \useRanTok{6}'', which is the exact same random order. To +obtain a different order, re-execute the \cs{ranToks} command with the same +arguments.\footnote{{\ttfamily\string\ranToks\darg{myPals}\darg{\darg{Jim}\darg{Richard}\darg{Don}\darg{Alex}\darg{Tom}\darg{J\string\"\darg{u}rgen}}} in this example.} Doing just that, \ranToks{myPals}{{Jim}{Richard}{Don} +{Alex}{Tom}{J\"{u}rgen}}we obtain, ``I have {\nToksFor{myPals}} pals, they +are \useRanTok{1}, \useRanTok{2}, \useRanTok{3}, \useRanTok{4}, +{\useRanTok{5}} and \useRanTok{6}.'' A new order? +An alternative to re-executing \cs{ranToks} is to use the \cs{reorderRanToks} command: +\bVerb\takeMeasure{\string\reorderRanToks\darg{\meta{name}}}% +\begin{minipage}{\bxSize}\kern0pt +\begin{Verbatim}[frame=single,commandchars=!()] +\reorderRanToks{!meta(name)} +\end{Verbatim} +\end{minipage}\eVerb Now, executing \verb~\reorderRanToks{myPals}~ and compiling the sentence again yields, +``I have {\nToksFor{myPals}} pals, they are +\useRanTok{1}, \useRanTok{2}, \useRanTok{3}, \useRanTok{4}, +{\useRanTok{5}} and \useRanTok{6}.'' For most applications, re-randomizing +the same token list in the same document is not very likely something you +need to do. + +The \cs{reorderRanToks\darg{\meta{name}}} rearranges the list of tokens +associated with \ameta{name}, which may not be what you want; the +\cs{copyRanToks} command, on the other hand, makes a (randomized) copy of its +first required argument \ameta{name\SUB1} and saves it as \ameta{name\SUB2}, without +effecting the order of \ameta{name\SUB1}. +\bVerb\takeMeasure{\string\copyRanToks\darg{\ameta{name\SUB1}}\darg{\ameta{name\SUB2}}}% +\begin{minipage}{\bxSize}\kern0pt +\begin{Verbatim}[frame=single,commandchars=!()] +\copyRanToks{!ameta(name!SUB1)}{!ameta(name!SUB2)} +\end{Verbatim} +\end{minipage}\eVerb Thus, if \verb!\copyRanToks{myPals}{myPals1}! is executed, the token list name +\texttt{myPals1} contains the names of my pals in another randomized order, +while maintaining the same order of \texttt{myPals}. + + +\newtopic +My original application for this, the one that motivated writing this +package at long last, was the need to arrange several form buttons +randomly on the page. My point is that the listing given in the argument +of \cs{ranToks} can pretty much be anything that is allowed to be an +argument of a macro; this would exclude verbatim text created by \cs{verb} +and verbatim environments. + +\subsection{The +\texorpdfstring{\protect\cs{bRTVToks}/\protect\cs{eRTVToks}} + {\CMD{bRTVToks}/\CMD{eRTVToks}} pair of commands}\label{ss:RTVToks} + +Sometimes the content to be randomized is quite large or contains verbatim +text. For this, it may be more convenient to use the +\cs{bRTVToks}/\penalty0\cs{eRTVToks} command pair. The syntax is +\bVerb\takeMeasure{\string\bRTVToks\darg{\meta{name}}\quad}% +\edef\WIDTH{\the\wd\webtempboxi}% +\def\1{\rlap{\hspace*{\WIDTH}\texttt{\% <-{\sffamily{ End token listing}}}}}% +\takeMeasure{\string\bRTVToks\darg{\meta{name}}\quad\% <-{\sffamily{ Begin token listing}}}% +\begin{minipage}{\bxSize}\kern0pt +\begin{Verbatim}[frame=single,commandchars=!()] +\bRTVToks{!meta(name)}!quad% <-!sffamily( Begin token listing) +\begin{rtVW} +!qquad!ameta(content!SUB(1)) +\end{rtVW} +... +... +\begin{rtVW} +!qquad!ameta(content!SUB(n)) +\end{rtVW} +!1\eRTVToks +\end{Verbatim} +\end{minipage}\eVerb +The \cs{bRTVToks}\texttt{\{\meta{name}\}} command begins the (pseudo) +environment and is ended by \cs{eRTVToks}. Between these two are a series of +\texttt{rtVW} (random toks verbatim write) environments. When the document is +compiled, the contents (\ameta{content\SUB{i}}) of each of these environments +are written to the computer hard drive and saved under a different name +(based on the parameter \meta{name}). Later, using the \cs{useRanTok} +commands, they are input back into the document in a random order. + +The use of \cs{useRTName} and \cs{useRanTok} were explained and illustrated +in the previous section. Let's go to the examples, +\begin{Verbatim}[xleftmargin=\amtIndent] +\bRTVToks{myThoughts} +\begin{rtVW} +\begin{minipage}[t]{.67\linewidth} +Roses are red and violets are blue, +I've forgotten the rest, have you too? +\end{minipage} +\end{rtVW} +\begin{rtVW} +\begin{minipage}[t]{.67\linewidth} +I gave up saying bad things like +\verb!$#%%%^*%^&#$@#! when I was just a teenager. +\end{minipage} +\end{rtVW} +\begin{rtVW} +\begin{minipage}[t]{.67\linewidth} +I am a good guy, pass it on! The code for this last sentence is, +\begin{verbatim} +%#$% I am a good guy, pass it on! ^&*&^* +\end{verbatim} +How did that other stuff get in there? +\end{minipage} +\end{rtVW} +\eRTVToks +\end{Verbatim} +OK, now, let's display these three in random order. Here we place them in +an \texttt{enumerate} environment. + +\bRTVToks{myThoughts}% +\begin{rtVW} +\begin{minipage}[t]{.67\linewidth} +Roses are red and violets are blue, +I've forgotten the rest, have you too? +\end{minipage} +\end{rtVW} +\begin{rtVW} +\begin{minipage}[t]{.67\linewidth} +I gave up saying bad things like +\verb!$#%%%^*%^&#$@#! when I was just a teenager. +\end{minipage} +\end{rtVW} +\begin{rtVW} +\begin{minipage}[t]{.67\linewidth} +I am a good guy, pass it on! The code for this last sentence is, +\begin{verbatim} +%#$% I am a good guy, pass it on! ^&*&^* +\end{verbatim} +How did that other stuff get in there? +\end{minipage} +\end{rtVW} +\eRTVToks +\begin{enumerate} + \item \useRanTok{1} + \item \useRanTok{2} + \item \useRanTok{3} +\end{enumerate} +The verbatim listing of the example above is +\begin{Verbatim}[xleftmargin=\amtIndent] +\begin{enumerate} + \item \useRanTok{1} + \item \useRanTok{2} + \item \useRanTok{3} +\end{enumerate} +\end{Verbatim} +The \cs{reorderRanToks} works for lists created by the \cs{bRTVToks}/\penalty0\cs{bRTVToks} construct. +If we say \cs{reorderRanToks\darg{myThoughts}} and reissue the above list, we obtain, +\begin{enumerate}\ranToksOn\reorderRanToks{myThoughts} + \displayListRandomly[\item]{myThoughts} +\end{enumerate} +The command \cs{copyRanToks} works for list created by +\cs{bRTVToks}/\penalty0\cs{bRTVToks} as well. + + +\paragraph*{On the \cs{displayListRandomly} command.}\label{para:DLR} +In the enumerate example immediately above, the items in the list are +explicitly listed as \cs{item \cs{useRanTok\darg{1}}} and so one; an +alternate approach is to use the command \cs{displayListRandomly}, like so, +\begin{Verbatim}[xleftmargin=\amtIndent] +\begin{enumerate} + \displayListRandomly[\item]{myThoughts} +\end{enumerate} +\end{Verbatim} +The full syntax for \cs{displayListRandomly} is displayed next. +\bVerb\takeMeasure{\string\displayListRandomly[\ameta{prior}][\ameta{post}]\darg{\meta{name}}}% +\begin{minipage}{\bxSize}\kern0pt +\begin{Verbatim}[frame=single,commandchars=!()] +\displayListRandomly[!ameta(prior)][!ameta(post)]{!meta(name)} +\end{Verbatim} +\end{minipage} +\eVerb The action of \cs{displayListRandomly} is to expand all tokens that +are listed in the \meta{name} token list, each entry is displayed as +\ameta{prior}\cs{useRanTok\darg{i}}\ameta{post}, where \texttt{i} +goes from~1 to \cs{nToksFor\darg{\meta{name}}}. In the example above, +\meta{prior} is \cs{item}, but normally, its default is empty. The defaults +for \ameta{prior} and \ameta{post} are both empty. + +\subparagraph*{The optional arguments.} When only one optional argument is present, +if is interpreted as \ameta{prior}. To obtain a \ameta{post} with no \ameta{prior} +use the syntax, +\begin{quote} +\cs{displayListRandomly[][\ameta{post}]\darg{\ameta{name}}} +\end{quote} +Within \emph{each optional argument}, the four commands \cs{i}, +\cs{first}, \cs{last}, and \cs{lessone} are (locally) defined. The \cs{i} command is the index +counter of the token currently being typeset; \cs{first} is the index of the +first item; \cs{last} is the index of the last item; and \cs{lessone} is one +less than \cs{last}. The two optional arguments and the four commands may use +to perform logic on the token as it is being typeset. For example: +\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small] +List of pals: \displayListRandomly + [\ifnum\i=\last and \fi] + [\ifnum\i=\last.\else, \fi]{myPals} +\end{Verbatim} +yields, +\begin{quote} +List of pals: \displayListRandomly + [\ifnum\i=\last and \fi] + [\ifnum\i=\last.\else, \fi]{myPals} +\end{quote} +The optional arguments are wrapped to the next line to keep them within the margins, cool. + +The example above shows the list of my pals with an Oxford comma. How would +you modify the optional argument to get the same listing without the Oxford +comma? (\displayListRandomly[\ifnum\i=\last and \fi][\ifnum\i=\last.\else\ifnum\i=\lessone\relax\space\else, \fi\fi]{myPals}) +Hint: a solution involves the other command \cs{lessone}. + + + +\section{Additional arguments and commands}\label{AddCmds} + +The syntax given earlier for \cs{useRanTok} was not completely specified. +It is +\bVerb\takeMeasure{\string\useRanTok[\meta{name}]\darg{\meta{num}}}% +\begin{minipage}{\bxSize}\kern0pt +\begin{Verbatim}[frame=single,commandchars=!()] +\useRanTok[!meta(name)]{!meta(num)} +\end{Verbatim} +\end{minipage}\eVerb +The optional first parameter specifies the \meta{name} of the list from +which to draw a random token; \meta{num} is the number of the +token in the range of 1 and \cs{nToksFor\darg{\meta{name}}}, +inclusive. The optional argument is useful in special circumstances when +you want to mix two random lists together. + +\newtopic\noindent To illustrate: \useRanTok[myPals]{1}, \useRanTok[myThoughts]{2} + +\newtopic\noindent The verbatim listing is +\begin{Verbatim}[xleftmargin=\amtIndent] +To illustrate: \useRanTok[myPals]{1}, \useRanTok[myThoughts]{2} +\end{Verbatim} +The typeset version looks a little strange, but recall, the text of +\texttt{myThoughts} were each put in a \texttt{minipage} of width \texttt{.67\cs{linewidth}}. +Without the \texttt{minipage}, the text would wrap around normally. + +\paragraph*{Accessing the original order.} The original order of the list of tokens is not lost, you can retrieve +them using the command \cs{rtTokByNum}, +\bVerb\takeMeasure{\string\rtTokByNum[\meta{name}]\darg{\meta{num}}}% +\begin{minipage}{\bxSize}\kern0pt +\begin{Verbatim}[frame=single,commandchars=!()] +\rtTokByNum[!meta(name)]{!meta(num)} +\end{Verbatim} +\end{minipage}\eVerb +This command expands to the token declared in the list named \meta{name} +that appears at the \meta{num} place in the list. (Rather awkwardly written.) +For example, my really best pals are {\rtTokByNum[myPals]{3}} and +\rtTokByNum[myPals]{4}, but don't tell them. The listing is, +\begin{Verbatim}[xleftmargin=\amtIndent] +For example, my really best pals are {\rtTokByNum[myPals]{3}} +and \rtTokByNum[myPals]{4}, but don't tell them. +\end{Verbatim} +In some sense, \cs{rtTokByNum[\meta{name}]} acts like a simple array, the +length of which is \cs{nToksFor\{\meta{name}\}}, and whose $k^{\text{th}}$ +element is \cs{rtTokByNum[\meta{name}]\{\meta{k}\}}. + +\paragraph*{Turning off randomization.} The randomization may be turned off +using \cs{ranToksOff} or turned back on with \cs{ranToksOn}. +\bVerb\takeMeasure{\string\ranToksOff\quad\string\ranToksOn}% +\begin{minipage}{\bxSize}\kern0pt +\begin{Verbatim}[frame=single,commandchars=!()] +\ranToksOff!quad\ranToksOn +\end{Verbatim} +\end{minipage}\eVerb +This can be done globally in the preamble for the whole of the document, +or in the body of the document just prior to either \cs{ranToks} or +\cs{bRTVToks}. For example, +\begin{Verbatim}[xleftmargin=\amtIndent] +\ranToksOff +\ranToks{integers}{ {1}{2}{3}{4} } +\ranToksOn +\end{Verbatim} +As a check, executing `$\cs{useRanTok\darg{3}} = \cs{rtTokByNum\darg{3}} = 3 $' yields +`\ranToksOff\ranToks{integers}{ {1}{2}{3}{4}}\ranToksOn +$\useRanTok{3} = \rtTokByNum{3} = 3 $'? As anticipated. + +To create a non-randomized list of tokens that already have been created (and randomized), use +\cs{copyRanToks}: +\begin{Verbatim}[xleftmargin=\amtIndent] +\ranToksOff\copyRanToks{myPals}{myOriginalPals}\ranToksOn +\end{Verbatim} +Then, using \cs{displayListRandomly} in a clever way, +\begin{Verbatim}[xleftmargin=\amtIndent] +\displayListRandomly[\ifnum\i=\last\space and \fi(\the\i)~] + [\ifnum\i=\last.\else,\fi\space]{myOriginalPals} +\end{Verbatim} +we obtain: \ranToksOff\copyRanToks{myPals}{myOriginalPals}\ranToksOn +\displayListRandomly[\ifnum\i=\last\space and \fi(\the\i)~][\ifnum\i=\last.\else,\fi\space]{myOriginalPals} +The original list for \texttt{myPals} remains unchanged: +\displayListRandomly[\ifnum\i=\last\space and \fi(\the\i)~][\ifnum\i=\last.\else,\fi\space]{myPals} + +The \cs{useRanTok} command---whether it operates on a randomized token list +or not---behaves similarly to an array. Thus, if we wanted the extract +the third entry of the non-randomized token list (array) +\texttt{myOriginalPals}, we do so by expanding the command +\verb!\useRanTok[myOriginalPals]{3}! to produce +\useRanTok[myOriginalPals]{3}. + +\subparagraph*{Document preparation.} +The command \cs{ranToksOff} is probably best in the preamble to turn off +all randomization while the rest of the document is being composed. + +\paragraph*{The \textsf{ran\_toks} auxiliary file.} The package writes to a file named +\cs{jobname\_rt.sav}, below represents two typical lines in this file. +\begin{Verbatim}[xleftmargin=\amtIndent] +1604051353 % initializing seed value +5747283528 % last random number used +\end{Verbatim} +The first line is the initializing seed value used for the last +compilation of the document; the second line is the last value of the +pseudo-random number generator used in the document. + +Normally, the pseudo-random number generator provided by +\texttt{random.tex} produces a new initial seed value every minute. So if +you recompile again before another minute, you'll get the same initial +seed value. + +\paragraph*{Controlling the initial seed value.} To obtain a new initial seed +value each time you compile, place \cs{useLastAsSeed} in the preamble. +\bVerb\takeMeasure{\string\useLastAsSeed}% +\begin{minipage}{\bxSize}\kern0pt +\begin{Verbatim}[frame=single] +\useLastAsSeed +\end{Verbatim} +\end{minipage}\eVerb +When the document is compiled, the initial seed value taken as the second +line in the \cs{jobname\_rt.sav} file, as seen in the above example. +With this command in the preamble, a new set of random numbers is +generated on each compile. If the file \cs{jobname\_rt.sav} does not +exist, the generator will be initialized by its usual method, using the time and date. + +The command \cs{useThisSeed} allows you to reproduce a previous +pseudo-random sequence. +\bVerb\takeMeasure{\string\useThisSeed\darg{\meta{init\_seed\_value}}}% +\begin{minipage}{\bxSize}\kern0pt +\begin{Verbatim}[frame=single,commandchars=!()] +\useThisSeed{!meta(init_seed_value)} +\end{Verbatim} +\end{minipage}\eVerb +This command needs to be placed in the preamble. The value of +\meta{init\_seed\_value} is an integer, normally taken from the +first line of the \cs{jobname\_rt.sav} file. + +When creating tests (possibly using \textsf{eqexam}), the problems, or +contiguous collections of problems, can be randomly ordered using the +\cs{bRTVToks}/\penalty0\cs{eRTVToks} command pair paradigm. For example, +suppose there are two classes and you want a random order (some of) the +problems for each of the two classes. Proceed as follows: +\begin{enumerate} +\item Compile the document, open \cs{jobname\_rt.sav}, and copy the + first line (in the above example, that would be + \texttt{1604051353}). +\item Place \cs{useThisSeed\darg{1604051353}} in the preamble. Compiling + will bring back the same pseudo-random sequence very time. +\item Comment this line out, and repeat the process (use + \cs{useLastAsSeed} to generate new random sequences at each + compile) until you get another distinct randomization, open + \cs{jobname\_rt.sav}, and copy the first line again, say its \texttt{735794511}. +\item Place \cs{useThisSeed\darg{735794511}} in the preamble. +\item Label each +\begin{Verbatim} +%\useThisSeed{1604051353} % 11:00 class +%\useThisSeed{735794511} % 12:30 class +\end{Verbatim} +To reproduce the random sequence for the class, just uncomment the random +seed used for that class. +\end{enumerate} +If you are using \textsf{eqexam}, the process can be automated as follows: +\begin{Verbatim}[xleftmargin=\amtIndent,commandchars=!()] +\vA{\useThisSeed{1604051353}} % 11:00 class +\vB{\useThisSeed{735794511}} % 12:30 class +\end{Verbatim} +Again, this goes in the preamble. + +\section{Commands to support a DB application}\label{s:DBConcept} + +One user wanted to create exams using \pkg{eqexam}, but wanted to randomly +select questions from a series of `database' files. My thought was that +\pkg{ran\_toks} would do the job for him. After setting up a demo for him, I +added the new command \cs{useTheseDBs} to \pkg{ran\_toks}: +\bVerb\takeMeasure{\string\useTheseDBs\darg{\ameta{db\SUB{1}},\ameta{db\SUB{2}},...,\ameta{db\SUB{n}}}}% +\begin{minipage}{\bxSize}\kern0pt +\begin{Verbatim}[frame=single,commandchars=!()] +\useTheseDBs{!ameta(db!SUB(1)),!ameta(db!SUB(2)),...,!ameta(db!SUB(n))} +\useProbDBs{!ameta(db!SUB(1)),!ameta(db!SUB(2)),...,!ameta(db!SUB(n))} +\end{Verbatim} +\end{minipage}\eVerb The argument of \cs{useTheseDBs} is a comma-delimited +list of file names. Each file name contains a +\cs{bRTVToks}/\penalty0\cs{eRTVToks} construct. Within this pair are +\env{rtVW} environments, as described in +\hyperref[ss:RTVToks]{Section~\ref*{ss:RTVToks}}. The \cs{useTheseDBs} +command inputs the files listed in its comma-delimited argument; a warning is +emitted if one or more of the files are not found. The default extension is +\texttt{.tex}, \cs{useTheseDBs\darg{db1,db2}} inputs the files +\texttt{db1.tex} and \texttt{db2.tex}, if they exist, while +\cs{useTheseDBs\darg{db1.def,db2.db}} inputs the files \texttt{db1.def} and +\texttt{db2.db}, if they exist. The command \cs{useProbDBs} is an alias for +\cs{useTheseDBs}. + +The placement of \cs{useTheseDBs} is anywhere prior to the insertion of the +problems into the document, usually in the preamble. + +Refer to the demonstration file \texttt{mc-db.tex} for an example. + +\newtopic\noindent +Now, I simply must get back to my retirement. \dps + +\end{document} diff --git a/macros/latex/contrib/ran_toks/examples/db1.tex b/macros/latex/contrib/ran_toks/examples/db1.tex new file mode 100644 index 0000000000..45a8b67124 --- /dev/null +++ b/macros/latex/contrib/ran_toks/examples/db1.tex @@ -0,0 +1,76 @@ +% +% First DB, uses ran_toks and eqexam +% +\bRTVToks{DB1-} + +\begin{rtVW} +\begin{problem}[5] +DB1: First: Which is correct? +\begin{answers}{4} +\bChoices[nCols=1,random,label=db1-1] + \Ans1 True\eAns + \Ans0 False\eAns + \Ans0 Maybe\eAns + \Ans0 Perhaps\eAns +\eChoices +\end{answers} +\begin{solution} +It is obvious that the answer is `\useSavedAns{db1-1}', that is, alternative \useSavedAlts{db1-1} is correct. +\end{solution} +\end{problem} +\end{rtVW} + +\begin{rtVW} +\begin{problem}[5] +DB1: Second: Which is correct? +\begin{answers}{4} +\bChoices[nCols=1,random,label=db1-2] + \Ans1 True\eAns + \Ans0 False\eAns + \Ans0 Maybe\eAns + \Ans0 Perhaps\eAns +\eChoices +\end{answers} +\begin{solution} +According to the guy sitting next to me, the answer might be \useSavedAlts{db1-2} +\end{solution} +\end{problem} +\end{rtVW} + +\begin{rtVW} +\begin{problem}[5] +DB1: Third: Which is correct? +\begin{answers}{4} +\bChoices[nCols=1,random,label=db1-3] + \Ans1 True\eAns + \Ans0 False\eAns + \Ans0 Maybe\eAns + \Ans0 Perhaps\eAns +\eChoices +\end{answers} +\begin{solution} +I know the answer in advance to be \useSavedAlts{db1-3}, but don't tell anyone. +\end{solution} +\end{problem} +\end{rtVW} + +\begin{rtVW} +\begin{problem}[5] +DB1: Fourth: Which is correct? +\begin{answers}{4} +\bChoices[nCols=1,random,label=db1-4] + \Ans1 True\eAns + \Ans0 False\eAns + \Ans0 Maybe\eAns + \Ans0 Perhaps\eAns +\eChoices +\end{answers} +\begin{solution} +After meditating in the lotus position on this question for many hours, we determine that the correct answer is \textbf{\useSavedAltsAns{db1-4}}. +\end{solution} +\end{problem} +\end{rtVW} + +\eRTVToks + +\endinput diff --git a/macros/latex/contrib/ran_toks/examples/db2.tex b/macros/latex/contrib/ran_toks/examples/db2.tex new file mode 100644 index 0000000000..dc18b86faa --- /dev/null +++ b/macros/latex/contrib/ran_toks/examples/db2.tex @@ -0,0 +1,65 @@ +% +% Second DB, uses ran_toks and eqexam +% + +\bRTVToks{DB2-} + +\begin{rtVW} +\begin{problem}[5] +DB2: First: Which is correct? +\begin{answers}{4} +\bChoices[nCols=2,random] + \Ans1 True\eAns + \Ans0 False\eAns + \Ans0 Maybe\eAns + \Ans0 Perhaps\eAns +\eChoices +\end{answers} +\end{problem} +\end{rtVW} + +\begin{rtVW} +\begin{problem}[5] +DB2: Second: Which is correct? +\begin{answers}{4} +\bChoices[nCols=2,random] + \Ans1 True\eAns + \Ans0 False\eAns + \Ans0 Maybe\eAns + \Ans0 Perhaps\eAns +\eChoices +\end{answers} +\end{problem} +\end{rtVW} + +\begin{rtVW} +\begin{problem}[5] +DB2: Third: Which is correct? +\begin{answers}{4} +\bChoices[nCols=2,random] + \Ans1 True\eAns + \Ans0 False\eAns + \Ans0 Maybe\eAns + \Ans0 Perhaps\eAns +\eChoices +\end{answers} +\end{problem} +\end{rtVW} + +\begin{rtVW} +\begin{problem}[5] +DB2: Fourth: Which is correct? +\begin{answers}{4} +\bChoices[nCols=2,random] + \Ans1 True\eAns + \Ans0 False\eAns + \Ans0 Maybe\eAns + \Ans0 Perhaps\eAns +\eChoices +\end{answers} +\end{problem} +\end{rtVW} + +\eRTVToks + +\endinput
\ No newline at end of file diff --git a/macros/latex/contrib/ran_toks/examples/db3.tex b/macros/latex/contrib/ran_toks/examples/db3.tex new file mode 100644 index 0000000000..1948692f1f --- /dev/null +++ b/macros/latex/contrib/ran_toks/examples/db3.tex @@ -0,0 +1,65 @@ +% +% Third DB, uses ran_toks and eqexam +% + +\bRTVToks{DB3-} + +\begin{rtVW} +\begin{problem}[5] +DB3: First: Which is correct? +\begin{answers}{4} +\bChoices[nCols=2,random] + \Ans1 True\eAns + \Ans0 False\eAns + \Ans0 Maybe\eAns + \Ans0 Perhaps\eAns +\eChoices +\end{answers} +\end{problem} +\end{rtVW} + +\begin{rtVW} +\begin{problem}[5] +DB3: Second: Which is correct? +\begin{answers}{4} +\bChoices[nCols=2,random] + \Ans1 True\eAns + \Ans0 False\eAns + \Ans0 Maybe\eAns + \Ans0 Perhaps\eAns +\eChoices +\end{answers} +\end{problem} +\end{rtVW} + +\begin{rtVW} +\begin{problem}[5] +DB3: Third: Which is correct? +\begin{answers}{4} +\bChoices[nCols=2,random] + \Ans1 True\eAns + \Ans0 False\eAns + \Ans0 Maybe\eAns + \Ans0 Perhaps\eAns +\eChoices +\end{answers} +\end{problem} +\end{rtVW} + +\begin{rtVW} +\begin{problem}[5] +DB3: Fourth: Which is correct? +\begin{answers}{4} +\bChoices[nCols=2,random] + \Ans1 True\eAns + \Ans0 False\eAns + \Ans0 Maybe\eAns + \Ans0 Perhaps\eAns +\eChoices +\end{answers} +\end{problem} +\end{rtVW} + +\eRTVToks + +\endinput
\ No newline at end of file diff --git a/macros/latex/contrib/ran_toks/examples/db4.tex b/macros/latex/contrib/ran_toks/examples/db4.tex new file mode 100644 index 0000000000..64b1d241ef --- /dev/null +++ b/macros/latex/contrib/ran_toks/examples/db4.tex @@ -0,0 +1,65 @@ +% +% Fourth DB, uses ran_toks and eqexam +% + +\bRTVToks{DB4-} + +\begin{rtVW} +\begin{problem}[5] +DB4: First: Which is correct? +\begin{answers}{4} +\bChoices[nCols=2,random] + \Ans1 True\eAns + \Ans0 False\eAns + \Ans0 Maybe\eAns + \Ans0 Perhaps\eAns +\eChoices +\end{answers} +\end{problem} +\end{rtVW} + +\begin{rtVW} +\begin{problem}[5] +DB4: Second: Which is correct? +\begin{answers}{4} +\bChoices[nCols=2,random] + \Ans1 True\eAns + \Ans0 False\eAns + \Ans0 Maybe\eAns + \Ans0 Perhaps\eAns +\eChoices +\end{answers} +\end{problem} +\end{rtVW} + +\begin{rtVW} +\begin{problem}[5] +DB4: Third: Which is correct? +\begin{answers}{4} +\bChoices[nCols=2,random] + \Ans1 True\eAns + \Ans0 False\eAns + \Ans0 Maybe\eAns + \Ans0 Perhaps\eAns +\eChoices +\end{answers} +\end{problem} +\end{rtVW} + +\begin{rtVW} +\begin{problem}[5] +DB4: Fourth: Which is correct? +\begin{answers}{4} +\bChoices[nCols=2,random] + \Ans1 True\eAns + \Ans0 False\eAns + \Ans0 Maybe\eAns + \Ans0 Perhaps\eAns +\eChoices +\end{answers} +\end{problem} +\end{rtVW} + +\eRTVToks + +\endinput
\ No newline at end of file diff --git a/macros/latex/contrib/ran_toks/examples/mc-db.tex b/macros/latex/contrib/ran_toks/examples/mc-db.tex new file mode 100644 index 0000000000..0e8ceab7b7 --- /dev/null +++ b/macros/latex/contrib/ran_toks/examples/mc-db.tex @@ -0,0 +1,75 @@ +\documentclass{article} +\usepackage[allowrandomize,nosolutions, + forpaper,pointsonleft,noparttotals]{eqexam} +\usepackage{ran_toks} + +\useLastAsSeed +% To reproduce the same pseudo-random sequence, you need to supply a seed +%\useThisSeed{1125676795} + +\examNum{1} +\title[T\nExam]{Test \nExam} +\author{D. P. Story} +\subject[MC]{My Course} +\date{Spring \the\year} +\keywords{Test~\nExam, Section 001} + +\university +{% + THE UNIVERSITY OF AKRON\\ + Theoretical and Applied Mathematics +} +\email{dpstory@uakron.edu} + +% Input the DB files used in the demo file +\useTheseDBs{db1,db2,db3,db4} + + +\begin{document} +\maketitle + +\begin{exam}{Part1} + +\begin{instructions} +Solve each without error. Passing is 100\%. + +\medskip\noindent +This part demonstrates how to not only randomly pull problems (two from each of the DB files) at random, but +to randomize the order they are listed in the exam. +\end{instructions} + +\ranToks{myExam}{% + {\useRanTok[DB1-]{1}} + {\useRanTok[DB1-]{2}} + {\useRanTok[DB2-]{1}} + {\useRanTok[DB2-]{2}} + {\useRanTok[DB3-]{1}} + {\useRanTok[DB3-]{2}} + {\useRanTok[DB4-]{1}} + {\useRanTok[DB4-]{2}} +} +\displayListRandomly{myExam} + +\end{exam} + +\begin{exam}{Part2} + +\begin{instructions} +In this part, we take the same two problems from each of the four DB files, but do not randomize +the order of the questions. +\end{instructions} + +\useRanTok[DB1-]{1} +\useRanTok[DB1-]{2} +\useRanTok[DB2-]{1} +\useRanTok[DB2-]{2} +\useRanTok[DB3-]{1} +\useRanTok[DB3-]{2} +\useRanTok[DB4-]{1} +\useRanTok[DB4-]{2} + +\end{exam} + +\end{document} + + diff --git a/macros/latex/contrib/ran_toks/examples/mytext.verb b/macros/latex/contrib/ran_toks/examples/mytext.verb new file mode 100644 index 0000000000..82865ace47 --- /dev/null +++ b/macros/latex/contrib/ran_toks/examples/mytext.verb @@ -0,0 +1 @@ +Hello \verb!$%$#$^~_! world! diff --git a/macros/latex/contrib/ran_toks/examples/ran_toks.tex b/macros/latex/contrib/ran_toks/examples/ran_toks.tex new file mode 100644 index 0000000000..e10238aa5a --- /dev/null +++ b/macros/latex/contrib/ran_toks/examples/ran_toks.tex @@ -0,0 +1,95 @@ +\documentclass{article} +\usepackage{ran_toks} +\usepackage{ifthen} + +\useThisSeed{606574325} % comment out this line, and uncomment next line to get ... +%\useLastAsSeed % a new pseudo-random sequence each time you compile. + +% Other useful switches +%\ranToksOn % the default +%\ranToksOff + +\parindent0pt \parskip6pt +\def\cs#1{\texttt{\char`\\#1}} + +\begin{document} +\begin{center}\bfseries + Test file for \textsf{ran\_toks} Package\\[3pt] + D. P. Story +\end{center} + +Test of the \verb!\ranToks! command. + +\ranToks{myPals}{% + {Jim}{Richard}{Don} + {Alex}{Tom}{J\"{u}rgen} +} +I have {\nToksFor{myPals}} pals, they are \useRanTok{1}, \useRanTok{2}, +\useRanTok{3}, \useRanTok{4}, {\useRanTok{5}} and \useRanTok{6}. (Listed +in the order of best friend to least best friend.) + +Test of the \verb!\bRTVToks!/\verb!\eRTVToks! pair of commands, which encloses +\texttt{rtVW} environments. + +\bRTVToks{myThoughts}% +\begin{rtVW} +\begin{minipage}[t]{.67\linewidth} +Roses are red and violets are blue, +I've forgotten the rest, have you too? +\end{minipage} +\end{rtVW} +\begin{rtVW} +\begin{minipage}[t]{.67\linewidth} +I gave up saying bad things like +\verb!$#%%%^*%^&#$@#! when I was just a teenager. +\end{minipage} +\end{rtVW} +\begin{rtVW} +\begin{minipage}[t]{.67\linewidth} +I am a good guy, pass it on! The code for this last sentence is, +\begin{verbatim} +%#$% I am a good guy, pass it on! ^&*&^* +\end{verbatim} +How did that other stuff get in there? +\end{minipage} +\end{rtVW} +\eRTVToks +\begin{enumerate} + \displayListRandomly[\item]{myThoughts} +\end{enumerate} +Use \verb!\useRTName! command when another list separates the current +position from the list you want to use. Here we want to use the list named +\texttt{myPals}, but since that definition, a new list named +\texttt{myThoughts} was declared. + +\useRTName{myPals} +List of pals: \useRanTok{1}, \useRanTok{2}, \useRanTok{3}, +\useRanTok{4}, \useRanTok{5}, and \useRanTok{6}. + +For mixing lists. it might be easier to use the optional parameter: +{\useRanTok[myPals]{1}} and \useRanTok[myThoughts]{1} + +The \cs{rtTokByNum} can retrieve an item from the list in its declared order; +eg, from the \texttt{myPals} list, the first and last are +{\rtTokByNum[myPals]{1}} and \rtTokByNum[myPals]{\nToksFor{myPals}}. + +We demonstrate the command \cs{reorderRanToks} and the optional parameters of \cs{displayListRandomly}: +\begin{quote}\reorderRanToks{myPals}% +List of pals: \displayListRandomly[\ifnum\i=\last\space and \fi][\ifnum\i=\last.\else,\fi\space]{myPals} +\end{quote} +The reordering is global, so \displayListRandomly[\ifnum\i=\last\space and \fi][\ifnum\i=\last\else, \fi]{myPals} +are listed in the same order as above, and different from the original random order seen in the second paragraph +of this document. + +Without the Oxford comma: My pals are +\displayListRandomly[\ifnum\i=\last and \fi][\ifnum\i=\last.\else\ifnum\i=\lessone\relax\space\else, \fi\fi]{myPals} + +The following is the same logic but uses the syntax of the \textsf{ifthen} package: My pals are +\displayListRandomly[\ifthenelse{\i=\last}{and }{}][\ifthenelse{\i=\last}{.}{\ifthenelse{\i=\lessone}{\space}{, }}]{myPals} + +Test the \cs{copyRanToks} command: +\copyRanToks{myPals}{myPals1}\displayListRandomly[\ifthenelse{\i=\last}{and }{}][\ifthenelse{\i=\last}{.}{\ifthenelse{\i=\lessone}{\space}{, }}]{myPals1} +This does not change the order of the \texttt{myPals} list, which is still +\displayListRandomly[\ifnum\i=\last\space and \fi][\ifnum\i=\last.\else,\fi\space]{myPals} + +\end{document} diff --git a/macros/latex/contrib/ran_toks/examples/random_tst.tex b/macros/latex/contrib/ran_toks/examples/random_tst.tex new file mode 100644 index 0000000000..1f64c79907 --- /dev/null +++ b/macros/latex/contrib/ran_toks/examples/random_tst.tex @@ -0,0 +1,103 @@ +% +% This demo file shows how to randomize the questions of an exam created +% by the eqexam package. +% +\documentclass{article} +\usepackage[allowrandomize,nosolutions, + forpaper,pointsonleft,noparttotals]{eqexam} +\usepackage{ran_toks} + +\useLastAsSeed +%\useThisSeed{452836675} % fi,t,f,s + +\examNum{1} +\title[T\nExam]{Test \nExam} +\author{D. P. Story} +\subject[MC]{My Course} +\date{Spring \the\year} +\keywords{Test~\nExam, Section 001} + +\university +{% + THE UNIVERSITY OF AKRON\\ + Theoretical and Applied Mathematics +} +\email{dpstory@uakron.edu} + +\begin{document} +\maketitle + + +\begin{exam}{Exam\nExam} + +\begin{instructions} +Solve each problem without error. +\end{instructions} + +\bRTVToks{Exam\nExam} + +\begin{rtVW} +\begin{problem}[5] +First: Which is correct? +\begin{answers}{4} +\bChoices[nCols=2,random] + \Ans1 True\eAns + \Ans0 False\eAns + \Ans0 Maybe\eAns + \Ans0 Perhaps\eAns +\eChoices +\end{answers} +\end{problem} +\end{rtVW} + +\begin{rtVW} +\begin{problem}[5] +Second: Which is correct? +\begin{answers}{4} +\bChoices[nCols=2,random] + \Ans1 True\eAns + \Ans0 False\eAns + \Ans0 Maybe\eAns + \Ans0 Perhaps\eAns +\eChoices +\end{answers} +\end{problem} +\end{rtVW} + +\begin{rtVW} +\begin{problem}[5] +Third: Which is correct? +\begin{answers}{4} +\bChoices[nCols=2,random] + \Ans1 True\eAns + \Ans0 False\eAns + \Ans0 Maybe\eAns + \Ans0 Perhaps\eAns +\eChoices +\end{answers} +\end{problem} +\end{rtVW} + +\begin{rtVW} +\begin{problem}[5] +Fourth: Which is correct? +\begin{answers}{4} +\bChoices[nCols=2,random] + \Ans1 True\eAns + \Ans0 False\eAns + \Ans0 Maybe\eAns + \Ans0 Perhaps\eAns +\eChoices +\end{answers} +\end{problem} +\end{rtVW} + +\eRTVToks + +% Ok, now display this questions in a random order. +\displayListRandomly{Exam\nExam} + + +\end{exam} + +\end{document} diff --git a/macros/latex/contrib/ran_toks/examples/random_tst_qz.tex b/macros/latex/contrib/ran_toks/examples/random_tst_qz.tex new file mode 100644 index 0000000000..3ca3c4043e --- /dev/null +++ b/macros/latex/contrib/ran_toks/examples/random_tst_qz.tex @@ -0,0 +1,115 @@ +% +% This demo file shows how to randomize the choices of a quiz created +% by the exerquiz package, where the choices have verbatim text. +% +% The questions themselves are not randomized, but they can be, see random_tst.tex +% to see how to do this. +% +\documentclass{article} +\usepackage[designiv]{web} +\usepackage[allowrandomize,showgrayletters]{exerquiz} +\usepackage{ran_toks} + +% When using cross-referencing and \useLastAsSeed, the cross-references are never up to date. +% Once you randomize, read the auxiliary file (\jobname_rt.save), copy the first seed listed +% and paste in as the argument of \useThisSeed. Compile a few more times to bring cross-refereces +% up to date. +%\useLastAsSeed +\useThisSeed{1327548830} + +\rowsepDefault{3pt} + + +\begin{document} + +\begin{quiz*}{myRandomQuiz} + Riddle me this. +\begin{questions} + \item Try to guess the correct answer. + \begin{answers}{2} + \bChoices[random] + \Ans0 1 a choice\eAns + \Ans1\label{eq} 2 another choice\eAns + \Ans0 3 still another choice\eAns + \Ans0 4 another\eAns + \Ans0 5 incoming\eAns + \Ans0 6 more choices\eAns + \Ans0 7 another still\eAns + \Ans0 8 too many\eAns + \Ans0 9 choices\eAns + \Ans0 10 \input{mytext.verb}\eAns + \eFreeze + \Ans0 10 None of these\eAns + \eChoices + \end{answers} +\end{questions} +\end{quiz*}\quad\ScoreField\currQuiz\CorrButton\currQuiz + + +\newpage + +\bRTVToks{myChoices} +\begin{rtVW} +\verb!$ true $! +\end{rtVW} +\begin{rtVW} +\verb!~ false %! +\end{rtVW} +\begin{rtVW} +\verb!% maybe ^! +\end{rtVW} +\begin{rtVW} +\verb!$& perhaps #$! +\end{rtVW} +\eRTVToks + +\begin{quiz*}{myQuiz} +Solve each. +\begin{questions} + + \item Which is true? (Answer: \hyperref[rtAns3]{(\REF*{rtAns3})}) +\useRTName{myChoices} +\begin{manswers}*{1} +\bChoices[random=true,label=rtAns] + \Ans{1}\label{rtAns3}\rtTokByNum{1}\eAns + \Ans{0} Wow, \rtTokByNum{2}, this is great!\eAns + \Ans{0}\rtTokByNum{3}\eAns + \Ans{0}\rtTokByNum{4}\eAns +\eFreeze + \Ans{1} Hello mom!\eAns +\eChoices +\end{manswers} +\begin{solution} +The answer is \useSavedAlts{rtAns}, or to be more precise, +\useSavedAltsAns{rtAns}. \hyperref[rtAns3]{(\REF*{rtAns3})} +\end{solution} + + \item Which is true? (Ans: \hyperref[rtAns1]{(\REF*{rtAns1})}) +\useRTName{myChoices} +\begin{answers}*{3} + \bChoices[random,nCols=2] + \Ans{1}\label{rtAns1} \rtTokByNum{1}\eAns + \Ans{0} \rtTokByNum{2}\eAns + \Ans{0} \rtTokByNum{3}\eAns + \Ans{0} \rtTokByNum{4}\eAns + \eChoices +\end{answers} +\begin{solution} +The answer is \hyperref[rtAns1]{(\REF*{rtAns1})} found in the +\nameref{rtAns1} on page~\pageref{rtAns1}. +\end{solution} + + \item Which is true? +\useRTName{myChoices} +\begin{answers}{3} + \bChoices[random] + \Ans{1} \rtTokByNum{1}\eAns + \Ans{0} \rtTokByNum{2}\eAns + \Ans{0} \rtTokByNum{3}\eAns + \Ans{0} \rtTokByNum{4}\eAns + \eChoices +\end{answers} +\end{questions} +\end{quiz*} + +\end{document} diff --git a/macros/latex/contrib/ran_toks/ran_toks.dtx b/macros/latex/contrib/ran_toks/ran_toks.dtx new file mode 100644 index 0000000000..0a36c48614 --- /dev/null +++ b/macros/latex/contrib/ran_toks/ran_toks.dtx @@ -0,0 +1,643 @@ +%\iffalse +% makeindex -s gglo.ist -o ran_toks.gls ran_toks.glo +% makeindex -s gind.ist -o ran_toks.ind ran_toks.idx +%<*copyright> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Web package, %% +%% Copyright (C) 1999-2017 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}[1997/12/01] +%<package>\ProvidesPackage{ran_toks} +%<package> [2017/05/04 v1.1 Randomizing tokens (dps)] +%<*driver> +\documentclass{ltxdoc} +\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} +\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} +%</driver> +% \fi +% \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 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{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{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{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 +% and \texttt{random.tex}, the package was written by Donald Arseneau. +% \begin{macrocode} +\RequirePackage{verbatim} +% \end{macrocode} +% \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}}{} +% \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}. +% \changes{v1.0c}{2013/08/03}{Save the initial seed value to \string\cs{rtInitSeedValue}.} +% \begin{macrocode} + \xdef\InitSeedValue{\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{\rt@useLastAsSeed} +\@onlypreamble\useLastAsSeed +\def\rt@useLastAsSeed{% + \IfFileExists{\jobname_rt.sav}{% + \PackageInfo{ran_toks}{Inputting \jobname_rt.sav}% + \@ifundefined{readsavfile}{\newread\readsavfile}{}% + \openin\readsavfile=\jobname_rt.sav + \read\readsavfile to \InitSeedValue + \read\readsavfile to \lastRandomNum + \closein\readsavfile + \randomi=\lastRandomNum +% \end{macrocode} +% When \cs{useLastAsSeed}, the last becomes the first. +% \begin{macrocode} + \xdef\InitSeedValue{\the\randomi} + }{% + \PackageInfo{ran_toks}{\jobname_rt.sav cannot + be found, \MessageBreak + using the random initializer}% + }% +} +\@ifundefined{aeb@randomizeChoices}{% + \let\inputRandomSeed\useLastAsSeed + \let\useRandomSeed\useThisSeed}{} +% \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\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} +% \end{macrocode} +% Save the initial seed value to hard drive. +% \begin{macrocode} +\AtEndDocument{\rt@writeSeedData}% +% \end{macrocode} +% \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\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}}} +% \end{macrocode} +% \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={}% + \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, +%\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\z@ +\ifrtdebug\typeout{LISTING: \the\rt@listIn}\fi + \the\rt@listIn + \rt@loopTest +} +\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}% + \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@nCnt\@ne + \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} +% 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} +% \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\z@\r@ndToks#1\rt@NIL} +\def\rt@NIL{@nil} +% \end{macrocode} +% \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} +% \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\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}} +% \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@nCnt\@ne + \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@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 \string\texttt{\#1} are the same, +% we get an incorrect decision} +% \begin{macrocode} +\def\rt@PAR{\par} +\long\def\r@ndToks#1{\def\rt@rgi{#1}% +% \end{macrocode} +% 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@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} +% \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} +% 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{\global +% \end{macrocode} +% Save the number of tokens counted +% \begin{macrocode} + \rt@nameedef{nMax4\rt@BaseName}{\the\rt@nMax}% + \rt@performRanDefns{\the\rt@nMax}\endgroup} +% \end{macrocode} +% \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} +\def\reorderRanToks#1{\begingroup\useRTName{#1}\expandafter + \ifx\csname nMax4#1\endcsname\relax +% \end{macrocode} +% Document author has not run \cs{ranToks} yet for this basename (\texttt{\#1}) +% \begin{macrocode} + \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} +% \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\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}\hskip-\marginparsep\texttt{\darg{\ameta{name}}} +% expands the the number of tokens whose name is \ameta{name} (\texttt{\#1}). +% \begin{macrocode} +\newcommand{\nToksFor}[1]{\expandafter + \ifx\csname nMax4#1\endcsname\relax + \textbf{??}\rt@badTokName{#1}\else + \@nameuse{nMax4#1}\fi} +% \end{macrocode} +% \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]{\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} +% 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} + \rt@badIndex{#2}{#1}\@nameuse{rtRanTok\rt@mod#1}\else + \@nameuse{rtRanTok#2#1}\fi\fi\egroup} +% \end{macrocode} +% \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 \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} +%</package> +% \end{macrocode} +% \Finale +\endinput diff --git a/macros/latex/contrib/ran_toks/ran_toks.sty b/macros/latex/contrib/ran_toks/ran_toks.sty new file mode 100644 index 0000000000..f5f253e0b1 --- /dev/null +++ b/macros/latex/contrib/ran_toks/ran_toks.sty @@ -0,0 +1,302 @@ +%% +%% This is file `ran_toks.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% ran_toks.dtx (with options: `copyright,package') +%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Web package, %% +%% Copyright (C) 1999-2017 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. %% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\NeedsTeXFormat{LaTeX2e}[1997/12/01] +\ProvidesPackage{ran_toks} + [2017/05/04 v1.1 Randomizing tokens (dps)] +\RequirePackage{verbatim} +\@ifundefined{nextrandom}{\input{random.tex}}{} +\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 + \xdef\InitSeedValue{\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 +} +\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 +\def\rt@nameedef#1{\expandafter\edef\csname #1\endcsname} +\def\ranToksOn{\werandomizetrue} +\def\ranToksOff{\werandomizefalse} +\def\useThisSeed#1{\saveseedfalse\randomi=#1} +\@onlypreamble\useThisSeed +\def\useLastAsSeed{\rt@useLastAsSeed} +\@onlypreamble\useLastAsSeed +\def\rt@useLastAsSeed{% + \IfFileExists{\jobname_rt.sav}{% + \PackageInfo{ran_toks}{Inputting \jobname_rt.sav}% + \@ifundefined{readsavfile}{\newread\readsavfile}{}% + \openin\readsavfile=\jobname_rt.sav + \read\readsavfile to \InitSeedValue + \read\readsavfile to \lastRandomNum + \closein\readsavfile + \randomi=\lastRandomNum + \xdef\InitSeedValue{\the\randomi} + }{% + \PackageInfo{ran_toks}{\jobname_rt.sav cannot + be found, \MessageBreak + using the random initializer}% + }% +} +\@ifundefined{aeb@randomizeChoices}{% + \let\inputRandomSeed\useLastAsSeed + \let\useRandomSeed\useThisSeed}{} +\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} +\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} +\AtEndDocument{\rt@writeSeedData}% +\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}}} +\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 + \global\rt@nameedef{\rt@BaseName-List}{\the\rt@listOut}} +\def\rt@randomizeList{\let\\=\rt@processi + \setrannum{\rt@getRanNum}{1}{\the\rt@nMax}% +\ifrtdebug\typeout{\string\rt@getRanNum=\the\rt@getRanNum}\fi + \rt@nCnt\z@ +\ifrtdebug\typeout{LISTING: \the\rt@listIn}\fi + \the\rt@listIn + \rt@loopTest +} +\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}% + \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 +} +\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}}% +\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 +} +\def\rt@modarith#1#2{\count\z@=#1\relax\count\tw@=#1\relax + \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@}} +\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}% +} +\def\ranToks#1{\begingroup + \useRTName{#1}% + \r@nToks +} +\long\def\r@nToks#1{\rt@nMax\z@\r@ndToks#1\rt@NIL} +\def\rt@NIL{@nil} +\newcommand{\useRTName}[1]{\gdef\rt@BaseName{#1}}% +\let\rt@BaseName\@empty +\newcommand{\bRTVToks}[1]{\rt@nCnt\z@\useRTName{#1}} +\newcommand{\eRTVToks}{\global + \rt@nameedef{\rt@BaseName Cnt}{\the\rt@nCnt}% + \expandafter\r@nVToks\expandafter{\rt@BaseName}} +\def\reVerbEnd{\ifhmode\unskip\fi} +\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 + \verbatimwrite +}{% + \endverbatimwrite + \immediate\write\rt@Verb@write{\string\reVerbEnd}% + \immediate\closeout\rt@Verb@write +} +\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@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}} +\def\rt@PAR{\par} +\long\def\r@ndToks#1{\def\rt@rgi{#1}% + \ifx\rt@rgi\rt@PAR\def\rt@next{\r@ndToks}\else + \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} +\def\rt@performRanDefns#1{% + \rt@RandomizeList{#1}\rt@nCnt\z@ + \let\\\rt@ssign\the\rt@listOut} +\def\rt@endToks{\global + \rt@nameedef{nMax4\rt@BaseName}{\the\rt@nMax}% + \rt@performRanDefns{\the\rt@nMax}\endgroup} +\def\reorderRanToks#1{\begingroup\useRTName{#1}\expandafter + \ifx\csname nMax4#1\endcsname\relax + \rt@badTokName{#1}\else + \rt@performRanDefns{\@nameuse{nMax4#1}}\fi +\endgroup} +\newcommand\copyRanToks[2]{\begingroup\expandafter + \ifx\csname nMax4#1\endcsname\relax + \rt@badTokName{#1}% + \else\expandafter + \ifx\csname nMax4#2\endcsname\relax + \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 + \rt@warnTokName{#2}\fi + \fi +\endgroup} +\def\rt@ssign#1{\advance\rt@nCnt\@ne\global + \rt@nameedef{rtRanTok\the\rt@nCnt\rt@BaseName}{\noexpand + \@nameuse{rtTok#1\rt@BaseName}}} +\newcommand{\nToksFor}[1]{\expandafter + \ifx\csname nMax4#1\endcsname\relax + \textbf{??}\rt@badTokName{#1}\else + \@nameuse{nMax4#1}\fi} +\newcommand{\rtTokByNum}[2][\rt@BaseName]{\expandafter + \ifx\csname nMax4#1\endcsname\relax + \textbf{??}\rt@badTokName{#1}\else + \@nameuse{rtTok#2#1}\expandafter\ignorespaces\fi} +\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}}% + \rt@badIndex{#2}{#1}\@nameuse{rtRanTok\rt@mod#1}\else + \@nameuse{rtRanTok#2#1}\fi\fi\egroup} +\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 + \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 +} +\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} +\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 +\endinput +%% +%% End of file `ran_toks.sty'. |