summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/eq-pin2corr
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2021-06-06 03:02:43 +0000
committerNorbert Preining <norbert@preining.info>2021-06-06 03:02:43 +0000
commit4338972cc175be565a3441c4ae8a6aa0dfcbe9f9 (patch)
tree9ec52a5d0d9c8a00b1a6801cc82248c0c008465d /macros/latex/contrib/eq-pin2corr
parent4e703bdd2f304028698cd4ab92b0dda0b95a95a8 (diff)
CTAN sync 202106060302
Diffstat (limited to 'macros/latex/contrib/eq-pin2corr')
-rw-r--r--macros/latex/contrib/eq-pin2corr/README.md11
-rw-r--r--macros/latex/contrib/eq-pin2corr/doc/eq-pin2corr.pdfbin256673 -> 101085 bytes
-rw-r--r--macros/latex/contrib/eq-pin2corr/doc/eqpin2corrman.pdfbin245015 -> 426168 bytes
-rw-r--r--macros/latex/contrib/eq-pin2corr/doc/eqpin2corrman.tex376
-rw-r--r--macros/latex/contrib/eq-pin2corr/eq-pin2corr.dtx328
-rw-r--r--macros/latex/contrib/eq-pin2corr/examples/get-hash-string.pdfbin83433 -> 78863 bytes
-rw-r--r--macros/latex/contrib/eq-pin2corr/examples/get-hash-string.tex18
-rw-r--r--macros/latex/contrib/eq-pin2corr/examples/qz-p2c.pdfbin0 -> 141525 bytes
-rw-r--r--macros/latex/contrib/eq-pin2corr/examples/qz-p2c.tex (renamed from macros/latex/contrib/eq-pin2corr/examples/qz-pin-to-correct.tex)6
-rw-r--r--macros/latex/contrib/eq-pin2corr/examples/qz-pin-to-correct.pdfbin171609 -> 0 bytes
10 files changed, 672 insertions, 67 deletions
diff --git a/macros/latex/contrib/eq-pin2corr/README.md b/macros/latex/contrib/eq-pin2corr/README.md
index 78c08c4d5f..7e20ddd9d4 100644
--- a/macros/latex/contrib/eq-pin2corr/README.md
+++ b/macros/latex/contrib/eq-pin2corr/README.md
@@ -1,6 +1,6 @@
The eq-pin2corr package
Author: D. P. Story
-Dated: 2021-02-20
+Dated: 2021-05-29
This package is an add-on to the quiz environment of the exerquiz
package (part of the acrotex bundle). It adds PIN security to a quiz created by
@@ -11,6 +11,15 @@ the students effort on that quiz.
The package works for a the usual workflows
+What's New (2021-05-29) Added (optional) PIN security to the Begin Quiz button.
+ Added (an optional) `warn and freeze' feature to a quiz. Added (an optional)
+ \qzResetTally field that holds the number of times a student retakes any given
+ quiz. Add (an optional) feature where the document author can set the maximum
+ number of times a student can retake a quiz. Demo files for these
+ features are found on the AcroTeX Blog site:
+ http://www.acrotex.net/blog/?p=1516
+ http://www.acrotex.net/blog/?p=1519
+
D. P. Story
www.acrotex.net
blog.acrotex.net
diff --git a/macros/latex/contrib/eq-pin2corr/doc/eq-pin2corr.pdf b/macros/latex/contrib/eq-pin2corr/doc/eq-pin2corr.pdf
index 92c3cec32b..bd008ba7f1 100644
--- a/macros/latex/contrib/eq-pin2corr/doc/eq-pin2corr.pdf
+++ b/macros/latex/contrib/eq-pin2corr/doc/eq-pin2corr.pdf
Binary files differ
diff --git a/macros/latex/contrib/eq-pin2corr/doc/eqpin2corrman.pdf b/macros/latex/contrib/eq-pin2corr/doc/eqpin2corrman.pdf
index 0103c028ca..55e7438520 100644
--- a/macros/latex/contrib/eq-pin2corr/doc/eqpin2corrman.pdf
+++ b/macros/latex/contrib/eq-pin2corr/doc/eqpin2corrman.pdf
Binary files differ
diff --git a/macros/latex/contrib/eq-pin2corr/doc/eqpin2corrman.tex b/macros/latex/contrib/eq-pin2corr/doc/eqpin2corrman.tex
index aa2f13dbc9..a660f2c3bb 100644
--- a/macros/latex/contrib/eq-pin2corr/doc/eqpin2corrman.tex
+++ b/macros/latex/contrib/eq-pin2corr/doc/eqpin2corrman.tex
@@ -6,16 +6,27 @@
\documentclass[10pt]{article}
\usepackage[fleqn]{amsmath}
%\usepackage{hyperref}
-\usepackage[
- web={centertitlepage,designv,forcolorpaper,latextoc,pro},
+\usepackage[%
+ web={centertitlepage,
+ designv,
+ forcolorpaper,
+ latextoc,
+% uselatexparts,
+ extended
+ },
exerquiz,
% linktoattachments,
aebxmp
]{aeb_pro}
+\usepackage{aeb_mlink}
\usepackage[!showscore]{eq-pin2corr}
%\previewOn\pmpvOn
+%\tocPartTitle{\protect\makebox[0pt][r]{\thepart\hspace{.5em}}#1}
+\tocPartTitle{\tops{\protect\makebox[0pt][r]{\thepart\hspace{.5em}}}{\thepart\space}#1}
+
+
\useBeginQuizButton[\CA{Begin}]
\useEndQuizButton[\CA{End}]
\useMCCircles
@@ -115,8 +126,8 @@
email={dpstory@acrotex.net},
subject={Documentation for the eq-pin2corr package from AcroTeX: Apply PIN security to quizzes},
talksite={\url{www.acrotex.net}},
- version={0.5, 2021/15/06},
- Keywords={AcroTeX, mini-toc},
+ version={2.0, 2021/05/29},
+ Keywords={AcroTeX, PIN security},
copyrightStatus=True,
copyrightNotice={Copyright (C) \the\year, D. P. Story},
copyrightInfoURL={http://www.acrotex.net}
@@ -146,7 +157,7 @@
if (resp != null) {
var f=this.getField("txt");
f.value=Collab.hashString(resp);
- }
+ }
\end{defineJS}
@@ -204,6 +215,13 @@ _path=_path.substring(0,pos)+"/"+manualfilename;
\hypersetup{linktocpage}
+\part{Version 1.0}\label{prt:One}
+
+In this part of the manual, we document the features of the \pkg{eq-pin2corr} package
+as they originally appeared. In addition to the features documented here, version~2.0
+adds a number of features, some of which were suggested by Tahir Y. These additional features
+are documented in \hyperref[prt:Two]{Part~\ref*{prt:Two}} on page~\pageref{prt:Two} of this manual.
+
\section{Introduction}
This package is an add-on to the \env{quiz} environment of the \pkg{exerquiz}
@@ -297,7 +315,7 @@ The minimal preamble for documents that use the \pkg{eq-pin2corr} package.
\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
!1\documentclass{article}
!2\usepackage[!ameta(options)]{web}
-\usepackage[!ameta(options)]{exerquiz}!textbf([2021/02/17])
+\usepackage[!ameta(options)]{exerquiz}!textbf([2021/04/27])
\usepackage[!ameta(options)]{eq-pin2corr}
...
\declPINId{!ameta(pin-num)}{!ameta(hash-string)}
@@ -305,14 +323,14 @@ The minimal preamble for documents that use the \pkg{eq-pin2corr} package.
...
\begin{document}
\end{Verbatim}
-\eVerb A recent version of \pkg{exerquiz} (2021/02/17 or later) is required;
-\pkg{eq-pin2corr} brings in the \pkg{eq-save} package (2021/02/17 or later).
+\eVerb A recent version of \pkg{exerquiz} (2021/05/29 or later) is required;
+\pkg{eq-pin2corr} brings in the \pkg{eq-save} package (2021/04/27 or later).
\section{Package options}
There are two options for this package: \opt{showscore} and \opt{!showscore}.
If you took the test on page~3, you will have noticed that when \uif{End
-Quiz} control is pressed the phase \textsf{"Success! Now save and send to the
+Quiz} control is pressed the phrase \textsf{"Success! Now save and send to the
instructor"} appears in the \cs{ScoreField} or the \cs{PointsField}, this is
the default behavior. Passing \FmtMP{\opt{showscore}}\opt{showscore} in the
optional argument list of \pkg{eq-key2corr} causes the actual score to appear
@@ -330,24 +348,32 @@ Refer to the \texttt{eformsman.pdf} for a discussion of \cs{flJSStr}.
\paragraph*{Local controls.} The two options can be turned off and on locally with \FmtMP{\cs{showScoreOff}}\cs{showScoreOff} and
\FmtMP{\cs{showScoreOn}}\cs{showScoreOn} commands.
-\section{Setting the pin-hash values}
+\section{Setting the pin-hash values}\label{s:pin-hash}
In the preamble, as indicated above, are two commands, the first is required,
the second is optional.
\bVerb\takeMeasure{\string\declPINId\darg{\ameta{pin-num}}\darg{\ameta{hash-string}}}%
%\setlength{\dimen0}{\wd\webtempboxi+2\fboxsep+2\fboxrule}%
-\def\1{\rlap{\sffamily\hskip\linewidth(optional)}}
+%\def\1{\rlap{\sffamily\hskip\linewidth(\cs{numPINId} expands to \ameta{pin-num})}}
+\def\2{\rlap{\sffamily\hskip\linewidth(optional)}}
\begin{dCmd}[commandchars=!()]{\bxSize}
\declPINId{!ameta(pin-num)}{!ameta(hash-string)}
-!1\classPINVar{!ameta(class-pin-var)}
+\numPINId
+!2\classPINVar{!ameta(class-pin-var)}
\end{dCmd}
-\eVerb It is through the \cs{declPINId} command that the PIN security is set up.
-
-\paragraph*{\cs{declPINId\darg{\ameta{pin-num}}\darg{\ameta{hash-string}}}} The \ameta{pin-num} is a number, perhaps four digits,
-that is used to pass through the security of the \uif{Correct} button.\footnote{The \ameta{pin-num} does not have to be a number,
-it can be any password (passcode) that is easy to remember. I prefer a four digit number.} Once you decide on the
-PIN number, you need to generate the corresponding \emph{hash-string}. The hash-string is obtained from the demo file
-\texttt{get-hash-string.pdf}, the contents of that files is reproduced below.
+\eVerb It is through the \cs{declPINId} command that the PIN security is set
+up. The command \cs{numPINId} expands to \ameta{pin-num} is not normally
+typeset into the document, but is used for documentation or demonstration
+purposes, such as in this document.
+
+\paragraph*{\cs{declPINId\darg{\ameta{pin-num}}\darg{\ameta{hash-string}}}}
+The \ameta{pin-num} is a number, perhaps four digits, that is used to pass
+through the security of the \uif{Correct} button.\footnote{The
+\ameta{pin-num} does not have to be a number, it can be any password
+(passcode) that is easy to remember. I prefer a four digit number.} Once you
+decide on the PIN number, you need to generate the corresponding
+\emph{hash-string}. The hash-string is obtained from the demo file
+\texttt{get-hash-string.pdf}, the contents of that file is reproduced below.
\begin{aebQuote}
\pushButton[\CA{Push}\AAmouseup{\btnAct}]{btn}{}{11bp}\olBdry
\textField[\textSize{8}]{txt}{2in}{11bp}\olBdry
@@ -416,6 +442,318 @@ commands.
\eVerb These can placed anywhere outside a \env{quiz} environment. The
commands take effect beginning at the next quiz in the document.
+\part{Version 2.0}\label{prt:Two}
+
+\section{Introduction}
+
+Version~2 of this package provides additional security options for the
+document author (instructor or professor).
+
+\newtopic\noindent The source files (TEX) for the working examples in this
+part of the manual may be found on the {\AcroTeX} Blog web site:
+\begin{itemize}
+ \item \href{http://www.acrotex.net/blog/?p=1516}{\pkg{eq-pin2corr}: PIN security with warning and freezing}\footnote
+ {\url{http://www.acrotex.net/blog/?p=1516}}
+ \item \href{http://www.acrotex.net/blog/?p=1519}{\protect\pkg{eq-pin2corr}:
+ PIN security on \protect\uif{Begin Quiz} and tracking retakes of a quiz}\footnote
+ {\url{http://www.acrotex.net/blog/?p=1519}}
+\end{itemize}
+
+\section{Security with warn and freeze on \tops{\protect\uif}{}{End Quiz}}
+
+When the student presses the \uif{End Quiz} control, an alert dialog box
+opens which warns\FmtMP{warn and freeze} the user that quiz will be `frozen'
+which means active form fields are made readonly, except for the \uif{Ans}
+button. The user has a choice of responding \uif{Yes} or \uif{No}, in the
+later case, the student can continue with the quiz. If the student presses
+\uif{Yes}, the quiz is frozen, all the student can do is to save the file and
+to send it to the instructor.
+\bVerb\takeMeasure{\uif{Click 'Yes' to end the quiz or 'No' to continue working on the quiz.}\}}%
+\settowidth{\eflength}{\cs{useWarnEndQuiz}}
+\def\1{\leavevmode\rlap{\hspace{\eflength} \%\sffamily{ use with \cs{usePINCorrBtn}}}}%
+\def\2{\leavevmode\rlap{\sffamily\hskip\linewidth(Turn off PIN security)}}%
+\begin{dCmd}[commandchars=!()]{\bxSize}
+!1\useWarnEndQuiz
+\restoreEndQuiz
+\flJSStr{\EndQuizG@te@Msg}{!uif(Warning:)
+!uif(Are you sure you want to end this quiz?)\r\r
+!uif(The quiz will be frozen and no more changes will be allowed.)
+!uif(Click 'Yes' to end the quiz or 'No' to continue working on the quiz.)}
+\end{dCmd}
+\eVerb Expand \cs{useWarnEndQuiz} prior to the quiz for which the `warn and
+freeze' security is to be employed. After the quiz, optionally expand
+\cs{restoreEndQuiz} to its original definition.
+
+\useWarnEndQuiz
+
+\newtopic\noindent
+Prior to the following quiz, \cs{usePINCorrBtn}\cs{useWarnEndQuiz} are
+expanded.
+\begin{quiz*}{qz2}
+Solve each, passing is 100\%.
+\begin{questions}
+ \item The sum of 1 and 1 is \dots
+\begin{answers}{8}
+\bChoices
+ \Ans0 0\eAns
+ \Ans0 1\eAns
+ \Ans1 2\eAns
+ \Ans0 3\eAns
+ \Ans0 4\eAns
+\eChoices
+\end{answers}
+ \item $ \cos(\pi) = \RespBoxMath{-1}{1}{.0001}{[0,1]}\cgBdry[1bp]
+\CorrAnsButton{-1} $
+
+\item $\displaystyle\frac{d}{dx}{\sin(x)}=\RespBoxMath{cos(x)}{4}{.0001}{[0,1]}\cgBdry[1bp]
+\CorrAnsButton{cos(x)} $
+\end{questions}
+\end{quiz*}\quad\ScoreField[\rectW{2.25in}]\currQuiz\olBdry\CorrButton{\currQuiz} (PIN: \numPINId)
+
+\noindent
+Answers: \AnswerField\currQuiz
+
+\section{PIN security with freeze on \tops{\protect\uif}{}{Correct}}
+
+In the previous section, the quiz is made readonly (frozen) when the student
+presses the \uif{End Quiz} control. We can also freeze the quiz when the
+\uif{Correct} control is pressed.
+
+This strategy allows the student to take and retake the quiz if the score is
+not to his liking; assuming the \texttt{showscore} option is in effect.
+Freezing the quiz on the \uif{Correct} control allows the quiz to be marked
+up and returned to the student, without fear the student will later modify
+his answers and complain to the teacher that the score is incorrect.
+
+\newtopic\noindent To freeze the quiz when the \uif{Correct} control is pressed,
+expand \cs{FreezeThisQuiz}.
+\bVerb\takeMeasure{\string\FreezeThisQuizNot}%
+\def\1{\rlap{\sffamily\hskip\linewidth(use with \cs{usePINCorrBtn})}}
+\begin{dCmd}[commandchars=!()]{\bxSize}
+!1\FreezeThisQuiz
+\FreezeThisQuizNot
+\end{dCmd}
+\eVerb There are two methods of expanding \cs{FreezeThisQuiz}: (1) expand
+prior to the quiz (and expand \cs{FreezeThisQuizNot} following the quiz); or
+(2) pass \cs{FreezeThisQuiz} through the optional argument of the
+\cs{CorrButton} (the \uif{Correct} control) using the syntax
+\verb|\CorrButton[\cmd{\FreezeThisQuiz}]{\currQuiz}|. The latter method make
+the change local, hence \cs{FreezeThisQuizNot} is not needed following the
+quiz.
+
+\showScoreOn
+\restoreEndQuiz
+
+\newtopic\noindent
+The following quiz uses \verb|\CorrButton[\cmd{\FreezeThisQuiz}]{\currQuiz}|
+at the end of the quiz. Prior to this quiz, \cs{showScoreOn} and
+\cs{restoreEndQuiz} are expanded, the later to recover from `warn and freeze'
+of the previous quiz.
+\begin{quiz*}{qz3}
+Solve each, passing is 100\%.
+\begin{questions}
+ \item The sum of 1 and 1 is \dots
+\begin{answers}{8}
+\bChoices
+ \Ans0 0\eAns
+ \Ans0 1\eAns
+ \Ans1 2\eAns
+ \Ans0 3\eAns
+ \Ans0 4\eAns
+\eChoices
+\end{answers}
+ \item $ \cos(\pi) = \RespBoxMath{-1}{1}{.0001}{[0,1]}\cgBdry[1bp]
+\CorrAnsButton{-1} $
+
+\item $\displaystyle\frac{d}{dx}{\sin(x)}=\RespBoxMath{cos(x)}{4}{.0001}{[0,1]}\cgBdry[1bp]
+\CorrAnsButton{cos(x)} $
+\end{questions}
+\end{quiz*}\quad\ScoreField[\rectW{2.25in}]\currQuiz\olBdry\CorrButton[\cmd{\FreezeThisQuiz}]{\currQuiz} (PIN: \numPINId)
+
+\noindent
+Answers: \AnswerField\currQuiz
+
+\section{Tallying the number of retakes of a quiz}
+
+One problem with digital PDF quizzes (\`a la Acro\negthinspace\TeX) is a
+student takes and retakes a quiz until a desired score of 100\% is attained,
+assuming no PIN security is on the \uif{Correct} control. This problem is
+partially mitigated by the PIN security on the \uif{Correct} control, but
+still, teachers, when administering an exam for credit, do not like to see
+student retaking the quiz multiple times. The \pkg{eq-pin2corr} package now offers
+the following commands:
+\bVerb\takeMeasure{\string\qzResetTally[\ameta{options}]}%
+\def\1{\rlap{\sffamily\hskip\linewidth(optionally, use with \cs{usePINCorrBtn})}}
+\begin{dCmd}[commandchars=!()]{\bxSize}
+!1\useBeginQuizCnt
+\restorBeginQuiz
+\qzResetTally[!ameta(options)]
+\end{dCmd}
+\eVerb Expanding \cs{useBeginQuizCnt} modifies the action of the \uif{Begin
+Quiz} control to count the number of times the student as retaken the same
+quiz. The count show up in the readonly text field created by
+\cs{qzResetTally}. Restore the original action of the \uif{Begin Quiz} control
+by expanding \cs{restorBeginQuiz}.
+
+This next quiz has PIN security with freeze on the \uif{Correct} control. The
+\uif{Begin Quiz} controls tracks the number of times the student
+\emph{re-takes the quiz}. Prior to the quiz we expand
+\cs{showScoreOn}\cs{useBeginQuizPIN}\cs{useBeginQuizCnt}. The
+\cs{qzResetTally} field is place to the right of the \cs{CorrButton} command.
+Speaking of the \cs{CorrButton}, \verb|\cmd{\FreezeThisQuiz}| is passed to
+this command through its optional argument so that the quiz is frozen when
+the instructor presses the \uif{Correct} control and successfully enters the
+PIN.
+
+\showScoreOn
+\useBeginQuizPIN
+\useBeginQuizCnt
+%\restorBeginQuiz
+
+\begin{quiz*}{qz4}
+\textbf{Instructions:} Take and retake this quiz until you obtain 100\%.
+\begin{questions}
+ \item The sum of 1 and 1 is \dots
+\begin{answers}{8}
+\bChoices
+ \Ans0 0\eAns
+ \Ans0 1\eAns
+ \Ans1 2\eAns
+ \Ans0 3\eAns
+ \Ans0 4\eAns
+\eChoices
+\end{answers}
+ \item $ \cos(\pi) = \RespBoxMath{-1}{1}{.0001}{[0,1]}\cgBdry[1bp]
+\CorrAnsButton{-1} $
+
+\item $\displaystyle\frac{d}{dx}{\sin(x)}=\RespBoxMath{cos(x)}{4}{.0001}{[0,1]}\cgBdry[1bp]
+\CorrAnsButton{cos(x)} $
+\end{questions}
+\end{quiz*}\quad\ScoreField[\rectW{2.25in}]\currQuiz\olBdry\CorrButton[\cmd{\FreezeThisQuiz}]{\currQuiz} (PIN: \numPINId)\hfill\qzResetTally
+
+\noindent
+Answers: \AnswerField\currQuiz
+
+\section{Setting the maximum number of retakes}
+
+This quiz has PIN security on the \uif{Correct} control. The \uif{Begin Quiz} controls
+tracks the number of times the student \emph{re-takes the quiz}. It also sets the maximum
+number of times the student retake the quiz.
+\bVerb\takeMeasure{\string\setMaxRetakes\darg{\ameta{qz-name}\darg{\ameta{num}}}}%
+\def\1{\rlap{\sffamily\hskip\linewidth(use with \cs{usePINCorrBtn})}}
+\begin{dCmd}[commandchars=!()]{\bxSize}
+\setMaxRetakes{!ameta(qz-name)}{!ameta(num)}
+\nMaxRetakes{!ameta(qz-name)}
+\end{dCmd}
+\eVerb When declared prior to the quiz whose name is \ameta{qz-name},
+\cs{setMaxRetakes} sets the maximum of times a student can \emph{retake the same
+quiz} to \ameta{num}, where \ameta{num} is a nonnegative integer. Declaring
+\cs{setMaxRetakes\darg{\ameta{qz-name}}\darg{0}} means the student may only
+take the quiz once (no retakes allowed); \cs{setMaxRetakes\darg{\ameta{qz-name}}\darg{2}} means he
+can retake the quiz twice (for a total of three times).
+
+The command \cs{nMaxRetakes\darg{\ameta{qz-name}}} is a way of typesetting
+the number \ameta{num} into the document as part of the instructions for the
+quiz, for example.
+
+\showScoreOn
+\useBeginQuizCnt
+\setMaxRetakes{qz5}{2}
+
+\newtopic\noindent The following quiz has PIN security with freeze under the \uif{Correct} control and it
+allows the student to retake the quiz at most \nMaxRetakes{qz5}~times.
+
+\begin{quiz*}{qz5}
+Solve each, passing is 100\%. Be aware that you will be allowed to
+\emph{retake} this quiz at most \nMaxRetakes{qz5}~times.
+\begin{questions}
+ \item The sum of 1 and 1 is \dots
+\begin{answers}{8}
+\bChoices
+ \Ans0 0\eAns
+ \Ans0 1\eAns
+ \Ans1 2\eAns
+ \Ans0 3\eAns
+ \Ans0 4\eAns
+\eChoices
+\end{answers}
+ \item $ \cos(\pi) = \RespBoxMath{-1}{1}{.0001}{[0,1]}\cgBdry[1bp]
+\CorrAnsButton{-1} $
+
+\item $\displaystyle\frac{d}{dx}{\sin(x)}=\RespBoxMath{cos(x)}{4}{.0001}{[0,1]}\cgBdry[1bp]
+\CorrAnsButton{cos(x)} $
+\end{questions}
+\end{quiz*}\quad\ScoreField[\rectW{2.25in}]\currQuiz\olBdry\CorrButton[\cmd{\FreezeThisQuiz}]{\currQuiz} (PIN: \numPINId)\hfill\qzResetTally
+
+\noindent
+Answers: \AnswerField\currQuiz
+
+\section{PIN Security for \tops{\protect\uif}{}{Begin Quiz} and \tops{\protect\uif}{}{Correct}}
+
+For this final example, the student can see his quiz score (which can be
+optionally changed by expanding \cs{showScoreOff}); however, to retake the
+quiz a PIN must be entered when the \uif{Begin Quiz} button is pressed. The
+PIN under the \uif{Begin Quiz} control is (usually) different from the PIN
+under the \uif{Correct} button.
+\bVerb\takeMeasure{\string\flJSStr\darg{\string\BeginQuizG@te@Msgii}\{\uif{Press the Begin Quiz}}%
+%\def\1{\rlap{\sffamily\hskip\linewidth(\cs{numRePINId} expands to \ameta{pin-num})}}
+\begin{dCmd}[commandchars=!()]{\bxSize}
+\declRePINId{!ameta(pin-num)}{!ameta(hash-string)}
+\numRePINId
+\flJSStr{\BeginQuizG@te@Msgi}{!uif(Enter the PIN number)
+!uif(to retake this quiz)}
+\flJSStr{\BeginQuizG@te@Msgii}{!uif(Press the Begin Quiz)
+!uif(control to begin the quiz again)}
+\end{dCmd}
+\eVerb \cs{declRePINId} is used to declare the PIN number for retaking the
+quiz, as well as the corresponding hash string. Refer to \cs{declPINId} above
+(\hyperref[s:pin-hash]{Section~\ref{s:pin-hash}}) for information of how to
+acquire the hash string for the PIN.
+
+The command \cs{numREPINId} expands to \ameta{pin-num} is not normally
+typeset into the document, but is used for documentation or demonstration
+purposes, such as in this document.
+
+The final two, \cs{BeginQuizG@te@Msgi} and \cs{BeginQuizG@te@Msgii} expand to
+the messages the respondent reads. These may be redefined as desired.
+
+\newtopic\noindent
+The PIN for the \uif{Begin Quiz} button is \numRePINId. The \uif{Begin Quiz}
+button does not need a PIN for the first time it is pressed. It requires a
+PIN after the first press.
+
+\showScoreOn
+\useBeginQuizPIN
+
+\begin{quiz*}{qz6}
+Solve each, passing is 100\%.
+\begin{questions}
+ \item The sum of 1 and 1 is \dots
+\begin{answers}{8}
+\bChoices
+ \Ans0 0\eAns
+ \Ans0 1\eAns
+ \Ans1 2\eAns
+ \Ans0 3\eAns
+ \Ans0 4\eAns
+\eChoices
+\end{answers}
+ \item $ \cos(\pi) = \RespBoxMath{-1}{1}{.0001}{[0,1]}\cgBdry[1bp]
+\CorrAnsButton{-1} $
+
+\item $\displaystyle\frac{d}{dx}{\sin(x)}=\RespBoxMath{cos(x)}{4}{.0001}{[0,1]}\cgBdry[1bp]
+\CorrAnsButton{cos(x)} $
+\end{questions}
+\end{quiz*}\quad\ScoreField[\rectW{2.25in}]\currQuiz\olBdry\CorrButton{\currQuiz} (PIN: \numPINId)\hfill\qzResetTally
+
+\noindent
+Answers: \AnswerField\currQuiz\vcgBdry[6pt]
+
+This kind of security is best when the students are taking a quiz in a
+computer lab with a proctor in the room. The student can ask the proctor to
+reset the quiz. Note that we keep a tally on the number of requests as the
+proctor may not write it down or remember.
+
\medbreak\noindent
Now, I really must get back to retirement.\enspace\dps
diff --git a/macros/latex/contrib/eq-pin2corr/eq-pin2corr.dtx b/macros/latex/contrib/eq-pin2corr/eq-pin2corr.dtx
index 091ba8a94f..537bc48894 100644
--- a/macros/latex/contrib/eq-pin2corr/eq-pin2corr.dtx
+++ b/macros/latex/contrib/eq-pin2corr/eq-pin2corr.dtx
@@ -16,7 +16,7 @@
%</copyright>
%<package>\NeedsTeXFormat{LaTeX2e}
%<package>\ProvidesPackage{eq-pin2corr}
-%<package> [2021/02/20 v1.0 Applies PIN security to quizzes]
+%<package> [2021/05/29 v2.0 Applies PIN security to quizzes]
%<*driver>
\documentclass{ltxdoc}
%\usepackage[colorlinks,hyperindex=false,linktocpage,bookmarksnumbered]{hyperref}
@@ -52,6 +52,19 @@
{-3.5ex \@plus -1ex \@minus -.2ex}%
{2.3ex \@plus.2ex}%
{\normalfont\Large\bfseries}}
+\renewcommand{\subsection}
+ {\renewcommand{\@seccntformat}[1]{\thesubsection\quad}%
+ \@startsection {subsection}{1}{\z@}%
+ {-3.5ex \@plus -1ex \@minus -.2ex}%
+ {2.3ex \@plus.2ex}%
+ {\normalfont\large\bfseries}}
+\renewcommand{\subsubsection}
+ {\renewcommand{\@seccntformat}[1]{\thesubsubsection\quad}%
+ \@startsection {subsubsection}{1}{\z@}%
+ {-3.5ex \@plus -1ex \@minus -.2ex}%
+ {2.3ex \@plus.2ex}%
+ {\normalfont\large\bfseries}}
+%
\renewcommand{\paragraph}
{\renewcommand{\@seccntformat}[1]{\theparagraph\unskip\,}%
\@startsection{paragraph}{4}{0pt}{6pt}{-3pt}{\bfseries}}
@@ -63,8 +76,9 @@
{\list{}{\leftmargin\amtIndent}%
\item\relax}
{\endlist}
+\let\@latex@warning\@gobble
\makeatother
-\InputIfFileExists{aebdocfmt.def}{\PackageWarning{eq-pin2corr}{Inputting aebdocfmt.def}}
+\InputIfFileExists{aebdocfmt.def}{\PackageInfo{eq-pin2corr}{Inputting aebdocfmt.def}}
{\def\IndexOpt{\DescribeMacro}\def\IndexKey{\DescribeMacro}\let\setupFullwidth\relax
\PackageInfo{eq-pin2corr}{aebdocfmt.def cannot be found}}
\begin{document}
@@ -147,8 +161,8 @@
\DeclareOption{showscore}{\PINshowScoretrue}
\DeclareOption{!showscore}{\PINshowScorefalse}
\ProcessOptions\relax
-\RequirePackage{exerquiz}[2021/02/17]
-\RequirePackage{eq-save}[2021/02/17]
+\RequirePackage{exerquiz}[2021/05/21]
+\RequirePackage{eq-save}[2021/04/27]
% \end{macrocode}
% \section{Package commands}
% Implement local versions\DescribeMacro{\showScoreOn}\DescribeMacro{\showScoreOff}{} of the package options \opt{showscore} and \opt{!showscore},
@@ -157,37 +171,38 @@
\def\showScoreOn{\PINshowScoretrue}
\def\showScoreOff{\PINshowScorefalse}
% \end{macrocode}
+% \subsection{PIN security on the \textsf{Correct} control}
% Define \DescribeMacro{\SaveAndSendMsg} a message that appears on the console when the PIN entered is not correct.
% \begin{macrocode}
\flJSStr[noquotes]{\SaveAndSendMsg}{Success! %
Now save and send to the instructor}
% \end{macrocode}
-% Make changes to the \uif{End Quiz} control and to the \uif{Correct} control.
-% Begin by modifying the \DescribeMacro{\postSubmitQuiz}\cs{postSubmitQuiz} command, which is a hook within the executing
-% code of the \uif{End Quiz} control.
+% \DescribeMacro\postSubmitQuizPIN
+% Begin by modifying the \cs{postSubmitQuiz} command,
+% which is a hook within the executing code of the \uif{End Quiz} control.
% \begin{macrocode}
-\begin{defineJS*}[\makeesc\@\makecmt\%]{\postSubmitQuiz}
+\begin{defineJS*}[\makeesc\@\makecmt\%]{\postSubmitQuizPIN}
// Begin post submit quiz code%
@ifPINSecurity%
@ifPINshowScore@else
- var f = this.getField("ScoreField.@oField");
- if ( f!=null ) {
- f.textSize=0;
- f.value = "@SaveAndSendMsg";
- } else {
- var f = this.getField("PointsField.@oField");
- if (f!=null) {
+ var f = this.getField("ScoreField.@oField");
+ if ( f!=null ) {
f.textSize=0;
- f.value = "Success! Now save and send to instructor";
- }
- }@fi@fi
- oRecordOfQuizData["ScoreData.@oField"]=%
+ f.value = "@SaveAndSendMsg";
+ } else {
+ var f = this.getField("PointsField.@oField");
+ if (f!=null) {
+ f.textSize=0;
+ f.value = "@SaveAndSendMsg";
+ }
+ }@fi@fi
+ oRecordOfQuizData["ScoreData.@oField"]=%
[1*Score,1*NQuestions,1*ptScore,1*NPointTotal];
- oRecordOfQuizData["RightWrong.@oField"]=%
+ oRecordOfQuizData["RightWrong.@oField"]=%
eval(RightWrong.toSource());
- oRecordOfQuizData["ProbDist.@oField"]=%
+ oRecordOfQuizData["ProbDist.@oField"]=%
eval(ProbDist.toSource());
- cntCorrectResponses();
+ cntCorrectResponses();
\end{defineJS*}
% \end{macrocode}
% The command name for the action of the \uif{End Quiz} control is
@@ -195,10 +210,15 @@ eval(ProbDist.toSource());
% We save this and pre-pend a single code line, as needed.
% \begin{macrocode}
\let\eQzBtnActnsSave\eQzBtnActns
-\def\eQzBtnActns{\ifPINshowScore\else
+\def\makeEndQuizPIN{%
+ \let\eQzBtnActns\eQzBtnActnsPIN
+ \let\postSubmitQuiz\postSubmitQuizPIN
+}
+\def\eQzBtnActnsPIN{\ifPINshowScore\else
var bDisplaySilent=true;\r\fi
\eQzBtnActnsSave
}
+%\makeEndQuizPIN
% \end{macrocode}
% The command name for the action of the \uif{Correct} control is \cs{CorrBtnActionsJS}
% we save this and later modify it.
@@ -210,8 +230,10 @@ eval(ProbDist.toSource());
% \begin{macrocode}
\newif\ifPINSecurity \PINSecurityfalse
\def\usePINCorrBtn{\PINSecuritytrue
+ \makeEndQuizPIN % dps5-25
\let\CorrBtnActionsJS\CorrBtnActionsPwdJS}
\def\restoreCorrBtn{\PINshowScoretrue\PINSecurityfalse
+ \restoreEndQuiz % dps5-25
\let\CorrBtnActionsJS\CorrBtnActionsJSSave}
% \end{macrocode}
% The instructor can tediously press the \uif{Correction} button, or place
@@ -226,18 +248,31 @@ eval(ProbDist.toSource());
%and string hash values. The \DescribeMacro\classPINVar\cs{classPINVar} is a convenient
%way of declaring the PIN variable name; eg, if |\classPINVar{_PinCode1}| is declared
%prior to the \env{quiz} environment, the instructor need not manually enter the PIN.
+%\changes{v1.1}{2021/05/22}{Added \string\cs{ifFreezeQuiz} switch and \string\cs{FreezeThisQuiz}
+%convenience macro}
% \begin{macrocode}
\def\classPINVar#1{\def\PINclassPV{#1}}
\let\PINclassPV\@empty
% \end{macrocode}
+% \DescribeMacro\FreezeThisQuiz
+% Causes the interactive parts of a quiz to be readonly. This can be passed
+% into the \uif{End Quiz} control so that when the student presses \uif{End Quiz}
+% the quiz will be frozen (after a warning); or through the \uif{Correct} button,
+% then the returned quiz will be readonly.
+% \begin{macrocode}
+\newif\ifFreezeQuiz\FreezeQuizfalse
+\def\FreezeThisQuiz{\FreezeQuiztrue}
+\def\FreezeThisQuizNot{\FreezeQuizfalse}
+% \end{macrocode}
+% \DescribeMacro\CorrBtnActionsPwdJS
% The modified action for the \uif{Correct} button.
% we save this and later modify it.
% \begin{macrocode}
-\begin{defineJS*}[\makeesc\!\makecmt\%]{\CorrBtnActionsPwdJS}
-!ifx!PINclassPV!@empty%
-var userPIN = "";!else%
-var userPIN = "!PINclassPV";!fi
-if (userPIN == "" ) userPIN = undefined;
+\begin{defineJS*}[\makeesc\|\makecmt\%]{\CorrBtnActionsPwdJS}
+|ifx|PINclassPV|@empty%
+var userPIN = "";|else%
+var userPIN = "|PINclassPV";|fi
+if (userPIN == "") userPIN = undefined;
try {
if ( typeof eval(userPIN) == "undefined") userPIN = undefined;
} catch(e) { userPIN = undefined; }
@@ -247,34 +282,245 @@ if (typeof userPIN == "undefined") {
cTitle: "View Answers",
bPassword: true
});
- var _resp=Collab.hashString(resp);
- var _bQzResults = ( _resp ==_PinCode );
+ var _resp=Collab.hashString(resp);
+ if (resp != null) var _bQzResults = ( _resp ==_PinCode );
} else var _bQzResults = ( eval(userPIN) ==_PinCode );
if (_bQzResults) {
- RightWrong=eval("RightWrong.!currQuiz");
- ProbDist=eval("ProbDist.!currQuiz");
- correctQuiz("!currQuiz",3);
- DisplayQuizResults("!currQuiz",3,3);
- if (typeof correctSumryTbl == "function")
- correctSumryTbl("!currQuiz",3);
+% \end{macrocode}
+% (2021/05/24) Do nothing if no quiz data
+% \begin{macrocode}
+ if (typeof oRecordOfQuizData["ScoreData.|currQuiz"]!="undefined") {
+ RightWrong=eval("RightWrong.|currQuiz");
+ ProbDist=eval("ProbDist.|currQuiz");
+ correctQuiz("|currQuiz",3);
+ DisplayQuizResults("|currQuiz",3,3);
+ if (typeof correctSumryTbl == "function")
+ correctSumryTbl("|currQuiz",3);%
+% \end{macrocode}
+% (2021/05/22) If \cs{ifFreezeQuiz} is true, we add some code to freeze all operational
+% components of this quiz.
+% \begin{macrocode}
+|ifFreezeQuiz
+ var aFrzExt=new Array("obj.","grpobj.","essay.",%
+"beginQuiz.","endQuiz.");
+ for (var i=0; i<aFrzExt.length; i++) {
+ var f=this.getField(aFrzExt[i]+"|currQuiz");
+ if (f!=null) f.readonly=true;
+ }|fi
+ } else {
+ var retn=app.alert({%
+cMsg: "No quiz data, do you want to mark it anyway?",%
+cTitle: "AcroTeX", nIcon: 2, nType: 2});
+ if (retn==4) {
+ var bDisplaySilent=false;
+ InitializeQuiz("|currQuiz",1,0);
+ var f=this.getField("ScoreData.|currQuiz");
+ f.value="0;0;0;0";
+ cntCorrectResponses();
+ correctQuiz("|currQuiz",3);
+ DisplayQuizResults("|currQuiz",3,3,false);
+ if (typeof correctSumryTbl == "function")
+ correctSumryTbl("|currQuiz",3);
+ }
+ }
} else {
- console.println("Something went wrong, \\
-you entered an incorrect PIN Id, \\
+ if (resp != null) {
+ console.clear()
+ console.println("Something went wrong, %
+you entered an incorrect PIN Id, %
or the class PIN Id (\\\\classPINVar) was incorrect or undefined");
- console.show();
+ app.beep(0);
+ console.show();
+ }
}
\end{defineJS*}
% \end{macrocode}
-% \DescribeMacro\declPINId\hskip-\marginparsep\texttt{\darg{\ameta{PIN-Id}}\darg{\ameta{hash-str}}}
-% Set the basic parameters of this PIN security scheme: the pin-id and its corresponding hash-string.
+%
+% \subsection{Declare PIN for \textsf{Correction} and \textsf{Begin Quiz} controls}
+% Two PIN-related commands are defined: (1) \cs{declPINId} is for security on the
+% \uif{Correct} control; (2) \cs{declRePINId} is for security on the \uif{Begin Quiz}
+% control.\medskip
+%
+% \noindent\DescribeMacro\declPINId\hskip-\marginparsep\texttt{\darg{\ameta{PIN-Id}}\darg{\ameta{hash-str}}}
+% Set the basic parameters of this PIN security scheme for the \uif{Correct} control:
+% the pin-id and its corresponding hash-string.
% \begin{macrocode}
\def\declPINId#1#2{\def\numPINId{#1}\def\hashPINId{#2}}
\@onlypreamble\declPINId
\declPINId{5243}{02JRVZdRgYgCA-Rtje8VkD} % PIN Id, hash-str
+% \end{macrocode}
+% \DescribeMacro\declRePINId\hskip-\marginparsep\texttt{\darg{\ameta{PIN-Id}}\darg{\ameta{hash-str}}}
+% Set the basic parameters of this PIN security scheme on the \uif{Begin Quiz} control:
+% the pin-id and its corresponding hash-string.
+% \begin{macrocode}
+\def\declRePINId#1#2{\def\numRePINId{#1}\def\hashRePINId{#2}}
+\@onlypreamble\declRePINId
+\declRePINId{1234}{By9mbLF0NJMA2sN2x4D0VB}
\begin{insDLJS}{pin}{Pin Code}
var _PinCode = "\hashPINId";
+var _rePinCode = "\hashRePINId";
\end{insDLJS}
% \end{macrocode}
+% \subsection{Warn and Freeze on \textsf{End Quiz}}
+% \DescribeMacro\useWarnEndQuiz
+% (2021/05/22) Optional modifications to the \uif{End Quiz} control.
+% \changes{v1.1}{2021/05/22}{Define \string\cs{useWarnEndQuiz} and
+% \string\cs{EndQuizG@tePIN}}
+% \begin{macrocode}
+\def\useWarnEndQuiz{\let\EndQuizG@te\EndQuizG@tePIN}
+\flJSStr{\EndQuizG@te@Msg}{Warning:
+Are you sure you want to end this quiz?\r\r
+The quiz will be frozen and no more changes will be allowed.
+Click 'Yes' to end the quiz or 'No' to continue working on the quiz.}
+\def\PINgobii#1#2{}
+\begin{defineJS}[\makeesc\|\makecmt\%]{\EndQuizG@tePIN}
+// Begin insertion of new code
+ var retn=app.alert({cMsg: |EndQuizG@te@Msg,%
+cTitle: "AcroTeX", nIcon: 2, nType: 2});
+ if (retn==4) {
+% \end{macrocode}
+% Freeze this quiz; we make a relevant fields readonly.
+% \begin{macrocode}
+ var aFrzExt=new Array("mc.","obj.","grpobj.",%
+"beginQuiz.","endQuiz.");
+ for (var i=0; i<aFrzExt.length; i++) {
+ var f=this.getField(aFrzExt[i]+"|currQuiz");
+ if (f!=null) f.readonly=true;
+ }%
+|PINgobii
+\end{defineJS}
+% \end{macrocode}
+% The \cs{PINglobii} vacuums up `\verb*! {!', which appears in \cs{eQzBtnActns} of
+% \pkg{exerquiz}, in the line \verb*!*EndQuizG@te {!.
+%
+% \subsection{PIN Security on \textsf{Begin Quiz}}
+%
+% \DescribeMacro\useBeginQuizPIN (2021/05/29) This command redefines the \uif{Begin Quiz} control to
+% require PIN security to retake the quiz.
+% \changes{v2.0}{2021/05/29}{Define \string\cs{useBeginQuizPIN}}
+% \begin{macrocode}
+\def\useBeginQuizPIN{%
+ \ifx\BeginQuizG@te\BeginQuizG@tePIN\else
+ \let\BeginQuizG@te\BeginQuizG@tePIN\fi}
+% \end{macrocode}
+% \cs{restoreBeginQuiz} is defined in \pkg{exerquiz}, but because of a typo,
+% it was originally defined as \cs{restorBeginQuiz} (no `e'); until the changes trickle
+% through the system, we cover ourselves by \cs{let}ing \cs{restoreBeginQuiz}
+% to \cs{restorBeginQuiz}, if the correct spelling of the command does not already
+% exist.
+% \begin{macrocode}
+\@ifundefined{restoreBeginQuiz}{\let\restoreBeginQuiz\restorBeginQuiz}{}
+% \end{macrocode}
+% \begin{macrocode}
+\flJSStr{\BeginQuizG@te@Msgi}{Enter the PIN number
+to retake this quiz}
+\flJSStr{\BeginQuizG@te@Msgii}{Press the Begin Quiz control to begin
+the quiz again}
+\def\PINgobiii#1#2#3{}
+% \end{macrocode}
+% \begin{macrocode}
+\begin{defineJS}[\makeesc\|\makecmt\%]{\BeginQuizG@tePIN}
+if (typeof oRecordOfQuizData["ScoreData.|currQuiz"] != "undefined" ) {
+ var resp=app.response({
+ cQuestion: |BeginQuizG@te@Msgi,
+ cTitle: "AcroTeX",
+ bPassword: true
+ });
+ var _respHash=_resp=Collab.hashString(resp);
+ if (_resp == _rePinCode) {
+ oRecordOfQuizData["ScoreData.|currQuiz"]=undefined;
+ app.alert(|BeginQuizG@te@Msgii);
+ var f=this.getField("tallyresets.|currQuiz");
+ if (f!=null) f.value=1+f.value;
+ }
+} else {
+|PINgobiii
+\end{defineJS}
+% \end{macrocode}
+% \cs{PINglobiii} gobbles the three tokens `\verb*! {\jsR!', which appear in the definition of \cs{@initQuiz} in
+% \pkg{exerquiz}, in the line \verb*!\BeginQuizG@te\space\jsLB\jsR\jsT!.
+%
+% \section{Tracking the number of \textsf{Begin Quiz} events}
+% A command \cs{qzResetTally} is defined to hold the number of times a user has taken
+% the same quiz. This field is readonly, and does not reset, unless you have know how to do it.
+% \begin{macrocode}
+% \end{macrocode}
+% \DescribeMacro{\qzResetTally}\hskip-\marginparsep\texttt{[\ameta{options}]}
+% The \cs{qzResetTally} text field, similar to \cs{sqTallyTotal}, is used to
+% count the number of times a student needs to retake the same quiz.
+% \begin{macrocode}
+% \end{macrocode}
+% The default appearance of \cs{qzResetTally}
+% \begin{macrocode}
+\def\qzTallyTotalDefaults{%
+ \rawPDF{}\W{1}\BC{0 0 0}\S{I}\textColor{1 0 0 rg}
+ \Q{2}}
+% \end{macrocode}
+% The definition of \cs{qzResetTally}
+% \begin{macrocode}
+\newcommand\qzResetTally[1][]{%
+ \textField[\presets{\qzTallyTotalDefaults}#1\DV{0}\V{0}
+ \Ff{\FfReadOnly}
+ ]{tallyresets.\currQuiz}{\TBW}{\DefaultHeightOfWidget}}
+% \end{macrocode}
+% \subsection{Placing a maximum on the number of resets}
+% The next level of complication is to add a restriction onto the number of
+% times the user can retake the quiz.\medskip\par
+%
+% \noindent
+% \DescribeMacro\setMaxRetakes\hskip-\marginparsep\texttt{\darg{\ameta{qz-name}}\darg{\ameta{num}}}
+% A command that sets the maximum number of retakes \ameta{num} (nonneg integer) by declaring \cs{setMaxRetakes} prior
+% to the quiz \ameta{qz-name}. \DescribeMacro\nMaxRetakes\cs{nMaxRetakes\darg{\ameta{qz-name}}}
+% is a public macro that expands to the max number of retakes (\ameta{num}).
+% \begin{macrocode}
+\newcommand{\setMaxRetakes}[2]{\expandafter
+ \def\csname1MaxReset#1\endcsname{#2}}
+\def\nMaxRetakes#1{\@nameuse{1MaxReset#1}}
+% \end{macrocode}
+% \subsection{JavaScript support for tracking}
+% \DescribeMacro\useBeginQuizCnt Modifies \cs{BeginQuizG@te} (\pkg{exerquiz}, 2021/05/21 or later).
+% \cs{useBeginQuizPIN} also modifies \cs{BeginQuizG@te}. These two are incompatible;
+% one will overwrite the other. \cs{restoreBeginQuiz} retores \uif{Begin Quiz} to its default definition.
+% \changes{v2.0}{2021/05/29}{Define \string\cs{useBeginQuizCnt}}
+% \begin{macrocode}
+\def\useBeginQuizCnt{%
+ \ifx\BeginQuizG@te\BeginQuizG@teCNT\else
+ \let\BeginQuizG@te\BeginQuizG@teCNT\fi}
+% \end{macrocode}
+% \DescribeMacro\maxRetake@Msg The message that appears in an alert dialog box
+% after the student has started the quiz more than the max number, as set by
+% \cs{setMaxRetakes}.
+% \begin{macrocode}
+\flJSStr[noquotes]{\maxRetake@Msg}{You have taken the quiz the maximum
+number of times permitted ("+nMaxReset+"). You will not be allowed to
+continue to re-take this quiz. Move on with your life.}
+% \end{macrocode}
+% The action added to \uif{Begin Quiz}, it determines if \cs{qzResetTally} is present for the current quiz
+% and if so, increments the current value.
+% \begin{macrocode}
+\begin{defineJS}[\makeesc\|\makecmt\%]{\BeginQuizG@teCNT}
+if (typeof oRecordOfQuizData["ScoreData.|currQuiz"] != "undefined" )
+{
+ var _bOKReset=true;
+ var f=this.getField("tallyresets.|currQuiz");
+ if (f!=null) var value=1*f.value;%
+|expandafter|ifx|csname1MaxReset|currQuiz|endcsname|relax|else
+ var nMaxReset=|csname1MaxReset|currQuiz|endcsname;
+ if (f!=null && value==nMaxReset) {
+ app.alert("|maxRetake@Msg");
+ _bOKReset=false;
+ }|fi
+ if (_bOKReset) {
+ oRecordOfQuizData["ScoreData.|currQuiz"]=undefined;
+ app.alert(|BeginQuizG@te@Msgii);
+ if (f!=null) f.value=1+value;
+ }
+} else {
+|PINgobiii
+\end{defineJS}
+% \end{macrocode}
+% \cs{PINglobiii} gobbles the three tokens `\verb*! {\jsR!', which appear in the definition of \cs{@initQuiz} in
+% \pkg{exerquiz}, in the line \verb*!\BeginQuizG@te\space\jsLB\jsR\jsT!.
% \begin{macrocode}
%</package>
% \end{macrocode}
diff --git a/macros/latex/contrib/eq-pin2corr/examples/get-hash-string.pdf b/macros/latex/contrib/eq-pin2corr/examples/get-hash-string.pdf
index c1920bddba..20b55a7bd9 100644
--- a/macros/latex/contrib/eq-pin2corr/examples/get-hash-string.pdf
+++ b/macros/latex/contrib/eq-pin2corr/examples/get-hash-string.pdf
Binary files differ
diff --git a/macros/latex/contrib/eq-pin2corr/examples/get-hash-string.tex b/macros/latex/contrib/eq-pin2corr/examples/get-hash-string.tex
index 29422f836b..3e41710a69 100644
--- a/macros/latex/contrib/eq-pin2corr/examples/get-hash-string.tex
+++ b/macros/latex/contrib/eq-pin2corr/examples/get-hash-string.tex
@@ -3,6 +3,7 @@
\usepackage{eforms}
%\previewOn\pmpvOn
+\def\cs#1{\texttt{\eqbs#1}}
\begin{defineJS}{\btnHashStrAct}
var resp=app.response({
@@ -17,6 +18,10 @@ if (resp !=null) {
f.value=resp;
f=this.getField("txtdeclPINId");
f.value = "\\\\declPINId{"+resp+"}{"+hashStr+"}";
+ f=this.getField("txtdeclPINId");
+ var g=this.getField("txtdeclRePINId");
+ g.value = "\\\\declRePINId{"+resp+"}{"+hashStr+"}";
+
}
\end{defineJS}
@@ -30,10 +35,13 @@ if (resp !=null) {
Push the button and enter the four digit number you just created into the response box.
When you press the \textsf{OK} button,
the hash string of the PIN number you entered appears in the text field. The PIN number goes in as the
-first argument of \verb|\declPINId|, and the hash string is the second argument of \verb|\declPINId|; eg,
+first argument of \verb|\declPINId| (\verb|\declRePINId|), and the hash string is the second argument of
+\verb|\declPINId| (\verb|\declRePINId|); eg,
\begin{verbatim}
-\declPINId{5243}{02JRVZdRgYgCA-Rtje8VkD} % PIN number, hash string
+\declPINId{5243}{02JRVZdRgYgCA-Rtje8VkD} % PIN/hash string (default)
+\declRePINId{1234}{By9mbLF0NJMA2sN2x4D0VB} % PIN/hash string (default)
\end{verbatim}
+Normally, the PIN numbers for \cs{declPINId} and \cs{declRePINId} are different.\medskip
\textbf{Brief Instructions.} Press \textsf{Push}, enter your PIN, press \textsf{OK}.\medskip\par\noindent
\pushButton[\CA{Push}\AAmouseup{\btnHashStrAct}]{btn}{}{11bp}\olBdry
@@ -44,9 +52,13 @@ Save these two values as arguments of \verb|\declPINId| and place in the preambl
quiz document.\medskip
\noindent
-Copy to quiz document: \textField[\textSize{8}]{txtdeclPINId}{3in}{13bp}\olBdry
+For \cs{declPINId}, copy to quiz document:\\[6pt]\null
+ \hspace{15pt}\textField[\textSize{8}]{txtdeclPINId}{3in}{13bp}\vcgBdry[6pt]
+For \cs{declRePINId}, copy to quiz document:\\[6pt]\null
+ \hspace{15pt}\textField[\textSize{8}]{txtdeclRePINId}{3in}{13bp}\vcgBdry[6pt]
\pushButton[\CA{Reset}\AAmouseup{this.resetForm();}]{reset}{}{13bp}
+
\end{document}
diff --git a/macros/latex/contrib/eq-pin2corr/examples/qz-p2c.pdf b/macros/latex/contrib/eq-pin2corr/examples/qz-p2c.pdf
new file mode 100644
index 0000000000..18ec5466cb
--- /dev/null
+++ b/macros/latex/contrib/eq-pin2corr/examples/qz-p2c.pdf
Binary files differ
diff --git a/macros/latex/contrib/eq-pin2corr/examples/qz-pin-to-correct.tex b/macros/latex/contrib/eq-pin2corr/examples/qz-p2c.tex
index b084b55c5a..23642d4d6b 100644
--- a/macros/latex/contrib/eq-pin2corr/examples/qz-pin-to-correct.tex
+++ b/macros/latex/contrib/eq-pin2corr/examples/qz-p2c.tex
@@ -1,5 +1,5 @@
\documentclass{article}
-\usepackage[designv,forcolorpaper]{web}
+\usepackage[designv]{web} %,forcolorpaper
\usepackage{exerquiz}[2021/02/17]
\usepackage[!showscore]{eq-pin2corr}
@@ -27,8 +27,8 @@
\section*{PIN Security for Quizzes}
-This demo file implements a feature that prevents that student from
-correcting his/her own quiz. The \uif{Correct} button appears at the end of
+This demo file implements a feature that prevents students from
+correcting their own quiz. The \uif{Correct} button appears at the end of
the quiz, but a PIN number is needed for it to execute. For the purpose of
this demo files, the PIN number is given to the right of the \uif{Correct}
button; of course, the PIN is not given to the student. \verb~:-{)~ Test it
diff --git a/macros/latex/contrib/eq-pin2corr/examples/qz-pin-to-correct.pdf b/macros/latex/contrib/eq-pin2corr/examples/qz-pin-to-correct.pdf
deleted file mode 100644
index 1fca51e00a..0000000000
--- a/macros/latex/contrib/eq-pin2corr/examples/qz-pin-to-correct.pdf
+++ /dev/null
Binary files differ