diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/ran_toks/ran_toks.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/ran_toks/ran_toks.dtx | 470 |
1 files changed, 400 insertions, 70 deletions
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 |