diff options
author | Karl Berry <karl@freefriends.org> | 2021-01-25 22:07:26 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2021-01-25 22:07:26 +0000 |
commit | 6d43e49e73d6a7bead2c0f4eabe85242cf7b200b (patch) | |
tree | 859451473f27cd242ebf73a5a56e8e566a515482 | |
parent | 5ad1fa692489b668a06f329a4d8a5c0cec34e096 (diff) |
ran_toks (25jan21)
git-svn-id: svn://tug.org/texlive/trunk@57520 c570f23f-e606-0410-a88d-b1316a301751
22 files changed, 1340 insertions, 261 deletions
diff --git a/Master/texmf-dist/doc/latex/ran_toks/README.md b/Master/texmf-dist/doc/latex/ran_toks/README.md index c4c67686b7a..8c3b618c71c 100644 --- a/Master/texmf-dist/doc/latex/ran_toks/README.md +++ b/Master/texmf-dist/doc/latex/ran_toks/README.md @@ -1,6 +1,6 @@ The ran_toks Package Author: D. P. Story -Dated: 2019-12-28 +Dated: 2021-01-19 This short package, with minimal requirements, defines macros for randomizing a list of tokens. There are two approaches: @@ -40,7 +40,15 @@ 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 (2019-12-28 ) Defined \rtVWHook to insert at the top of the +What's New (2021-01-19) A new option, usedbapp, was added to +support a DB application. Extensive work was done on the DB +application. Added \uniqueXDBChoicesOn, which if expanded, tries +to choose a random token that has not already been chosen, +across versions of a multi-version eqexam document. Changes are +discussed in the documentation and in the new examples in the +distribution. + +What's New (2019-12-28) Defined \rtVWHook to insert at the top of the rtVW environment. Also created an alternate package name of ran-toks. What's new in v1.1: Added the convenience command \useTheseDBs to input files for diff --git a/Master/texmf-dist/doc/latex/ran_toks/docs/ran_toks.pdf b/Master/texmf-dist/doc/latex/ran_toks/docs/ran_toks.pdf Binary files differindex 8896ea676cb..bfc8e7bc9b2 100644 --- a/Master/texmf-dist/doc/latex/ran_toks/docs/ran_toks.pdf +++ b/Master/texmf-dist/doc/latex/ran_toks/docs/ran_toks.pdf diff --git a/Master/texmf-dist/doc/latex/ran_toks/docs/rantoks_man.pdf b/Master/texmf-dist/doc/latex/ran_toks/docs/rantoks_man.pdf Binary files differindex 8d7c1e06e9e..62ee68da81c 100644 --- a/Master/texmf-dist/doc/latex/ran_toks/docs/rantoks_man.pdf +++ b/Master/texmf-dist/doc/latex/ran_toks/docs/rantoks_man.pdf diff --git a/Master/texmf-dist/doc/latex/ran_toks/docs/rantoks_man.tex b/Master/texmf-dist/doc/latex/ran_toks/docs/rantoks_man.tex index c17c9e9a7e4..8f8b0c6246b 100644 --- a/Master/texmf-dist/doc/latex/ran_toks/docs/rantoks_man.tex +++ b/Master/texmf-dist/doc/latex/ran_toks/docs/rantoks_man.tex @@ -1,8 +1,9 @@ +\RequirePackage[!use=preview,!use=efpmca,!use=usebw]{spdef} \documentclass{article} \usepackage[fleqn]{amsmath} \usepackage[ web={centertitlepage,designv,forcolorpaper, - latextoc,pro}, %tight, + latextoc,extended}, eforms,aebxmp ]{aeb_pro} \usepackage{ran_toks} @@ -16,6 +17,7 @@ \let\pkg\textsf \let\env\texttt +\let\opt\textsf %\rtdebugtrue %\ranToksOn @@ -50,6 +52,19 @@ \def\takeMeasurei#1{\global\setbox\webtempboxi\hbox{\ttfamily#1}\egroup} \def\bxSize{\wd\webtempboxi+2\fboxsep+2\fboxrule} +\newcommand{\FmtMP}[2][0pt]{\mbox{}\marginpar{% + \raisebox{.5\baselineskip+#1}{% + \expandafter\parbox\expandafter[\parboxValign]% + {\marginparwidth}{\aebbkFmtMp#2}}}} +\def\aebbkFmtMp{\kern0pt\itshape\small + \ifusebw\color{gray}\else\color{blue}\fi + \raggedleft\hspace{0pt}}\newcommand{\BlogArticle}{% + \makebox[0pt][l]{\hspace{-1pt}\color{blue}\Pisymbol{webd}{254}% + }\raisebox{.5pt}{\ifusebw\color{black}\else + \color{red}\fi\ding{045}}} +\def\parboxValign{t} + + \usepackage[active]{srcltx} \let\amtIndent\leftmargini @@ -72,8 +87,8 @@ email={dpstory@acrotex.net}, subject=Documentation for the ran\_toks package, talksite={\url{www.acrotex.net}}, - version={1.2, 2019/12/28}, - Keywords={LaTeX,PDF,random, tokens, JavaScript,Adobe Acrobat}, + version={1.3.1, 2021/01/19}, + Keywords={LaTeX, PDF, random, tokens, JavaScript, Adobe Acrobat}, copyrightStatus=True, copyrightNotice={Copyright (C) \the\year, D. P. Story}, copyrightInfoURL={http://www.acrotex.net} @@ -155,37 +170,65 @@ _path=_path.substring(0,pos)+"/"+manualfilename; \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 +is long overdue; users of \textsf{\textbf{AeB}} and of \pkg{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: +\newtopic\noindent\exSrc The \texttt{examples} folder contains nine 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 + \item \texttt{ran-toks.tex} reproduces the sample code of this manual. + \item \texttt{rt-tst-eqe.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 + \item \texttt{rt-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 + \item \texttt{rt-cb.tex} is a demonstration of how to use the + \pkg{collectbox} package to place verbatim content into a token list + (see \cs{ranToks}, \hyperref[s:ranToks]{Section~\ref*{s:ranToks}}). +\xdef\svEnumi{\the\value{enumi}} +\end{enumerate} +The next five files concern the DB application and require the \opt{usedbapp} option, +they are discussed in \hyperref[s:DBApp]{Section~\ref*{s:DBApp}}. +\begin{enumerate}\setcounter{enumi}{\svEnumi} + \item \texttt{mc-db.tex} is an \pkg{eqexam} file, 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. + to \hyperref[s:DBApp]{Section~\ref*{s:DBApp}} for a few more details. + \item \texttt{mc-dbu.tex} is an \pkg{eqexam} file that draws from the + database test file, 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. However, \texttt{mc-dbu.tex} + differs from \texttt{mc-db.tex} for it selects unique questions + cross the four versions of the document. Refer to + \hyperref[s:DBApp]{Section~\ref*{s:DBApp}} for a few more details. + \item \texttt{viewDB.tex} A demo file of how to view the DB files for + the purpose of reviewing the questions, modifying them, or adding + to them. + \item \texttt{mc-dbu-ctrld.tex} is a variation on \texttt{mc-dbu.tex}, + it is not meant to be compiled directly, but by the file + \texttt{ctrl-build.tex}. + \item \texttt{ctrl-build.tex} is a simple TEX file that controls the + compilation of a targeted file (\texttt{mc-dbu-ctrld.tex} in this + example) over the various versions supported by the targeted file. + Try it, you'll like it. Uses the \pkg{shellesc} package to control + the process. \end{enumerate} \section{The Preamble and Package Options} The preamble for this package is -\bVerb\takeMeasure{\string\usepackage\darg{ran\_toks}}% +\bVerb\takeMeasure{\string\usepackage[\ameta{options}]\darg{ran\_toks}}% \begin{minipage}{\bxSize}\kern0pt -\begin{Verbatim}[frame=single] -\usepackage{ran_toks} +\begin{Verbatim}[frame=single,commandchars=!()] +\usepackage[!ameta(options)]{ran_toks} \end{Verbatim} \end{minipage}\eVerb -The package itself has no options. +The one option of \pkg{ran\_toks} is \opt{usedbapp}\FmtMP{\opt{usedbapp} option}, which brings in +specialized code to support a database test application. This option is +discussed in \hyperref[s:DBApp]{Section~\ref*{s:DBApp}}, beginning on page~\pageref*{s:DBApp}. The requirements for \textsf{ran\_toks} are the \textsf{verbatim} package (part of the standard {\LaTeX} distribution, and the macro file @@ -198,52 +241,52 @@ 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} +\subsection{The \texorpdfstring{\protect\cs{ranToks}}{\CMD{ranToks}} command}\label{s:ranToks} The \cs{ranToks} command was the original concept; declare a series of tokens to be randomized. -\bVerb\takeMeasure{\string\ranToks\darg{\meta{name}}\{\%\enspace}% +\bVerb\takeMeasure{\string\ranToks\darg{\ameta{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))} +\ranToks{!ameta(name)}{% +!quad{!ameta(token!SUB(1))} +!quad{!ameta(token!SUB(2))} +!quad... +!quad{!ameta(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 +were \ameta{token\SUB{k}} is any non-verbatim content;\footnote{However, for workarounds, see +\texttt{rt-cb.tex} and \texttt{rt-tst-qz.tex.}} each token is enclosed in braces +(\darg{}), this is required. The \ameta{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. +\cs{ranToks} commands must have a different \ameta{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}}}% +\bVerb\takeMeasure{\string\nToksFor\darg{\ameta{name}}}% \begin{minipage}{\bxSize}\kern0pt \begin{Verbatim}[frame=single,commandchars=!()] -\nToksFor{!meta(name)} +\nToksFor{!ameta(name)} \end{Verbatim} \end{minipage}\eVerb -The one argument is \meta{name}, and will expand to the total number +The one argument is \ameta{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}}}% +\bVerb\takeMeasure{\string\useRTName\darg{\ameta{name}}}% \begin{minipage}{\bxSize} \begin{Verbatim}[frame=single,commandchars=!()] -\useRanTok{!meta(num)} -\useRTName{!meta(name)} +\useRanTok{!ameta(num)} +\useRTName{!ameta(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{nToksFor\darg{\ameta{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 @@ -285,10 +328,10 @@ arguments.\footnote{{\ttfamily\string\ranToks\darg{myPals}\darg{\darg{Jim}\darg{ 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}}}% +\bVerb\takeMeasure{\string\reorderRanToks\darg{\ameta{name}}}% \begin{minipage}{\bxSize}\kern0pt \begin{Verbatim}[frame=single,commandchars=!()] -\reorderRanToks{!meta(name)} +\reorderRanToks{!ameta(name)} \end{Verbatim} \end{minipage}\eVerb Now, executing \verb~\reorderRanToks{myPals}~ and compiling the sentence again yields, ``I have {\nToksFor{myPals}} pals, they are @@ -297,7 +340,7 @@ An alternative to re-executing \cs{ranToks} is to use the \cs{reorderRanToks} co 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 +The \cs{reorderRanToks\darg{\ameta{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 @@ -327,36 +370,55 @@ and verbatim environments. 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}}}% +\bVerb\takeMeasure{\string\bRTVToks\darg{\ameta{name}}}% +%\edef\WIDTH{\the\wd\webtempboxi}% +\def\1{\rlap{\hspace*{\linewidth}\texttt{\%{\sffamily{ \raisebox{1pt}{<--}Begin token listing}}}}}% +\def\2{\rlap{\hspace*{\linewidth}\texttt{\%{\sffamily{ \raisebox{1pt}{<--}End token listing}}}}}% +%\takeMeasure{\string\bRTVToks\darg{\ameta{name}}\quad\%{\sffamily{ <-Begin token listing}}}% \begin{minipage}{\bxSize}\kern0pt \begin{Verbatim}[frame=single,commandchars=!()] -\bRTVToks{!meta(name)}!quad% <-!sffamily( Begin token listing) +!1\bRTVToks{!ameta(name)} \begin{rtVW} -!qquad!ameta(content!SUB(1)) +!quad!ameta(content!SUB(1)) \end{rtVW} ... ... \begin{rtVW} -!qquad!ameta(content!SUB(n)) +!quad!ameta(content!SUB(n)) \end{rtVW} -!1\eRTVToks +!2\eRTVToks \end{Verbatim} \end{minipage}\eVerb -The \cs{bRTVToks}\texttt{\{\meta{name}\}} command begins the (pseudo) +%\bVerb\takeMeasure{\string\bRTVToks\darg{\ameta{name}}\quad}% +%\edef\WIDTH{\the\wd\webtempboxi}% +%\def\1{\rlap{\hspace*{\WIDTH}\texttt{\% <-{\sffamily{ End token listing}}}}}% +%\takeMeasure{\string\bRTVToks\darg{\ameta{name}}\quad\% <-{\sffamily{ Begin token listing}}}% +%\begin{minipage}{\bxSize}\kern0pt +%\begin{Verbatim}[frame=single,commandchars=!()] +%\bRTVToks{!ameta(name)}!quad% <-!sffamily( Begin token listing) +%\begin{rtVW} +%!quad!ameta(content!SUB(1)) +%\end{rtVW} +%... +%... +%\begin{rtVW} +%!quad!ameta(content!SUB(n)) +%\end{rtVW} +%!1\eRTVToks +%\end{Verbatim} +%\end{minipage}\eVerb +The \cs{bRTVToks}\texttt{\darg{\ameta{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} +(based on the parameter \ameta{name}). Later, using the \cs{useRanTok} commands, they are input back into the document in a random order. -The \env{rtWVW} environment also writes the command +The \env{rtVW} environment also writes the command \cs{RTVWHook}\marginpar{\small\itshape\flushright\cs{RTVWHook}} to the top of -the file. Its initial value is \cs{relax}. It can be redefined using the convenience -command \cs{rtVWHook\darg{\ameta{arg}}}, which expands to +the file. Its initial value is \cs{relax}. It can be redefined with +\cs{rtVWHook\darg{\ameta{arg}}}, which expands to \verb|\def\RTVWHook{|\ameta{arg}\verb|}|. The use of \cs{useRTName} and \cs{useRanTok} were explained and illustrated @@ -436,7 +498,7 @@ The command \cs{copyRanToks} works for list created by \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 +explicitly listed as \cs{item \cs{useRanTok\darg{1}}} and so on; an alternate approach is to use the command \cs{displayListRandomly}, like so, \begin{Verbatim}[xleftmargin=\amtIndent] \begin{enumerate} @@ -444,17 +506,17 @@ alternate approach is to use the command \cs{displayListRandomly}, like so, \end{enumerate} \end{Verbatim} The full syntax for \cs{displayListRandomly} is displayed next. -\bVerb\takeMeasure{\string\displayListRandomly[\ameta{prior}][\ameta{post}]\darg{\meta{name}}}% +\bVerb\takeMeasure{\string\displayListRandomly[\ameta{prior}][\ameta{post}]\darg{\ameta{name}}}% \begin{minipage}{\bxSize}\kern0pt \begin{Verbatim}[frame=single,commandchars=!()] -\displayListRandomly[!ameta(prior)][!ameta(post)]{!meta(name)} +\displayListRandomly[!ameta(prior)][!ameta(post)]{!ameta(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 +are listed in the \ameta{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 +goes from~1 to \cs{nToksFor\darg{\ameta{name}}}. In the example above, +\ameta{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, @@ -492,16 +554,16 @@ 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}}}% +It is, +\bVerb\takeMeasure{\string\useRanTok[\ameta{name}]\darg{\ameta{num}}}% \begin{minipage}{\bxSize}\kern0pt \begin{Verbatim}[frame=single,commandchars=!()] -\useRanTok[!meta(name)]{!meta(num)} +\useRanTok[!ameta(name)]{!ameta(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}}}, +The optional first parameter specifies the \ameta{name} of the list from +which to draw a random token; \ameta{num} is the number of the +token in the range of 1 and \cs{nToksFor\darg{\ameta{name}}}, inclusive. The optional argument is useful in special circumstances when you want to mix two random lists together. @@ -517,23 +579,23 @@ 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}}}% +\bVerb\takeMeasure{\string\rtTokByNum[\ameta{name}]\darg{\ameta{num}}}% \begin{minipage}{\bxSize}\kern0pt \begin{Verbatim}[frame=single,commandchars=!()] -\rtTokByNum[!meta(name)]{!meta(num)} +\rtTokByNum[!ameta(name)]{!ameta(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.) +This command expands to the token declared in the list named \ameta{name} +that appears at the \ameta{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}\}}. +In some sense, \cs{rtTokByNum[\ameta{name}]} acts like a simple array, the +length of which is \cs{nToksFor\{\ameta{name}\}}, and whose $k^{\text{th}}$ +element is \cs{rtTokByNum[\ameta{name}]\{\ameta{k}\}}. \paragraph*{Turning off randomization.} The randomization may be turned off using \cs{ranToksOff} or turned back on with \cs{ranToksOn}. @@ -596,7 +658,7 @@ Normally, the pseudo-random number generator provided by 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 +\paragraph*{Controlling the initial seed value.}\label{para:ControlSeed} 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 @@ -612,14 +674,14 @@ exist, the generator will be initialized by its usual method, using the time and The command \cs{useThisSeed} allows you to reproduce a previous pseudo-random sequence. -\bVerb\takeMeasure{\string\useThisSeed\darg{\meta{init\_seed\_value}}}% +\bVerb\takeMeasure{\string\useThisSeed\darg{\ameta{init\_seed\_value}}}% \begin{minipage}{\bxSize}\kern0pt \begin{Verbatim}[frame=single,commandchars=!()] -\useThisSeed{!meta(init_seed_value)} +\useThisSeed{!ameta(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 +\ameta{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 @@ -653,17 +715,47 @@ If you are using \textsf{eqexam}, the process can be automated as follows: \end{Verbatim} Again, this goes in the preamble. -\section{Commands to support a DB application}\label{s:DBConcept} +\section{Commands to support a DB application}\label{s:DBApp} + +The commands described in this section are only available with the \opt{usedbapp} option, +\begin{Verbatim} +\usepackage[usedbapp]{ran_toks} +\end{Verbatim} +This option was designed for an \pkg{eqexam} document. + +\subsection{Basic functionality}\label{s:basicFunc} + +The premise here is that you have an \pkg{eqexam} document (a test) and you have a series +of standard questions you ask students. Over the years, you have accumulated questions of a similar type +that you like to pose to your students. The questions of a similar type are placed in a DB test file. For example, +you have a file named \texttt{db1.tex} containing questions on a certain narrow topic. The format for this file +is, +\begin{Verbatim}[commandchars=!()] +% +% !textsf(Questions on some narrow topic) +% +\bRTVToks{DB1} %<-!textsf(DB !ameta(name)) +\begin{rtVW} +% !textsf(an !pkg(eqexam) question is contained in this rtVW environment) +\end{rtVW} +\begin{rtVW} +% !textsf(an !pkg(eqexam) question is contained in this rtVW environment) +\end{rtVW} +... +\eRTVToks +\end{Verbatim} +Refer to the file \texttt{db1.tex}, \texttt{db2.tex},\dots, \texttt{db4.tex} for more specific +examples. The DB \ameta{name} must be unique among all the DB test files used. -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}: +The next step is to input your DB files. To do this, execute either of the commands +\cs{useTheseDBs} or \cs{useProbDBs} prior to the opening of an \env{exam} environment (\pkg{eqexam}), +or perhaps in the preamble. The syntax is, \bVerb\takeMeasure{\string\useTheseDBs\darg{\ameta{db\SUB{1}},\ameta{db\SUB{2}},...,\ameta{db\SUB{n}}}}% -\begin{minipage}{\bxSize}\kern0pt +\setlength\eflength{\bxSize}% +\begin{minipage}{\bxSize}\kern0pt\def\1{\rlap{\sffamily\hskip\eflength(An alias for \cs{useTheseDBs})}}\relax \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))} +!1\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 @@ -678,11 +770,190 @@ emitted if one or more of the files are not found. The default extension is \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. +Once the database files have been input, in the body of the document you can extract +questions using \cs{useRanTok}; for example, \cs{useRanTok[DB1]\darg{1}} extracts the question +with an index of 1 from the database file DB1;\footnote{It is assumed that DB1 is the \ameta{name} +is the required argument of \cs{bRTVToks}, which is declared in the \texttt{db1.tex} file.} \cs{useRanTok[DB2]\darg{2}} extracts the question +with an index of 2 from the database file DB2, and so on. Refer to the demonstration file \texttt{mc-db.tex} for an example. +\subsection{Striving for uniqueness of choices} + +By default, when you expand \cs{useRanTok\darg{1}} and later you expand +\cs{useRanTok\darg{1}} again you get the exact same result;\footnote{Here, we +are assuming the \ameta{name} of the token list is the same for both +expansions of \cs{useRanTok\darg{1}}.} this is the normal behavior. However, +in the context of posing questions from a database of questions, repeating +the questions is not what is wanted necessarily. In the next two subsections, +we speak to the problem, first within a single-version document, and +secondly, within a multi-version document. + + +\subsubsection{For documents with a single version} + +The issue of not wanting to repeat a question from a database comes up when +you want to pose several questions from a given database file. We illustrate +using the demo file \texttt{mc-db.tex} found in the \texttt{examples} folder. +In that file, the exam has two parts, as shown in +\hyperref[fig:2prts]{Figure~\ref*{fig:2prts}}.\footnote{The verbatim listing +here has been simplified.} +\begin{figure}[htb]\centering +\settowidth{\eflength}{\ttfamily\string\useRanTok[DB1]\darg{1}}% +\edef\x{\the\eflength}% +\setlength\eflength{\x+\widthof{\textsf{\quad\%An alternate approach}\texttt{ }}}% +\def\0{\rlap{\hskip\x\relax\quad\% \textsf{An alternate approach}}}% +\def\1{\rlap{\hskip\x\relax\quad\% \cs{begin\darg{Part2}}}}% +\def\2{\rlap{\hskip\x\relax\quad\% \cs{useRanTok[DB1]\darg{3}}}}% +\def\3{\rlap{\hskip\x\relax\quad\% \cs{useRanTok[DB1]\darg{4}}}}% +\def\4{\rlap{\hskip\x\relax\quad\% \cs{end\darg{Part2}}}}% +\fboxsep0pt +\begin{minipage}{\eflength} +\begin{Verbatim}[commandchars=!()] +\begin{Part1} +\useRanTok[DB1]{1} +\useRanTok[DB1]{2} +\end{Part1} + +!0% !textsf( First approach) +!1\begin{Part2} +!2\useRanTok[DB1]{1} +!3\useRanTok[DB1]{2} +!4\end{Part2} +\end{Verbatim} +\end{minipage} +\caption{Simplified two-part exam}\label{fig:2prts} +\end{figure} +For \textsf{Part1}, we take two problems (at random) from \textsf{DB1}. In +\textsf{Part2}, we take two problems again from \textsf{DB1}; these two will +be the \emph{same} as the ones chosen from \textsf{Part1}. To get two +\emph{different} questions the natural approach is to write +\cs{useRanTok[DB1]\darg{3}} and \cs{useRanTok[DB1]\darg{4}}, as shown on the +right in \hyperref[fig:2prts]{Figure~\ref*{fig:2prts}}. Now, returning to the \textsf{First approach}, there is a way of forcing +\pkg{ran\_toks} to choose two different question even though the indexes used are the same. + +To have different questions appear when you specify \verb~\useRanTok[DB1]{1}~ +and \verb~\useRanTok[DB1]{2}~, first expand the command +\cs{uniqueXDBChoicesOn}, perhaps between parts or in the preamble. When +\cs{uniqueXDBChoicesOn} is expanded, \cs{useRanTok} tries to find an +``unused'' choice. +\begin{Verbatim}[xleftmargin=\parindent,commandchars=!()] +\uniqueXDBChoicesOn +\begin{document} +... +\begin{Part1} +\useRanTok[DB1]{1} +\useRanTok[DB1]{2} +\end{Part1} + +%\uniqueXDBChoicesOn + +\begin{Part2} +\useRanTok[DB1]{1} +\useRanTok[DB1]{2} +\end{Part2} +\end{Verbatim} +The command \cs{uniqueXDBChoicesOff} turns off the feature of striving to +find ``unused'' choices. Additional discussion on \cs{uniqueXDBChoicesOn} is +found in the next section; the command \cs{InputUsedIDs}, discussed in the +next section, is not needed when the \pkg{eqexam} document \emph{does not +have} multiple versions. You can experiment with striving to find unused +questions in the demo file \texttt{mc-db.tex}. + +\subsubsection{For documents with multiple versions} + +The scheme outlined in \hyperref[s:basicFunc]{Section~\ref*{s:basicFunc}} works well for an +\pkg{eqexam} document that only has one version in the source file. The way +\pkg{ran\_toks} works, it will not repeat random choices --- unless you +sample from a same DB file more times than there are problems in that file; +for example, suppose \texttt{db1.tex} has two questions in it, if you execute +\cs{useRanTok[DB1]\darg{1}}, \cs{useRanTok[DB1]\darg{2}}, and +\cs{useRanTok[DB1]\darg{3}}, then the problem selected by +\cs{useRanTok[DB1]\darg{3}} is the same as \cs{useRanTok[DB1]\darg{1}}. This +latter situation is not likely, is it? + +One of the very powerful features of \pkg{eqexam} is that a single source +file can have multiple versions in it. +\begin{Verbatim}[xleftmargin=\parindent,commandchars=!()] +\examNum{1} +\numVersions{4} +\forVersion{a} %!textsf( a, b, c, d) +\vA{\useThisSeed{54356}} +\vB{\useThisSeed{577867}} +\vC{\useThisSeed{6746788}} +\vD{\useThisSeed{856785}} +\end{Verbatim} +The above shows how to set up a multi-version \pkg{eqexam} document, see the +\pkg{eqexam} documentation for more details. Here, as in the demo file +\texttt{mc-dbu.tex}, we declare 4 versions (a, b, c, and d). +\cs{forVersion\darg{a}} declares the next compile is for version a (or A, +either one). List also is a method of passing an initial seed to the +pseudo-random number generator, for each version. (These can be arbitrarily +typed in, or obtained by the methods discussed in +\textbf{\nameref{para:ControlSeed}} on page~\pageref*{para:ControlSeed}.) + +\paragraph*{The problem.} For a multi-version \pkg{eqexam} document, where +each version samples from the same set of DB Test files, later versions of the exam +may have questions that are repeats of the ones posed in earlier versions of +the same source file. This may or may not be a problem if the different +versions are given to different classes at approximately the same time where +there is no opportunity for the details of the test to ``leak out'' from one +class to another. + +\paragraph*{The solution.} The solution to this problem requires the introduction of several +new commands. +\bVerb\takeMeasure{\string\uniqueXDBChoicesOn}% +\setlength\eflength{\bxSize}% +\begin{minipage}{\bxSize}\kern0pt\def\1{\rlap{\sffamily\hskip\eflength\%\textsf{ to view the IDs of problems used}}}\relax +\def\2{\rlap{\sffamily\hskip\eflength\%\textsf{ preamble only (required)}}}\relax +\def\3{\rlap{\sffamily\hskip\eflength\%\textsf{ there is also \cs{uniqueXDBChoicesOff} (the default)}}}\relax +\begin{Verbatim}[frame=single,commandchars=!()] +!3\uniqueXDBChoicesOn +!2\InputUsedIDs +!1%\viewIDstrue +\end{Verbatim} +\end{minipage}\eVerb The \cs{uniqueXDBChoicesOn} command +brings some special code into the \cs{useRanTok} command; this special code +tries to select problems that have not already been selected by earlier +versions of the source document. Key to this selection process is that the +special code needs to know which questions were earlier selected; that is the +role of the \cs{InputUsedIDs}. This latter command uses the value declared in +\cs{numVersions}, so it must appear \emph{after} the declaration of the +number of versions. + +When \cs{uniqueXDBChoicesOn} is expanded, as the source document is compiled, +an auxiliary file named \cs{jobname-ver\ameta{Ltr}.cut} is written. This +file keeps a record of the problem ID of the problems selected, believe it or +not. \cs{InputUsedIDs} inputs the appropriate CUT files: +\begingroup\tightsettings +\begin{itemize} +\item for version B, \cs{jobname-verA.cut} is input; +\item for version C, \cs{jobname-verA.cut}, \cs{jobname-verB.cut} are input; +\item for version D, \cs{jobname-verA.cut}, \cs{jobname-verB.cut}, \cs{jobname-verC.cut} are input; +\item and so on. +\end{itemize} +\endgroup\noindent +In this way, when you compile version \ameta{Ltr}, the document inputs all +the information it needs about previous versions to make in informed choice. + +\paragraph*{Workflow.} When compiling a multi-version \pkg{eqexam} document, do the following: +\begin{enumerate} + \item Build each version in \emph{alphabetical order}, that is, compile with \cs{forVersion\darg{a}}, + then \cs{forVersion\darg{b}}, and so on. + \item Rename PDF produced to reflect the version \ameta{Ltr}; eg, \verb~\jobname-verA.pdf~ or + \verb!\jobname-sec02.pdf!, or whatever.\footnote{The demo file \texttt{ctrl-build.tex} shows + how to build all versions and rename the final PDF files all from one controlling file.} +\end{enumerate} + +%\paragraph*{Final comments.} \cs{uniqueXDBChoicesOn} does several things, it causes \cs{useRanTok} +%to use some special code to ensure cross-version uniqueness of choices, but +%it also initiates writing of the choice history to the auxiliary CUT files +%\cs{jobname-ver\ameta{Ltr}.cut}. By placing \cs{uniqueXDBChoicesOff} in +%the body of the document (outside a group, perhaps) that turns off the +%execution of the special code as well and writing to the CUT files. I believe +%you can later in the document turn this back on with \cs{uniqueXDBChoicesOn}, +%though I have not done a lot of testing of this. + \newtopic\noindent Now, I simply must get back to my retirement. \dps diff --git a/Master/texmf-dist/doc/latex/ran_toks/examples/ctrl-build.tex b/Master/texmf-dist/doc/latex/ran_toks/examples/ctrl-build.tex new file mode 100644 index 00000000000..c5401a303d9 --- /dev/null +++ b/Master/texmf-dist/doc/latex/ran_toks/examples/ctrl-build.tex @@ -0,0 +1,58 @@ +\documentclass{article} +\usepackage{shellesc} +\usepackage{fancyvrb} + +\newif\ifcompileit \compileittrue + +\begin{document} + +\noindent +This is a dummy file to help compile multiple versions of the same source file. +The commands are very simple, they can be improved in a variety of ways. + +\def\basename{mc-dbu-ctrld} % base name of target file +\def\altbasename{mc-dbu} % base name of output file +% define a simple \forVersion command, convert letter to upper case +\def\forVersion#1{\uppercase{\edef\selVersion{#1}}} + +% select the version letter (upper or lower case) +\forVersion{a} +% define a suffix that follows \altbasename, redefine as desired +\edef\altsuffix{% + \if\selVersion Asec01\else + \if\selVersion Bsec02\else + \if\selVersion Csec03\else + \if\selVersion Dsec04\fi\fi\fi\fi} + +\begin{VerbatimOut}[commandchars=!()]{build-info.tex} +\examNum{1} +\numVersions{4} +\forVersion{!selVersion} +\vA{\useThisSeed{54356}} +\vB{\useThisSeed{577867}} +\vC{\useThisSeed{6746788}} +\vD{\useThisSeed{856785}} +%\viewIDstrue % to view the IDs of problems used +\end{VerbatimOut} + +\medskip\noindent +Compiling the file \texttt{\basename.tex} for version~\selVersion\space(\altsuffix), and renaming the final +PDF produced to \texttt{\altbasename-\altsuffix.pdf} + + +\ifcompileit + +% compile using the PDF creator of your choice, copy and paste this next +% line to execute multiple compiles to bring labels, if any, up to date +\ShellEscape{pdflatex \basename} +%\ShellEscape{pdflatex \basename} +%\ShellEscape{pdflatex \basename} + +% copy the newly created file to a new file name +\ShellEscape{move \basename.pdf \altbasename-\altsuffix.pdf} +% delete build-info.tex +\ShellEscape{del build-info.tex} + +\fi + +\end{document}
\ No newline at end of file diff --git a/Master/texmf-dist/doc/latex/ran_toks/examples/db1.tex b/Master/texmf-dist/doc/latex/ran_toks/examples/db1.tex index 45a8b671246..f51bf5b74b9 100644 --- a/Master/texmf-dist/doc/latex/ran_toks/examples/db1.tex +++ b/Master/texmf-dist/doc/latex/ran_toks/examples/db1.tex @@ -1,7 +1,7 @@ % % First DB, uses ran_toks and eqexam % -\bRTVToks{DB1-} +\bRTVToks{DB1} \begin{rtVW} \begin{problem}[5] diff --git a/Master/texmf-dist/doc/latex/ran_toks/examples/db2.tex b/Master/texmf-dist/doc/latex/ran_toks/examples/db2.tex index dc18b86faad..bb1cfb8e758 100644 --- a/Master/texmf-dist/doc/latex/ran_toks/examples/db2.tex +++ b/Master/texmf-dist/doc/latex/ran_toks/examples/db2.tex @@ -2,7 +2,7 @@ % Second DB, uses ran_toks and eqexam % -\bRTVToks{DB2-} +\bRTVToks{DB2} \begin{rtVW} \begin{problem}[5] @@ -62,4 +62,4 @@ DB2: Fourth: Which is correct? \eRTVToks -\endinput
\ No newline at end of file +\endinput
\ No newline at end of file diff --git a/Master/texmf-dist/doc/latex/ran_toks/examples/db3.tex b/Master/texmf-dist/doc/latex/ran_toks/examples/db3.tex index 1948692f1f8..099eeb2c7b1 100644 --- a/Master/texmf-dist/doc/latex/ran_toks/examples/db3.tex +++ b/Master/texmf-dist/doc/latex/ran_toks/examples/db3.tex @@ -2,7 +2,7 @@ % Third DB, uses ran_toks and eqexam % -\bRTVToks{DB3-} +\bRTVToks{DB3} \begin{rtVW} \begin{problem}[5] @@ -62,4 +62,4 @@ DB3: Fourth: Which is correct? \eRTVToks -\endinput
\ No newline at end of file +\endinput
\ No newline at end of file diff --git a/Master/texmf-dist/doc/latex/ran_toks/examples/db4.tex b/Master/texmf-dist/doc/latex/ran_toks/examples/db4.tex index 64b1d241ef3..b6b4556a6fc 100644 --- a/Master/texmf-dist/doc/latex/ran_toks/examples/db4.tex +++ b/Master/texmf-dist/doc/latex/ran_toks/examples/db4.tex @@ -2,7 +2,7 @@ % Fourth DB, uses ran_toks and eqexam % -\bRTVToks{DB4-} +\bRTVToks{DB4} \begin{rtVW} \begin{problem}[5] @@ -62,4 +62,4 @@ DB4: Fourth: Which is correct? \eRTVToks -\endinput
\ No newline at end of file +\endinput
\ No newline at end of file diff --git a/Master/texmf-dist/doc/latex/ran_toks/examples/mc-db.tex b/Master/texmf-dist/doc/latex/ran_toks/examples/mc-db.tex index 1eb2ce548a5..549da16f2ce 100644 --- a/Master/texmf-dist/doc/latex/ran_toks/examples/mc-db.tex +++ b/Master/texmf-dist/doc/latex/ran_toks/examples/mc-db.tex @@ -1,7 +1,9 @@ -\documentclass{article} -\usepackage[allowrandomize,nosolutions, - forpaper,pointsonleft,noparttotals]{eqexam} -\usepackage{ran_toks} +\documentclass[a4paper]{article} +\usepackage[% + allowrandomize, + nosolutions, + forpaper,pointsonleft,noparttotals]{eqexam} +\usepackage[usedbapp]{ran_toks} \useLastAsSeed % To reproduce the same pseudo-random sequence, you need to supply a seed @@ -13,14 +15,21 @@ \subject[MC]{My Course} \date{Spring \the\year} \keywords{Test~\nExam, Section 001} - -\university + \university {% THE UNIVERSITY OF AKRON\\ Theoretical and Applied Mathematics } \email{dpstory@uakron.edu} + + +%\uniqueXDBChoicesOn +%\viewIDstrue % to view the IDs of problems used\university +%\doNotRandomizeChoices % eqexam 2021/01/20 +%\allowRandomizedChoices % eqexam 2021/01/20 + + % Input the DB files used in the demo file \useTheseDBs{db1,db2,db3,db4} @@ -38,38 +47,47 @@ This part demonstrates how to not only randomly pull problems (two from each of 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}} +\ranToksOff + +\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} +\newpage + +%\uniqueXDBChoicesOff + \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. +In this part, when \verb~\uniqueXDBChoicesOff~ (the default) is +expanded, we take the same two problems from each of the four DB +files, but here, we do not randomize the order of the questions. However, +when \verb~\uniqueXDBChoicesOn~ is expanded in the preamble, +this set of eight questions are entirely different from the ones +of \textsf{Part1}. \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} +\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/Master/texmf-dist/doc/latex/ran_toks/examples/mc-dbu-ctrld.tex b/Master/texmf-dist/doc/latex/ran_toks/examples/mc-dbu-ctrld.tex new file mode 100644 index 00000000000..0f0b9b140a1 --- /dev/null +++ b/Master/texmf-dist/doc/latex/ran_toks/examples/mc-dbu-ctrld.tex @@ -0,0 +1,62 @@ +\documentclass{article} +\usepackage[allowrandomize,nosolutions, + forpaper,pointsonleft,noparttotals]{eqexam} +\usepackage[usedbapp]{ran_toks} + +%\rtdebugtrue + +% This file is not compiled directly, but by the file ctrl-build.tex, see that file for details +\input{build-info} + +\uniqueXDBChoicesOn +\InputUsedIDs + +\title[T\nExam]{Test \nExam} +\author{D. P. Story} +\subject[MC]{My Course} +\date{Spring \the\year} +\keywords{Test~\nExam, Section 001} +\altTitle{Section~% + \if\selVersion A01\else + \if\selVersion B02\else + \if\selVersion C03\else + 04\fi\fi\fi\space(Version~\selVersion)} + +\makeInfoAWarning + +\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), but +to randomize the order they are listed in the exam. +\end{instructions} + +\ranToks{myExam} +{% + {\useRanTok[DB1]{1}} + {\useRanTok[DB2]{1}} + {\useRanTok[DB3]{1}} + {\useRanTok[DB4]{1}} +} +\displayListRandomly{myExam} + +\end{exam} + +\end{document} diff --git a/Master/texmf-dist/doc/latex/ran_toks/examples/mc-dbu.tex b/Master/texmf-dist/doc/latex/ran_toks/examples/mc-dbu.tex new file mode 100644 index 00000000000..b0790c8bbaa --- /dev/null +++ b/Master/texmf-dist/doc/latex/ran_toks/examples/mc-dbu.tex @@ -0,0 +1,75 @@ +\documentclass{article} +\usepackage[allowrandomize,nosolutions, + forpaper,pointsonleft,noparttotals]{eqexam} +\usepackage[usedbapp]{ran_toks} + +%\rtdebugtrue + +%\useLastAsSeed +% To reproduce the same pseudo-random sequence, you need to supply a seed +%\useThisSeed{1125676795} + +\examNum{1} +\numVersions{4} +\forVersion{d} +\vA{\useThisSeed{54356}} +\vB{\useThisSeed{577867}} +\vC{\useThisSeed{6746788}} +\vD{\useThisSeed{856785}} + +\uniqueXDBChoicesOn +\InputUsedIDs +\viewIDstrue % to view the IDs of problems used + +\title[T\nExam]{Test \nExam} +\author{D. P. Story} +\subject[MC]{My Course} +\date{Spring \the\year} +\keywords{Test~\nExam, Section 001} +\altTitle{Section~% + \if\selVersion A01\else + \if\selVersion B02\else + \if\selVersion C03\else + 04\fi\fi\fi\space(Version~\selVersion)} + +%\makeInfoAWarning + +\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), but to randomize the order they +are listed in the exam. +\end{instructions} + +\ranToksOff % turn off randomization of the order + +\ranToks{myExam} +{% + {\useRanTok[DB1]{1}} + {\useRanTok[DB2]{1}} + {\useRanTok[DB3]{1}} + {\useRanTok[DB4]{1}} +} +\displayListRandomly{myExam} + +\end{exam} + +\end{document} diff --git a/Master/texmf-dist/doc/latex/ran_toks/examples/ran_toks.tex b/Master/texmf-dist/doc/latex/ran_toks/examples/ran-toks.tex index e10238aa5a7..0408003d246 100644 --- a/Master/texmf-dist/doc/latex/ran_toks/examples/ran_toks.tex +++ b/Master/texmf-dist/doc/latex/ran_toks/examples/ran-toks.tex @@ -57,6 +57,7 @@ How did that other stuff get in there? \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 diff --git a/Master/texmf-dist/doc/latex/ran_toks/examples/rt-cb.tex b/Master/texmf-dist/doc/latex/ran_toks/examples/rt-cb.tex new file mode 100644 index 00000000000..c8e20e4d171 --- /dev/null +++ b/Master/texmf-dist/doc/latex/ran_toks/examples/rt-cb.tex @@ -0,0 +1,36 @@ +\documentclass{article} +\usepackage{ran_toks} +\usepackage{collectbox} + +\useLastAsSeed + +\newbox\rtcollectbox + +\parindent0pt + + +\begin{document} + +In this file, a method of placing verbatim content in as a token argument of +\verb~\ranToks~ The key is to use the \textsf{collectbox} package, and collect +the verbatim content with \verb~\collectboxto~. + +\def\cbCont{\def\myVerb{\usebox{\rtcollectbox}}} +\collectboxto{\rtcollectbox}{\cbCont}{\verb!$x^2+1$!} + +%\ranToksOff +\ranToks{CB} +{% + {Don-1} + {Kira-2} + {Alex-3} + {Jim-4} + {Rick-5} + {\myVerb-6} +} + +\useRanTok{1}, \useRanTok{2}, \useRanTok{3}, \useRanTok{4}, \useRanTok{5}, +\useRanTok{6}%, \useRanTok{7} + + +\end{document} diff --git a/Master/texmf-dist/doc/latex/ran_toks/examples/random_tst.tex b/Master/texmf-dist/doc/latex/ran_toks/examples/rt-tst-eqe.tex index 1f64c79907c..5d4d6653962 100644 --- a/Master/texmf-dist/doc/latex/ran_toks/examples/random_tst.tex +++ b/Master/texmf-dist/doc/latex/ran_toks/examples/rt-tst-eqe.tex @@ -8,8 +8,7 @@ \usepackage{ran_toks} \useLastAsSeed -%\useThisSeed{452836675} % fi,t,f,s - +%\useThisSeed{452836675} \examNum{1} \title[T\nExam]{Test \nExam} \author{D. P. Story} @@ -25,6 +24,7 @@ \email{dpstory@uakron.edu} \begin{document} + \maketitle @@ -97,7 +97,6 @@ Fourth: Which is correct? % Ok, now display this questions in a random order. \displayListRandomly{Exam\nExam} - \end{exam} \end{document} diff --git a/Master/texmf-dist/doc/latex/ran_toks/examples/random_tst_qz.tex b/Master/texmf-dist/doc/latex/ran_toks/examples/rt-tst-qz.tex index 3ca3c4043ef..07be7738833 100644 --- a/Master/texmf-dist/doc/latex/ran_toks/examples/random_tst_qz.tex +++ b/Master/texmf-dist/doc/latex/ran_toks/examples/rt-tst-qz.tex @@ -8,14 +8,16 @@ \documentclass{article} \usepackage[designiv]{web} \usepackage[allowrandomize,showgrayletters]{exerquiz} -\usepackage{ran_toks} +\usepackage{ran-toks} % alt pkg name + +% \previewOn\pmpvOn % 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 +% Once you randomize, read the auxiliary file (\jobname_rt.sav), copy the first seed listed +% and paste in as the argument of \useThisSeed. Compile a few more times to bring cross-references % up to date. %\useLastAsSeed -\useThisSeed{1327548830} +\useThisSeed{955908747} \rowsepDefault{3pt} @@ -27,7 +29,7 @@ \begin{questions} \item Try to guess the correct answer. \begin{answers}{2} - \bChoices[random] + \bChoices[random=true] \Ans0 1 a choice\eAns \Ans1\label{eq} 2 another choice\eAns \Ans0 3 still another choice\eAns @@ -38,8 +40,8 @@ \Ans0 8 too many\eAns \Ans0 9 choices\eAns \Ans0 10 \input{mytext.verb}\eAns - \eFreeze - \Ans0 10 None of these\eAns + \eFreeze + \Ans0 11 None of these\eAns \eChoices \end{answers} \end{questions} @@ -71,10 +73,10 @@ Solve each. \useRTName{myChoices} \begin{manswers}*{1} \bChoices[random=true,label=rtAns] - \Ans{1}\label{rtAns3}\rtTokByNum{1}\eAns + \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 + \Ans{0} \rtTokByNum{3}\eAns + \Ans{0} \rtTokByNum{4}\eAns \eFreeze \Ans{1} Hello mom!\eAns \eChoices @@ -110,6 +112,6 @@ The answer is \hyperref[rtAns1]{(\REF*{rtAns1})} found in the \eChoices \end{answers} \end{questions} -\end{quiz*} +\end{quiz*}\quad\ScoreField\currQuiz\CorrButton\currQuiz \end{document} diff --git a/Master/texmf-dist/doc/latex/ran_toks/examples/viewDB.tex b/Master/texmf-dist/doc/latex/ran_toks/examples/viewDB.tex new file mode 100644 index 00000000000..be9c5623b5c --- /dev/null +++ b/Master/texmf-dist/doc/latex/ran_toks/examples/viewDB.tex @@ -0,0 +1,40 @@ +\documentclass[12pt]{article} +\usepackage[usedbapp]{ran_toks} + +\usepackage[%allowrandomize, + nosolutions,forcolorpaper,pointsonleft,noparttotals]{eqexam} + +\everymath{\displaystyle} + +\examNum{1} +\title[ViewDB]{View a DB Test File} +\author{D. P. Story} +\subject[MC]{Demo file} +\university +{% + THE UNIVERSITY OF AKRON\\ + Theoretical and Applied Mathematics +} +\email{dpstory@uakron.edu} + +\useProbDBs{db1,db2,db3,db4} +\viewIDstrue + +\begin{document} + + +\begin{exam}{View} + +%%%%%%%%%%%%%%%% +% Typeset a DB % +%%%%%%%%%%%%%%%% +% The problems are input in the order they appear in the DB, the alternatives +% are not randomized either. +\viewDB{DB1} % DB1, DB2, DB3, DB4 + + +\end{exam} +\end{document} + + + 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 89aafdc826a..5549bbc01c6 100644 --- a/Master/texmf-dist/source/latex/ran_toks/ran_toks.dtx +++ b/Master/texmf-dist/source/latex/ran_toks/ran_toks.dtx @@ -4,7 +4,7 @@ %<*copyright> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% ran_toks package, %% -%% Copyright (C) 1999-2019 D. P. Story %% +%% Copyright (C) 1999-2021 D. P. Story %% %% dpstory@uakron.edu, dpstory@acrotex.net %% %% %% %% This program can redistributed and/or modified under %% @@ -16,10 +16,11 @@ %</copyright> %<package>\NeedsTeXFormat{LaTeX2e}[1997/12/01] %<package>\ProvidesPackage{ran_toks} -%<package> [2019/12/28 v1.2 Randomizing tokens (dps)] +%<package> [2021/01/19 v1.3.1 Randomizing tokens (dps)] %<*driver> \documentclass{ltxdoc} \usepackage[colorlinks,hyperindex=false]{hyperref} +\usepackage{fancyvrb} %\def\texorpdfstring#1#2{#1} %\pdfstringdefDisableCommands{\let\\\textbackslash} \OnlyDescription % comment out for implementation details @@ -37,6 +38,9 @@ \def\meta#1{\textsl{\texttt{#1}}} \def\SUB#1{\ensuremath{{}_{\mbox{\scriptsize\ttfamily#1}}}} \def\cs#1{\texttt{\bslash#1}} +\makeatletter +\let\@latex@warning@no@line\@gobble +\makeatother \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}} @@ -72,39 +76,42 @@ % \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} +%\begin{Verbatim}[xleftmargin=\parindent,fontsize=\small, +%commandchars={!()},codes={\catcode`\%=9}] +%\ranToks{!ameta(name)}{!% +%!quad{!ameta(tok!SUB1)}{!ameta(tok!SUB2)}...{!ameta(tok!SUB(n))} +%} +%\end{Verbatim} % The command defines a series of $n$ internal commands, one for each of the tokens. % The definitions are essentially randomized. The randomized tokens are accessed through -% the command \cs{useRanTok}. For example -%\begin{quote}\ttfamily -%\cs{useRanTok\darg{1}}, \cs{useRanTok\darg{2}},..., \cs{useRanTok\darg{n}} -%\end{quote} +% the command \cs{useRanTok}. For example, +%\begin{Verbatim}[xleftmargin=\parindent,fontsize=\small, +%commandchars={!()},codes={\catcode`\%=9}] +%\useRanTok{1}, \useRanTok{2},..., \useRanTok{n} +%\end{Verbatim} % gives a random listing of the $n$ tokens. These can be arranged on the page % as desired. % % There is a second construct, designed for more elaborate randomization. -%\begin{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} +%\begin{Verbatim}[xleftmargin=\parindent,fontsize=\small, +%commandchars={!()},codes={\catcode`\%=9}] +%\bRTVToks{!ameta(name)} +%\begin{rtVW} +%!quad!ameta(some content) +%\end{rtVW} +%... +%... +%\begin{rtVW} +%!quad!ameta(some content) +%\end{rtVW} +%\eRTVToks +%\end{Verbatim} % 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} +%\begin{Verbatim}[xleftmargin=\parindent,fontsize=\small, +%commandchars={!()},codes={\catcode`\%=9}] +%\useRanTok{1}, \useRanTok{2},..., \useRanTok{n} +%\end{Verbatim} % Other details are left to the readers' imagination. % % \paragraph{Requirements.} As of this writing, we require only the \texttt{verbatim} package @@ -158,11 +165,28 @@ \newif\ifrtdebug \rtdebugfalse \newif\ifwerandomize \werandomizetrue \newif\ifsaveseed\saveseedtrue +\newif\ifrt@InputUsedIDs\rt@InputUsedIDsfalse \newwrite\rt@Verb@write % \end{macrocode} +% Convenience commands. % \begin{macrocode} +\def\rtcsarg#1#2{\expandafter#1\csname#2\endcsname} \def\rt@nameedef#1{\expandafter\edef\csname #1\endcsname} % \end{macrocode} +% \leavevmode\IndexOpt{usedbapp}^^A +% The code to support a DB application has grown, so much so, it desirves +% a option so as to include the code only if needed. +% \changes{v1.3}{2021/01/14}{Added \string\opt{usedbapp} option} +% \begin{macrocode} +\DeclareOption{usedbapp}{\let\rtPkgInpt\rt@PkgInpt} +\def\rt@PkgInpt{\InputIfFileExists{rt-dbapp.def} + {\PackageInfo{ran_toks}{Inputting rt-dbapp.def}} + {\PackageInfo{ran_toks}{Cannot find rt-dbapp.def}} +} +\let\rtPkgInpt\relax +\AtEndOfPackage{\rtPkgInpt} +\ProcessOptions\relax +% \end{macrocode} % \begin{macrocode} %</package> %<*altpkgname> @@ -272,7 +296,7 @@ \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}|}| +% \DescribeMacro{\rt@RandomizeList}\hskip-\marginparsep\thinspace\texttt{\darg{\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 @@ -361,7 +385,7 @@ instead will use\MessageBreak \string\useRanTok{\rt@mod}, obtained from modular arithmetic.\MessageBreak - You might want to fix this} + You might want to fix this}% } \def\rt@badTokName#1{% \PackageWarningNoLine{ran_toks} @@ -414,14 +438,14 @@ % \cs{r@nVToks}. % \begin{macrocode} \newcommand{\eRTVToks}{\global - \rt@nameedef{\rt@BaseName Cnt}{\the\rt@nCnt}% - \expandafter\r@nVToks\expandafter{\rt@BaseName}} + \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. +% \verb!\jobname_\rt@BaseName-\the\rt@nCnt.cut!. The file is later input back into +% the source file in a random way. % J14 % \begin{macrocode} \def\reVerbEnd{\ifhmode\unskip\fi} % \end{macrocode} @@ -432,11 +456,21 @@ \def\rtVWHook#1{\def\@rgi{#1}\ifx\@rgi\@empty \let\RTVWHook\relax\else\def\RTVWHook{#1}\fi} \rtVWHook{} +\newwrite\wrtprobids +\newif\ifviewIDs\viewIDsfalse +\newif\ifxDBUnique\xDBUniquefalse +\def\wrtProbIds#1{\immediate\write\wrtprobids{\string + \rtcsarg\string\gdef{#1}{used}}} +\def\rtVWId#1{\ifviewIDs\noindent#1\fi + \ifxDBUnique\ifrt@InputUsedIDs\wrtProbIds{#1}\fi\fi +} \newenvironment{rtVW}{\global\advance\rt@nCnt\@ne \immediate\openout\rt@Verb@write - \jobname_\rt@BaseName\the\rt@nCnt.cut + \jobname_\rt@BaseName-\the\rt@nCnt.cut \let\verbatim@out\rt@Verb@write \rt@IWVO{\string\RTVWHook}% + \rt@IWVO{\string + \rtVWId{\rt@BaseName-\the\rt@nCnt}\string\relax}% \verbatimwrite }{% \endverbatimwrite @@ -454,11 +488,22 @@ \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}}}% + \the\rt@listIn{\noexpand\rt@inputVerb{#1-\the\rt@nCnt}}}% J14 \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\rt@inputVerb\hskip-\marginparsep\texttt{\darg{\ameta{db-name}-\ameta{num}}} This +% is the command that inputs a DB Test problem, it inputs it from the file named +% \cs{jobname\_\darg{\ameta{db-name}-\ameta{num}}}. As we input, we make a record of the +% problem we input by expanding \cs{rt@recordAsUsed\darg{\ameta{db-name}-\ameta{num}}}, which +% itself expands to \cs{rtcsarg\string\gdef\darg{\ameta{db-name}-\ameta{num}}\darg{used}}. This is necessary when we are +% choosing more than one item from a given DB Test file; it must be recorded immediately so that later +% it cannot be used again, if possible. +% \begin{macrocode} +\def\rt@inputVerb#1{\rt@recordAsUsed{#1}\input{\jobname_#1.cut}} +%\def\rt@recordAsUsed#1{\ifxDBUnique\rtcsarg\gdef{#1}{used}\fi} +\def\rt@recordAsUsed#1{\rtcsarg\gdef{#1}{used}} % \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 @@ -524,16 +569,18 @@ % 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 +\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 + \rt@badTokName{#1}% + \else % \end{macrocode} % Source list is defined % \begin{macrocode} + \expandafter \ifx\csname nMax4#2\endcsname\relax % \end{macrocode} % Destination list is not defined, which is good in this instance. This is @@ -545,14 +592,17 @@ \@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 + \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 + \rt@warnTokName{#2}% + \fi \fi -\endgroup} + \endgroup +} % \end{macrocode} % \end{macro} %\DescribeMacro{\rt@ssign}\hskip-\marginparsep\texttt{\darg{\ameta{name}}} makes the assignments that are expanded by \cs{useRanTok}. @@ -570,7 +620,8 @@ \newcommand{\nToksFor}[1]{\expandafter \ifx\csname nMax4#1\endcsname\relax \textbf{??}\rt@badTokName{#1}\else - \@nameuse{nMax4#1}\fi} + \@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 @@ -579,23 +630,66 @@ \newcommand{\rtTokByNum}[2][\rt@BaseName]{\expandafter \ifx\csname nMax4#1\endcsname\relax \textbf{??}\rt@badTokName{#1}\else - \@nameuse{rtTok#2#1}\expandafter\ignorespaces\fi} + \@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} +% We provide two commands to control the feature of try to select unique +% choices across multiple renditions of the same source file. +% \DescribeMacro\uniqueXDBChoicesOn\cs{uniqueXDBChoicesOn}, turns on this feature; +% the default is \DescribeMacro\uniqueXDBChoicesOff\cs{uniqueXDBChoicesOff} make +% no changes to how \cs{useRanTok} operates. One other command we define here is +% \DescribeMacro\makeInfoAWarning\cs{makeInfoAWarning}; this command applies only +% when \cs{uniqueXDBChoicesOn} is expanded. In the macro \cs{xdb@unique} which is +% expanded when \cs{uniqueXDBChoicesOn} is expanded first, there is one line that +% reports information to the log as \cs{PackageInfo}. By expanding \cs{makeInfoAWarning} +% we change \cs{PackageInfo} to \cs{PackageWarning}, which gives it greater +% visibility in the log and the log report. +% \changes{v1.3.1}{2021/01/19}{Added \string\cs{ifrt@recording}} +% \begin{macrocode} +\newcommand{\uniqueXDBChoicesOn}{\xDBUniquefalse + \PackageWarning{ran_toks} + {The \string\uniqueXDBChoicesOn\space requires the\MessageBreak + \texttt{usedbapp} option}} +\newcommand{\uniqueXDBChoicesOff}{\let\xdbunique\relax\xDBUniquefalse} +\let\xdbunique\relax +\newcommand{\makeInfoAWarning}{\def\pkgNotifType{\PackageWarning}} +\def\pkgNotifType{\PackageInfo} +\newif\ifrt@recording \rt@recordingtrue % dps +% \end{macrocode} +% Now for the definition of \cs{useRanTok}. % \begin{macrocode} - \rt@badIndex{#2}{#1}\@nameuse{rtRanTok\rt@mod#1}\else - \@nameuse{rtRanTok#2#1}\fi\fi\egroup} +\newcommand{\useRanTok}[2][\rt@BaseName]{\bgroup\expandafter + \ifx\csname nMax4#1\endcsname\relax + \rt@badTokName{#1}\global\let\rt@next\relax + \else + \ifnum#2>\@nameuse{nMax4#1}% + \rt@modarith{#2}{\@nameuse{nMax4#1}}% + \rt@badIndex{#2}{#1}\edef\Indx{\rt@mod}% + \else + \edef\Indx{#2}% + \fi + \xdef\rt@orig@Indx{\Indx}% +% \end{macrocode} +% If \cs{xdbunique} is \cs{relax}, \cs{useRanTok} executes as it did in the past +% (no change in behavior); otherwise, we expand \cs{xdb@unique} which attempts +% to avoid duplicate choices based on the DBs input by \cs{useProbDBs}. +% \begin{macrocode} + \ifx\xdbunique\relax + \ifrt@recording\rt@recordAsUsed{#1-\Indx}\fi + \xdef\rt@next{\noexpand\@nameuse{rtRanTok\Indx#1}}% + \else + \xdb@unique{#1}% + \fi + \fi + \egroup + \rt@next +} % \end{macrocode} % \DescribeMacro{\displayListRandomly}\hskip-\marginparsep\texttt{[\ameta{prior}][\ameta{post}]\darg{\ameta{name}}} % lists all items in the list as passed @@ -606,12 +700,14 @@ %\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 +\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 + \rt@recordingfalse % \end{macrocode} % Within the optional arguments, we define \DescribeMacro{\i}\cs{i}, % \DescribeMacro{\first}\cs{first}, \DescribeMacro{\last}\cs{last}, and @@ -620,28 +716,75 @@ % \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} + \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 +} +%</package> +%<*dbapp> +% \end{macrocode} +% \section{A DB application} +% This (optional) section supports an application of \pkg{ran\_toks} to the \pkg{eqexam} package; though, +% conceptually, the commands of this section may be applied in other settings. In this application, +% the document author has a series of DB test files (TEX files), each file contains \cs{bRTVToks}/\allowbreak +% \cs{eRTVToks} constructs, which contain a series of \env{rtVW} environments of verbatim content. In this application, +% the verbatim content are \env{problem}/\env{problem*} environments of \pkg{eqexam}. +% +% The following verbatim listing is taken from the preamble of \texttt{mc-db.tex}, which illustrates the layout +% of how to apply the commands of this section. +%\begin{Verbatim}[xleftmargin=\parindent,fontsize=\small, +%commandchars={!()},codes={\catcode`\%=9}] +%\examNum{1} +%\numVersions{4} +%\forVersion{a} +%!%!textsf( initial seeds for each of the four versions of this document) +%\vA{\useThisSeed{54356}} +%\vB{\useThisSeed{577867}} +%\vC{\useThisSeed{6746788}} +%\vD{\useThisSeed{856785}} +% +%\uniqueXDBChoicesOn !%!textsf( Try to avoid duplicate questions in multi-version doc) +%\InputUsedIDs !%!textsf( Input history of previous versions to current version) +%\viewIDstrue !%!textsf( To view the IDs of problems used) +%... +%\useTheseDBs{db1,db2,db3,db4} +%\end{Verbatim} +% \changes{v1.3}{2021/01/14}{Added several commands and macro to continue to support +% a DB application.} +% If \cs{ifxDBUnique} is true and if \pkg{eqexam} is loaded, we +% open \cs{wrtprobids} which is used to write the problem IDs of the problems +% already chosen in earlier version of this source file. The name of this file +% is \cs{jobname-ver\string\selVersion.cut}; eg, \texttt{mc-db-verA.cut}, +% \texttt{mc-db-verB.cut}, etc. +% \begin{macrocode} +\def\rt@OpenProbIds{\@ifpackageloaded{eqexam} + {\immediate\openout\wrtprobids\jobname-ver\selVersion.cut}{}} +% \end{macrocode} +% We open the file \cs{jobname-ver\cs{selVersion}.cut} when \cs{InputUsedIDs} is +% expanded in the preamble. +% \begin{macrocode} +%\def\rt@ABD{\ifxDBUnique\expandafter\rt@OpenProbIds\fi} +\def\rt@ABD{\@ifundefined{eq@nVersions}{} + {\ifnum\eq@nVersions>\@ne\expandafter\rt@OpenProbIds\fi}} % \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} + \let\rt@next\rt@gettonil\fi\rt@next +} \begingroup -\def\:{\rt@xifspc} -\expandafter\gdef\: {\futurelet\@let@token\rt@ifspc} +\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}|}| +% \begin{macro}{\useTheseDBs}\hskip-\marginparsep\thinspace\texttt{\darg{\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. @@ -662,10 +805,197 @@ \toks@=\expandafter{\rt@nextDB}% \edef\rt@DB@List{\the\toks\tw@\space\the\toks@}\fi }\expandafter\rt@DB@List\fi} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\useProbDBs}\hskip-\marginparsep\thinspace\texttt{\darg{\ameta{list}}} Is an alias of +% \cs{useTheseDBs}. +% \begin{macrocode} \let\useProbDBs\useTheseDBs % \end{macrocode} % \end{macro} +% \begin{macro}{\viewDB}\hskip-\marginparsep\thinspace\texttt{\darg{\ameta{name}}} +% Typeset the entire contents of a DB Test file. The argument \ameta{name} is the name +% of the DB Test file (as in |\bRTVToks{DB1}|, here \texttt{DB1} is the \ameta{name}. +% The DB test files should be input using \cs{useProbDBs}. +% \begin{macrocode} +\def\viewDB#1{\useRTName{#1}\rt@nCnt\z@ + \edef\nSTOP{\@nameuse{nMax4\rt@BaseName}}% + \loop\advance\rt@nCnt\@ne + \rtTokByNum{\the\rt@nCnt}% + \ifnum\rt@nCnt<\nSTOP\repeat +} +% \end{macrocode} +% \end{macro} +% The macro \DescribeMacro\getR@nIndx\cs{getR@nIndx} executes with each +% entry of |\@nameuse{#1-List}|. +% For an index value of \cs{Indx}, the macro goes through the +% arguments to the \cs{Indx}'th argument and reads +% the value of the argument at that point. It +% returns the argument of the \cs{Indx}'th as \cs{ranIndx}; +% eg, if |\Indx=1|, then |\ranIndx=3|, for the above example. +% \begin{macrocode} +%% uses \@tempcnta and \Indx +\def\getR@nIndx#1{\def\argi{#1}% + \ifx\argi\rt@STOP + % no match, something is wrong + \edef\ranIndex{-1}\else + \advance\@tempcnta\@ne + \ifnum\Indx=\@tempcnta + \def\ranIndx{#1}\fi + \fi +} +% \end{macrocode} +% \DescribeMacro\xdb@unique\hskip-\marginparsep\texttt{\darg{\ameta{name}}} +% An add-on command to \cs{useRanTok}. The command attempts +% to create a unique choice of a problem over several versions of the same document. This may not +% be possible if there are not enough choices to satisfy the number of declared versions. +% +% The \cs{xdb@unique} seems to work when the \pkg{eqexam} document has multiple parts (more then one +% \env{exam} environments). The id files for the parts are all combined; ideally, for multiple part +% exams, the second part draws form a set of DB test files different from the first part, as long as there are +% enough problems to choose from. +% +% Note that, if there is not a unique choice for a question from the designated DB test file, +% \cs{xdb@unique} reverts to the original choice so there may be duplicates across versions of the document. +% \begin{macrocode} +\def\rt@NoAltChoice#1#2{\PackageWarning{ran_toks} + {Cannot find an alternative to #1-#2,\MessageBreak + will use it but it may be a duplicate\MessageBreak + question}} +\def\xdb@unique#1{\@tempcnta\z@ + \def\rt@STOP{\relax}% +% \end{macrocode} +%We use the randomized list for the \ameta{name} +%\begin{verbatim} +% \@nameuse{#1-List} is the randomized list: eg, +% \\{3}\\{2}\\{4}\\{5}\\{1} +%\end{verbatim} +% \begin{macrocode} + \let\\\relax\edef\x{\@nameuse{#1-List}}% + \toks@=\expandafter{\x}\let\\\getR@nIndx + \the\toks@\\\rt@STOP +% \end{macrocode} +% We take as the default choice the original choice +% \begin{macrocode} + \xdef\rt@next{\noexpand + \@nameuse{rtRanTok\rt@orig@Indx#1}}% +% \end{macrocode} +% Begin to look at the results of |\the\toks@\\\rt@STOP|, +% \begin{macrocode} + \ifnum\ranIndx>\m@ne +% \end{macrocode} +% If \cs{ranIndx} is -1, we use the original index. +% \begin{macrocode} + \edef\rt@orig@ranIndx{\ranIndx}% + \expandafter + \ifx\csname#1-\ranIndx\endcsname\relax +% \end{macrocode} +% This question has not been chosen earlier, so we'll use it. +% \begin{macrocode} + \xdef\rt@next{\noexpand + \@nameuse{rtRanTok\Indx#1}}% + \else +% \end{macrocode} +% The question has been chosen in an earlier version of the document. +% Find the next higher unused one (cycle search). +% \begin{macrocode} + \@tempcntb\z@ + \rt@nCnt\rt@orig@Indx\relax +% \end{macrocode} +% As we move into the \cs{@whilenum} loop, we take as the default +% the original index. The loop may overwrite the definition of +% \cs{rt@next}. +% \begin{macrocode} + \xdef\rt@next{\noexpand\rt@NoAltChoice{#1}{\rt@orig@Indx}\noexpand + \@nameuse{rtRanTok\rt@orig@Indx#1}}% + \@whilenum\@tempcntb<\@nameuse{nMax4#1}\do{% + \advance\@tempcntb\@ne + \advance\rt@nCnt\@ne +% \end{macrocode} +% If the count is at the \texttt{nMax4} value, we start over from +% the beginning. +% \begin{macrocode} + \ifnum\rt@nCnt>\@nameuse{nMax4#1}\rt@nCnt\@ne\fi +% \end{macrocode} +% We search through \cs{toks@} again, so we have the initialize +% the dependent variables: \cs{Indx}, the index to search for; \cs{@tempcnta} +% the counter that is used by \cs{getR@nIndx}; nothing has changed +% |\let\\\getR@nIndx| should still be in effect. % \begin{macrocode} + \edef\Indx{\the\rt@nCnt}\@tempcnta\z@ + \the\toks@\\\rt@STOP +% \end{macrocode} +% If \cs{ranIndx} is -1, we use the original index. +% \begin{macrocode} + \ifnum\ranIndx>\m@ne + \expandafter + \ifx\csname#1-\ranIndx\endcsname\relax + \pkgNotifType{ran_toks}{#1-\rt@orig@ranIndx\space + has already been used,\MessageBreak + will use #1-\ranIndx}% + % exit the \@whilenum loop + \@tempcntb\@nameuse{nMax4#1}% + \advance\@tempcntb\@ne + \fi + \fi + \xdef\rt@next{\noexpand\@nameuse{rtRanTok\Indx#1}}% + }% do + \ifnum\@tempcntb=\@nameuse{nMax4#1}\relax + \xdef\rt@next{\noexpand + \rt@NoAltChoice{#1}{\rt@orig@ranIndx}\noexpand + \@nameuse{rtRanTok\rt@orig@Indx#1}}% + \fi + \fi + \fi +} +% \end{macrocode} +% Here is the operational definition of \DescribeMacro\uniqueXDBChoicesOn +% \cs{uniqueXDBChoicesOn}; when executed in the preamble, an attempt is made +% the select only problems that have not already been chosen in any prior +% renditions of the same source file. +% \begin{macrocode} +\renewcommand{\uniqueXDBChoicesOn}{\xDBUniquetrue + \let\xdbunique\xdb@unique} +% \end{macrocode} +% \begin{macro}{\InputUsedIDs} Input the user ID (CUT) files. These are files +% that document which questions were used for the various versions of the exam. +% \begin{macrocode} +\newif\ifrt@InputUsedIDs\rt@InputUsedIDsfalse +\def\InputUsedIDs{\rt@InputUsedIDstrue + \bgroup + \setcounter{eq@count}{0}% + \let\rt@InputUsedIDs\@empty + \let\rt@InputUsedIDsFIs\@empty + \@whilenum \value{eq@count}<\eq@nVersions\relax\do + {% + \stepcounter{eq@count}% + \g@addto@macro\rt@InputUsedIDs{\if\selVersion}% + \g@addto@macro\rt@InputUsedIDsFIs{\fi}% + \edef\x{\Alph{eq@count}}% + \edef\y{\noexpand\g@addto@macro\noexpand + \rt@InputUsedIDs{\x\expandafter\noexpand + \csname else\endcsname\noexpand\rt@IIFE}}\y + \edef\x{{\x}}\expandafter + \g@addto@macro\expandafter\rt@InputUsedIDs\expandafter{\x}% + }% do + \expandafter\g@addto@macro\expandafter + \rt@InputUsedIDs\expandafter{\rt@InputUsedIDsFIs}% + \egroup + \rt@InputUsedIDs + \AtBeginDocument{\rt@ABD}% +} +\@onlypreamble\InputUsedIDs +% \end{macrocode} +% \end{macro} +% A convenience command used by \cs{InputUsedIDs}. +% \begin{macrocode} +\def\rt@IIFE#1{\InputIfFileExists{\jobname-ver#1.cut} + {\PackageInfo{ran_toks}{Inputting \jobname-ver#1.cut}} + {\PackageInfo{ran_toks}{Cannot find \jobname-ver#1.cut}}} +% \end{macrocode} +% \begin{macrocode} +%</dbapp> +%<*package> %</package> % \end{macrocode} % \Finale diff --git a/Master/texmf-dist/source/latex/ran_toks/ran_toks.ins b/Master/texmf-dist/source/latex/ran_toks/ran_toks.ins index 4d2d77d191a..1d84cf5ce61 100644 --- a/Master/texmf-dist/source/latex/ran_toks/ran_toks.ins +++ b/Master/texmf-dist/source/latex/ran_toks/ran_toks.ins @@ -46,6 +46,7 @@ {% \file{ran_toks.sty}{\from{ran_toks.dtx}{copyright,package}} \file{ran-toks.sty}{\from{ran_toks.dtx}{copyright,altpkgname}} + \file{rt-dbapp.def}{\from{ran_toks.dtx}{copyright,dbapp}} } \Msg{***************************************************************} diff --git a/Master/texmf-dist/tex/latex/ran_toks/ran-toks.sty b/Master/texmf-dist/tex/latex/ran_toks/ran-toks.sty index 3d408de6222..73bc9bc9c2a 100644 --- a/Master/texmf-dist/tex/latex/ran_toks/ran-toks.sty +++ b/Master/texmf-dist/tex/latex/ran_toks/ran-toks.sty @@ -8,7 +8,7 @@ %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% ran_toks package, %% -%% Copyright (C) 1999-2019 D. P. Story %% +%% Copyright (C) 1999-2021 D. P. Story %% %% dpstory@uakron.edu, dpstory@acrotex.net %% %% %% %% This program can redistributed and/or modified under %% diff --git a/Master/texmf-dist/tex/latex/ran_toks/ran_toks.sty b/Master/texmf-dist/tex/latex/ran_toks/ran_toks.sty index aeb4e2772b5..ae2ae64747b 100644 --- a/Master/texmf-dist/tex/latex/ran_toks/ran_toks.sty +++ b/Master/texmf-dist/tex/latex/ran_toks/ran_toks.sty @@ -8,7 +8,7 @@ %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% ran_toks package, %% -%% Copyright (C) 1999-2019 D. P. Story %% +%% Copyright (C) 1999-2021 D. P. Story %% %% dpstory@uakron.edu, dpstory@acrotex.net %% %% %% %% This program can redistributed and/or modified under %% @@ -19,7 +19,7 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \NeedsTeXFormat{LaTeX2e}[1997/12/01] \ProvidesPackage{ran_toks} - [2019/12/28 v1.2 Randomizing tokens (dps)] + [2021/01/19 v1.3.1 Randomizing tokens (dps)] \RequirePackage{verbatim} \@ifundefined{nextrandom}{\input{random.tex}}{} \def\nextrandom{\begingroup @@ -52,8 +52,18 @@ \newif\ifrtdebug \rtdebugfalse \newif\ifwerandomize \werandomizetrue \newif\ifsaveseed\saveseedtrue +\newif\ifrt@InputUsedIDs\rt@InputUsedIDsfalse \newwrite\rt@Verb@write +\def\rtcsarg#1#2{\expandafter#1\csname#2\endcsname} \def\rt@nameedef#1{\expandafter\edef\csname #1\endcsname} +\DeclareOption{usedbapp}{\let\rtPkgInpt\rt@PkgInpt} +\def\rt@PkgInpt{\InputIfFileExists{rt-dbapp.def} + {\PackageInfo{ran_toks}{Inputting rt-dbapp.def}} + {\PackageInfo{ran_toks}{Cannot find rt-dbapp.def}} +} +\let\rtPkgInpt\relax +\AtEndOfPackage{\rtPkgInpt} +\ProcessOptions\relax \def\ranToksOn{\werandomizetrue} \def\ranToksOff{\werandomizefalse} \def\useThisSeed#1{\saveseedfalse\randomi=#1} @@ -155,7 +165,7 @@ instead will use\MessageBreak \string\useRanTok{\rt@mod}, obtained from modular arithmetic.\MessageBreak - You might want to fix this} + You might want to fix this}% } \def\rt@badTokName#1{% \PackageWarningNoLine{ran_toks} @@ -182,17 +192,27 @@ \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}} + \rt@nameedef{\rt@BaseName Cnt}{\the\rt@nCnt}\expandafter + \r@nVToks\expandafter{\rt@BaseName}} \def\reVerbEnd{\ifhmode\unskip\fi} \def\rtVWHook#1{\def\@rgi{#1}\ifx\@rgi\@empty \let\RTVWHook\relax\else\def\RTVWHook{#1}\fi} \rtVWHook{} +\newwrite\wrtprobids +\newif\ifviewIDs\viewIDsfalse +\newif\ifxDBUnique\xDBUniquefalse +\def\wrtProbIds#1{\immediate\write\wrtprobids{\string + \rtcsarg\string\gdef{#1}{used}}} +\def\rtVWId#1{\ifviewIDs\noindent#1\fi + \ifxDBUnique\ifrt@InputUsedIDs\wrtProbIds{#1}\fi\fi +} \newenvironment{rtVW}{\global\advance\rt@nCnt\@ne \immediate\openout\rt@Verb@write - \jobname_\rt@BaseName\the\rt@nCnt.cut + \jobname_\rt@BaseName-\the\rt@nCnt.cut \let\verbatim@out\rt@Verb@write \rt@IWVO{\string\RTVWHook}% + \rt@IWVO{\string + \rtVWId{\rt@BaseName-\the\rt@nCnt}\string\relax}% \verbatimwrite }{% \endverbatimwrite @@ -205,11 +225,12 @@ \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}}}% + \the\rt@listIn{\noexpand\rt@inputVerb{#1-\the\rt@nCnt}}}% J14 \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@inputVerb#1{\rt@recordAsUsed{#1}\input{\jobname_#1.cut}} +\def\rt@recordAsUsed#1{\rtcsarg\gdef{#1}{used}} \def\rt@PAR{\par} \long\def\r@ndToks#1{\def\rt@rgi{#1}% \ifx\rt@rgi\rt@PAR\def\rt@next{\r@ndToks}\else @@ -228,10 +249,12 @@ \rt@badTokName{#1}\else \rt@performRanDefns{\@nameuse{nMax4#1}}\fi \endgroup} -\newcommand\copyRanToks[2]{\begingroup\expandafter +\newcommand\copyRanToks[2]{\begingroup + \expandafter \ifx\csname nMax4#1\endcsname\relax - \rt@badTokName{#1}% - \else\expandafter + \rt@badTokName{#1}% + \else + \expandafter \ifx\csname nMax4#2\endcsname\relax \useRTName{#2}\global \rt@nameedef{nMax4#2}{\@nameuse{nMax4#1}}% @@ -239,68 +262,75 @@ \@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 + \advance\rt@nCnt\m@ne + }\rt@performRanDefns{\@nameuse{nMax4#2}}% + \else + \rt@warnTokName{#2}% + \fi \fi -\endgroup} + \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} + \@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 + \@nameuse{rtTok#2#1}\expandafter\ignorespaces + \fi +} +\newcommand{\uniqueXDBChoicesOn}{\xDBUniquefalse + \PackageWarning{ran_toks} + {The \string\uniqueXDBChoicesOn\space requires the\MessageBreak + \texttt{usedbapp} option}} +\newcommand{\uniqueXDBChoicesOff}{\let\xdbunique\relax\xDBUniquefalse} +\let\xdbunique\relax +\newcommand{\makeInfoAWarning}{\def\pkgNotifType{\PackageWarning}} +\def\pkgNotifType{\PackageInfo} +\newif\ifrt@recording \rt@recordingtrue % dps +\newcommand{\useRanTok}[2][\rt@BaseName]{\bgroup\expandafter + \ifx\csname nMax4#1\endcsname\relax + \rt@badTokName{#1}\global\let\rt@next\relax + \else + \ifnum#2>\@nameuse{nMax4#1}% + \rt@modarith{#2}{\@nameuse{nMax4#1}}% + \rt@badIndex{#2}{#1}\edef\Indx{\rt@mod}% + \else + \edef\Indx{#2}% + \fi + \xdef\rt@orig@Indx{\Indx}% + \ifx\xdbunique\relax + \ifrt@recording\rt@recordAsUsed{#1-\Indx}\fi + \xdef\rt@next{\noexpand\@nameuse{rtRanTok\Indx#1}}% + \else + \xdb@unique{#1}% + \fi + \fi + \egroup + \rt@next +} +\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 + \rt@recordingfalse \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 + \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 +} \endinput %% %% End of file `ran_toks.sty'. diff --git a/Master/texmf-dist/tex/latex/ran_toks/rt-dbapp.def b/Master/texmf-dist/tex/latex/ran_toks/rt-dbapp.def new file mode 100644 index 00000000000..ecbd1e6aaf4 --- /dev/null +++ b/Master/texmf-dist/tex/latex/ran_toks/rt-dbapp.def @@ -0,0 +1,148 @@ +%% +%% This is file `rt-dbapp.def', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% ran_toks.dtx (with options: `copyright,dbapp') +%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% ran_toks package, %% +%% Copyright (C) 1999-2021 D. P. Story %% +%% dpstory@uakron.edu, dpstory@acrotex.net %% +%% %% +%% 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. %% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\def\rt@OpenProbIds{\@ifpackageloaded{eqexam} + {\immediate\openout\wrtprobids\jobname-ver\selVersion.cut}{}} +\def\rt@ABD{\@ifundefined{eq@nVersions}{} + {\ifnum\eq@nVersions>\@ne\expandafter\rt@OpenProbIds\fi}} +\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 +\def\viewDB#1{\useRTName{#1}\rt@nCnt\z@ + \edef\nSTOP{\@nameuse{nMax4\rt@BaseName}}% + \loop\advance\rt@nCnt\@ne + \rtTokByNum{\the\rt@nCnt}% + \ifnum\rt@nCnt<\nSTOP\repeat +} +%% uses \@tempcnta and \Indx +\def\getR@nIndx#1{\def\argi{#1}% + \ifx\argi\rt@STOP + % no match, something is wrong + \edef\ranIndex{-1}\else + \advance\@tempcnta\@ne + \ifnum\Indx=\@tempcnta + \def\ranIndx{#1}\fi + \fi +} +\def\rt@NoAltChoice#1#2{\PackageWarning{ran_toks} + {Cannot find an alternative to #1-#2,\MessageBreak + will use it but it may be a duplicate\MessageBreak + question}} +\def\xdb@unique#1{\@tempcnta\z@ + \def\rt@STOP{\relax}% + \let\\\relax\edef\x{\@nameuse{#1-List}}% + \toks@=\expandafter{\x}\let\\\getR@nIndx + \the\toks@\\\rt@STOP + \xdef\rt@next{\noexpand + \@nameuse{rtRanTok\rt@orig@Indx#1}}% + \ifnum\ranIndx>\m@ne + \edef\rt@orig@ranIndx{\ranIndx}% + \expandafter + \ifx\csname#1-\ranIndx\endcsname\relax + \xdef\rt@next{\noexpand + \@nameuse{rtRanTok\Indx#1}}% + \else + \@tempcntb\z@ + \rt@nCnt\rt@orig@Indx\relax + \xdef\rt@next{\noexpand\rt@NoAltChoice{#1}{\rt@orig@Indx}\noexpand + \@nameuse{rtRanTok\rt@orig@Indx#1}}% + \@whilenum\@tempcntb<\@nameuse{nMax4#1}\do{% + \advance\@tempcntb\@ne + \advance\rt@nCnt\@ne + \ifnum\rt@nCnt>\@nameuse{nMax4#1}\rt@nCnt\@ne\fi + \edef\Indx{\the\rt@nCnt}\@tempcnta\z@ + \the\toks@\\\rt@STOP + \ifnum\ranIndx>\m@ne + \expandafter + \ifx\csname#1-\ranIndx\endcsname\relax + \pkgNotifType{ran_toks}{#1-\rt@orig@ranIndx\space + has already been used,\MessageBreak + will use #1-\ranIndx}% + % exit the \@whilenum loop + \@tempcntb\@nameuse{nMax4#1}% + \advance\@tempcntb\@ne + \fi + \fi + \xdef\rt@next{\noexpand\@nameuse{rtRanTok\Indx#1}}% + }% do + \ifnum\@tempcntb=\@nameuse{nMax4#1}\relax + \xdef\rt@next{\noexpand + \rt@NoAltChoice{#1}{\rt@orig@ranIndx}\noexpand + \@nameuse{rtRanTok\rt@orig@Indx#1}}% + \fi + \fi + \fi +} +\renewcommand{\uniqueXDBChoicesOn}{\xDBUniquetrue + \let\xdbunique\xdb@unique} +\newif\ifrt@InputUsedIDs\rt@InputUsedIDsfalse +\def\InputUsedIDs{\rt@InputUsedIDstrue + \bgroup + \setcounter{eq@count}{0}% + \let\rt@InputUsedIDs\@empty + \let\rt@InputUsedIDsFIs\@empty + \@whilenum \value{eq@count}<\eq@nVersions\relax\do + {% + \stepcounter{eq@count}% + \g@addto@macro\rt@InputUsedIDs{\if\selVersion}% + \g@addto@macro\rt@InputUsedIDsFIs{\fi}% + \edef\x{\Alph{eq@count}}% + \edef\y{\noexpand\g@addto@macro\noexpand + \rt@InputUsedIDs{\x\expandafter\noexpand + \csname else\endcsname\noexpand\rt@IIFE}}\y + \edef\x{{\x}}\expandafter + \g@addto@macro\expandafter\rt@InputUsedIDs\expandafter{\x}% + }% do + \expandafter\g@addto@macro\expandafter + \rt@InputUsedIDs\expandafter{\rt@InputUsedIDsFIs}% + \egroup + \rt@InputUsedIDs + \AtBeginDocument{\rt@ABD}% +} +\@onlypreamble\InputUsedIDs +\def\rt@IIFE#1{\InputIfFileExists{\jobname-ver#1.cut} + {\PackageInfo{ran_toks}{Inputting \jobname-ver#1.cut}} + {\PackageInfo{ran_toks}{Cannot find \jobname-ver#1.cut}}} +\endinput +%% +%% End of file `rt-dbapp.def'. |