summaryrefslogtreecommitdiff
path: root/texmf-dist/source/latex/acrotex/exerquiz.dtx
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2017-07-12 23:26:39 +0900
committerNorbert Preining <norbert@preining.info>2017-07-12 23:26:39 +0900
commit01c9ee84c09adfc3efe1cd93191a9c0473f985fe (patch)
tree6fe7c1648fa25e3dcc9b4c67657b89ac1525f289 /texmf-dist/source/latex/acrotex/exerquiz.dtx
parent542c5a785f8db8d4469e296c69c86bc030285f68 (diff)
add acrotex
Diffstat (limited to 'texmf-dist/source/latex/acrotex/exerquiz.dtx')
-rw-r--r--texmf-dist/source/latex/acrotex/exerquiz.dtx13306
1 files changed, 13306 insertions, 0 deletions
diff --git a/texmf-dist/source/latex/acrotex/exerquiz.dtx b/texmf-dist/source/latex/acrotex/exerquiz.dtx
new file mode 100644
index 00000000..0cae45ef
--- /dev/null
+++ b/texmf-dist/source/latex/acrotex/exerquiz.dtx
@@ -0,0 +1,13306 @@
+% \iffalse
+% makeindex -s gglo.ist -o exerquiz.gls exerquiz.glo
+% makeindex -s gind.ist -o exerquiz.ind exerquiz.idx
+%<*copyright>
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Exerquiz.sty package, %%
+%% Copyright (C) 1999-2017 D. P. Story %%
+%% dpstory@uakron.edu %%
+%% %%
+%% This program can redistributed and/or modified under %%
+%% the terms of the LaTeX Project Public License %%
+%% Distributed from CTAN archives in directory %%
+%% macros/latex/base/lppl.txt; either version 1 of the %%
+%% License, or (at your option) any later version. %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%</copyright>
+%<package>\NeedsTeXFormat{LaTeX2e}
+%<package>\ProvidesPackage{exerquiz}
+%<driver>\ProvidesFile{exerquiz.drv}
+%<aebjs>\ProvidesFile{aebjs.def}
+%<eqexam>\ProvidesFile{eqexam.def}
+%<randomize>\ProvidesFile{aebrandom.def}
+%<sumrytbls>\ProvidesFile{aebsumrytbls.def}
+%<template>\ProvidesFile{template.def}
+%<package|driver|aebjs|eqexam|randomize|sumrytbls|template> [2017/03/16 v7.8g %
+%<package> Exerquiz: Exercises and Quizzes for LaTeX/PDF package (dps)]
+%<driver> Exerquiz documentation driver file (dps)]
+%<aebjs> Exerquiz document level JavaScript (dps)]
+%<eqexam> Exerquiz support file for eqexam (dps)]
+%<randomize> Exerquiz support for randomization (dps)]
+%<sumrytbls> Exerquiz support for summary tables (dps)]
+%<template> Exerquiz template for language support (dps)]
+%<eqfr>\ProvidesFile{eqfr.def}
+%<eqde>\ProvidesFile{eqde.def}
+%<eqno>\ProvidesFile{eqno.def}
+%<eqnl>\ProvidesFile{eqnl.def}
+%<eqes>\ProvidesFile{eqes.def}
+%<eqit>\ProvidesFile{eqit.def}
+%<eqru>\ProvidesFile{eqru.def}
+%<eqda>\ProvidesFile{eqda.def}
+%<eqpo>\ProvidesFile{eqpo.def}
+%<eqfin>\ProvidesFile{eqfin.def}
+%<eqcat>\ProvidesFile{eqcat.def}
+%<eqcz>\ProvidesFile{eqcz.def}
+%<eqbr>\ProvidesFile{eqbr.def}
+%<eqtr>\ProvidesFile{eqtr.def}
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage[colorlinks,hyperindex=false]{hyperref}
+\pdfstringdefDisableCommands{\let\\\textbackslash}
+\OnlyDescription % comment out for implementation details
+\EnableCrossrefs
+\CodelineIndex
+\RecordChanges
+\InputIfFileExists{aebdocfmt.def}{\PackageInfo{exerquiz}{Inputting aebdocfmt.def}}
+ {\def\IndexOpt{\DescribeMacro}\def\IndexKey{\DescribeMacro}\let\setupFullwidth\relax
+ \PackageInfo{exerquiz}{aebdocfmt.def cannot be found}}
+\begin{document}
+ \let\env\texttt\let\pkg\textsf
+ \GetFileInfo{exerquiz.sty}
+ \title{Exerquiz: Exercises and Quizzes for \LaTeX/PDF}
+ \author{D. P. Story\\
+ Email: \texttt{dpstory@uakron.edu}}
+ \date{processed \today}
+ \maketitle
+ \tableofcontents
+ \let\Email\texttt
+ \DocInput{exerquiz.dtx}
+\IfFileExists{\jobname.ind}{\newpage\setupFullwidth\PrintIndex}{\paragraph*{Index}
+ The index goes here.\\Execute
+ \texttt{makeindex -s gind.ist -o exerquiz.ind exerquiz.idx} on the command line
+ and recompile \texttt{exerquiz.dtx}.}
+\IfFileExists{\jobname.gls}{\PrintChanges}{\paragraph*{Change History} The list of
+ changes goes here.\\Execute
+ \texttt{makeindex -s gglo.ist -o exerquiz.gls exerquiz.glo} on the command line
+ and recompile \texttt{exerquiz.dtx}.}
+\end{document}
+%</driver>
+% \fi
+%
+% \MakeShortVerb{|}
+% \InputIfFileExists{aebdonotindex.def}{\PackageInfo{exerquiz}{Inputting aebdonotindex.def}}
+% {\PackageInfo{exerquiz}{aebdonotindex.def cannot be found}}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+% \changes{v7.7k}{2016/04/18}{Minor bug fixes, improved driver recognition}
+% \changes{v7.7j}{2016/04/05}{Change in eforms to 2016/04/05 v2.8f}
+%
+% \section{Package options and setup}\label{options}
+%
+% Introduce a number of useful options for \textsl{exerquiz}.
+% \subsection{Options for paper, solutions, JavaScript and preview}
+% \begin{macrocode}
+\usepackage{keyval}
+% \end{macrocode}
+%\changes{v6.4t}{2012/06/18}{Added ifpdf as a required package}
+% \begin{macrocode}
+\RequirePackage{ifpdf}[2006/02/20]
+\RequirePackage{ifxetex}[2006/08/21]
+\@ifundefined{exqtable}{\def\exqtable{table}}{}
+\IfFileExists{xcolor.sty}{%
+ \def\eq@ColorPackage{xcolor}%
+ \PassOptionsToPackage{\exqtable,hyperref}{xcolor}}
+ {\def\eq@ColorPackage{color}}
+% \end{macrocode}
+% \IndexOpt{noxcolor} An option to force
+% the use of the \textsf{color} package.
+% \begin{macrocode}
+\DeclareOption{noxcolor}{\def\eq@ColorPackage{color}}
+% \end{macrocode}
+% \IndexOpt{forpaper}\IndexOpt{forcolorpaper}
+% Pass the |monochrome| option to the color package
+%\changes{v6.06a}{2007/04/09}
+%{
+% Added the \texttt{forcolorpaper} option for those using
+% \textsf{exerquiz} without \textsf{web}.
+%}
+% \begin{macrocode}
+\DeclareOption{forpaper}{%
+ \eqforpapertrue\PassOptionsToPackage{monochrome}{\eq@ColorPackage}
+ \AtBeginDocument{\ifnum\eq@drivernum=4 \else\AllowPeeking\fi}
+}
+\DeclareOption{forcolorpaper}{\eqforpapertrue % for print
+ \AtBeginDocument{\ifnum\eq@drivernum=4 \else\AllowPeeking\fi}
+}
+% \end{macrocode}
+% \IndexOpt{preview}
+% With this option, the bounding boxes of all form fields appear in the
+% dvi preview. Use this option of properly positioning your fields, then
+% remove this option on the final build of the document. This option is no
+% appropriate for the \texttt{pdftex} option which does not have a dvi preview.
+% \begin{macrocode}
+\DeclareOption{preview}{\PassOptionsToPackage{preview}{eforms}}
+% \end{macrocode}
+% \IndexOpt{nosolutions}
+% With the option, the solutions to the exercises are not
+% included in the typeset document.
+% \begin{macrocode}
+\DeclareOption{nosolutions}{\eq@nosolutionstrue\eq@nolinktrue}
+% \end{macrocode}
+% \IndexOpt{noquizolutions}
+% No solutions for quizzes (shortquiz and quiz environments).
+% \begin{macrocode}
+\DeclareOption{noquizsolutions}{\eq@noquizsolutionstrue\eq@nolinktrue}
+% \end{macrocode}
+% \IndexOpt{online}
+% An \texttt{online} options.
+% \begin{macrocode}
+%</package>
+%<*package|eqexam>
+\let\eq@YES=y \let\eq@NO=n
+\let\eq@One=1 \let\eq@Zero=0
+\def\eq@r{r}\let\eq@f=f \let\eq@l=l
+%</package|eqexam>
+%<*package>
+\DeclareOption{online}{\let\eq@online\eq@YES}
+\let\eq@online\eq@NO
+% \end{macrocode}
+% \IndexOpt{nohiddensolutions}\IndexOpt{noHiddensolutions}
+% Overrides any hidden solutions specified with the \texttt{exercise}
+% environment.
+% \begin{macrocode}
+\DeclareOption{nohiddensolutions}{\eq@globalshowsolutionstrue}
+\DeclareOption{noHiddensolutions}%
+ {\eq@globalshowsolutionstrue\AtBeginDocument{\def\Hidesymbol{h}}}
+% \end{macrocode}
+% \IndexOpt{solutionsafter}
+% Solutions will appear after the statement of the exercise.
+% \begin{macrocode}
+\DeclareOption{solutionsafter}{\eq@solutionsaftertrue\eq@nolinktrue}
+% \end{macrocode}
+% \IndexOpt{solutionsonly}
+% Here is a highly specialized option, put in at the request of a former friend.
+%\changes{v6.2f}{2007/12/21}{Added a solutionsonly option}
+% \begin{macrocode}
+\DeclareOption{solutionsonly}{\solutionsonlytrue\answerkeytrue
+ \therearesolutionstrue\AtEndOfPackage{\let\exerSolnsHeadnToc\relax}}
+\newif\ifsolutionsonly\solutionsonlyfalse
+% \end{macrocode}
+% \IndexOpt{contsolns}
+% This option requires both \textsf{web} and \textsf{exerquiz}. The package
+% tests for the presence of the \textsf{web} and whether webheadings pagestyle
+% is used.
+% \begin{macrocode}
+\DeclareOption{contsolns}{\AtEndOfPackage{\InputIfFileExists
+ {contsolns.def}{\contsolnsInputMsg}{\contsolnsErrorMsg}}}
+\def\contsolnsInputMsg{\PackageInfo{exerquiz}{contsolns option,
+ inputting file contsolns.def}}
+\def\contsolnsErrorMsg{\PackageWarning{exerquiz}{contsolns option,
+ cannot find file contsolns.def}}
+% \end{macrocode}
+% \IndexOpt{nocorrections}
+% The code for correcting the |quiz| environment is
+% not written; this results in a smaller file.
+% \begin{macrocode}
+\DeclareOption{nocorrections}{\nocorrectionstrue}
+% \end{macrocode}
+% \IndexOpt{proofing}
+% An option for marking the correct answers for shortquiz and quiz
+% \begin{macrocode}
+\DeclareOption{proofing}{\eq@proofingtrue}
+% \end{macrocode}
+% \IndexOpt{showgrayletters}
+% When this option is in effect, capital letters in gray appear under
+% the multiple choice question boxes of quizzes.
+% \begin{macrocode}
+\newif\ifaebshowgrayletters\aebshowgraylettersfalse
+\DeclareOption{showgrayletters}{\aebshowgrayletterstrue}
+% \end{macrocode}
+% \IndexOpt{vspacewithsolns}
+% This is for the \texttt{vspacewithsolns} option designed for
+% \textsf{eqexam}, but can be used in \textsf{exerquiz}. The switch
+% \cs{ifvspacewithsolns} is defined in \textsf{eqexam}, and we olnly
+% define it here is \textsf{eqexam} is not loaded.
+% \changes{v6.3x}{2011/04/05}{Added \texttt{vspacewithsolns}}
+% \begin{macrocode}
+\@ifundefined{ifvspacewithsolns}{%
+ \DeclareOption{vspacewithsolns}{\vspacewithsolnstrue}
+ \newif\ifvspacewithsolns\vspacewithsolnsfalse
+}{}
+% \end{macrocode}
+% \IndexOpt{nodljs}
+% An option for excluding all DLJS from the document. Useful with the
+% \texttt{forpaper} option, or a document destined to be printed. Pass
+% on to insdljs package.
+% \begin{macrocode}
+\DeclareOption{nodljs}{\PassOptionsToPackage{nodljs}{insdljs}%
+ \AtEndOfPackage{\let\importdljs\eq@YES}}
+% \end{macrocode}
+% \IndexOpt{execAfter}
+% Execute any JS defined within the \texttt{execJS} environment. Works only for
+% authors using Acrobat 5.0 or Acrobat Approval.
+% \begin{macrocode}
+\DeclareOption{execJS}{\PassOptionsToPackage{execJS}{insdljs}}
+% \end{macrocode}
+% \IndexOpt{exercisesonly}
+% If the document author wants only to create a series of exercises, no quizzes, there is no
+% need for the Document-level JavaScript. So, we have a couple of convenience options.
+% \begin{macrocode}
+\DeclareOption{exercisesonly}{\PassOptionsToPackage{nodljs}{insdljs}}
+% \end{macrocode}
+% \IndexOpt{debug}
+% An option for debugging JavaScript. Pass on to insdljs package.
+% \begin{macrocode}
+\DeclareOption{debug}{\PassOptionsToPackage{debug}{insdljs}}
+% \end{macrocode}
+% \IndexOpt{allowrandomize}
+% Beginning with version 6.1 of \textsf{exerquiz}, it is possible to randomize
+% the choices in a multiple choice question. These choices must be set off
+% by the command \cs{bChoices}/\cs{eChoices} pair. The command \cs{bChoices} now has
+% two optional arguments \texttt{nCols} and \texttt{random}. See \autoref{randomize}.
+% \begin{macrocode}
+\DeclareOption{allowrandomize}{\AtEndOfPackage{\inputRandomizeChoices}}
+\def\inputRandomizeChoices{\InputIfFileExists{aebrandom.def}
+ {\PackageInfo{exerquiz}{inputting aebrandom.def}}
+ {cannot find aebrandom.def}}
+% \end{macrocode}
+% \IndexOpt{usesumrytbls}
+% \begin{macrocode}
+\newif \ifusesumrytbls \usesumrytblsfalse
+\DeclareOption{usesumrytbls}{\usesumrytblstrue
+ \def\inputSumryTblCode{\InputIfFileExists{aebsumrytbls.def}
+ {\PackageInfo{exerquiz}{inputting aebsumrytbls.def}}%
+ {cannot find aebsumrytbls.def}}}
+\let\inputSumryTblCode\relax
+% \end{macrocode}
+% The \IndexOpt{usemcfi}\texttt{usemcfi} option inputs special code for creating a MC/math fill-in question, a type
+% of question suggested to me by Stefka K.\ of Bulgaria.
+% \begin{macrocode}
+\DeclareOption{usemcfi}{%
+ \def\inputMCFICode{\InputIfFileExists{usemcfi.def}
+ {\PackageInfo{exerquiz}{inputting usemcfi.def}}%
+ {cannot find usemcfi.def}}}
+\let\inputMCFICode\relax
+% \end{macrocode}
+% \changes{v7.7o}{2016/07/08}{Added switch \string\cs{ifwithinMCFI}}
+% The switch \cs{ifwithinMCFI} help to determine if a quiz problem occurs within
+% the command \cs{bMCFI}/\cs{eMCFI} pair.
+% \begin{macrocode}
+\newif\ifwithinMCFI\withinMCFIfalse
+% \end{macrocode}
+%
+% \subsection{Driver Options}
+% The \textsf{web} package passes these driver options to \textsf{exerquiz}.
+% These options are needed is \textsf{exerquiz} is used without
+% \textsf{web}; in this case, the options below must explicitly included.
+% \IndexOpt{dvipsone}\IndexOpt{dvips}\IndexOpt{pdftex}
+% Set the driver dependent code for the |quiz| environments.
+% \begin{macrocode}
+% \def\eq@drivernum{5} % 5 = no choice
+\DeclareOption{dvipsone}{%
+ \def\eq@drivernum{0}\def\eq@driver{dvipsone}%
+ \PassOptionsToPackage{dvipsone}{eforms}
+}
+\DeclareOption{dvips}{%
+ \def\eq@drivernum{0}\def\eq@driver{dvips}%
+ \PassOptionsToPackage{dvips}{eforms}
+}
+\DeclareOption{pdftex}{%
+ \def\eq@drivernum{1}\def\eq@driver{pdftex}%
+ \PassOptionsToPackage{pdftex}{\eq@ColorPackage}
+ \PassOptionsToPackage{pdftex}{eforms}
+}
+% \end{macrocode}
+% \IndexOpt{dvipdfm}\IndexOpt{dvipdfmx}\IndexOpt{xetex}
+% Set the driver dependent code for the \texttt{quiz} and \texttt{quiz}
+% environments.
+% \begin{macrocode}
+\DeclareOption{dvipdfm}{%
+ \def\eq@drivernum{2}\def\eq@driver{dvipdfm}%
+ \PassOptionsToPackage{dvipdfm}{\eq@ColorPackage}%
+ \PassOptionsToPackage{dvipdfm}{eforms}%
+}
+\DeclareOption{dvipdfmx}{%
+ \def\eq@drivernum{2}\def\eq@driver{dvipdfmx}%
+ \PassOptionsToPackage{dvipdfmx}{\eq@ColorPackage}%
+ \PassOptionsToPackage{dvipdfmx}{eforms}%
+}
+\DeclareOption{xetex}{%
+ \def\eq@drivernum{2}\def\eq@driver{xetex}%
+ \PassOptionsToPackage{xetex}{\eq@ColorPackage}
+ \PassOptionsToPackage{xetex}{eforms}%
+}
+% \end{macrocode}
+% \IndexOpt{textures}
+% This option, and testing are due to Ross Moore 3/6/02
+% \begin{macrocode}
+\DeclareOption{textures}{\def\eq@drivernum{3}%
+ \def\eq@driver{textures}%
+ \PassOptionsToPackage{textures}{\eq@ColorPackage}%
+ \PassOptionsToPackage{textures}{eforms}%
+}
+% \end{macrocode}
+% \IndexOpt{dviwindo}
+% Set \cmd{\eq@noformstrue}, this inserts an \cmd{\endinput} just after
+% the end of the |exercise| environment. No quizzes for
+% \texttt{dviwindo}.
+% \begin{macrocode}
+\DeclareOption{dviwindo}{\def\eq@drivernum{4}\def\eq@driver{dviwindo}%
+ \eq@noformstrue\PassOptionsToPackage{nodljs}{insdljs}}
+% \end{macrocode}
+% If no driver is passed to \textsf{exerquiz}, assume it is
+% dvipsone or dvips---\textsf{hyperref} defines the specials.
+% Default driver dvipsone/dvips
+% \def\eq@drivernum{5}
+% \def\eq@driver{dvipsone/dvips}
+% \def\eq@driver{no driver specified}
+% \IndexOpt{unicode}
+% Passes the unicode option to \textsf{hyperref}.
+% \changes{v6.3}{2008/03/19}
+% {
+% Added the \texttt{unicode} option, which is passed to hyperref.
+% }
+% \begin{macrocode}
+\DeclareOption{unicode}{\PassOptionsToPackage{unicode}{hyperref}}
+% \end{macrocode}
+% \IndexOpt{useui}
+% Passes the useui option to eforms. With this option,
+% the key-value pairs \textsl{\'{a} la xkeyval} can be used.
+% \changes{v6.3}{2008/03/19}
+% {
+% Added the \texttt{useui} option, which is passed to eforms.
+% }
+% \begin{macrocode}
+\DeclareOption{useui}{\PassOptionsToPackage{useui}{eforms}}
+% \end{macrocode}
+%
+% \subsection{Language Options}
+% \textsf{exerquiz} uses many language dependent typeset labels
+% and JavaScript messages. These messages are defined in the
+% English language in Section~\ref{ss:ldm}. The language options
+% defines the macro \cmd{\LangRedefinition} to input language
+% dependent redefinitions of these messages. Initially,
+% \cmd{\LangRedefinition} is set to relax and no redefinition files
+% are input.
+% \begin{macrocode}
+\let\LangRedefinitions\relax
+% \end{macrocode}
+% \IndexOpt{french}
+% Translations due to Jean-Michel SARLAT.
+% \begin{macrocode}
+\DeclareOption{french}{%
+ \def\LangRedefinitions{\InputIfFileExists{eqfr.def}%
+ {\PackageInfo{exerquiz}{Inputting French Option}}%
+ {\PackageInfo{exerquiz}{French Option: Cannot find the file
+ eqfr.def, using the default, English.}}}}
+% \end{macrocode}
+% \IndexOpt{german}
+% Translation due to Michael Wiedmann.
+% \begin{macrocode}
+\DeclareOption{german}{%
+ \def\LangRedefinitions{\InputIfFileExists{eqde.def}%
+ {\PackageInfo{exerquiz}{Inputting German Option}}%
+ {\PackageInfo{exerquiz}{German Option: Kann die Datei eqde.def
+ nicht finden, benutze Default, Englisch.}}}}
+% \end{macrocode}
+% \IndexOpt{norsk}
+% Translation due to Hans Fredrik Nordhaug.
+% \begin{macrocode}
+\DeclareOption{norsk}{%
+ \def\LangRedefinitions{\InputIfFileExists{eqno.def}%
+ {\PackageInfo{exerquiz}{Inputting Norsk Option}}%
+ {\PackageInfo{exerquiz}{Norsk Option: Cannot find the file eqno.def,
+ using the default, English.}}}}
+% \end{macrocode}
+% \IndexOpt{dutch}
+% Translation due to Henny Wilbrink
+% \begin{macrocode}
+\DeclareOption{dutch}{%
+ \def\LangRedefinitions{\InputIfFileExists{eqnl.def}%
+ {\PackageInfo{exerquiz}{Inputting Dutch Option}}%
+ {\PackageInfo{exerquiz}{Dutch Option: Kan bestand eqnl.def niet
+ vinden, gebruik default, Engels.}}}}
+% \end{macrocode}
+% \IndexOpt{spanish}
+% Translation due to Pedro Luis Luque
+% \begin{macrocode}
+\DeclareOption{spanish}{%
+ \def\LangRedefinitions{\InputIfFileExists{eqes.def}%
+ {\PackageInfo{exerquiz}{Inputting Spanish Option}}%
+ {\PackageInfo{exerquiz}{Spanish Option: Opci\'on Espa\~nola: no puede
+ encontrar el fichero eqes.def, usar\'a por defecto, English.}}}}
+% \end{macrocode}
+% \IndexOpt{italian}
+% Translation due to PierLuigi Zezza
+% \begin{macrocode}
+\DeclareOption{italian}{%
+ \def\LangRedefinitions{\InputIfFileExists{eqit.def}%
+ {\PackageInfo{exerquiz}{Opzione Lingua Italiana}}%
+ {\PackageInfo{exerquiz}{pzione Italiano: Non trovo il file eqit.def,
+ utilizzo quello di default, English.}}}}
+% \end{macrocode}
+% \IndexOpt{russian}
+% Translation due to Sergei V. Znamenskii
+% \begin{macrocode}
+\DeclareOption{russian}{%
+ \@ifpackageloaded{hyperref}{%
+ \ifHy@unicode\else\PackageWarning{exerquiz}{%
+ The unicode option recommended for hyperref\MessageBreak}\fi
+ }{\PassOptionsToPackage{unicode}{hyperref}}
+ \def\LangRedefinitions{\InputIfFileExists{eqru.def}%
+ {\PackageInfo{exerquiz}{Inputting Russian Option}}%
+ {\PackageInfo{exerquiz}{Russian Option: Cannot find the file
+ eqru.def, using the default, English.}}}}
+% \end{macrocode}
+% \IndexOpt{dansk}
+% Translation due to Erik Leimand
+% \begin{macrocode}
+\DeclareOption{dansk}{%
+ \def\LangRedefinitions{\InputIfFileExists{eqda.def}%
+ {\PackageInfo{exerquiz}{Inputting Dansk Option}}%
+ {\PackageInfo{exerquiz}{Dansk Option: Cannot find the file eqda.def,
+ using the default, English.}}}}
+% \end{macrocode}
+% \IndexOpt{polish}
+% Translation due to Jerzy Mycielski
+% \begin{macrocode}
+\DeclareOption{polish}{%
+ \def\LangRedefinitions{\InputIfFileExists{eqpo.def}%
+ {\PackageInfo{exerquiz}{Inputting Polish Option}}%
+ {\PackageInfo{exerquiz}{Polish Option: Cannot find the file
+ eqpo.def, using the default, English.}}}}
+% \end{macrocode}
+% \IndexOpt{finnish}
+% Translation due to Paivi Porras
+% \begin{macrocode}
+\DeclareOption{finnish}{%
+ \def\LangRedefinitions{\InputIfFileExists{eqfin.def}%
+ {\PackageInfo{exerquiz}{Inputting Finnish Option}}%
+ {\PackageInfo{exerquiz}{Finnish Option: Cannot find the file
+ eqfin.def, using the default, English.}}}}
+% \end{macrocode}
+% \IndexOpt{catalan}
+% Translation due to Ramon Ballester
+% \begin{macrocode}
+\DeclareOption{catalan}{%
+ \def\LangRedefinitions{\InputIfFileExists{eqcat.def}%
+ {\PackageInfo{exerquiz}{Inputting Catalan Option}}%
+ {\PackageInfo{exerquiz}{Catalan Option: Cannot find the file
+ eqcat.def, using the default, English.}}}}
+% \end{macrocode}
+% \IndexOpt{czech}
+% Translation due to Robert Marik
+% \begin{macrocode}
+\DeclareOption{czech}{%
+ \def\LangRedefinitions{\InputIfFileExists{eqcz.def}%
+ {\PackageInfo{exerquiz}{Inputting Czech Option}}%
+ {\PackageInfo{exerquiz}{Czech Option: Cannot find the file eqcz.def,
+ using the default, English.}}}}
+% \end{macrocode}
+% \IndexOpt{brazil}
+% Translation due to Koichi Sameshima
+% \begin{macrocode}
+\DeclareOption{brazil}{%
+ \def\LangRedefinitions{\InputIfFileExists{eqbr.def}%
+ {\PackageInfo{exerquiz}{Inputting Brazilian Portuguese Option}}%
+ {\PackageInfo{exerquiz}{Portuguese Option: Opc\~ao Portugu\^es:
+ n\~ao foi poss\'ivel encontrar o arquivo eqbr.def, usaremos
+ o padr\~ao, English.}}}}
+% \end{macrocode}
+% \IndexOpt{turkish}
+% Translation due to Mahmut Ko\c{c}ak
+% \begin{macrocode}
+\DeclareOption{turkish}{%
+ \@ifpackageloaded{hyperref}{%
+ \ifHy@unicode\else\PackageWarning{exerquiz}{%
+ The unicode option recommended for hyperref\MessageBreak}\fi
+ }{\PassOptionsToPackage{unicode}{hyperref}}
+ \def\LangRedefinitions{\InputIfFileExists{eqtr.def}%
+ {\PackageInfo{exerquiz}{Inputting Turkish Option}}%
+ {\PackageInfo{exerquiz}{Cannot find the file eqtk.def,
+ using the default, English.}}}}
+% \end{macrocode}
+% \begin{macrocode}
+\DeclareOption*{\PassOptionsToPackage{\CurrentOption}{\eq@ColorPackage}}
+\@ifpackageloaded{xcolor}%
+{%
+ \@ifpackagelater{xcolor}{2004/07/04}{}
+ {%
+ \PackageError{exerquiz}{%
+ *************************************************\MessageBreak
+ * Your Version of `xcolor.sty' is too old!\MessageBreak
+ * You need the version from 2004/07/04 or newer\MessageBreak
+ * or use: \string\usepackage[noxcolor]{exerquiz}\MessageBreak
+ *************************************************}{}%
+ }%
+}{}
+% \end{macrocode}
+% \subsection{Switches}
+% Boolean switches used by the declared options.
+% \begin{macrocode}
+\let\iterate\relax
+\newif\ifeq@solutionsafter \eq@solutionsafterfalse
+\newif\ifeq@hidesolution \eq@hidesolutionfalse
+\newif\ifeq@globalshowsolutions \eq@globalshowsolutionsfalse
+\newif\ifeq@nosolutions \eq@nosolutionsfalse
+\newif\ifeq@proofing \eq@proofingfalse
+\providecommand\turnProofingOn{\eq@proofingtrue}
+\providecommand\turnProofingOff{\eq@proofingfalse}
+\newif\ifeqforpaper \eqforpaperfalse
+%</package>
+%<*package|eqexam>
+\newif\ifeq@noforms \eq@noformsfalse
+\newif\ifeq@noquizsolutions \eq@noquizsolutionsfalse % dps new
+\newif\ifnocorrections \nocorrectionsfalse
+% changed \ifeq@nocorrections to \ifnocorrections
+%\newif\ifeq@nocorrections \eq@nocorrectionsfalse
+% \end{macrocode}
+% (4/28/11) A switch to control whether the declared vertical space
+% for the \texttt{solution} environment will be preserved during the \texttt{answerkey}
+% option. This is an \textsf{eqexam} feature.
+%\changes{v6.3z}{2011/04/28}{%
+%Created a switch \cs{ifkeepdeclaredvspacing}, used primarily by \textsf{eqexam}}
+% \begin{macrocode}
+\newif\ifkeepdeclaredvspacing \keepdeclaredvspacingfalse
+\newif\ifeq@nolink \eq@nolinkfalse
+\def\eq@ckglobalhide{\ifeq@globalshowsolutions\eq@hidesolutionfalse\fi}
+\def\hidesymbol{h}\def\Hidesymbol{H}
+% \end{macrocode}
+% When the first solution is written, \cs{therearesolutions} is
+% made true. When the solutions are input back into the file, and
+% this switch is still false, then no exercise header is typeset;
+% this avoids an empty exercise section with only the header.
+% \begin{macrocode}
+\newif\iftherearesolutions \therearesolutionsfalse
+% \end{macrocode}
+%\DescribeMacro{\ifIsRespBox}\cmd{\ifIsRespBox} is a switch used to detect the presence
+% of a response box, math or text, on a page. The switch is used to automatically place
+% an \cs{AnswerField} in the running footer.
+% \begin{macrocode}
+\newif\ifIsRespBox \global\IsRespBoxfalse
+% \end{macrocode}
+% \begin{macro}{\SolutionsAfter}
+% \begin{macro}{\SolutionsAtEnd}
+% \begin{macro}{\NoSpaceToWork}
+% \begin{macro}{\SpaceToWork}
+% Some macros to turn \cs{eq@solutionsafter} on or off, and to suppress
+% the vertical space in the solutions environment when the \texttt{nosolutions}
+% option is in effect. Concerning leaving space to work, the default is to
+% leave space to work (\cs{SpaceToWork}).
+% \begin{macrocode}
+\def\SolutionsAfter{\eq@solutionsaftertrue\eq@nolinktrue}
+\newif\ifcqSA\cqSAfalse
+\def\SolutionsAtEnd{\eq@solutionsafterfalse\eq@nolinkfalse}
+\def\NoSpaceToWork{\let\eq@insertverticalspace\eq@NO}
+\def\SpaceToWork{\let\eq@insertverticalspace\eq@YES}
+\SpaceToWork
+% \end{macrocode}
+% (2017/03/16) Made def of \cs{ifNoSolutions} long.
+% \changes{v7.8g}{2017/03/16}{Made def of \string\cs{ifNoSolutions} long}
+% \begin{macrocode}
+\long\def\ifNoSolutions#1#2{%
+ \ifeq@nosolutions\expandafter#1\else
+ \expandafter#2\fi
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% Some switches to control the randomization process, which comes into play
+% with the \texttt{allowrandomize} option. These are set to \texttt{false} initially,
+% The first one is set locally by the random option of \cs{bChoices}; the second
+% one overrides the first so that all multiple choice questions can be randomized
+% without having to edit every \cs{bChoices} command. The user has access to this
+% switch through the \cs{turnOnRandomize} and \cs{obeyLocalRandomize} commands.
+% The topic of randomizing the choices is taken up in \autoref{randomize}.
+% \begin{macrocode}
+\newif\ifeq@randomizeChoices \eq@randomizeChoicesfalse
+\newif\ifeq@randomizeallChoices \eq@randomizeallChoicesfalse
+% \end{macrocode}
+% \begin{macro}{\turnOnRandomize}
+% \begin{macro}{\obeyLocalRandomize}
+% When the \texttt{allowrandomize} option is in effect, the randomization can be
+% turned on and off locally by the optional parameter in \cs{bChoices}. These
+% two commands can be used to override \texttt{random=false}. Consequently,
+% by saying \cs{turnOnRandomize} you can convert your old multiple choice
+% questions so that are randomly arranged, without having to edit them and
+% add the optional \texttt{random} key.
+% \begin{macrocode}
+\def\turnOnRandomize{\eq@randomizeallChoicestrue}
+\def\obeyLocalRandomize{\eq@randomizeallChoicesfalse}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\saveRandomSeed}
+% \begin{macro}{\inputRandomSeed}
+% These two commands are used when the \texttt{allowrandomize} option is in effect,
+% Until then, they do nothing. See the definition in the section \autoref{randomize}.
+% \begin{macrocode}
+\let\saveRandomSeed\relax
+\let\inputRandomSeed\relax
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macrocode}
+%</package|eqexam>
+%<*package>
+% \end{macrocode}
+% \begin{macro}{\CorrectionsOn}
+% \begin{macro}{\CorrectionsOff}
+% Use these macros to locally turn on or off the inclusion
+% of the correction code.
+% \begin{macrocode}
+\def\CorrectionsOn{\global\nocorrectionsfalse}
+\def\CorrectionsOff{\global\nocorrectionstrue}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \subsection{Process Options and Require Packages}
+% The \texttt{quiz} environments use Acrobat forms and JavaScript
+% so we need to load in the AcroForm Dictionary---unless the
+% \texttt{dviwindo} (\cmd{\eq@noformstrue}) option is requested.
+%\changes{v6.3y}{2011/04/23}{%
+% As per Heiko's suggestion, I've change the \texttt{Form} environment
+% no longer creates a grouping. This was causing problems with
+% the \textsf{atveryend} package.
+%}
+% \begin{macrocode}
+\AtBeginDocument{\ifeq@noforms\else\Form\fi}
+\AtEndDocument{%
+ \include@solutions
+ \ifeq@noforms\else\include@quizsolutions\fi
+ \clearpage
+ \csname endForm\endcsname
+% \end{macrocode}
+% (04/12/07) I put a \cs{clearpage} for some good reason, can't remember, I think
+% it had to do with templates, but dvipdfm has problems with this. The document
+% level JavaScript are not inserted, they are cleared out by the \cs{clearpage}.
+% So, we'll only to a \cs{clearpage} if the driver is not dvipdfm.
+% \begin{macrocode}
+ \if\eq@drivernum2\else\clearpage\fi
+}
+% \end{macrocode}
+% \subsection{Load Configuration File: exerquiz.cfg}
+% Look for configuration file, exerquiz.cfg.
+%\begin{verbatim}
+% \ExecuteOptions{noquizsolutions,nocorrections}
+%\end{verbatim}
+% sets several options.
+% \begin{macrocode}
+\InputIfFileExists{exerquiz.cfg}{}{}
+% \end{macrocode}
+% If web is already loaded, we use its driver.
+% \changes{v6.4t}{2012/06/18}{Testing for pdflatex and xetex}
+% \begin{macrocode}
+\@ifpackageloaded{web}{%
+ \ExecuteOptions{\eq@driver@name}%
+}{%
+ \ifpdf\ExecuteOptions{pdftex}\else
+ \ifxetex\ExecuteOptions{xetex}\else
+ \InputIfFileExists{web.cfg}{}
+ {\@ifundefined{l@tex@@@@driver}{\ExecuteOptions{dvips}}
+ {\ExecuteOptions{dvipsone}}}\fi\fi
+}
+% \end{macrocode}
+% \begin{macrocode}
+\ProcessOptions
+% \end{macrocode}
+% Input required packages.
+% \changes{v7.03}{2015/03/02}{Added the \texttt{array} package, mostly
+% for use in the tabular setup of parts in tabular mode.}
+% \begin{macrocode}
+\RequirePackage{array}
+\RequirePackage{\eq@ColorPackage}
+\RequirePackage{verbatim}
+\RequirePackage{comment}
+\RequirePackage{hyperref}
+\RequirePackage{amssymb}% used for return symbols
+\RequirePackage{eforms}[2012/06/20]
+% \end{macrocode}
+% \begin{macrocode}
+\@ifundefined{eq@drivernum}{%
+ \PackageError{exerquiz}%
+ {You have not specified dvips, dvipsone, pdftex, dvipdfm,
+ dvipdfmx, or xetex
+ \MessageBreak in the option list of the exerquiz package}
+ {Place one of the drivers dvips, dvipsone, pdftex, dvipdfm,
+ dvipdfmx, or xetex
+ \MessageBreak in the option list of the exerquiz package.}
+}{}
+% \end{macrocode}
+% Determine whether we have solutions at end.
+% \begin{macrocode}
+\@ifundefined{ifsolutionsAtEnd}
+ {\newif\ifsolutionsAtEnd\solutionsAtEndtrue}{}
+\ifeq@nosolutions\solutionsAtEndfalse\fi
+\ifeq@solutionsafter\solutionsAtEndfalse\fi
+\@ifundefined{if@fleqn}{\let\fleqnOn\relax\let\fleqnOff\relax}
+ {\def\fleqnOn{\@fleqntrue}\def\fleqnOff{\@fleqnfalse}}
+% \end{macrocode}
+% \changes{v7.7o}{2016/07/08}{Added Boolean \string\cs{if@inclkey} in support of the
+% \string\textsf{eq2db} package}
+% \begin{macrocode}
+\@ifundefined{if@inclkey}{\newif\if@inclkey\@inclkeytrue}{}
+%</package>
+% \end{macrocode}
+% \subsection{The Template \& Language dependent messages}\label{ss:ldm}
+% The following define labels and messages for the exercise and
+% various quiz environments. They are all redefined when a
+% language option is used. All of them can be redefined to
+% customize a users document.
+%
+% In attempt to better manage the language localizations, I've placed the
+% template for Web and Exerquiz in the Exerquiz.dtx file.
+% \begin{macrocode}
+%<*template>
+%%------------- Instructions ------------------------------------
+%% Make your language localizations to this file and rename it to
+%% something like \texttt{eq<mylang>.def}, where \texttt{<mylang>}
+%% is a short 2-letter designator of the language. Test the tile
+%% by inputting it in the preamble of your document
+%% \input{eq<mylang>.def}. When satisfied, send it to me at
+%% dpstory@uakron.edu or dpstory@acrotex.net.
+%</template>
+%<template>%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%<template>%% Web.sty %%
+%<template>%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%<template>% Language dependent definitions for Web.sty
+%<*template>
+\DeclareOption{newlanguage}{%
+ \AtEndOfPackage{%
+ \def\today{\ifcase\month\or January
+ \or February \or March \or April
+ \or May \or June \or July \or August
+ \or September \or October \or November
+ \or December \fi \the\day, \the\year}
+ \def\web@versionlabel{Version}
+ \def\web@toc{Table of Contents}
+ \def\web@continued{cont.}
+ \def\web@article{Begin \hyperlink{section.1}{Article}}
+ \def\web@directory{Directory}
+ \def\web@revision{Last Revision Date:}
+ \def\web@copyright{Copyright}
+ \def\web@section{Section}
+ % Label Navibar
+ \def\web@back{Back}
+ \def\web@doc{Doc}} % restricted to three characters
+ \PassOptionsToPackage{newlanguage}{exerquiz}
+}
+%</template>
+% \end{macrocode}
+% \begin{macrocode}
+%<template>%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%<template>%% Exerquiz.sty %%
+%<template>%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%<template>\DeclareOption{newlanguage}{%
+%<template> \def\LangRedefinitions{\InputIfFileExists{eqlang.def}%
+%<template> {\PackageInfo{exerquiz}{Inputting a New Language Option}}%
+%<template> {\PackageInfo{exerquiz}{Language Option: Cannot find the file
+%<template> eqpo.def, using the default, English.}}}}
+%<template>
+%<package>\def\eqretnSymb{$\blacksquare$}%{\rule{6bp}{6.8bp}}
+% The exercise label
+%<package>\newcommand\exlabel{Exercise}
+%<package>\newcommand\exlabelsol{\exlabel}
+%<template>% The exercise label
+%<template>% Accents: \renewcommand\exlabel{\"Ubung} (German)
+%<template>\renewcommand\exlabel{Exercise}
+%<template>% The value of this macro is written to \jobname.sol,
+%<template>% accented characters must be protected with a \protect
+%<template>% E.g., \renewcommand\exlabelsol{\protect\"Ubung} (German)
+%<template>\renewcommand\exlabelsol{\exlabel}
+% \end{macrocode}
+% \begin{macrocode}
+% Title of exercise solution section
+%<package>\newcommand\exsectitle{Solutions to \exlabel s}
+%<package>\newcommand\exsecrunhead{\exsectitle} %% change to @ form
+%<template>
+%<template>% Title of exercise solution section
+%<template>% E.g.: \renewcommand\exsectitle
+%<template>% {L\"osungen der \exlabel en} (German)
+%<template>\renewcommand\exsectitle{Solutions to \exlabel s}
+%<template>\renewcommand\exsecrunhead{\exsectitle} %% change to @ form
+% \end{macrocode}
+% \begin{macrocode}
+%<*package|eqexam>
+% \end{macrocode}
+% \begin{macro}{\exsolafter}
+% Solution label for \texttt{solutionafter} option for exercise, this is a command
+% that may be redefined. Either by a \cs{recommand} or by the use of
+% \cs{renameSolnAfterTo}.
+% \begin{macro}{\resetSolnAfterToDefault}
+% This command resets \cs{exsolafter} to the default value.
+% \begin{macro}{\exsolafterDefault}
+% Takes one argument, the argument is the default value of \cs{exsolafter}
+% \begin{macro}{\renameSolnAfterTo}
+% This command takes one command, it redefines \cs{exsolafter}, but does
+% not change the default value.
+%\changes{v6.05g}{2007/01/28}
+%{
+% Added to commands for use in exerquiz or in \textsf{eqexam}. They are
+% \cs{renameSolnAfterTo} for conveniently changing the solution
+% after label, and \cs{resetSolnAfterToDefault} for resetting
+% back to the default.
+%}
+% \begin{macrocode}
+\newcommand{\exsolafter}{\eq@exsolafterDefault}
+\newcommand{\resetSolnAfterToDefault}{%
+ \def\exsolafter{\eq@exsolafterDefault}}
+\newcommand{\exsolafterDefault}[1]{\def\eq@exsolafterDefault{#1}%
+ \def\exSolafterDefault{#1}\resetSolnAfterToDefault}
+\exsolafterDefault{\textit{Solution}:}
+\newcommand{\renameSolnAfterTo}[1]{\def\exsolafter{#1}}
+\def\recoverDisplayBelow{\vskip\belowdisplayskip}
+\newcommand{\adjDisplayBelow}{\vskip-\lastskip\vskip-\baselineskip}
+% \ifsolutionsAtEnd\recoverDisplayBelow\fi}
+\newcommand{\adjDisplayBelowPlus}{\adjDisplayBelow\recoverDisplayBelow}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macrocode}
+%</package|eqexam>
+%<template>
+%<template>% Solution label for solutionafter option for exercise
+%<template>\renewcommand\exsolafter{\textit{Solution}:}
+% \end{macrocode}
+% \begin{macrocode}
+% Title of quiz solution section
+%<package>\newcommand\eq@sqslsectitle{Solutions to Quizzes}
+%<package>\newcommand\sqslsectitle{\eq@sqslsectitle}
+%<template>
+%<template>% Title of short quiz solution section
+%<template>% Example: \renewcommand\eq@sqslsectitle
+%<template>% {L\"osungen der Aufgaben} (German)
+%<template>\renewcommand\eq@sqslsectitle{Solutions to Quizzes}
+%<template>\renewcommand\sqslsectitle{\eq@sqslsectitle}
+% \end{macrocode}
+% \begin{macrocode}
+% Running header/section title for solutions to short quizzes
+%<package>\newcommand\eq@sqslsecrunhead{Solutions to Quizzes}
+% User access
+%<package>\newcommand\sqslsecrunhead{\eq@sqslsecrunhead}
+%<template>
+%<template>% Running header/section title for solutions to short quizzes
+%<template>\renewcommand\eq@sqslsecrunhead{Solutions to Quizzes}
+%<template>% User access
+%<template>\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}
+% \end{macrocode}
+% \begin{macrocode}
+% Label for solutions to quizzes, appears in solutions sections
+%<package>\newcommand\eq@sqsllabel{\protect\textbf{Solution to Quiz:}}
+% User access
+%<package>\newcommand\sqsllabel{\eq@sqsllabel}
+%<template>
+%<template>% Label for solutions to short quizzes, appears
+%<template>% in solutions sections
+%<template>% Protect accents with \protect
+%<template>% E.g.: \renewcommand\eq@sqsllabel
+%<template>% {\string\textbf{L\protect\"osung zu Aufgabe:}} (German)
+%<template>\renewcommand\eq@sqsllabel{\string\textbf{Solution to Quiz:}}
+%<template>% User access
+%<template>\renewcommand\sqsllabel{\eq@sqsllabel}
+% \end{macrocode}
+% \begin{macrocode}
+% Solution label for solutionafter option for shortquiz
+%<package>\newcommand\sqsolafter{\textit{Solution}:}
+%<template>
+%<template>% Solution label for solutionafter option for shortquiz
+%<template>\renewcommand\sqsolafter{\textit{Solution}:}
+% \end{macrocode}
+% \begin{macrocode}
+% Here is the default short quiz label.
+%<package>\newcommand{\sqDefaultFmtTitle}[1]%
+%<package> {\def\eq@sqlabel{#1}\def\sqlabel{#1}}
+% User access to shortquiz label
+%<package>\newcommand\sqlabel{\eq@sqlabel}
+%<package>\sqDefaultFmtTitle{\textcolor{red}{Quiz}}
+%<template>
+%<template>% User access to shortquiz label
+%<template>\renewcommand\sqlabel{\eq@sqlabel}
+%<template>% Here is the default short quiz label.
+%<template>\sqDefaultFmtTitle{\textcolor{red}{Quiz.}}
+% \end{macrocode}
+% \begin{macrocode}
+% Here is the default short quiz return label
+% No formatting allowed
+%<package>\newcommand\eq@sqslrtnlabel{\protect\eqretnSymb}
+% User access to shortquiz label
+%<package>\newcommand\sqslrtnlabel{\eq@sqslrtnlabel}
+%<template>
+%<template>% Here is the default short quiz return label
+%<template>% No formatting allowed
+%<template>\renewcommand\eq@sqslrtnlabel{End Quiz}
+%<template>% User access to shortquiz label
+%<template>\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}
+% \end{macrocode}
+% \begin{macrocode}
+% Short quiz feedback messages
+%<package>\newcommand\eqsqrtmsg{"Right!"}
+%<package>\newcommand\eqsqwgmsg{"Wrong!"}
+%<package>\newcommand\doNotShowAgainMsg{Do not show this message again}
+%<template>
+%<template>% Short quiz feedback messages
+%<template>\renewcommand\eqsqrtmsg{"Right!"}
+%<template>\renewcommand\eqsqwgmsg{"Wrong!"}
+%<template>\renewcommand\doNotShowAgainMsg{Do not show this message again}
+% \end{macrocode}
+% \begin{macrocode}
+% Here is the default quiz label.
+%<package>\newcommand\eq@bqlabel{Begin Quiz}
+% User access to quiz label
+%<package>\newcommand\bqlabel{\eq@bqlabel}
+% Used for writing JavaScript Messages on screen
+%<package>\newcommand\eq@bqlabelISO{\eq@bqlabel}
+%<package>\newcommand\bqlabelISO{\eq@bqlabelISO}
+% Default title for a quiz used for \verb!\@currentlablename!
+%<package|eqexam>\newcommand\setDefShortQuizLabelName[1]%
+%<package|eqexam> {\def\eq@defaultShortQuizLabelName{#1}}
+%<package|eqexam>\setDefShortQuizLabelName{Quiz}
+%<package>\newcommand\setDefQuizLabelName[1]
+%<package> {\def\eq@defaultQuizLabelName{#1}}
+%<package>\setDefQuizLabelName{Quiz}
+%<template>
+%<template>% Here is the default quiz label.
+%<template>% No formatting allowed
+%<template>% For Example: \renewcommand\eq@bqlabel{D\'ebut} (French)
+%<template>\renewcommand\eq@bqlabel{Begin Quiz}
+%<template>% User access to shortquiz label
+%<template>\renewcommand\bqlabel{\eq@bqlabel}
+%<template>% Used for writing JavaScript Messages on screen.
+%<template>% Use PDFDocEncoding
+%<template>% For Example:
+%<template>% \renewcommand\eq@bqlabelISO{D\string\351but} (French)
+%<template>% Use \string not \protect, this helps out
+%<template>% TeX4ht by Eitan Gurari.
+%<template>\renewcommand\eq@bqlabelISO{\eq@bqlabel}
+%<template>\renewcommand\bqlabelISO{\eq@bqlabel}
+%<template>% Default title for a quiz used for \verb!\@currentlablename!
+%<template>\setDefShortQuizLabelName{Quiz}
+%<template>\setDefQuizLabelName{Quiz}
+% \end{macrocode}
+% \begin{macrocode}
+% Here is the default quiz label.
+% No formatting allowed
+%<package>\newcommand\eq@eqlabel{End Quiz}
+% User access to quiz label
+%<package>\newcommand\eqlabel{\eq@eqlabel}
+%<template>
+%<template>% Here is the default quiz label.
+%<template>% No formatting allowed
+%<template>\renewcommand\eq@eqlabel{End Quiz}
+%<template>% User access to shortquiz label
+%<template>\renewcommand\eqlabel{\eq@eqlabel}
+% \end{macrocode}
+% \begin{macrocode}
+% JavaScript Messages for Quiz Environments
+%<package>\newcommand\eq@Score{Score:}\newcommand\eq@OutOf{out of}
+%<package>\newcommand\eq@ptScore{Score:}
+%<package>\newcommand\stOutOf{of}
+%<package>\newcommand\eqScore{\eq@Score}\newcommand\eqOutOf{\eq@OutOf}
+%<package>\newcommand\eqptScore{\eq@ptScore}
+%<template>
+%<template>% JavaScript Messages for Quiz Environments. Use PDFDocEncoding
+%<template>% Note: Use \string rather than \protect for escape codes,
+%<template>% i.e. \string\374
+%<template>%
+%<template>% In the Text Field showing the score, there is the default
+%<template>% phrase in English
+%<template>% Score: 2 out of 3, the word "Score" and "out of" needs
+%<template>% translation.
+%<template>\renewcommand\eq@Score{Score:}\renewcommand\eq@OutOf{out of}
+%<template>\renewcommand\eq@ptScore{Score:}
+%<template>% used in summary tables
+%<template>\renewcommand\stOutOf{of}
+% \end{macrocode}
+% \begin{macrocode}
+%<package>\newcommand\eqInitQuizMsg{%
+%<package> "You must initialize the Quiz! Click on "+msg+"."}
+%<template>% If you are taking a quiz and click on an alternative without
+%<template>% initializing the quiz
+%<template>% first, this message appears.
+%<template>% This string is placed in the DLJS, so the escape sequences
+%<template>% need to be protected more. Instead of \string\340 we need
+%<template>% \string\\340.
+%<template>% Example: \renewcommand\eqInitQuizMsg{% (German)
+%<template>% "Sie m\string\\374ssen die Aufgaben initialisieren!
+%<template>% Bitte klicken Sie auf "+msg+"."}
+%<template>\renewcommand\eqInitQuizMsg{%
+%<template> "You must initialize the Quiz! Click on "+msg+"."}
+% \end{macrocode}
+% \begin{macrocode}
+%<package>\newcommand\eqQuizTotalMsg{%
+%<package> "\eqScore\space"+Score+" \eqOutOf\space"+nQuestions}
+%<package>\newcommand\eqQuizPointsMsg{%
+%<package> "\eqptScore\space"+ptScore+" \eqOutOf\space"+nPointTotal}
+%<package>\newcommand\eqQuizPercentMsg{pcScore+"\%"}
+%<package>\newcommand\eqQuizGradeMsg{quizGrade}
+%<template>
+%<template>% This macro doesn't usually need translation, it uses \eqScore
+%<template>% and \eqOutOf. However, if the sentence "Score: 2 out of 3"
+%<template>% does not translate conveniently into a particular language,
+%<template>% this macro may have to be modified. It's the one that puts
+%<template>% the message in the message box.
+%<template>\renewcommand\eqQuizTotalMsg
+%<template> {"\eqScore\space"+Score+" \eqOutOf\space"+nQuestions}
+%<template>\renewcommand\eqQuizPointsMsg{%
+%<template> "\eqptScore\space"+ptScore+" \eqOutOf\space"+nPointTotal}
+%<template>\renewcommand\eqQuizPercentMsg{pcScore+"\%"}
+%<template>\renewcommand\eqQuizGradeMsg{quizGrade}
+% \end{macrocode}
+% \begin{macrocode}
+%<package>\newcommand\eqMadeChoice{%
+%<package> "You have already made a choice."
+%<package> + " Your choice was ("+Responses[probno]+")."
+%<package> + " Do you want to change it?"}
+%<template>
+%<template>% In the link form of a quiz, of you change your choice,
+%<template>% this message appears. This string is placed in the
+%<template>% DLJS, so the escape sequences need to be protected more.
+%<template>% Instead of \string\340 we need \string\\340.
+%<template>% For Example: \renewcommand\eqMadeChoice{%
+%<template>% "Vous avez d\string\\351j\string\\340 fait un choix,
+%<template>% ce choix est ("+Responses[probno]+").
+%<template>% Souhaitez vous le modifier ?"} (French)
+%<template>\renewcommand\eqMadeChoice{%
+%<template> "You have already made a choice.
+%<template> Your choice was ("+Responses[probno]+").
+%<template> Do you want to change it?"}
+% \end{macrocode}
+% Default language phrases used by \cmd{\eqButton}. These are overwritten by the
+% language options.
+% \begin{macrocode}
+%<package>\newcommand\eq@local@CA{Correct}
+%<package>\newcommand\eq@local@RC{My Answers!}
+%<package>\newcommand\eq@local@AC{Please!}
+%<template>% Default button labels for \eqButton
+%<template>% Accents are handled as above:
+%<template>% A French Language Example
+%<template>% \renewcommand\eq@local@CA{R\string\351ponses}
+%<template>% \renewcommand\eq@local@RC{Correctes}
+%<template>% \renewcommand\eq@local@AC{SVP !}
+%<template>\renewcommand\eq@local@CA{Correct}
+%<template>\renewcommand\eq@local@RC{My Answers!}
+%<template>\renewcommand\eq@local@AC{Please!}
+% \end{macrocode}
+% Default language phrases used by \cmd{\CorrAnsButton}. These are overwritten by the
+% language options.
+% \begin{macrocode}
+%<package>\newcommand\eq@local@CorrAnsButton{Ans}
+%<template>
+%<template>% Default button label of \CorrAnsButton.
+%<template>\renewcommand\eq@local@CorrAnsButton{Ans}
+%<package>\newcommand{\eq@local@sqClearButton}{Clear}
+%<template>% Default button label of \sqClearButton
+%<template>\renewcommand{\eq@local@sqClearButton}{Clear}
+%<template>% Short string used by the \PromptButton
+%<template>\renewcommand{\AnsPromptBtnStr}{Answer:\space}
+% \end{macrocode}
+% The following are (error) messages generated from the math fill-in questions.
+% \begin{macrocode}
+%<*package>
+\newcommand\eqerrABS{"Absolute values not balanced. Please correct."}
+\dlJSStr[noquotes]\eqerrBadMathFunc{"The expression \""+aF[i]
+ +"\" is neither a defined function nor a valid math expression."}
+\newcommand\eqParens{"Parentheses"}
+\newcommand\eqBrackets{"Brackets"}
+\newcommand\eqBraces{"Braces"}
+\newcommand\eqerrDelimNotBal{aGroup[i][2] + " not balanced.
+ Please correct."}
+\newcommand\eqerrBadExp{"Invalid mathematical expression.
+ A problem with one of the exponents. Please correct."}
+\newcommand\eqerrUnfinishQuiz{"There is an unfinished quiz,
+ please finish before moving on to another."}
+\newcommand\noPeekMsg{"Viewing Solutions to quizzes is not allowed
+ until you take or finish this quiz!"}
+\newcommand\highThresholdMsg{"You are required to respond to all
+ questions before the quiz is evaluated."}
+\newcommand\eqSyntaxErrorUndefVar{"Syntax Error: Possibly an undefined
+ variable present, or an expression is not written in an expected
+ format."}
+\dlJSStr[noquotes]{\eqSyntaxErrorComma}{%
+ "Syntax Error: A comma was found"
+ + " in your response \""
+ + UserAns + "\". Please remove the comma, or this answer"
+ + " will be marked as wrong."}
+\newcommand{\limSelWarningMsg}{"For this question, you are allowed to
+ make at most " + n + " selections."}
+\newcommand{\defaultReqFormMsg}{%
+ "The expression is not in the expected form."}
+%</package>
+%<template>
+%<template>% These (error) messages are generated when the user enters an
+%<template>% invalid math expression into a math fill-in response box.
+%<template>% The messages come in the form of an eqAppAlert() so
+%<template>% PDFDocEncoding needs to be used.
+%<*template>
+\renewcommand\eqerrABS{"Absolute values not balanced. Please correct."}
+\renewcommand\eqerrBadMathFunc{"The expression \""+aF[i]+"\" is neither
+ a defined " +"function, nor a valid math expression."}
+\renewcommand\eqParens{"Parentheses"}
+\renewcommand\eqBrackets{"Brackets"}
+\renewcommand\eqBraces{"Braces"}
+\renewcommand\eqerrDelimNotBal{aGroup[i][2] + " not balanced.
+ Please correct."}
+\renewcommand\eqerrBadExp{"Invalid mathematical expression.
+ A problem with one of the exponents. Please correct."}
+\renewcommand\eqerrUnfinishQuiz{"There is an unfinished quiz,
+ please finish before moving on to another."}
+\renewcommand\noPeekMsg{"Viewing Solutions to quizzes is not allowed
+ until you take or finish this quiz!"}
+\renewcommand\highThresholdMsg{"You are required to respond to all
+ questions before the quiz is evaluated."}
+\renewcommand\eqSyntaxErrorUndefVar{"Syntax Error: Possibly an
+ undefined variable present."}
+\newcommand{\eqSyntaxErrorComma}{"Syntax Error: A comma was found"
+ + " in your response \\""
+ + UserAns + "\\". Please remove the comma, or this answer"
+ + " will be marked as wrong."}
+\renewcommand{\limSelWarningMsg}{"For this questions, you are allowed to
+ make at most " + n + " selections."}
+\renewcommand{\promptButtonMsg}{%
+ "Would you like to see the correct answer at this time? "
+ + "Your current answer will be the one that will be scored. "
+ + "If you click on \\"Yes\\",
+ you will not be able to change your answer."
+}
+\renewcommand{\defaultReqFormMsg}{%
+ "The expression is not in the expected form."}
+\renewcommand\eqAnd{and}
+%</template>
+%<*template>
+%%%%%%%%%%%%%%%%%%%%%% End Message Section %%%%%%%%%%%%%
+%% Some typeout messages %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% In exerquiz.sty
+\typeout{Inputting French Option}
+\typeout{French Option: Cannot find the file eqfr.def, using the
+ default, English.}
+\typeout{Solutions not allowed with this option}
+\typeout{Check: `#1' is not an acceptable option, inserting
+ default, `check'.}
+%</template>
+% \end{macrocode}
+%
+% Announce driver option
+% \begin{macrocode}
+%<*package>
+\typeout{^^Jexerquiz: * Using \eq@driver\space option *^^J}
+% \end{macrocode}
+% \subsection{Handles, counters and such}
+% Handles to write solutions to quizzes and exercises to a file.
+% \begin{macrocode}
+%</package>
+%<*package|eqexam>
+\ifsolutionsonly
+\InputIfFileExists{\jobname_xdefs.cut}{%
+ \typeout{^^JExerquiz|Eqexam: Reading \jobname_xdefs.cut^^J}}
+ {\PackageWarningNoLine{exerquiz|eqexam}{%
+ \jobname_xdefs.cut not found.\MessageBreak
+ Recompile file under the vspacewithsolns\MessageBreak
+ option, then compile with the solutionsonly\MessageBreak
+ option}}
+\else
+\newwrite\ex@solns \immediate\openout \ex@solns \jobname.sol
+\newcommand{\writeToExSolns}[1]{%
+ \set@display@protect
+ \immediate\write\ex@solns{#1}%
+ \set@typeset@protect
+}
+% \end{macrocode}
+% If we are not in \cs{ifsolutionsonly} mode, we write some definitions to a .def
+% file to be read back in at the beginning of the document.
+% \begin{macrocode}
+\newwrite\eq@xrefdefns \immediate\openout\eq@xrefdefns\jobname_xdefs.cut
+\fi
+\newwrite\quiz@solns \immediate\openout \quiz@solns \jobname.qsl
+\newcommand{\writeToQzSolns}[1]{%
+ \set@display@protect
+ \immediate\write\quiz@solns{#1}%
+ \set@typeset@protect
+}
+\def\eq@IWAuxOut#1{\immediate\write\@auxout{#1}}
+\def\eq@IWDefs#1{\immediate\write\eq@xrefdefns{#1}}
+% \end{macrocode}
+% Counters to keep track of exercise questions.
+% \begin{macrocode}
+\newcounter{eqexno} \setcounter{eqexno}{0}
+\newcounter{@exno} \setcounter{@exno}{0} % running exno
+% \end{macrocode}
+% Counter to keep track of quiz questions.
+% \begin{macrocode}
+\newcounter{quizno} \setcounter{quizno}{0}
+\renewcommand\thequizno{\alph{quizno}}
+%</package|eqexam>
+%<*package>
+\def\theHquizno{\curr@quiz.\theeqquestionnoi.%
+ \ifcase\@eqquestiondepth\or\or\arabic{eqquestionnoii}.%
+ \or\arabic{eqquestionnoii}.\roman{eqquestionnoiii}.%
+ \else\fi\alph{quizno}}
+% \end{macrocode}
+% (2016/05/17) \cs{eqemargin} is used in \textsf{eqexam}, but some calculations use it for the list version of
+% answers. We declare this length to be 0pt. The \textsf{eqexam} resets this value.
+% \begin{macrocode}
+\newlength\eqemargin \eqemargin=0pt
+% \end{macrocode}
+% \begin{macrocode}
+%</package>
+%<*package|eqexam>
+% \end{macrocode}
+% Keep track of point values of quizzes
+% \begin{macrocode}
+\newcounter{eqpointvalue} \setcounter{eqpointvalue}{0}
+% \end{macrocode}
+% Some scratch registers and boxes.
+% \begin{macrocode}
+\newlength\eq@tmplength
+\newlength\eqtmplength
+% \end{macrocode}
+% \begin{macro}{eqquestionno}
+% The counter that keeps track of the question number.
+% Used by the \texttt{questions environment}
+% \begin{macrocode}
+\newcounter{questionno}
+\newcounter{eqquestionnoi}
+\newcounter{eqquestionnoii}
+\newcounter{eqquestionnoiii}
+\newcount\@eqquestiondepth \@eqquestiondepth=0
+% \end{macrocode}
+% \begin{macrocode}
+%</package|eqexam>
+%<*package>
+\newcounter{grpquestionno}
+%</package>
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{partno}
+% This counter keeps track of the parts of an exercise, when the *-option
+% is used.
+% \begin{macrocode}
+%<*package|eqexam>
+\newcounter{partno}
+% \end{macrocode}
+% (2017/01/11) Added \DescribeMacro{\numberParts}\cs{numberParts} to change how this counter is displayed
+% as a number. The default is \DescribeMacro{\alphaParts}\cs{alphaParts} to display the \texttt{partno}
+% counter as a letter.
+%\begin{verbatim}
+% \renewcommand{\partnoFmt}{\arabic}
+% \setPartsWidth{(00)}
+% \partsformat{\makebox[\widthOfParts][c]{(\hfil\thepartno\hfil)}}
+%\end{verbatim}
+% With this code, the items in the \texttt{parts} environment are numbered.
+% \changes{v7.8d}{2017/01/11}{Added \string\cs{partnoFmt} to change how this counter is displayed}
+% \begin{macrocode}
+\newif\ifuseNumForParts\useNumForPartsfalse
+\def\alphaParts{\def\partnoFmt{\alph}\useNumForPartsfalse}\alphaParts
+\def\numberParts{\def\partnoFmt{\arabic}\useNumForPartstrue}
+\renewcommand\thepartno{\partnoFmt{partno}}
+\newtoks\eq@scratchtoks
+%</package|eqexam>
+%<*package>
+\def\theHpartno{partno\the@exno\thepartno}
+%</package>
+%<*package|eqexam>
+% \end{macrocode}
+% \end{macro}
+% \subsection{Write to a file}
+% We must have a way to write the solutions of our exercises and
+% quizzes to a file. The following \cmd{\verbatimwrite} was
+% taken from the \texttt{moreverb} package, it uses the
+% \texttt{verbatim} package.
+%
+% \begin{macrocode}
+\def\verbatimwrite{\@bsphack
+ \let\do\@makeother\dospecials
+ \catcode`\^^M\active \catcode`\^^I=12
+ \def\verbatim@processline{%
+ \immediate\write\verbatim@out
+ {\the\verbatim@line}}%
+ \verbatim@start}
+\def\endverbatimwrite{\@esphack}
+% \end{macrocode}
+% \section{The \texttt{exercise} Environment}
+%
+% We use \cmd{\raggedright} within a \texttt{tabular} environment,
+% so we must use a little trick, illustrated in the \textsl{\LaTeX\
+% Companion} by M. Goossens et al. This macro is used with \texttt{exercise}
+% with parts, \texttt{shortquiz} and \texttt{quiz} environments.
+% \begin{macrocode}
+\providecommand\PBS[1]{\let\temp=\\#1\let\\=\temp}
+%</package|eqexam>
+%<*package>
+% \end{macrocode}
+% Define some formatting commands. These can all be redefined to
+% customize the document.
+% \begin{macro}{\exlabelformat}
+% This is the formatted label for the exercise environment.
+% \begin{macrocode}
+\newcommand\exlabelformat{{\scshape\exlabel\ \theeqexno.}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\exlabelformatwp}
+% This is the formatted label for the exercise environment with parts.
+% When an exercises has parts, the word `Exercise' is not a link,
+% so we color this word for emphasis.
+% \begin{macrocode}
+%\newcommand\exlabelformatwp{{\scshape\exlabel\ \theeqexno.}}
+\newcommand\exlabelformatwp{\exlabelformat}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\exsllabelformat}
+% This is the formatted solution label.
+% \begin{macrocode}
+\newcommand\exsllabelformat{\protect\textbf{\exlabelsol\ \theeqexno.}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\exsllabelformatwp}
+% This is the formatted solution when the *-options is use, that is,
+% when there are multiple parts to the question.
+% \begin{macrocode}
+\newcommand\exsllabelformatwp
+ {\protect\textbf{\exlabelsol\ \theeqexno(\thepartno)}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\exrtnlabelformat}
+% This is the formatted return label (return from the solution).
+% \begin{macrocode}
+\newcommand\exrtnlabelformat{$\square$}
+%\newcommand\exrtnlabelformat{\exlabelsol\ \theeqexno}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\exrtnlabelformat}
+% This is the formatted return label (return from the solution),
+% for an exercise with parts.
+% \begin{macrocode}
+\newcommand\exrtnlabelformatwp{$\square$}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\aboveexskip}
+% \begin{macro}{\belowexskip}
+% Amount of skip before and after exercise environment
+% \begin{macrocode}
+%</package>
+%<*package|eqexam>
+\newcommand{\belowexskip}[1]{\setlength{\eq@tmplength}{#1}%
+ \edef\eq@exerskip{\noexpand\removelastparskip
+ \noexpand\vskip\the\eq@tmplength\relax\kern0pt}}
+\let\eqexerskip\belowexskip
+\belowexskip{\medskipamount}
+\newcommand{\aboveexskip}[1]{\setlength{\eq@tmplength}{#1}%
+ \edef\eq@priorexskip{\noexpand\vskip\the\eq@tmplength\relax
+ \kern0pt}}
+\let\priorexskip\aboveexskip
+\aboveexskip{\medskipamount}
+\let\eq@postexerciseHook\relax
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\belowexsolnskip}
+% Amount of skip after solutions, this one is written to a file, so
+% we must protect it from early expansion.
+% \begin{macrocode}
+\newcommand\belowexsolnskip{\protect\medskip}
+%\let\eqafterexersolnskip\belowexsolnskip
+% \end{macrocode}
+% \changes{v7.4}{2015/03/23}{added \cmd\removelastparskip}
+% \DescribeMacro\removelastparskip removes last \cmd\parskip, as needed.
+% \begin{macrocode}
+\def\removelastparskip{\ifdim\parskip>0pt\vskip-\parskip\fi}
+%</package|eqexam>
+%<*package>
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\nolinkcolor}
+% This is the color to paint the word 'Exercise' with parts;
+% or it colors all the 'Exercise's when the nosolutions option
+% has been used
+% \changes{v6.05a}{2006/05/08}
+% {
+% Changed \cs{nolinkcolor} into a text fill-in. Now, the command \cs{nolinkcolor}
+% fills in \cs{@nolinkcolor}, which holds the named color.
+% }
+% \begin{macrocode}
+\newcommand{\nolinkcolor}[1]{\def\@nolinkcolor{#1}}
+\nolinkcolor{blue}
+% \end{macrocode}
+% \end{macro}
+% \subsection{Define \texttt{exercise} Environment}
+% Defines the \texttt{exercise} environment for writing exercises,
+% and solutions. The solutions are written to the file
+% \cmd{\jobname.sol}, and input at the end of the file. Hypertext
+% links connect the statement of the exercise with its solution.
+%
+%\smallskip\noindent\textbf{Basic usage}
+%\begin{verbatim}
+%\begin{exercise}
+%The exercise question is posed.
+%\begin{solution}
+%The solution to exercise goes here.
+%\end{solution}
+%\end{exercise}
+%\end{verbatim}
+% These environments should be nested as illustrated above.
+%
+% The \texttt{exercise} environment has three optional arguments. The syntax
+% for an exercise without parts is\dots
+%\begin{verbatim}
+% \begin{exercise}[<ctr>][h|H] ...\end{exercise}
+%\end{verbatim}%
+%
+% (1) The value of this first optional argument, \texttt{<ctr>}, is a counter.
+% You can use the \texttt{exercise}
+% environment then to create other environments with their own
+% counters. A special value of zero (0) for this optional argument,
+% means not to associate any counter with the environment. These
+% features can be used in combination with the \cs{SolutionsAfter}
+% and \cs{SolutionsAtEnd} commands to obtain different effects,
+% see the manual for examples
+%
+% (2) The second optional argument is an `\texttt{h}' or an \texttt{H}, this signals that the
+% solution to the exercise should not be written to the \cmd{\jobname.sol}
+% file. See manual for examples.
+%
+% The \texttt{exercise} environment has three optional arguments. The syntax
+% for an exercise with parts is\dots
+%\begin{verbatim}
+% \begin{exercise}[<ctr>]* ...\end{exercise}
+% \begin{exercise*}[<ctr>] ...\end{exercise*}
+%\end{verbatim}%
+%
+% (1) The value of this first optional argument, \texttt{<ctr>}, is a counter.
+% You can use the \texttt{exercise}
+% environment then to create other environments with their own
+% counters. A special value of zero (0) for this optional argument,
+% means not to associate any counter with the environment. These
+% features can be used in combination with the \cs{SolutionsAfter}
+% and \cs{SolutionsAtEnd} commands to obtain different effects,
+% see the manual for examples
+%
+% (2) The second argument is a star \texttt{*}. The presence of a * signals
+% that this exercise has multiple parts. See the manual for the proper
+% syntax.
+%
+% Beginning with version 6.07, there is now a \texttt{exercise*}
+% environment, this is what I should have done originally, but now its
+% done. The \texttt{exercise*} signals an exercise with parts. It takes
+% one optional parameter, the name of a counter \texttt{<ctr>} that is to
+% be used.
+% \begin{macro}{\exerSolnInExtFile}
+% With the exercises, you have the option of including them in the main document, or putting them
+% in an external document. The \cs{exerSolnsInExtFile} command lets you specify an external file name.
+% Just use the \textit{basename}, hyperref will add the extension. If an external file is specified, all
+% solution links are changed to links between documents. Usage:
+%\begin{verbatim}
+%\exerSolnsInExtFile{myExSonls}
+%\end{verbatim}
+% \begin{macrocode}
+\newcommand{\exerSolnsInExtFile}[2][]
+ {\let\exerSolns@ExtFile\eq@YES\gdef\eq@exerSolns@fileName{#2}%
+ \gdef\exerSolns@ReturnPath{#1}}
+\let\exerSolns@ExtFile\eq@NO
+\def\exerSolns@ReturnPath{}
+% \end{macrocode}
+% \end{macro}
+% \begin{macrocode}
+%</package>
+%<*package|eqexam>
+% \end{macrocode}
+%\DescribeMacro{\marginparpriorhook}\DescribeMacro{\marginparafterhook}
+%\DescribeMacro{\afterlabelhskip} Various hooks into an exercise.
+% \begin{macrocode}
+\let\marginparpriorhook\@empty % used to material before the exercise
+\let\marginparafterhook\@empty % used to material after the exercise
+\let\afterlabelhskip\space
+% \end{macrocode}
+% \DescribeMacro{\exersolnheadhook}
+% Inserted in the header of each exercise solution. May be used for inserting
+% addition text or macros in the solution.
+% \begin{macrocode}
+\let\exersolnheadhook\@empty
+\let\exer@solnheadhook\@empty
+% \end{macrocode}
+% \begin{macro}{\eqexheader}
+% \begin{macro}{\eqexheader@wrapper}
+% \cs{eqexheader} typesets `Exercise xx'. \cs{eqexheader@wrapper} creates a hypertarget
+% at the heading. Portions of \cs{eqexheader} is also used by \textsf{eqExam}.
+% \begin{macrocode}
+\newcommand{\eqexheader}
+{%
+%</package|eqexam>
+%<*package>
+ \ifeq@nolink % no link to solution
+%</package>
+%<*package|eqexam>
+ \mbox{\color{\@nolinkcolor}\if\exerstar*\exlabelformatwp\else
+ \exlabelformat\fi}%
+%</package|eqexam>
+%<*package>
+ \else
+ \if\exerSolns@ExtFile\eq@YES
+ \mbox{\href{\eq@exerSolns@fileName\#ex.\the@exno}%
+ {\exlabelformat}}%
+ \else
+ \mbox{\hyperlink{ex.\the@exno}{\exlabelformat}}%
+ \fi
+ \fi
+%</package>
+%<*package|eqexam>
+}
+\def\eqexheader@wrapper{\hypertarget{qex.\the@exno}{\eqexheader}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\eqexlisttabheader}
+% \cs{eqexlisttabheader} typesets `(a)' when we have exercises with parts.
+% Portions are also used by \textsf{eqExam}.
+% \begin{macrocode}
+\newcommand{\partsformat}[1]{\def\eq@partsformat{#1}}
+\partsformat{(\hfil\thepartno\hfil)}
+\newcommand{\defaultpartsformat}{%
+ \partsformat{(\hfil\thepartno\hfil)}}
+\let\exlisttabheaderpriorhook\@empty
+\let\exlisttabheaderafterhook\@empty
+\newcommand{\eqexlisttabheader}
+{%
+ \exlisttabheaderpriorhook
+%</package|eqexam>
+%<*package>
+ \ifeq@nolink
+%</package>
+%<*package|eqexam>
+ \color{\@nolinkcolor}\eq@partsformat
+%</package|eqexam>
+%<*package>
+ \else
+ \if\exerSolns@ExtFile\eq@YES
+ \href{\eq@exerSolns@fileName\#ex.\the@exno\thepartno}%
+ {\eq@partsformat}%
+ \else
+ \hyperlink{ex.\the@exno\thepartno}{\eq@partsformat}%
+ \fi
+ \fi
+%</package>
+%<*package|eqexam>
+}
+% \end{macrocode}
+% \end{macro}
+% Introduce a method of copying questions from \env{exercise} environment to solution page. The \env{cq@CQ}
+% is \cs{let} to the \env{cq} environment, only defined within the \env{exercise} environment.
+% \changes{v7.8}{2016/11/02}{Added support to copy questions in the exercise environment to solution pages.}
+% \begin{macrocode}
+\newcount\cq@Cnt
+\def\cq@CutName{cq-\the\cq@Cnt.cut}
+% \end{macrocode}
+% \begin{environment}{cq}
+% The \env{cq} environment is \cs{let} to the \env{cq@CQ} environment at the beginning of
+% the \env{exercise} environment, \env{cq@CQ} begin the internal name of the environment.
+% \par\medskip\noindent\textbf{Example}
+%\begin{verbatim}
+% \begin{exercise}
+% \begin{cq}
+% This is the question
+% \end{cq}
+% \begin{solution}
+% This is its solution
+% \end{solution}
+% \end{exercise}
+%\end{verbatim}
+% \begin{macrocode}
+\let\cq@star\eq@NO
+% \end{macrocode}
+% We declare a new switch \cs{ifcqs}
+% \changes{v7.8}{2016/11/02}{Added code to copy questions of exercises to
+% the solution page}
+% \begin{macrocode}
+\newif\ifcqqs \cqqstrue
+\newif\ifcqIsActive \cqIsActivefalse
+\def\cqQS{\@ifstar{\cqQSV}{\cqQSA}}
+\def\cqQSA#1#2{\ifcqqs#1\else#2\fi}
+% \end{macrocode}
+% Also defined in the \pkg{web} package.
+% \begin{macrocode}
+\@ifpackageloaded{web}{\@ifundefined{IF@AorBswitch}{%
+ \PackageWarningNoLine{A version of the web package
+ dated\MessageBreak 2016/11/03 or later is required
+ for \string\cqQS}}}{}%
+\@ifundefined{webtempboxi}{\newbox\webtempboxi
+ \newbox\webtempboxii}{}
+\providecommand\SHOWTEMPBOXi{\unhbox\webtempboxi}
+\providecommand\TRUEACTIONi{\aftergroup\SETTEMPBOXii}
+\providecommand\TRUEACTIONia{\aftergroup\SHOWTEMPBOXi}
+\providecommand\FALSEACTIONii{\aftergroup\SETTEMPBOXi}
+\providecommand\FALSEACTIONiia{\aftergroup\SHOWTEMPBOXi}
+\providecommand\SETTEMPBOXi{\IF@AorBswitch\else
+ \afterassignment\TRUEACTIONia\fi
+ \setbox\webtempboxi=\hbox}
+\providecommand\SETTEMPBOXii{\IF@AorBswitch
+ \afterassignment\FALSEACTIONiia\fi
+ \setbox\webtempboxii=\hbox}
+\def\cqQSV{\let\IF@AorBswitch\ifcqqs
+ \IF@AorBswitch
+ \def\eq@next{\afterassignment\TRUEACTIONi\SETTEMPBOXi}\else
+ \def\eq@next{\afterassignment\FALSEACTIONii\SETTEMPBOXii}\fi
+ \eq@next}
+\def\eq@turnMessageOff{\let\save@message\message
+ \let\message\@gobble}
+\def\eq@turnMessageOn{\let\message\save@message}
+\def\eqCQDeclarations{\cqqsfalse\eq@turnMessageOff
+ \includecomment{sPage}\excludecomment{qPage}%
+ \eq@turnMessageOn}
+\def\eqTopOfSolnPage{\cqSAfalse
+ \eqCQDeclarations}
+\eq@turnMessageOff
+\includecomment{qPage}\excludecomment{sPage}
+\eq@turnMessageOn
+%</package|eqexam>
+%<*package>
+\def\writecqQSfalse{\writeToExSolns{\protect\eqTopOfSolnPage}}
+\AtBeginDocument{\writecqQSfalse}
+%</package>
+%<*package|eqexam>
+\newenvironment{cq@CQ}
+{%
+% \end{macrocode}
+% Begin verbatim write, the listing is saved to \cs{cq@CutName}, indexed by
+% \cs{cq@Cnt}.
+% \begin{macrocode}
+ \global\cqIsActivetrue
+ \global\advance\cq@Cnt1\relax
+ \immediate\openout\CommentStream=\cq@CutName
+ \let\verbatim@out\CommentStream
+ \verbatimwrite
+}{%
+ \endverbatimwrite
+ \immediate\closeout\CommentStream
+% \end{macrocode}
+% Close out the stream, define \cs{cq@INPUTCUT}, which is then input back in
+% after the end of the group.
+% \begin{macrocode}
+ \ifx\cq@star\eq@YES
+ \xdef\cq@INPUTCUT{\noexpand\cqqstrue
+ \noexpand\input{\cq@CutName}\noexpand
+ \def@QuesToSoln}\else
+ \xdef\cq@INPUTCUT{\noexpand\cqqstrue
+ \noexpand\input{\cq@CutName}\noexpand
+ \p@ssQuesToSoln}\fi
+ \aftergroup\cq@INPUTCUT
+}
+% \end{macrocode}
+% \end{environment}
+% \begin{environment}{cq*}
+% The \env{cq*} version of \env{cq}; within the \env{exercise} environment \env{cq*}
+% is \cs{let} to \env{cqs@CQ}. This version does not automatically paste the question
+% into the solution, instead, the command \cs{cqCopiedQues} is defined for that solution,
+% which expands to the question statement.
+% \begin{macrocode}
+\newenvironment{cqs@CQ}{\let\cq@star\eq@YES\cq@CQ}{\endcq@CQ}
+% \end{macrocode}
+% \end{environment}
+% The default formatting on the solution page is, when \env{cq} is used,
+%\begin{flushleft}
+%\textbf{Exercise 1.} \emph{Question}: This is the question
+%\medskip\par
+%\emph{Solution}: This is its solution
+%\end{flushleft}
+%The word `Question' may be localized using \cs{declCQQuesStr}\DescribeMacro{\declCQQuesStr}, the default is
+%seen below. The word `Solution' can be localized with \cs{declCQSolStr}\DescribeMacro{\declCQSolStr}, the default is seen below.
+% \begin{macrocode}
+\def\declCQQuesStr#1{\def\cqQStr{#1}}
+\declCQQuesStr{Question}
+\def\declCQSolStr#1{\def\cqSStr{#1}}
+\declCQSolStr{Solution}
+% \end{macrocode}
+% Aside from the words `Question' and `Solution', the way these two are formatting is determined
+% through \cs{declCQPre}\DescribeMacro{\declCQPre} and \cs{declCQPost}\DescribeMacro{\declCQPost}.
+% These declarations are seen below. The \cs{declCQPost} is more complicated in that it handles the
+% formatting after the copied question; in the default definition, we skip a \cs{medskip} and do a \cs{indent}.
+% Trailing the string \cs{cqSStr}, the internal command defined by \cs{declCQSolnStr}, is a space and
+% an \cs{ignorespaces}. Use \cs{writeToExSolns} to make local changes, for example,
+%\begin{verbatim}
+%...
+%\end{exercise}
+% Changed the string from Solution to Answer, do this prior to the
+% exercise.
+%\writeToExSolns{\protect\declCQSolStr{Answer}}
+%
+%\begin{exercise*}
+%...
+%\end{verbatim}
+%Best placed between exercises.
+% \begin{macrocode}
+\newcommand\declCQPre[1]{\def\cq@Pre{#1}}
+\declCQPre{\emph{\cqQStr}:\space}
+\newcommand\declCQPost[1]{\def\cq@Post{#1}}
+\declCQPost{\par\medskip\noindent\emph{\cqSStr}:\space\ignorespaces}
+% \end{macrocode}
+% The command \cs{cqFmtPasteQues}\DescribeMacro{\cqFmtPasteQues} inputs the copied question text,
+% along with \cs{cq@Pre} to the left and \cs{cq@Post} to the right. This command is normally
+% not redefined.
+% \begin{macrocode}
+\def\cqFmtPasteQues#1{\cq@Pre\input{#1}\cq@Post}
+% \end{macrocode}
+% The command \cs{p@ssQuesToSoln} does the work of formatting the question that is pasted
+% to the solution page. It is executed at the end of the \env{cq} environment.
+% \begin{macrocode}
+\def\p@ssQuesToSoln{\ifeq@hidesolution\else
+% \end{macrocode}
+% Inform the system that the definition of \cs{eqterminex} is changing. This to prevent
+% writing the same line multiple times.
+% \begin{macrocode}
+ \global\terminexchangedtrue % dps cq
+ \writeToExSolns{\protect
+ \decleqterminex{\protect\cqFmtPasteQues{\cq@CutName}}}\fi}
+\def\declCopyQues#1{\def\cqCopiedQues{#1}}
+\def\def@QuesToSoln{\restoreNormalSolns
+% \end{macrocode}
+% Here we restore \cs{eqterminex} to its default value, we set the stitch to false.
+% \begin{macrocode}
+ \global\terminexchangedfalse % dps cq
+ \ifeq@hidesolution\else\writeToExSolns{\protect
+ \declCopyQues{\protect\input{\cq@CutName}}}\fi}
+% \end{macrocode}
+% \cs{restoreNormalSolns}\DescribeMacro{\restoreNormalSolns} restores \cs{eqterminex} to its
+% default definition. It is place between exercises.
+% \begin{macrocode}
+\newcommand\restoreNormalSolns{%
+ \writeToExSolns{\protect\decleqterminex{\protect\eqterminexDEF}}}
+% \end{macrocode}
+% \begin{environment}{exercise}
+% With some of the preliminaries out of the way, we begin the exercise `environment'.
+% \begin{macrocode}
+\newcommand{\eq@CommonCmd}[1]{\def\eq@@CommonCmd{#1}#1}
+\let\eq@@CommonCmd\@empty
+\newcommand\gExCommonCmd[1]{\gdef\gEx@CommonCmd{\eq@CommonCmd{#1}}}
+\let\gEx@CommonCmd\@empty
+\let\endexerhook\@empty
+\newenvironment{exercise}
+{%
+ \let\cq\cq@CQ\let\endcq\endcq@CQ
+ \csarg\let{cq*}\cqs@CQ
+ \csarg\let{endcq*}\endcqs@CQ
+ \par\removelastskip\eq@priorexskip\noindent
+ \let\eqCommonCmd\eq@CommonCmd
+ \def\eq@argi{eqexno}%% use eqexno counter
+ \if\eq@exerstarEnv*\def\exerstar{*}\else\def\exerstar{x}\fi
+ \def\currhideopt{x}%
+ \@ifnextchar[{\exercise@}%
+ {\if\exerstar*\def\eq@next{\@exercise}\else
+ \def\eq@next{\exercise@@}\fi\eq@next}%
+}{\eq@postexerciseHook\endexerhook\par
+ \global\eq@exerciseheadingtrue\removelastskip\eq@exerskip}
+% \end{macrocode}
+% the exercise environment takes two sets of optional parameter,
+% the first one is a counter (or 0) and second one is either \texttt{h} or \texttt{H}.
+% \begin{macrocode}
+\def\exercise@[#1]{\edef\eq@arg{#1}%
+ \if\eq@arg h\def\currhideopt{h}%
+ \eq@hidesolutiontrue\eq@nolinktrue%
+ \ifeq@globalshowsolutions
+ \eq@hidesolutionfalse\eq@nolinkfalse\fi
+ \def\eq@next{\@exercise}% h, no *, no counter
+ \else
+ \if\eq@arg H%
+ \edef\currhideopt{\Hidesymbol}%
+ \eq@hidesolutiontrue\eq@nolinktrue%
+ \ifeq@globalshowsolutions
+ \eq@hidesolutionfalse\eq@nolinkfalse
+ \fi
+ \def\eq@next{\@exercise}% H, no *, no counter
+ \else
+ \def\currhideopt{x}%
+ \ifx\eq@arg\@empty\else\def\eq@argi{#1}\fi
+ \if\exerstar*\def\eq@next{\@exercise}\else
+ \def\eq@next{\exercise@@}\fi
+ \fi
+ \fi
+\eq@next}
+% \end{macrocode}
+% Specified counter, test for *
+% \begin{macrocode}
+\def\exercise@@{\@ifstar{\def\exerstar{*}\@exercise}{\exercise@@@}}
+% \end{macrocode}
+% We have recorded the presence of a star, is there
+% another optional argument, h
+% \begin{macrocode}
+\def\exercise@@@{\@ifnextchar[{\exercise@@@@}{\@exercise}}
+% \end{macrocode}
+% \begin{macrocode}
+\def\exercise@@@@[#1]{\edef\eq@arg{#1}%
+ \if\eq@arg h\def\currhideopt{h}%
+ \eq@hidesolutiontrue\eq@nolinktrue
+ \ifeq@globalshowsolutions
+ \eq@hidesolutionfalse\eq@nolinkfalse\fi
+ \def\eq@next{\@exercise}% h, no *, no counter
+ \else
+ \if\eq@arg H\edef\currhideopt{\Hidesymbol}%
+ \eq@hidesolutiontrue\eq@nolinktrue%
+ \def\eq@next{\@exercise}% h, no *, no counter
+ \else
+ \def\currhideopt{x}%
+ \PackageWarning{exerquiz}{The option #1 is not recognized}
+ \let\eq@next\relax
+ \fi
+ \fi
+\eq@next}
+% \end{macrocode}
+% \begin{macro}{\exerSolnHeader}
+% When a solution is written to the .sol file, there is a header line that contains formatting information.
+% This command can be redefined as desired. We also introduce to markers, \cs{eqEXt} and \cs{endeqEXt} which
+% can be used in any way your imaginations can conjure up. Basically, the mark the beginning and ending of the solution.
+% \begin{macrocode}
+\newif\ifeq@exerciseheading \eq@exerciseheadingtrue
+% \end{macrocode}
+% \changes{v6.7q}{2013/12/15}{Added this hook for use by \textsf{contsolns.dtx}}
+% \begin{macrocode}
+\let\prior@exerSolnHeaderHook\@empty
+\newcommand\exerSolnHeader[3]{%
+ \prior@exerSolnHeaderHook
+ \ifeqforpaper\else\webnewpage\fi\markright{#1}%\par\noindent%
+%</package|eqexam>
+%<*package>
+ \noindent\hypertarget{#2}{#3}\relax
+%</package>
+%<*eqexam>
+ #3%
+%</eqexam>
+%<*package|eqexam>
+ \solnhspace
+}
+% \end{macrocode}
+% (2015/05/18) Made this definition conditional on whether \textsf{eqexam}
+% is loaded. The command is meant for \textsf{eqexam}. The \textsf{exerquiz}
+% package should be loaded after \textsf{eqexam} if the two are to be used
+% together, preferably by the \texttt{links} or \texttt{online} options of \textsf{eqexam}.
+% \begin{macrocode}
+%\newif\iffirstitem
+\let\solnItemMngt\relax
+%\def\eqeSolnItemMngt{\iffirstitem\global\firstitemfalse
+% \let\eqe@next\@empty\else\let\eqe@next\item\fi\eqe@next\relax}
+%\@ifpackageloaded{eqexam}{\let\solnItemMngt\eqeSolnItemMngt}
+% {\let\solnItemMngt\relax}
+% \end{macrocode}
+% \end{macro}
+% \DescribeMacro{\eqEXt}These two mark the beginning and end of solution to an exercise. \cs{eqEXt} is
+% set up to have two required arguments, usually both empty. The arguments are
+% used for filtering. The first might be a number, so we can filter out even numbered
+% exercises from odd ones. The second one is a keyword, we can filter by keyword.
+%\changes{v6.7}{2013/04/07}{Changing \cs{eqEXt} so that it has two
+%required arguments}
+% \begin{macrocode}
+%\let\eqEXt\@gobble
+\let\eqEXt\@gobbletwo
+\let\endeqEXt\relax
+% \end{macrocode}
+% \DescribeMacro{\eqExtArg}\cs{eqExtArg} and \DescribeMacro{\eqFilterArg}\cs{eqFilterArg}
+% are the arguments for \cs{eqEXt}. They are redefined at the creation of the
+% exercise.
+% \begin{macrocode}
+\let\eqExtArg\@empty
+\let\eqFilterArg\@empty
+% \end{macrocode}
+% The format of the solutions to exercises as they appear in the SOL file is,
+%\begin{verbatim}
+%\eqEXt{\eqExtArg}{\eqFilterArg}\exerSolnHeader
+% {\exsecrunhead}{ex.1}{\textbf{Exercise\ 1.}}\relax
+% ...
+% <solution content>
+% ...
+%\ReturnTo{qex.1}{\hbox {$\square $}}\endeqEXt\par\medskip
+%\end{verbatim}
+% \changes{v6.7a}{2013/05/03}{Change name of \cs{eq@writeexheader} to \cs{eqExerSolnHeader}}
+% \begin{macrocode}
+\let\eqExerSolnHeader\@empty
+%\let\eq@writeexheader\@empty
+% \end{macrocode}
+% The \cs{solutionparshape} is a command that supports the \cs{leadinitem} command
+% of \texttt{eqexam}. Its normal value is \cs{@empty}.
+% \begin{macrocode}
+\let\solutionparshape\@empty
+% \end{macrocode}
+%\changes{v7.2}{2015/03/22}{added \cs{setPrbSolnAftrIndent}}
+% \DescribeMacro{\setPrbSolnAftrIndent}\cmd{\setPrbSolnAftrIndent} sets the amount of indent
+% for the statement of problem and the solution-after solution. The command saves its argument
+% in \cs{eq@pslnaindnt} (default \texttt{0pt}) and sets the hook
+% \cs{eq@setPrbSolnAftrIndnt}. This latter macro appears in \cs{@exercise} below. Its
+% initial value is \cs{relax}; otherwise, it sets \cs{parindent=\#1}.
+% \begin{macrocode}
+\def\eq@pslnaindnt{0pt}
+\let\eq@setPrbSolnAftrIndnt\relax
+\newcommand{\setPrbSolnAftrIndent}[1]{\ifdim#1=0pt
+ \def\eq@pslnaindnt{0pt}\let\eq@setPrbSolnAftrIndnt\relax\else
+ \edef\eq@pslnaindnt{#1}\edef\eq@setPrbSolnAftrIndnt{%
+ \expandafter\noexpand\expandafter\parindent#1\noexpand\relax}\fi
+}
+% \end{macrocode}
+%\changes{v7.2}{2015/03/22}{added \cs{restorejustify}}
+%The command \DescribeMacro\restorejustify\cmd{\restorejustify} is designed
+%for use in the \texttt{solution} environment of an \cs{item} within the
+%\texttt{parts} environment in \texttt{tabular} mode. By default,
+%\texttt{parts[2]}, for example, sets up a tabular, each entry is in a
+%paragraph (\texttt{p\{\}}) but \cs{raggedright} is used. We change this for
+%the solution using \cmd{\restorejustify}. Use \DescribeMacro\restoreJustifyOn\cmd{\restoreJustifyOn}
+% to turn on this feature and \DescribeMacro\restoreJustifyOff\cmd{\restoreJustifyOff}
+% to turn it off (default).
+% \begin{macrocode}
+\newif\if@restorejustify \@restorejustifyfalse
+\newcommand\restoreJustifyOn{\@restorejustifytrue}
+\newcommand\restoreJustifyOff{\@restorejustifyfalse}
+\def\restorejustify{\if@restorejustify
+ \@rightskip\z@skip \rightskip\@rightskip
+ \leftskip\z@skip \let\\\@normalcr\fi}
+% \end{macrocode}
+% The \DescribeMacro\@exercise definition of the \texttt{exercise} environment continues here.
+% \begin{macrocode}
+\def\@exercise{%
+ \global\let\solutionparshape\@empty
+ \let\verbatim@out=\ex@solns
+ \if\eq@argi0\else\refstepcounter{\eq@argi}\fi\stepcounter{@exno}%
+ \if\exerstar*% if exercise with parts
+ \eq@nolinktrue
+ \else
+ \if\currhideopt H%
+ \else
+ \ifeq@solutionsafter
+ \eq@nolinktrue % no link to solution
+ \else
+ \eq@ckglobalhide %
+ \ifeq@hidesolution\else
+% \end{macrocode}
+% Here's where we write the header to the .sol file.
+% \begin{macrocode}
+ \global\let\eqExerSolnHeader\eq@@writeexheader
+ \fi
+ \fi
+ \fi
+ \fi
+ \ifvmode\ifdim\lastskip>\z@
+ \vskip-\lastskip
+ \fi\fi
+ \if\exerstar*%
+ \let\solution\solnexer@woparts
+ \let\endsolution\endsolnexer@woparts
+ \let\parts\exercise@parts
+ \let\endparts\endexercise@parts
+ \else
+ \let\solution\solnexer@woparts
+ \let\endsolution\endsolnexer@woparts
+ \let\parts\relax
+ \let\endparts\relax
+ \if\Hidesymbol h\eq@nolinkfalse\ifeq@solutionsafter
+ \eq@nolinktrue\fi\fi
+ \fi
+% \end{macrocode}
+% Here is where `Exercise' is typeset; the commands \cs{marginparpriorhook} and \cs{marginpartafterhook}
+% can be used to insert content in before and after the `Exercise'.
+% \begin{macrocode}
+ \eq@initializeContAnnot
+ \ifeq@exerciseheading
+ \prior@questionsHook\marginparpriorhook\noindent\eqexheader@wrapper
+ \afterlabelhskip\marginparafterhook\gEx@CommonCmd
+ \eq@setPrbSolnAftrIndnt\ignorespaces\fi
+}
+% \end{macrocode}
+% \end{environment}
+% \changes{v6.4z}{2012/11/28}{Extracted code to make it available elsewhere.}
+% (2012/11/28) Extracted the code below from the macro above so it can be used
+% elsewhere as well.
+%\par\medskip\noindent
+% The \cs{eqterminex} command is one that appears on the solution page, just after the exercise number.
+% We redefine it to do our will. The convenience macro \cs{decleqterminex}\DescribeMacro{\decleqterminex} is used for that purpose.
+% We use \cs{ifterminexchanged} to track whether the default definition is changed.
+% \begin{macrocode}
+\newif\ifterminexchanged \terminexchangedfalse % dps cq
+\newcommand\decleqterminex[1]{\def\eqterminex{#1}}
+% \end{macrocode}
+% The default definition of \cs{eqterminex} is saved under \cs{eqterminexDEF}.
+% \begin{macrocode}
+\def\eqterminexDEF{\relax\ignorespaces}
+\decleqterminex{\eqterminexDEF}
+% \end{macrocode}
+%\changes{v6.7}{2013/04/07}{Inserted another argument into \cs{eqEXt}}
+% Added another argument into \cs{eqEXt}, used for filtering.
+% \begin{macrocode}
+\def\eqExerSolnHeaderSngl{%
+ \protect\eqEXt{\eqExtArg}{\eqFilterArg}\protect
+ \solnItemMngt\protect\exerSolnHeader{\exsecrunhead}{ex.\the@exno}%
+ {\exsllabelformat}\exer@solnheadhook
+ \exersolnheadhook\protect\eqterminex
+}
+\def\eq@@writeexheader{\set@display@protect
+ \immediate\write\verbatim@out{\eqExerSolnHeaderSngl}%
+ \set@typeset@protect
+}
+% \end{macrocode}
+%\changes{v6.7}{2013/04/07}{Inserted another argument into \cs{eqEXt}}
+% Added another argument into \cs{eqEXt}, used for filtering.
+% \begin{macrocode}
+\def\eqExerSolnHeaderList{%
+ \protect\eqEXt{\eqExtArg}{\eqFilterArg}\protect
+ \solnItemMngt\protect\exerSolnHeader{\exsecrunhead}%
+ {ex.\the@exno\thepartno}{\exsllabelformatwp}%
+ \exer@solnheadhook\exersolnheadhook\protect\eqterminex
+}
+\def\eq@@writeexheaderlist{\set@display@protect
+ \immediate\write\verbatim@out{\eqExerSolnHeaderList}%
+ \set@typeset@protect
+}
+% \end{macrocode}
+% \subsection{Define \texttt{solution} Environment for \texttt{exercise}}
+% \begin{macro}{solution}
+% This is the \texttt{solution} environment for
+% \texttt{exercise}; either start \cmd{\verbatim} or,
+% \cmd{\eq@solutionsaftertrue} write the label \cmd{\exsolafter}.
+%
+% The solution macro for the \texttt{exercise} environment now takes an optional
+% argument. This argument must be a vertical skip ( i.e., \texttt{[1in]} ). When the solution
+% does not correspond to a tabular multi-part question, a vertical skip
+% |\vspace{#1}| is introduced when the \texttt{nosolutions} is in effect and when
+% \texttt{solutionsafter} is not. This feature may be useful for constructing
+% tests in this space is left for the student to write in the answer; yet, later
+% when \texttt{solutionsafter} is true, the solutions appear instead of the vertical
+% white space.
+% \begin{macrocode}
+\long\def\setsolnspace#1{\def\newsolnspace{#1}%
+ \let\solnspace\newsolnspace}
+% \end{macrocode}
+% \begin{macro}{\ckSolnOpt}
+% \begin{macro}{\noSolnOpt}
+% \cs{noSolnOpt} turns off the check for the option argument
+% of the \texttt{solution} environment for the \texttt{exercise}
+% environment. Designed for use with \textsf{eqexam}.
+% \changes{v6.4v}{2012/07/27}{Added \cs{ckSolnOpt} and \cs{noSolnOpt}
+% to switch on and off checking for the optional vertical space in the
+% \texttt{solution} environment.}
+% \begin{macrocode}
+\newif\ifeq@ckSolnVspace \eq@ckSolnVspacetrue
+\def\ckSolnOpt{\global\eq@ckSolnVspacetrue}
+\def\noSolnOpt{\global\eq@ckSolnVspacefalse}
+\let\solnhspace\space
+\let\solnspace\space
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% This macro is the beginning of the \texttt{solution} environment for
+% exercises.
+% \begin{macrocode}
+\def\solnexer@woparts{\def\bLeaveVspace{x}% = no vertical space added
+ \ifeq@ckSolnVspace
+ \def\eq@next{\@ifnextchar[{\solnexer@@woparts}%
+ {\solnexer@@woparts[\null]}}\else
+ \def\eq@next{\solnexer@@woparts[\null]}\fi
+% \end{macrocode}
+% The code below, now removed, used to deny the use of the optional parameter
+% in the parts-tabular environment. (2013/03/26)
+%\begin{verbatim}
+% \ifx\endparts\endexercise@parts@tabular
+% \def\eq@next{\solnexer@@@woparts}\fi
+%\end{verbatim}
+% \begin{macrocode}
+ \eq@next
+}
+\let\eqPriorVspace\@gobble
+\newif\if@eqlinedfiller \@eqlinedfillerfalse
+\newcommand{\vspaceFiller}[1]{\vfill}
+\newcommand{\vspaceFillerDefault}[1]{\vfill}
+\def\eqWriteLine{\hfill}
+\def\eq@linesXPgs{%
+ \begingroup\offinterlineskip\parskip0pt
+ \@tempcnta=0
+ \@whilenum\@tempcnta<\soln@keys@nLines\relax\do
+ {\vskip0pt\penalty-50\vglue\wlVspace\eqWriteLine
+ \advance\@tempcnta1\relax}\par\endgroup
+}
+\newcommand{\vspaceFmt}[1]{%
+ \ifx\solutionparshape\@empty\else
+% \end{macrocode}
+% This must be part of the solution for a \cs{leadinitem} question.
+% We need to make an adjustment to the \cs{linewidth}.
+% \begin{macrocode}
+ \advance\linewidth-\leadinIndentPrtSep\fi
+ \ifdim\sameVspace>0pt
+ \let\bLeaveVspace\@empty
+ \def\leavevspace{%
+ \ifx\eq@insertverticalspace\eq@YES\par
+ \eqPriorVspace{#1}{\nobreak\noindent
+% \end{macrocode}
+% If \texttt{nLines} is non-empty, we'll use some spacial code
+% to generate the lines so it breaks across pages.
+% \begin{macrocode}
+ \ifx\soln@keys@nLines\@empty
+ \if@eqlinedfiller
+ \def\eq@lines@next{\vspaceFiller{#1}}\else
+ \def\eq@lines@next{\parbox[b][#1][t]{\linewidth}
+ {\vspaceFiller{#1}}}\fi
+ \else
+ \def\eq@lines@next{\eq@linesXPgs}%
+ \fi\eq@lines@next
+ }%
+ \fi
+ }%
+ \fi
+}
+% \end{macrocode}
+% \changes{v6.8g}{2014/04/08}{Added key-val here for \textsf{eqexam}.}
+% New option for the \texttt{solution} environment, \IndexKey{nLines}\texttt{nLines}.
+% \begin{macrocode}
+\define@key{soln@keys}{nLines}[]{\def\soln@keys@nLines{#1}}
+\let\soln@keys@nLines\@empty
+% \end{macrocode}
+% \cs{eqKV@errx} is a hack into the \textsf{keyval} package. The change, made
+% below in \cs{solnexer@@woparts} is temporary. We use it to get the dimen
+% of the \texttt{solution} env. Necessary since we have an \texttt{nLines} key defined
+% for \textsf{eqexam}.
+% \begin{macrocode}
+% keyval package \@tempa contains undefined key
+\def\eqKV@errx#1{\xdef\XKV@rm{\@tempa}}
+% \end{macrocode}
+% \begin{macrocode}
+\def\eqSolnForEqexam#1{%
+ \let\soln@keys@nLines\@empty
+ \setkeys*{soln@keys}{#1}%
+ \ifx\soln@keys@nLines\@empty
+ \ifx\minVspacet@bs\@empty\xdef\sameVspace{\XKV@rm}\else
+ \xdef\sameVspace{\minVspacet@bs}\fi
+ \else
+ \@tempdima\wlVspace
+ \@tempdima=\soln@keys@nLines\@tempdima
+ \xdef\sameVspace{\the\@tempdima}%
+ \ifx\XKV@rm\@empty\else
+ \if@equsedim\let\soln@keys@nLines\@empty
+ \xdef\sameVspace{\XKV@rm}\fi
+ \fi
+ \fi
+ \ifx\sameVspace\@empty\gdef\sameVspace{0pt}\fi
+}
+% \end{macrocode}
+% Now the beginning of the \textsf{solution} environment for \texttt{exercise} env.
+% \begin{macrocode}
+\def\solnexer@@woparts[#1]{%
+ \ifcqIsActive\else\ifterminexchanged
+% \end{macrocode}
+% If this problem does not use \env{cq} or \env{cq*}, we reset the solution page,
+% to the default definition of \cs{eqterminex}.
+% \begin{macrocode}
+ \restoreNormalSolns\fi\fi % dps cq
+ \global\cqIsActivefalse
+% \end{macrocode}
+% \changes{v6.3z}{2011/04/28}{Added definition of \cs{sameVspace} for the cases
+% where there is no vertical space specified.}
+% Is the argument \cs{null}? If yes, same as \texttt{0pt}.
+% \begin{macrocode}
+ \def\eq@argi{#1}\def\eq@null{\null}%
+ \ifx\eq@argi\@empty\gdef\sameVspace{0pt}\else
+ \ifx\eq@argi\eq@null\gdef\sameVspace{0pt}\else
+% \end{macrocode}
+% \changes{v6.8g}{2014/04/08}{Added key-val here for \textsf{eqexam}.}
+% Now, if the optional argument is non-null, we must discern the argument:
+% is it a vertical space or a key-value?
+% \begin{macrocode}
+ \@ifundefined{PointsOnLeft}{%
+ \let\eqKV@errx@SAVE\KV@errx
+ \let\KV@errx\eqKV@errx\let\XKV@rm\@empty
+ \edef\temp@exp{\noexpand\setkeys*{soln@keys}{#1}}\temp@exp
+ \let\KV@errx\eqKV@errx@SAVE
+ \ifx\soln@keys@nLines\@empty\else
+ \PackageInfo{exerquiz}{%
+ nLines key detected in solution environment,\MessageBreak
+ is not not recognized without eqexam,\MessageBreak
+ will remove it}%
+ \let\soln@keys@nLines\@empty\fi
+ \xdef\sameVspace{\XKV@rm}%
+ }{\eqSolnForEqexam{#1}}%
+% \end{macrocode}
+% (03/04/11) Try to insert a new option: if there are \cs{ifvspacewithsolns} option
+% then \textsf{eqexam} should leave space for writing an answer, and put solutions at the end
+% of the document.
+% \begin{macrocode}
+ \ifx\sameVspace\@empty\gdef\sameVspace{0pt}\fi
+ \ifvspacewithsolns\vspaceFmt{\sameVspace}\fi
+ \ifeq@nosolutions\ifeq@solutionsafter\else
+ \vspaceFmt{\sameVspace}\fi\fi
+ \fi\fi
+ \solnexer@@@woparts
+}
+% \end{macrocode}
+% \changes{v7.7q}{2016/07/22}{Added \string\cs{solnsafterSkip}}
+% \begin{macrocode}
+\def\solnsafterSkip#1{\setlength{\@tempdima}{#1}%
+ \def\solnsafterSkipAmt{\the\@tempdima}%
+ \def\solutionsafterSkip{\vskip#1\relax}}
+\solnsafterSkip{\smallskipamount}
+% \end{macrocode}
+% The next two definitions are used for debugging the
+% \cs{ifkeepdeclaredvspacing} feature (\textsf{eqexam} only).
+% \begin{macrocode}
+\def\eqe@debugVertSkip#1{}
+\def\eqe@showEndHere#1{#1}
+% \end{macrocode}
+% Used to set the starting point of the solution
+% \begin{macrocode}
+\def\eqe@setStartSolns{%
+ \xdef\eq@startSoln{\the\pagetotal}%
+ \eqe@debugVertSkip{\marginpar{\smash{b[\sameVspace]}}}%
+}
+% \end{macrocode}
+%\changes{v6.4b}{2011/06/30}{%
+% Save the definitions of \cs{comment} and \cs{endcomment}. For some reason,
+% yet to be determined, there are problems when using the \texttt{fortextbook}
+% option when hiding solutions.
+%}
+% \begin{macrocode}
+\let\eqSavedComment\comment
+\let\eqSavedEndCommet\endcomment
+% \end{macrocode}
+%\changes{v7.4}{2015/03/23}{added \cs{setTabulrSolnEnv}}
+% \begin{macrocode}
+\def\setTabulrSolnEnv{%
+ \@ifundefined{@listii@SAVE}{\global\let\@listii@SAVE\@listii}{}%
+ \expandafter\def\expandafter\@listii\expandafter{\@listii@SAVE
+ \leftmargin\leftmarginii \labelwidth\leftmarginii
+ \advance\labelwidth-\labelsep}%
+ \def\everyparShape{\everypar{\parshape \@ne 0pt \linewidth}}%
+% \end{macrocode}
+% \cmd{\reset@doendpe} resets the definition of the core command
+% \cmd{\@doendpe} so behavior is correct whether list environment
+% starts in vertical mode or not.
+% \begin{macrocode}
+ \reset@doendpe{\parshape \@ne 0pt \linewidth}%
+% \expandafter\def\expandafter\@par\expandafter{\@par\everyparShape}%
+ \parshape \@ne 0pt \linewidth
+ \everyparShape
+}
+\newif\ifthereissolution
+\let\priorexsolafterList\@empty
+\let\priorexsolafterTab\@empty
+\let\priorexsolafterSngl\@empty
+\def\eq@Hid{H}\def\eq@hid{h}
+\def\solnexer@@@woparts{%
+ \global\thereissolutiontrue
+ \def\exerwparts@cols{0}%
+ \let\verbatim@out\ex@solns
+ \if\currhideopt\eq@Hid
+% \end{macrocode}
+% (2017/02/09) Hide \cs{minVspacet@bs} for `H' option
+% \changes{v7.8e}{2017/02/09}{Hide \string\cs{minVspacet@bs} for `H' option}
+% \begin{macrocode}
+ \let\minVspacet@bs\@empty
+ \let\procsoln\eqSavedComment
+ \let\endprocsoln\eqSavedEndCommet
+ \def\eq@next{\procsoln}%
+ \else
+ \eq@ckglobalhide
+ \ifeq@hidesolution
+ \let\procsoln\eqSavedComment
+ \let\endprocsoln\eqSavedEndCommet
+ \else
+ \ifx\bLeaveVspace\@empty\leavevspace\fi
+ \ifeq@solutionsafter\else
+ \ifx\eq@@CommonCmd\@empty\else
+ \set@display@protect
+ \immediate\write\verbatim@out{\eq@@CommonCmd}%
+ \set@typeset@protect
+ \fi
+ \fi
+ \let\procsoln\verbatimwrite
+ \let\endprocsoln\endverbatimwrite
+ \fi
+ \def\eq@next{%
+ \ifeq@solutionsafter%\par
+ \removelastskip\removelastparskip
+ \cqSAtrue\eqCQDeclarations
+ \declCopyQues{\input{\cq@CutName}}%
+ \ifx\exsolafter\@empty
+% \end{macrocode}
+% If we have solutions after and there is no label and no vertical
+% skip specified, we do nothing other than to execute \cs{eqe@setStartSolns},
+% which marks the beginning of the ``solution.''
+% \begin{macrocode}
+ \ifdim\sameVspace=0pt\eqe@setStartSolns
+ \else
+% \end{macrocode}
+% If there is vertical space specified, we do a standard skip, and mark the beginning
+% of the solution with \cs{eqe@setStartSolns}.
+% \begin{macrocode}
+ \solutionsafterSkip
+ \eqe@setStartSolns
+ \fi
+ \else\par\kern0pt
+ \solutionsafterSkip
+ \noindent\strut\eqe@setStartSolns
+ \fi
+ \parskip\eqeques@parsep
+ \ifx\endparts\endexercise@parts@tabular
+ \eq@setPrbSolnAftrIndnt
+ \restorejustify
+% \expandafter\setTabulrSolnEnv
+ \fi
+% \end{macrocode}
+% (2017/02/09) Added prior \cs{exsolafter} hooks.
+% \changes{v7.8e}{2017/02/09}{Added prior \string\cs{exsolafter} hooks}
+% \begin{macrocode}
+ \ifx\endparts\endexercise@parts@tabular\expandafter
+ \priorexsolafterTab\else
+ \ifx\endparts\endexercise@parts@list\expandafter
+ \priorexsolafterList\else\expandafter
+ \priorexsolafterSngl\fi\fi
+% \end{macrocode}
+% The solution after label, followed by a space.
+% \begin{macrocode}
+ \exsolafter\space\ignorespaces
+% \end{macrocode}
+% We set the shape of the solutionafter.
+% This is empty if \cs{leadinitem} is not used.
+% \begin{macrocode}
+ \solutionparshape
+ \else
+% \end{macrocode}
+% Write the solution header 11/03/05
+% \begin{macrocode}
+ \eqExerSolnHeader
+ \global\let\eqExerSolnHeader\@empty
+ \global\therearesolutionstrue\expandafter\procsoln
+ \fi
+ }%
+ \fi
+\eq@next}
+% \end{macrocode}
+% \end{macro}
+% \begin{macrocode}
+\let\endsolnexerhook\@empty
+\let\pkg@endsolnexerhook\@empty
+\let\endsolnexerhookaux\@empty
+% \end{macrocode}
+% This macro attempts to insert the return link at the end of the
+% last paragraph of the solutions, this makes the return label
+% look nice, and saves a little space.
+% \begin{macrocode}
+\def\eq@fititin#1{\noindent\unskip\nobreak\hfill\penalty100
+ \hskip1em\hbox{}\nobreak\hfill#1}%
+\let\eqfititin\eq@fititin
+%</package|eqexam>
+%<*package>
+\def\ReturnTo#1#2{\eq@fititin{\hyperlink{#1}{#2}}}
+\def\xReturnTo#1#2{\eq@fititin{\href{#1}{#2}}}
+%</package>
+% \end{macrocode}
+% \begin{macro}{\eqExerSolnTrailer}
+% The material that follows the solution in the .sol file.
+% \begin{macrocode}
+%<*package|eqexam>
+\newcommand\eqExerSolnTrailer{%
+%</package|eqexam>
+%<*package>
+ \if\exerSolns@ExtFile\eq@YES\protect\xReturnTo
+ {\exerSolns@ReturnPath\jobname\#qex.\the@exno}%
+ \else\protect\ReturnTo{qex.\the@exno}\fi
+ {\protect\mbox{\if\exerstar*\exrtnlabelformatwp\else
+ \exrtnlabelformat\fi}}%
+ \protect\endeqEXt\ifeqforpaper\protect\par{\belowexsolnskip}\fi^^J%
+%</package>
+%<*eqexam>
+ \protect\ReturnTo{page.\the\c@page}%
+ {\protect\mbox{\if\exerstar*\exrtnlabelformatwp\else
+ \exrtnlabelformat\fi}}%
+ \protect\endeqEXt\ifeqforpaper\protect\par{\belowexsolnskip}\fi^^J%
+%</eqexam>
+%<*package|eqexam>
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\endsolnexer@woparts}
+% Unless \cmd{\eq@solutionsaftertrue}, then \cmd{\endverbitim},
+% and write return labels.
+% \begin{macrocode}
+\def\endsolnexer@woparts{%
+ \if\currhideopt H%
+ \ifkeepdeclaredvspacing\vskip\sameVspace\fi
+ \csname endprocsoln\endcsname
+ \else
+% \end{macrocode}
+% If solutions after, we start a new paragraph, then add some kerning glue,
+% this gives a better gauge for calculating the \cs{pagetotal}.
+% \begin{macrocode}
+ \ifeq@solutionsafter
+ \if\exerstar*%
+ \eq@fititin{\mbox{\exrtnlabelformatwp}}\else
+ \eq@fititin{\mbox{\exrtnlabelformat}}\fi
+ \ifx\istabularexer\eq@YES\kern0pt\else\par\fi
+% \ifnum\exerwparts@cols>0\relax\kern0pt\else\par\fi
+% \end{macrocode}
+% \changes{v6.3z}{2011/04/28}{if \cs{ifkeepdeclaredvspacing} is true, we attempt
+% to preserve the vertical space declared by the \textsf{solution} environment when
+% \cs{ifeq@solutionsafter} is true.}
+% \begin{macrocode}
+\ifx\minVspacet@bs\@empty
+ \ifkeepdeclaredvspacing
+% \end{macrocode}
+% We get the current \cs{pagetotal}, and subtract off the page total as recorded
+% by \cs{eq@startSoln}.
+% \begin{macrocode}
+ \@tempdima\pagetotal
+ \advance\@tempdima-\eq@startSoln
+% \end{macrocode}
+% \changes{v6.4w}{2012/26/27}{Added \cs{relax} following the assignment.}
+% {\TeX} was looking ahead looking for the rest of the dimension, this caused
+% problems because later code was expanded when it should not have been. Inserted
+% \cs{relax}, \verb~\@tempdimb\sameVspace\relax~.
+% \begin{macrocode}
+ \@tempdimb\sameVspace\relax
+% \end{macrocode}
+% if \cs{soln@keys@nLines} is nonempty, we put \cs{sameVspace} to \texttt{1sp},
+% unless the author asks for \texttt{1sp}, this is how it is set.
+% \begin{macrocode}
+ \ifdim\@tempdimb>1sp\relax
+% \end{macrocode}
+% If there is a positive value for \cs{sameVspace}, we calculate
+% the difference between\cs{@tempdimab} and \cs{@tempdima}, that is, we calculate
+%\begin{verbatim}
+% \sameVspace-(\pagetotal-\eq@startSoln)
+%\end{verbatim}
+% \begin{macrocode}
+ \advance\@tempdimb-\@tempdima
+% \end{macrocode}
+% If this difference is positive, we will skip this amount.
+% \begin{macrocode}
+ \ifdim\@tempdimb>0pt\vglue\@tempdimb\kern0pt
+ \let\eqe@showEndHere\@gobble
+ \edef\tmp@exp{\noexpand\marginpar{%
+ \noexpand\smash{e: adj \the\@tempdimb}}}%
+ \eqe@debugVertSkip{\tmp@exp}%
+ \fi
+ \fi
+ \fi
+ \eqe@showEndHere{\eqe@debugVertSkip{\marginpar{\smash{e}}}}%
+\fi
+ \else
+ \endprocsoln
+ \eq@ckglobalhide
+ \ifeq@hidesolution\else
+ \endsolnexerhookaux
+% \end{macrocode}
+% Here's were we write the trailer for the solution
+% \begin{macrocode}
+ \set@display@protect
+ \immediate\write\verbatim@out{\eqExerSolnTrailer}%
+ \set@typeset@protect
+ \fi
+ \fi
+ \fi
+\pkg@endsolnexerhook\endsolnexerhook}
+% \end{macrocode}
+% \end{macro}
+% \subsection{The \texttt{exercise*} Environment: Exercises with Parts}
+% Exercises with parts are enclosed within a \texttt{parts} environment. There are two types
+% of parts listing: list-type and tabular-type.
+% \begin{environment}{exercise*}
+% For the exercise* environment, we set a flag to indicate that the \cs{exerstar}
+% has been set in the star environment, the begin the \cs{exercise} and finished with
+% \cs{endexercise}.
+%\changes{v6.07}{2007/05/05}
+%{
+% Created the \texttt{exercise*} environment, this is equivalent to the \texttt{*} option of the
+% \texttt{exercise} environment. You can use either version, but now, \texttt{exercise*} is preferred.
+%}
+% \begin{macrocode}
+\let\eq@exerstarEnv\relax
+\newenvironment{exercise*}{\def\eq@exerstarEnv{*}\exercise}
+{\endexercise}
+% \end{macrocode}
+% \end{environment}
+% \begin{environment}{parts}
+% Initially, we see if there is an optional argument, if yes, the
+% tabular environment is used, the argument is the number of columns
+% requested. Otherwise, we use a list environment.
+% \begin{macrocode}
+\def\exerwparts@cols{0}
+\let\topofpartshook\relax
+\let\@listiiredefined\eq@NO
+\let\itsExerParts\eq@NO
+% \end{macrocode}
+% (2015/05/30) Added a feature for lead in for tabular mode for parts environment.
+% \DescribeMacro{\tableadin}\cmd{\tableadin} is placed prior to
+% \verb!\begin{parts}[2}!, no preamble leading into the question is assumed.
+% Using the switch \cs{if@tableadinitem} we remove any \cs{par}s and \cs{vskip}s.
+% \begin{macrocode}
+\newif\if@tableadinitem\@tableadinitemfalse
+\newcommand{\tableadin@external}{\PackageError{exerquiz/eqexam}
+ {The \string\tableadin\space command is designed\MessageBreak
+ for the problem* environment of eqexam}{Use \string\tableadin\space
+ in the problem* environment of eqexam.}%
+}
+\let\tableadin\tableadin@external
+\newcommand{\eq@tableadinparts}{\item\relax
+ \PackageError{exerquiz/eqexam}{The \string\tableadin\space
+ command is not allowed in the\MessageBreak
+ parts environment}{Use \string\tableadin\space
+ in the problem* environment of eqexam.}%
+}
+% \end{macrocode}
+% (2016/12/16) Define a flag \cs{istabularexer} that signals to the solution environment it is in a tab environment
+% \changes{v7.8b}{2016/12/16}{Added \string\cs{istabularexer}}
+% \begin{macrocode}
+\let\istabularexer\eq@NO % dps 2016/12/16
+\def\exercise@parts{\let\rlspar\relax
+ \ifx\solutionparshape\@empty
+ \let\isitleadin\eq@NO
+% \end{macrocode}
+% If \cs{tableadin}, we remove the \cs{removelastskip} and \cs{par} that follows.
+% \begin{macrocode}
+ \if@tableadinitem\let\rlspar\@gobbletwo\fi
+ \else\let\isitleadin\eq@YES\fi
+ \rlspar\removelastskip\par
+ \if\isitleadin\eq@YES
+% \end{macrocode}
+% \changes{v7.6}{2015/05/24}{Some vspace adjustment at the beginning of
+% a leadinitem.} If there is a lead-in, we set \cs{topsep} to \texttt{0pt}
+% and skip \cs{itemsep}.
+% \begin{macrocode}
+ \def\eqparts@topsep{0pt}% dps88
+ \vskip\eqparts@itemsep\relax\fi % dps88
+ \topofpartshook
+ \let\itsExerParts\eq@YES % dps17
+ \global\let\@listiiredefined\eq@NO
+ \def\exerwparts@cols{0}\@ifnextchar[%
+ {%
+% \end{macrocode}
+% When there is a \cs{tableadin}, we remove \cs{removelastparskip} because it does not occur above.
+% \begin{macrocode}
+ \if@tableadinitem\else\removelastparskip\fi % dps11
+% \keepdeclaredvspacingfalse
+ \let\endparts\endexercise@parts@tabular\exercise@parts@tabular@}%
+ {\let\endparts\endexercise@parts@list\exercise@parts@list}}
+% \end{macrocode}
+% \subsubsection{List-type Parts Question}
+% This is a redesigned \texttt{list} environment. Meant to be used with the
+% \texttt{exercise} environment with the *-option.
+% \begin{macrocode}
+\def\eq@extralabelsep{0pt}
+% \end{macrocode}
+% \begin{macro}{\setPartsWidth}
+% Convenience macro to set \cs{part@indent}.
+%\changes{v6.4h}{2011/07/28}{%
+% Added \cs{setPartsWidth} to set \cs{part@indent}. Also
+% defined \cs{eqe@prtsepPrb}.
+%}
+% \begin{macrocode}
+\newcommand{\setPartsWidth}[1]{\def\parts@indent{\normalfont#1}%
+ \bgroup\settowidth{\eq@tmpdima}{\parts@indent}%
+ \xdef\widthOfParts{\the\eq@tmpdima}\egroup}
+\setPartsWidth{(d)}
+% \end{macrocode}
+% \end{macro}
+% \DescribeMacro{\eqe@prtsepPrb} is used to set \cs{labelsep}.
+% I've also added the two hooks \DescribeMacro{\prior@parts@hook}\cs{prior@parts@hook} and
+% \DescribeMacro{\post@parts@hook}\cs{post@parts@hook} as well; these are used
+% by \textsf{eqexam} for hanging the solutions with parts correctly.
+% \begin{macrocode}
+\def\eqe@prtsepPrb{\ }
+\providecommand{\prbPrtsep}[1]{\def\eqe@prtsepPrb{#1}}
+\providecommand{\exPrtsep}[1]{\def\eqe@prtsepPrb{#1}}
+\providecommand{\eqequesparsep}[1]{\def\eqeques@parsep{#1}}
+\eqequesparsep{0pt}
+\let\prior@parts@hook\@empty
+\let\post@parts@hook\@empty
+\let\abovepartshook\@empty
+\let\belowpartshook\@empty
+\let\eqp@rtc@lcm@rk\relax
+\let\eq@insertContAnnot\relax
+% \end{macrocode}
+% (2012/02/04) Common code to the definition of \cs{item}
+% both list and tabular versions.
+% \begin{macrocode}
+\def\eq@item@common{\eq@insertContAnnot\eqp@rtc@lcm@rk
+ \def\currhideopt{x}\eq@hidesolutionfalse\eq@nolinkfalse
+ \@ifnextchar[{\@ckhide}{\eq@item}}
+% \end{macrocode}
+% \DescribeMacro{\eqpartsitemsep}(2012/02/03) Fine tune the control over space between
+% parts.
+%\changes{v6.4o}{2012/02/04} {Fine tune the control over space between parts.}
+% \begin{macrocode}
+\newcommand{\partsitemsep}[1]{{% dps88
+ \setlength{\@tempdima}{#1}%
+ \xdef\eqparts@itemsep{\the\@tempdima}}}
+\let\eqpartsitemsep\partsitemsep
+\def\eqparts@itemsep{0pt}
+\newcommand\partsparsep[1]{{% dps88
+ \setlength{\@tempdima}{#1}%
+ \xdef\eqparts@parsep{\the\@tempdima}}}
+\def\eqparts@parsep{0pt}
+\newcommand\partstopsep[1]{{% dps88
+ \setlength{\@tempdima}{#1}%
+ \xdef\eqparts@topsep{\the\@tempdima}}}
+\def\eqparts@topsep{3pt}
+% \end{macrocode}
+% The next two commands are in support of the \cs{leadinitem} definition
+% of \textsf{eqexam}
+% \begin{macrocode}
+\newcommand{\leadinitem@external}{\PackageError{exerquiz/eqexam}
+ {The \string\leadinitem\space command is designed to be\MessageBreak
+ the first item in the problem*\MessageBreak
+ environment above the parts environment}
+ {Use \string\leadinitem\space in the problem* environment.}%
+}
+\let\leadinitem\leadinitem@external
+\let\itsforleadinitem\eq@NO
+\newcommand{\eq@leadinitemparts}{\item\relax
+ \PackageError{exerquiz/eqexam}{The \string\leadinitem\space
+ command is not allowed in the\MessageBreak
+ parts environment}
+ {Use \string\leadinitem\space in the problem* environment.}%
+}
+% \end{macrocode}
+% (2014/03/23) Problems when description env is used with parts env. The
+% hook \cs{exlisttabheaderafterhook} is interfering with the optional argument.
+% \begin{macrocode}
+\def\eq@handleOptArg[#1]{\def\eq@optArg{[#1]}\eq@handleOptArgi}
+\def\eq@handleOptArgi{\expandafter
+ \eq@item@latex\eq@optArg\exlisttabheaderafterhook}
+% \end{macrocode}
+% We add a new switch \cs{ifwithinparts} (2014/12/03) that is used to detect whether
+% we are within the parts environment.
+% \begin{macrocode}
+\newif\ifwithinparts
+\let\ex@listtabheader@fterhook\@empty
+% \end{macrocode}
+% Begin the list version of the parts environment.
+% \begin{macrocode}
+\newenvironment{exercise@parts@list}{%
+ \settowidth{\eq@tmplength}{\parts@indent}%
+ \edef\widthOfParts{\the\eq@tmplength}%
+ \eq@initializeContAnnot\eq@nolinkfalse\prior@parts@hook
+ \abovepartshook\list{\normalfont
+ \if\Hidesymbol h\eq@nolinkfalse\ifeq@solutionsafter
+ \eq@nolinktrue\fi\fi
+ \if\currhideopt H%
+ \else
+ \ifeq@solutionsafter
+ \eq@nolinktrue % no link to solution
+ \else
+ \ifeq@nosolutions
+ \eq@nolinktrue % no link to solution
+ \else
+ \eq@ckglobalhide
+ \ifeq@hidesolution\eq@nolinktrue\else
+% \end{macrocode}
+% Write the solution header to .sol for list type question.
+% \begin{macrocode}
+ \global\let\eqExerSolnHeader\eq@@writeexheaderlist
+ \fi
+ \fi
+ \fi
+ \fi
+% \end{macrocode}
+% (2013/04/28) Inserted \texttt{[r]}
+% \begin{macrocode}
+ \makebox[\widthOfParts][r]{\eqexlisttabheader}%
+}{%
+ \usecounter{partno}%
+% \end{macrocode}
+% (2012/11/30) If \cs{solutionparshape} is nonempty, the user has used
+% \cs{leadinitem}, so we increment \texttt{partno}.
+% \begin{macrocode}
+ \if\isitleadin\eq@YES % dps7
+ \settowidth{\eq@tmplength}{\parts@indent\eqe@prtsepPrb}%
+ \xdef\prtsIndntSep{\the\eq@tmplength}% dps7
+% \advance\linewidth-\prtsIndntSep\relax
+ \if\itsforleadinitem\eqe@YES\setcounter{partno}{\fliPartNo}\else
+ \setcounter{partno}{1}\fi\fi
+ \let\leadinitem\eq@leadinitemparts
+ \let\tableadin\eq@tableadinparts
+ \global\let\solutionparshape\@empty
+% \setlength{\topsep}{3pt}%
+ \setlength{\topsep}{\eqparts@topsep}%
+% \ifdim\parskip>\z@
+% \addtolength{\topsep}{-\parskip}\fi
+ \setlength{\parskip}{0pt}%
+ \setlength{\partopsep}{0pt plus 1pt minus 1pt}%
+ \ifdim\eqeques@parsep=0pt
+ \setlength{\parsep}{\eqparts@parsep}%
+% \setlength{\itemsep}{\eqparts@itemsep-\eqparts@parsep}%
+ \else
+ \setlength{\parsep}{\eqeques@parsep}%
+% \setlength{\itemsep}{\eqparts@itemsep-\eqeques@parsep}%
+ \fi
+ \setlength{\itemsep}{\eqparts@itemsep-\parsep}%
+ \setlength{\itemindent}{0pt}%
+ \setlength{\listparindent}{\parindent}%
+% \end{macrocode}
+% For \cs{itemsep}, we subtract off, for reasons not precisely known to me.
+% This is done for \textsf{eqexam}, what effect does it have on a straight
+% \textsf{exerquiz} file?
+% \begin{macrocode}
+% \setlength{\itemsep}{\eqparts@itemsep-\eqparts@parsep}%
+ \settowidth{\labelsep}{\normalfont\eqe@prtsepPrb}%
+ \addtolength{\labelsep}{\eq@extralabelsep}%
+ \settowidth{\labelwidth}{\parts@indent}%
+ \setlength{\leftmargin}{\labelwidth}%
+ \addtolength{\leftmargin}{\labelsep}%
+% \end{macrocode}
+% When a \texttt{trivlist} appear with the parts environment, it executes
+% \cs{item}\cs{relax}, which causes problems because \cs{item} has been
+% redefined. We try to correct this.
+% \begin{macrocode}
+ \let\eq@item@latex\item
+% \def\eq@item{\eq@item@latex\exlisttabheaderafterhook}%
+% \end{macrocode}
+% We handle the problem of seeing the optional argument by getting the argument,
+% if there is one, and switching commands around.
+% \begin{macrocode}
+ \def\eq@item{\@ifnextchar[{\eq@handleOptArg}
+ {\eq@item@latex\ex@listtabheader@fterhook
+ \exlisttabheaderafterhook}}%
+ \def\eqthisenv{parts}\withinpartstrue
+ \def\item{\ifx\@currenvir\eqthisenv
+ \def\eq@next{\eq@item@common}\else
+ \def\eq@next{\eq@item}\fi
+ \eq@next}%
+}}{\endlist\global\let\leadinitem\leadinitem@external
+ \post@parts@hook\belowpartshook}
+% \end{macrocode}
+% The following command is inserted at the beginning of the parts environment
+% and defines the current problem number and the page the \texttt{problem*} environment
+% starts. The command is used by the \textsf{eqexam} package.
+% \begin{macrocode}
+\def\eq@initializeContAnnot{\@ifundefined{eqequestions}
+ {\global\let\eqeCurrProb\relax}
+ {\xdef\eqeCurrProb{\theeqquestionnoi}}%
+ \xdef\eq@currProbStartPage{\arabic{page}}%
+}
+% \end{macrocode}
+% \subsubsection{Tabular-type Parts Question}
+% Now for the tabular style of multi-part exercise, the argument
+% \#1 is the number of columns requested.\medskip
+%
+% (2017/02/09) Added xkeyvals to optional argument of \texttt{parts}. Syntax is now
+%\begin{verbatim}
+% \begin{parts}[<num>|nCols=<num>,minVspace=<length>]
+%\end{verbatim}
+% \changes{v7.8e}{2017/02/09}{Added xkeyvals to optional argument of \string\texttt{parts}}
+% \begin{macrocode}
+\define@key{tabp@rts}{nCols}{\def\exerwparts@cols{#1}}
+\define@key{tabp@rts}{minVspace}{\def\minVspacet@bs{#1}}
+% \end{macrocode}
+% Code to create vertical space when \texttt{answerkey} are in effect and
+% \cs{vspacewithkeyOn} is present.
+% \changes{v7.8e}{2017/02/09}{Added code for tab parts environment}
+% \begin{macrocode}
+\let\minVspacet@bs\@empty
+\def\minVspacetabs#1{\def\minVspacet@bs{#1}}
+\def\priorexsolafterTab{\ifkeepdeclaredvspacing
+ \ifeq@solutionsafter\ifx\minVspacet@bs\@empty\else
+ \priorexsolafterTab@cont\fi\fi\fi}
+\def\priorexsolafterTab@cont{\let\exsolafter@save\exsolafter
+ \let\exsolafter\@empty
+ \makebox[0pt][r]{\parbox[t][\minVspacet@bs][t]{0pt}
+ {\strut\hfill\vfill\strut}}%
+ \minipage[t]{\linewidth}\exsolafter@save}
+\def\pkg@endsolnexerhook{\ifkeepdeclaredvspacing
+ \ifeq@solutionsafter\ifx\minVspacet@bs\@empty\else
+ \endminipage\fi\fi\fi}
+% \end{macrocode}
+% Begin the core of the \texttt{parts} tabular-mode environment.
+% \begin{macrocode}
+\def\exercise@parts@tabular@[#1]{%
+% \end{macrocode}
+% \cs{inittabMark} initializes the auto-tab feature. (2013/03/26)
+% \begin{macrocode}
+ \inittabMark
+% \end{macrocode}
+% locally, turn off continued annotations. Not allowed in tabular parts.
+% \begin{macrocode}
+ \let\eq@insertContAnnot\relax
+ \let\exerwparts@cols\@empty
+ \setkeys*{tabp@rts}{#1}\ifx\exerwparts@cols\@empty
+ \edef\exerwparts@cols{\XKV@rm}\fi
+ \ifx\minVspacet@bs\@empty\keepdeclaredvspacingfalse\fi
+ \let\istabularexer\eq@YES
+ \@tempcnta\exerwparts@cols\relax
+ \ifnum\@tempcnta<2\relax
+ \PackageError{exerquiz}{%
+ The number of columns for parts\MessageBreak
+ needs to be an integer greater than 1}
+ {Enter an integer, 2 or larger}\fi
+ \exercise@parts@tabular}
+% \end{macrocode}
+% For the tabular environment for the \texttt{exercise*} environment, we try
+% to automatically insert the column delimiter (\texttt{\&}) and the end of line.
+% \cs{eq@extabColCnt} keeps track of the column number for the auto-tab feature.
+% \begin{macrocode}
+\newcount\eq@extabColCnt
+% \end{macrocode}
+% \DescribeMacro{\autotabOn} turns on the auto-tab feature for the \texttt{parts} environment,
+% while \cs{autotabOff}\DescribeMacro{\autotabOff} turns it off. The off setting is the default.
+% \begin{macrocode}
+\def\autotabOn{\let\eq@tabMarkChk\relax%
+ \PackageInfo{exerquiz/eqexam}{Executing \string\autotabOn}}
+\def\autotabOff{\let\eq@tabMarkChk\@gobble
+ \PackageInfo{exerquiz/eqexam}{Executing \string\autotabOff}}
+\autotabOff
+\def\inittabMark{\global\eq@extabColCnt=0 }
+\def\resettabMark{\global\eq@extabColCnt=1 }
+% \end{macrocode}
+% \DescribeMacro{\autotabnewline} is the new line command for the auto-tab feature.
+% It does a |\\| and resets the column counter \cs{eq@extabColCnt}. The user can use
+% \texttt{[vspace]}, the default is \cs{eqparts@tabrowsep}. We use \cs{noalign} so that the space
+% is added to the bottom of the whole row.
+% \begin{macrocode}
+\newcommand\autotabnewline[1][\eqparts@tabrowsep]{%
+% \end{macrocode}
+% If this is not tabular env, \cs{autotabnewline} does nothing
+% \begin{macrocode}
+ \ifnum\exerwparts@cols>0\relax % dps cq
+ \ifx\eq@tabMarkChk\@gobble
+ \def\eq@atnext{\expandafter
+ \tabularnewline\expandafter[#1]}\else
+ \def\eq@atnext{\resettabMark\tabularnewline
+ \noalign{\expandafter\kern#1}}\fi % dps7
+ \expandafter\eq@atnext\fi}
+\def\eq@tabMark{%
+ \ifnum\eq@extabColCnt=0\relax
+ \global\advance\eq@extabColCnt1\relax
+ \let\eq@next\relax
+ \else
+ \ifnum\eq@extabColCnt=1\relax
+ \let\eq@next\relax
+ \else
+ \ifnum\eq@extabColCnt>\exerwparts@cols
+ \let\eq@next\autotabnewline
+ \else\def\eq@next{&}\fi
+ \fi
+ \fi
+ \eq@next
+ \global\advance\eq@extabColCnt1\relax
+}
+% \end{macrocode}
+% Set up the tabular environment, after making a lot of decisions.
+% \begin{macrocode}
+\newcommand\partstabcolsep[1]{\def\eq@partstabcolsep{#1}}
+\partstabcolsep{1.5pt}
+\newcommand\partstabtopsep[1]{\def\eq@partstabtopsep{#1}}
+\partstabtopsep{3pt}
+\def\eq@vpartstabtopsep{\vskip\eq@partstabtopsep\relax}
+\newcommand\partstabrowsep[1]{\setlength{\@tempdima}{#1}%
+ \edef\eqparts@tabrowsep{\the\@tempdima}}
+\partstabrowsep{0pt}
+\newenvironment{exercise@parts@tabular}{%
+% \ifx\eq@tabMarkChk\@gobble
+% \partstabrowsep{\@rowskip}\fi % detecting autotab off or on
+ \setcounter{partno}{0}%
+% \end{macrocode}
+% (2015/01/10) If \cs{solutionparshape} is nonempty, the user has used
+% \cs{leadinitem}, so we increment \texttt{partno}.
+% \begin{macrocode}
+ \def\tablrIndent{\hglue\prtsIndntSep\relax}%
+ \if\isitleadin\eq@YES % dps7
+ \if$\the\everypar$\let\tablrIndent\relax\fi
+ \setcounter{partno}{1}\fi
+ \let\leadinitem\eq@leadinitemparts
+ \let\tableadin\eq@tableadinparts
+ \global\let\solutionparshape\@empty
+ \settowidth{\eq@tmplength}{\parts@indent\eqe@prtsepPrb}%
+ \xdef\prtsIndntSep{\the\eq@tmplength}%
+ \sbox{\eq@tmpbox}{\parts@indent}%
+ \let\eq@item@latex\item
+ \let\eq@item\item@part@tabular
+ \def\eqthisenv{parts}\withinpartstrue
+ \def\item{\ifx\@currenvir\eqthisenv
+ \def\eq@next{\eq@tabMarkChk\eq@tabMark\eq@item@common}\else
+ \def\eq@next{\eq@item@latex}\fi
+ \eq@next}\eq@nolinkfalse
+% \end{macrocode}
+%\changes{v6.4x}{2012/11/27}{Added control over row spacing in parts environment}
+% Added control over row spacing in parts environment. The spacing
+% is controlled by \cs{eqpartstabrowsep}, default value of \texttt{0pt}. The macro
+% \cs{@xtabularcr} is from the {\LaTeX} core. Definition \cs{eq@xtabularcr} is found
+% after the current definition block.
+% \begin{macrocode}
+ \@ifundefined{@xtabularcr}{\let\@xarraycr\eq@xtabularcr}
+ {\let\@xtabularcr\eq@xtabularcr}%
+% \end{macrocode}
+% We reduce the width of the \cs{parbox}es (p|{width}|) by \cs{exertabsep} to leave
+% room for \cs{tabcolsep=}\cs{exertabsep} between columns.
+%\begin{verbatim}
+% n=\exerwparts@cols
+% width=(\linewidth-2*(n-1)*\tabcolsep)/n
+%\end{verbatim}
+% \begin{macrocode}
+ \eq@tmpdima=\linewidth
+% \ifx\isitleadin\eq@NO
+ \advance\eq@tmpdima-\prtsIndntSep\relax
+% \fi
+ \@tempcnta\exerwparts@cols\relax
+ \advance\@tempcnta-1\relax
+ \multiply\@tempcnta2\relax
+ \@tempdima\prtsIndntSep\relax
+ \divide\@tempdima 2\relax
+ \edef\halfWidth{\the\@tempdima}%
+% \ifx\isitleadin\eq@YES\@tempdima0pt\fi
+ \advance\@tempdima\eq@partstabcolsep\relax
+% \@tempdima\eq@partstabcolsep\relax
+ \tabcolsep\@tempdima
+ \multiply\@tempdima\@tempcnta
+ \advance\eq@tmpdima-\@tempdima
+ \divide\eq@tmpdima by\exerwparts@cols
+% \ifx\isitleadin\eq@NO
+ \advance\eq@tmpdima\prtsIndntSep\relax
+% \advance\eq@tmpdima\halfWidth\relax % dps17
+% \else\advance\eq@tmpdima\halfWidth\relax\fi
+% \end{macrocode}
+% If there is a \cs{tableadin}, we do not perform a \cs{vskip}.
+% \begin{macrocode}
+ \if@tableadinitem\else\vskip\eq@partstabtopsep\relax\fi % dps11
+ \noindent\normalbaselines\kern0pt
+ \prior@parts@hook\abovepartshook
+% \end{macrocode}
+%\changes{v7.03}{2015/03/02}{Added \texttt{>\{\cs{strut}\}}, this gives
+% better control over vertical spacing.}%
+% \changes{v7.4}{2015/03/23}{inserted \cmd\setTabulrSolnEnv}%
+% \begin{macrocode}
+ \tablrIndent\tabular[t]{@{}*{\exerwparts@cols}{>{\setTabulrSolnEnv
+ \parskip\eqeques@parsep\relax
+ \parindent0pt\relax\strut}p{\eq@tmpdima}}@{\hidewidth}}%
+}{\endtabular\kern0pt
+ \@ifundefined{@listii@SAVE}{}{\global\let\@listii\@listii@SAVE
+ \global\let\@listii@SAVE\relax}%
+ \post@parts@hook\belowpartshook
+% \end{macrocode}
+% \changes{v7.4}{2015/03/23}{added an adjustment to the command \cs{endexercise@parts@tabular}}
+% A vertical space adjustment
+% \begin{macrocode}
+% \ifeq@solutionsafter\adjDisplayBelow
+% \ifthereissolution\else\vskip\baselineskip\fi\fi
+% \end{macrocode}
+% (201/05/09) There is a problem of communicating the totals through
+% the \cs{mark} command (use in \textsf{eqexam}). In \textsf{eqexam}
+% the command \cs{eqe@innermarkpts} is defined. Once the group is closed
+% we emit this mark.
+% \begin{macrocode}
+ \aftergroup\eqe@innermarkpts
+ \aftergroup\eq@vpartstabtopsep}
+% \end{macrocode}
+% (201/05/09) We make a default definition for \cs{eqe@innermarkpts}, this is needed
+% when \textsf{exerquiz} is used without \textsf{eqexam}.
+% \begin{macrocode}
+\let\eqe@innermarkpts\relax
+% \end{macrocode}
+% Redefine \verb+\item+, could be risky
+% \begin{macrocode}
+\def\item@part@tabular{\refstepcounter{partno}%
+% \end{macrocode}
+% As of 2013/03/25, I am allowing solutions after for tabular parts. I'm commenting
+% out the following line.\\
+% |%\eq@solutionsafterfalse % no solutionsafter are allowed|
+% \begin{macrocode}
+ \global\let\eqExerSolnHeader\@empty
+ \ifeq@solutionsafter
+ \eq@nolinktrue % no link to solution
+ \else\ifeq@nosolutions
+ \eq@nolinktrue % no link to solution
+ \else
+ \eq@ckglobalhide
+ \ifeq@hidesolution\eq@nolinktrue\else
+% \end{macrocode}
+% Write the solution header to \texttt{.sol} for tabular type question.
+% \begin{macrocode}
+ \gdef\eqExerSolnHeader{\eq@@writeexheaderlist}%
+ \fi\fi\fi
+ \if@restorejustify\restorejustify\else\PBS\raggedright\fi
+ \settowidth{\eq@tmplength}{\parts@indent\eqe@prtsepPrb}%
+ \xdef\prtsIndntSep{\the\eq@tmplength}%
+ \sbox{\eq@tmpbox}{\parts@indent}%
+ \eq@tmpdima=\wd\eq@tmpbox
+ \addtolength\eq@tmplength{\eq@extralabelsep}%
+ \xdef\partshangamount{\the\eq@tmplength}%
+ \advance\linewidth-\eq@tmplength
+ \parshape \@ne 0pt \linewidth
+ \everypar{\parshape \@ne 0pt \linewidth}%
+ \eq@setPrbSolnAftrIndnt
+% \end{macrocode}
+% (2013/04/28) Inserted \texttt{[r]}
+% \begin{macrocode}
+ \makebox[0pt][r]{\eqexlisttabheader\eqe@prtsepPrb}%
+ \ex@listtabheader@fterhook
+ \exlisttabheaderafterhook\ignorespaces
+}
+% \end{macrocode}
+% \begin{macrocode}
+\def\@ckhide[#1]{\edef\eq@arg{#1}%
+ \def\currhideopt{x}%
+ \ifx\eq@arg\@empty\else
+ \if\eq@arg\eq@Hid
+ \eq@hidesolutiontrue\eq@nolinktrue%
+ \edef\currhideopt{\Hidesymbol}%
+ \else
+ \ifeq@globalshowsolutions\else
+ \if\eq@arg\eq@hid
+ \eq@hidesolutiontrue\eq@nolinktrue%
+ \def\currhideopt{h}%
+ \fi
+ \fi
+ \fi\fi
+ \eq@item
+}
+% \end{macrocode}
+% In the above tabular parts environment, \cs{@xtabularcr} is \cs{let} to
+% equal to \cs{eq@xtabularcr}.
+% \begin{macrocode}
+\def\tabControlOn{\@ifundefined{@xtabularcr}
+ {\let\save@@xtabularcr\@xarraycr}
+ {\let\save@@xtabularcr\@xtabularcr}}
+% \end{macrocode}
+%\changes{v7.0}{2014/11/05}{Added \cs{tabControlOn} and \cs{tabControlOff}.
+% Tab control is interfering with regular tabular environments, or anywhere
+% \texttt{d} is used.}
+% \begin{macrocode}
+\def\tabControlOff{\@ifundefined{@xtabularcr}
+ {\let\@xarraycr\save@@xtabularcr}
+ {\let\@xtabularcr\save@@xtabularcr}}
+\AtBeginDocument{\tabControlOn}
+\def\eq@xtabularcr{\@ifnextchar[{\save@@xtabularcr}
+ {\eqe@tab@parts@rowsep}}%
+\def\eqe@tab@parts@rowsep{\save@@xtabularcr
+ \noalign{\expandafter\kern\eqparts@tabrowsep}}%
+% \end{macrocode}
+% End of the \texttt{parts} environment.
+% \end{environment}
+% \begin{macrocode}
+%</package|eqexam>
+%<*package>
+% \end{macrocode}
+% \subsection{Enumerating exercises}
+% Here we provide the \texttt{exEnumerate} environment for enumerating exercises.
+% We provide several key-values for adjusting the spacing of the environment.
+% The keys defined here are \texttt{labelwidthTo}, \texttt{labelwidth}, \texttt{topsep},
+% \texttt{parsep},\texttt{itemsep}, \texttt{labelsep}, and \texttt{continue}.%
+% \IndexKey{labelwidthTo}\IndexKey{labelwidth}\IndexKey{topsep}%
+% \IndexKey{parsep}\IndexKey{itemsep}\IndexKey{labelsep}\IndexKey{continue}%
+% \begin{macrocode}
+\define@key{exEnum}{labelwidthTo}[\normalsize\normalfont\bfseries00.\ ]%
+ {\def\exE@labelwidthTo{#1}}
+\define@key{exEnum}{labelwidth}[\@empty]{\def\exE@labelwidth{#1}}
+\let\exE@labelwidth\@empty
+\define@key{exEnum}{topsep}[3pt]{\def\exE@topsep{#1}}
+\define@key{exEnum}{parsep}[3pt]{\def\exE@parsep{#1}}
+\define@key{exEnum}{itemsep}[0pt]{\def\exE@itemsep{#1}}
+\define@key{exEnum}{labelsep}[\normalsize\normalfont\ ]%
+ {\settowidth{\@tempdima}{#1}\edef\exE@labelsep{\the\@tempdima}}
+\define@key{exEnum}{continue}[]{\let\eq@ExEnumResetCnt\@empty}
+\def\eq@ExEnumResetCnt{\setcounter{questionno}{0}}
+\setkeys{exEnum}{labelwidthTo,topsep,parsep,itemsep,labelsep}%
+% \end{macrocode}
+% \begin{environment}{exEnumerate}
+% The environment for enumerating exercises. The companion definitions for
+% these exercises follow. The argument is expanded first before being passed
+% to \cs{setkeys}; therefore you can pass a command of key-value options through
+% the optional argument:
+% |\def\myOpts{topsep=0pt}|, |\begin{exEnumerate}[\myOpts]|.
+% \begin{macrocode}
+\newenvironment{exEnumerate}[1][]{\everypar{}%
+ \toks@=\expandafter{#1}%
+ \edef\tempexp{\noexpand\setkeys{exEnum}{\the\toks@}}\tempexp
+ \eq@ExEnumResetCnt
+ \let\afterlabelhskip\@empty
+ \let\solnhspace\@empty
+ \aboveexskip{0pt}\belowexskip{\exE@parsep}%\belowexskip{0pt}%
+ \def\eqexheader@wrapper{\makebox[0pt][r]{%
+ \hypertarget{qex.\the@exno}{\eqexheader}\hspace{\labelsep}}}%
+% \end{macrocode}
+% The next two definitions are to correctly format bookmarks for these exercises.
+% \begin{macrocode}
+ \def\exbookmarkfmt{\thequestionno.\space}
+ \def\partbookmarkfmt{(\thepartno)\space}
+% \end{macrocode}
+% The definition of \cmd{\setEnum} supports the \texttt{contsolns} option.
+% \begin{macrocode}
+ \def\setENum{\Elabel\if\exerstar*\thequestionno(\thepartno)\else
+ \thequestionno\fi}%
+ \ifExSolutionsSet\else
+ \writeToExSolns{\protect\begin{exEnumerate}}\fi
+ \list{}{%
+ \ifx\exE@labelwidth\@empty
+ \settowidth{\labelwidth}{\exE@labelwidthTo}\else
+ \setlength{\labelwidth}{\exE@labelwidth}\fi
+ \setlength{\topsep}{\exE@topsep}%
+ \ifdim\parskip>\z@\addtolength{\topsep}{-\parskip}\fi
+ \setlength{\parsep}{\exE@parsep}%
+ \setlength{\itemsep}{\exE@itemsep}%
+ \setlength{\itemindent}{0pt}%
+ \setlength{\listparindent}{0pt}%
+ \setlength{\itemindent}{0pt}%
+% \setlength{\labelsep}{0pt}%
+ \settowidth{\labelsep}{\normalfont\ }%
+ \setlength{\leftmargin}{\labelwidth}%
+ }\item\relax}{\ifExSolutionsSet\else
+ \writeToExSolns{\protect\end{exEnumerate}}\fi
+\endlist}
+% \end{macrocode}
+% \end{environment}
+% \begin{environment}{enumex}
+% \begin{environment}{enumex*}
+% Prototype environments for enumerating exercises. These can be redefined as desired.
+% \begin{macrocode}
+\newenvironment{enumex}{%
+ \renewcommand\exlabelformat{\textbf{\thequestionno.}}%
+ \renewcommand\exsllabelformat
+ {\protect\makebox[0pt][r]{\protect\textbf{\thequestionno.\ }}}%
+\begin{exercise}[questionno]}{\end{exercise}}
+\newenvironment{enumex*}{%
+ \renewcommand\exlabelformatwp{\textbf{\thequestionno.}}%
+ \renewcommand\exsllabelformatwp
+ {\protect\makebox[0pt][r]{\protect\textbf{\thequestionno.}\ }%
+ \protect\textbf{(\thepartno)}\ }%
+\begin{exercise*}[questionno]}{\end{exercise*}}
+% \end{macrocode}
+% \end{environment}
+% \end{environment}
+% \begin{macrocode}
+%</package>
+%<*package|eqexam>
+% \end{macrocode}
+% \subsection{Including the \texttt{exercise} Solutions}
+% Include solutions to the exercises back into the file. This
+% section also handles solutions to quizzes as well. This macro
+% was taken from the \TeX book.
+% \begin{macro}{\includeexersolutions}
+% This macro inserts the solutions to the exercises, if there are
+% any solutions. If a user uses this macro to insert the solutions
+% elsewhere, \cmd{\include@solutions} is called, then put is to
+% \cmd{\relax}.
+% \begin{macrocode}
+%\def\includeexersolutions{%
+\def\includeexersolutions{\@ifstar
+ {\let\resetEXsolns\relax\includeexersolutionsi}
+ {\def\resetEXsolns{\global\let\include@solutions\relax}%
+ \includeexersolutionsi}%
+}
+\newcommand{\includeexersolutionsi}[1][]{%
+ \filterFor{#1}\includeexersolutionsii
+}
+\def\includeexersolutionsii{%
+%</package|eqexam>
+%<*package>
+ \if\exerSolns@ExtFile\eq@NO
+%</package>
+%<*package|eqexam>
+% \end{macrocode}
+% \cmd{\include@solutions} is the internal command that insert solutions. This command
+% appears at the end of document, where it will insert the
+% solutions, unless it has been redefined to \cmd{\relax} by
+% \cmd{\includesolutions}.
+% \begin{macrocode}
+ \include@solutions
+ \resetEXsolns
+ \let\eqFilterArg\@empty
+%</package|eqexam>
+%<*package>
+ \fi
+%</package>
+%<*package|eqexam>
+}
+% \end{macrocode}
+%
+%\subsection{Filtering solutions to exercises}
+%
+% The \cs{eqEXt} command has two arguments designed to be used to filter
+% solutions to exercises. The demo document is \texttt{filter\_exercises.tex},
+% but basically, we can include the solutions several times, once for each set filtered set.
+% \begin{macrocode}
+\long\def\gobbleToEndEXt#1\endeqEXt{%
+ \ifeqforpaper\expandafter\@gobbletwo\fi}
+% \end{macrocode}
+% \DescribeMacro\filterFor is used to mark a exercise with a name
+% \begin{macrocode}
+\newcommand\filterFor[1]{\def\eqFilterArg{#1}}
+\newcommand\inclEXtFilter[2]{\def\eqargii{#2}\ifx\eqargii\eqFilterArg
+ \else\expandafter\gobbleToEndEXt\fi}
+% \end{macrocode}
+% \end{macro}
+% \DescribeMacro\useEXtFilter is used to \cs{let} \cs{eqEXt} to \cs{EXtFilter}, which does the
+% filtering based on the value of \cs{eqFilterArg}.
+% \begin{macrocode}
+\newcommand\useEXtFilter{\let\eqEXt\inclEXtFilter}
+% \end{macrocode}
+% The basic methodology is as follows: We use \cs{filterFor} to mark an exercise, or block
+% of exercises by a name, for example, \verb!\filterFor{Problems}!. Now, at the end of the document, we can
+% say
+%\begin{verbatim}
+%\useEXtFilter
+%\renewcommand\exsectitle{Solutions to Exercises}
+%\includeexersolutions*[Exercises]
+%\renewcommand\exsectitle{Solutions to Examples}
+%\includeexersolutions*[Examples]
+%\renewcommand\exsectitle{Solutions to Problems}
+%\includeexersolutions[Problems]
+%\end{verbatim}
+% \DescribeMacro{\eqsolutionshook}\DescribeMacro{\priorexsectitle}
+% \DescribeMacro{\priorexslinput} These are commands that can be
+% redefined by the user, their location can be found below.
+% \begin{macrocode}
+\let\eqsolutionshook\@empty
+\let\eq@solutionshook\@empty
+\let\priorexsectitle\@empty
+\let\priorexslinput\@empty
+% \end{macrocode}
+%\DescribeMacro{\exerSolnsHeadnToc} sets the section title for the solutions
+% to the exercises. May be redefined, I suppose.
+% \begin{macrocode}
+\def\exerSolnsHeadnToc{\section*{\exsectitle}%
+ \addcontentsline{toc}{section}{%
+ \@ifundefined{web@latextoc}{}{%
+ \ifx\web@latextoc\eq@YES\else
+ \protect\numberline{}\fi}\exsectitle}}
+% \end{macrocode}
+%\changes{v6.4q}{2012/03/23}{define \cs{eq@defaultlheader}}
+% Determine whether \textsf{web} package is loaded, and define \cs{eq@normallheader}
+% and \cs{eq@defaultlheader}. These are designed to fix a problem of disappearing
+% headers in the solutions section of the document.
+% \begin{macrocode}
+\@ifpackageloaded{web}{\def\eq@normallheader{\lheader{\rightmark}}}
+ {\let\eq@normallheader\relax}
+\@ifpackageloaded{web}{\def\eq@defaultlheader{\lheader{\aeb@setmarks}}}
+ {\let\eq@defaultlheader\relax}
+% \end{macrocode}
+% \DescribeMacro{\exerSolnInput} is the macro that formats the opening page
+% of the solutions page and inputs \cmd{\jobname.sol}.
+% \begin{macrocode}
+\newif\ifExSolutionsSet \ExSolutionsSetfalse
+\newcommand{\exerSolnInput}
+{%
+ \@ifundefined{eqe@IWO}{}{\ifsolutionsAtEnd%\ifvspacewithsolns
+ \eqe@IWO\@auxout{\string\expandafter\string\gdef
+ \string\csname\space eqExamQuesLastPage\string\endcsname
+ {\arabic{page}}}\fi}
+ \let\webnewpage\relax
+ \ifsolutionsonly\else\immediate\closeout\ex@solns\fi
+ \ifeq@nosolutions\else
+% \end{macrocode}
+%\changes{v6.3w}{2011/03/15}{%
+% Moved \cs{eqsolutionshook} from below to a higher position
+% in the macro \cs{exerSolnInput} so the running header for
+% the solution page appears on the first page of the solutions.
+%}%
+% Moved the following line to two location below.
+% \begin{macrocode}
+% \eqsolutionshook % moved 2012/02/24
+% \end{macrocode}
+% \changes{v6.4p}{2012/02/24}{Moved location of \cs{eqsolutionshook} again}%
+% \begin{macrocode}
+ \iftherearesolutions
+ \ifsolutionsonly\eq@solutionshook
+ \eqsolutionshook
+ \else
+% \end{macrocode}
+% If there are solutions and this is not the \texttt{solutionsonly} option,
+% we start a new page, clear the right mark and start a normal header.
+% \changes{v6.4q}{2012/03/23}{Inserted \cs{eq@normalheader} after \cs{newpage}
+% to get running headers to appear on each page of solutions}%
+% Inserted |\markright{}| and \cs{eq@normalheader} to fix a problem with
+% disappearing running headers.
+% \begin{macrocode}
+ \newpage\eq@solutionshook
+ \eqsolutionshook\markright{}\eq@normallheader
+ \fi
+% \end{macrocode}
+% We are still under the assumption that there are solutions to be input.
+% We set the mark of \cs{exsectitle}.
+% \begin{macrocode}
+ \markright{\exsectitle}%
+ \ifx\webnewpage\relax
+% \end{macrocode}
+% \cs{webnewpage} is a mechanism to initially do nothing, then
+% to be redefined to \cs{newpage}. It is used in \cs{exerSolnHeader}.
+% The reasons for this definition are lost in time.
+% \begin{macrocode}
+ \def\webnewpage{\let\webnewpage\newpage}%
+ \fi
+% \end{macrocode}
+% We have a prior command, followed by the section title
+% \cs{exerSolnsHeadnToc}, followed by a post command. The prior and
+% post commands may be defined as the document author wishes.
+% Both of these are used in the \textsf{APB} pacakge.
+% \begin{macrocode}
+ \priorexsectitle\exerSolnsHeadnToc\priorexslinput
+% \end{macrocode}
+% Finally, we input the solutions file, \cs{jobname.sol}, if one exists.
+% \begin{macrocode}
+ \InputIfFileExists{\jobname.sol}
+ {\global\ExSolutionsSettrue}{\PackageWarning{exerquiz}
+ {!!! Solutions to exercises not found}}%
+ \global\ExSolutionsSetfalse
+% \end{macrocode}
+% Convert back to \cs{eq@defaultlheader} cleanly by first executing \cs{newpage}
+% \begin{macrocode}
+ \newpage\eq@defaultlheader
+ \fi
+ \fi
+}
+% \end{macrocode}
+% The \cs{include@solutions} is a wrapper command for \cs{exerSolnInput}
+% \begin{macrocode}
+\def\include@solutions{%
+%</package|eqexam>
+%<*package>
+ \if\exerSolns@ExtFile\eq@NO
+%</package>
+%<*package|eqexam>
+ \exerSolnInput
+%</package|eqexam>
+%<*package>
+ \fi
+%</package>
+%<*package|eqexam>
+}
+%</package|eqexam>
+%<*package>
+% \end{macrocode}
+% \subsection{Bookmarking Exercises}
+%
+% Someone asked how to bookmark the exercises, it was an interesting
+% little exercise for a Saturday morning. So, here it is.
+% \par\medskip\noindent
+% \cs{eqexpdfentry} marks first entry into an exercise.
+% \begin{macrocode}
+\let\eqexpdfentry=0
+% \end{macrocode}
+% \cs{eq@postexerciseHook}: Restores the \cs{Hy@currentbookmarklevel} bookmark level to what it was when
+% we first entered the exercise. This is executed at the end of the exercise
+% environment.
+% \begin{macrocode}
+\let\eq@postexerciseHook\relax
+\def\eq@postexerciseHook@BM{%
+ \xdef\Hy@currentbookmarklevel{\eq@currentbookmarklevel}}
+% \end{macrocode}
+% \begin{macro}{\exbookmarkfmt}
+% \begin{macro}{\partbookmarkfmt}
+% \begin{macro}{\expdfbookmark}
+% ``Intelligent'' bookmarking for \textsf{Exerquiz} exercises. Detects the correct bookmark level
+% determines if this is a part of an exercise, or the entry into an exercise and
+% automatically sets a unique destination.
+%
+% \cs{expdfbookmark} is the main interface to bookmarking an exercise. The single argument
+% is the text that is to appear in the bookmark panel. \cs{exbookmarkfmt} and
+% \cs{partbookmarkfmt} formats the exercise number and part letter. These can be redefined.
+%
+%\changes{v6.2a}{2007/11/10 }
+%{
+% Added \cs{expdfbookmark} to bookmark exercises.
+%}
+% We have to increase the \texttt{tocdepth} so hyperref will create the bookmark at the
+% subsection level.
+% \begin{macrocode}
+{\count0=\value{tocdepth}
+\advance\count0by2 \xdef\eqbmkmrkdepth{\the\count0}}
+\@ifundefined{Hy@bookmarksdepth}
+ {\setcounter{tocdepth}{\eqbmkmrkdepth}}
+ {\hypersetup{bookmarksdepth=\eqbmkmrkdepth}}
+\newcommand{\exbookmarkfmt}{\exlabel\space\theeqexno.\space}
+\newcommand{\partbookmarkfmt}{(\thepartno)\space}
+\newcommand{\expdfbookmark}[1]{\relax
+ \def\expdfbookmarktitle{#1}%
+% \end{macrocode}
+% The default definition of \cs{eq@postexerciseHook} is \cs{relax}. We'll
+% check if someone is using \cs{eq@postexerciseHook}.
+% \begin{macrocode}
+ \ifx\eq@postexerciseHook\relax
+ \let\eq@postexerciseHook\eq@postexerciseHook@BM
+ \else
+% \end{macrocode}
+% Yes, \cs{eq@postexerciseHook} is in use, we'll add our stuff onto the end of it.
+% \begin{macrocode}
+ \let\eq@postexerciseHook@save\eq@postexerciseHook
+ \def\eq@postexerciseHook@BM@plus{\eq@postexerciseHook@save
+ \eq@postexerciseHook@BM}%
+ \let\eq@postexerciseHook\eq@postexerciseHook@BM@plus
+ \fi
+ \if\exerstar*%
+% \end{macrocode}
+% If entering an exercise with parts for the first time, we also capture current bookmark level,
+% and mark, using \cs{eqexpdfentry} that we have entered an exercises with parts.
+% \begin{macrocode}
+ \if\eqexpdfentry0\let\eqexpdfentry=1
+ \xdef\eq@currentbookmarklevel{\Hy@currentbookmarklevel}%
+ \def\eqex@next{\subpdfbookmark{\exbookmarkfmt#1}%
+ {qex.\the@exno}}%
+ \else
+% \end{macrocode}
+% Already in an exercise with parts, no need to reduce bookmark level again
+% \begin{macrocode}
+ \def\eqex@next{\belowpdfbookmark{\partbookmarkfmt#1}%
+ {qex.\the@exno.\thepartno}}%
+ \fi
+ \else
+% \end{macrocode}
+% A regular exercise, no parts, we also capture current bookmark level
+% \begin{macrocode}
+ \xdef\eq@currentbookmarklevel{\Hy@currentbookmarklevel}%
+ \def\eqex@next{\subpdfbookmark{\exbookmarkfmt#1}%
+ {qex.\the@exno}}%
+ \fi
+ \eqex@next\ignorespaces
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \section{Early end of input}
+%
+% There is no support for the Acrobat Forms features with the
+% \texttt{dviwindo} option by \textsf{hyperref}; therefore there is
+% none here as well. \textsf{dviwindo} can use the
+% \texttt{exercise} environment, but not the quizzes, so end here.
+% \begin{macrocode}
+\ifeq@noforms\endinput\fi
+% \end{macrocode}
+% \section{Common code for quizzes.}
+% Here, we include a few commands common to both
+% quiz environments.
+%
+% Colors used by \textsf{exerquiz}: \texttt{webgreen} normally defined in \textsf{web}
+% \begin{macrocode}
+\definecolor{webgreen}{rgb}{0,.6,0}
+% \end{macrocode}
+% \begin{macro}{\proofingsymbol}
+% \begin{macro}{\proofingsymbolColor}
+% Proofing symbol and accompanying color (little green bullet)
+% \changes{v6.05b}{2006/05/12}
+% {
+% added a command to change the color of the proofing symbol
+% changed the definition of \cs{proofingsymbol} to a text fillin. This creates the command
+% \cs{@proofingsymbol}. Can now control the symbol and the color (through \cs{proofingsymbolColor}
+% }
+% \begin{macrocode}
+\newcommand{\proofingsymbolColor}[1]{\def\@proofingsymbolColor{#1}}
+\proofingsymbolColor{red}
+%\newcommand{\proofingsymbol}[1]{%
+% \def\@proofingsymbol{\textcolor{\@proofingsymbolColor}{#1}}}
+%\proofingsymbol{$\bullet$}
+%\proofingsymbol{\ding{52}}
+\let\@proofsymbolredefined=0
+\newcommand{\proofingsymbol}[1]{\let\@proofsymbolredefined=1%
+ \def\@proofingsymbol{\textcolor{\@proofingsymbolColor}{#1}}}
+\def\@proofingsymbol{\textcolor{\@proofingsymbolColor}{\ding{52}}}
+\def\setproofingsymbol{%
+ \if\@proofsymbolredefined1\else
+ \@ifpackageloaded{pifont}{\proofingsymbol{\ding{52}}}
+ {\proofingsymbol{$\bullet$}}\fi
+}
+\AtBeginDocument{\setproofingsymbol}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macrocode}
+%</package>
+%<*package|eqexam>
+% \end{macrocode}
+%
+% \subsection{The \texttt{questions} Environment}
+% The \texttt{questions} environment is used inside the
+% \texttt{shortquiz} and \texttt{quiz} environments, though it can
+% also be used a stand alone list. Beginning with version 5.5, the \texttt{questions}
+% environment can be nested three deep.
+% \begin{macro}{questions}
+% This is a redesigned \texttt{list} environment.
+% \begin{macrocode}
+\newcommand{\prior@questionsHook}{}
+\let\qMark@Hook\@empty
+\let\aebtitleQuiz\@empty
+\newcommand{\post@questionsHook}{}
+\newcommand{\quesNumColor}[1]{\def\eq@quesNumCol{#1}}
+\quesNumColor{blue}
+\renewcommand{\theeqquestionnoi}{\arabic{eqquestionnoi}}
+\newcommand{\labeleqquestionnoi}{%
+ \color{\eq@quesNumCol}\bfseries\theeqquestionnoi.}
+\renewcommand\theeqquestionnoii{(\alph{eqquestionnoii})}
+\newcommand{\labeleqquestionnoii}{%
+ \color{\eq@quesNumCol}\bfseries\theeqquestionnoii}
+\renewcommand\theeqquestionnoiii{(\roman{eqquestionnoiii})}
+\newcommand{\labeleqquestionnoiii}{%
+ \color{\eq@quesNumCol}\bfseries\theeqquestionnoiii}
+% \end{macrocode}
+% \paragraph*{Properties of the questions environment.} (2013/07/10) These include
+% \IndexKey{labelwidthTo}\texttt{labelwidthTo} and
+% \IndexKey{labelwidth}\texttt{labelwidth}.
+% \begin{macrocode}
+\define@key{props@ques}{labelwidthTo}%
+ [\normalsize\normalfont\bfseries00.]%
+ {\def\propQ@labelwidthTo{#1}}
+\define@key{props@ques}{labelwidth}[]{\def\propQ@labelwidth{#1}}
+\let\propQ@labelwidth\@empty
+% \end{macrocode}
+% \IndexKey{topsep}\texttt{topsep}, \IndexKey{partopsep}\texttt{partopsep},
+% \IndexKey{parsep}\texttt{parsep}, and \IndexKey{itemsep}\texttt{itemsep}.
+% \begin{macrocode}
+\define@key{props@ques}{topsep}[\the\topsep]{\edef\propQ@topsep{#1}}
+\define@key{props@ques}{partopsep}[\the\partopsep]%
+ {\edef\propQ@partopsep{#1}}
+\define@key{props@ques}{parsep}[\the\parsep]{\edef\propQ@parsep{#1}}
+\define@key{props@ques}{itemsep}[\the\itemsep]{\edef\propQ@itemsep{#1}}
+% \end{macrocode}
+% \IndexKey{labelsepTo}\texttt{labelsepTo} and \IndexKey{labelsep}\texttt{labelsep}
+% \begin{macrocode}
+\define@key{props@ques}{labelsepTo}[\normalsize\normalfont\ ]%
+ {\def\propQ@labelsepTo{#1}}
+\define@key{props@ques}{labelsep}[\@empty]{\def\propQ@labelsep{#1}}
+\let\propQ@labelsep\@empty
+% \end{macrocode}
+% \IndexKey{color}\texttt{color}
+% \begin{macrocode}
+\define@key{props@ques}{color}[blue]{\quesNumColor{#1}}
+% \end{macrocode}
+% The default properties of the \texttt{questions} environment.
+% \begin{macrocode}
+\setkeys{props@ques}{labelwidthTo,topsep,partopsep,parsep,%
+ itemsep,labelsepTo,color}%
+% \end{macrocode}
+% Now we begin the \texttt{questions} environment. There is an optional parameter
+% wherein we pass the key-value pairs defined above.
+% \begin{macrocode}
+\newenvironment{questions}[1][]
+{%
+ \ifnum\@eqquestiondepth>\tw@\@toodeep\else
+ \advance\@eqquestiondepth\@ne\fi
+ \def\@quesctr{eqquestionno\romannumeral\the\@eqquestiondepth}%
+ \toks@=\expandafter\expandafter\expandafter{#1}\expandafter
+ \xdef\csname quesOpts\@quesctr\endcsname{\the\toks@}%
+ \edef\tempexp{\noexpand\setkeys{props@ques}{\the\toks@}}\tempexp
+ \list{\qMark@Hook\prior@questionsHook\gdef\eqPTs{1}%
+ \global\let\eqQT\eq@na%
+% \end{macrocode}
+% (06/06/10) We create a macro \cs{@currentQues} that holds the current
+% problem number 2(a)(i), for example.
+% \begin{macrocode}
+ {\@tempcnta=0 \let\@thispr@b\@empty
+ \@whilenum\@tempcnta<\@eqquestiondepth\do{\advance\@tempcnta\@ne
+ \ifx\@thispr@b\@empty\edef\@thispr@b{%
+ \csname theeqquestionno\romannumeral\the\@tempcnta\endcsname}\else
+ \edef\@thispr@b{\@thispr@b%
+ \csname theeqquestionno\romannumeral\the\@tempcnta\endcsname}\fi
+ }\xdef\@currentQues{\@thispr@b}}%
+ \makebox[\labelwidth][r]{\normalfont\@nameuse{label\@quesctr}}%
+ \xdef\eq@pageThisQ{\the\c@page}%
+ \post@questionsHook}{\usecounter{\@quesctr}%
+% \end{macrocode}
+% We set the list parameter for the \texttt{questions} environment.
+% \begin{macrocode}
+ \ifx\propQ@labelsep\@empty
+ \settowidth{\labelsep}{\propQ@labelsepTo}\else
+ \setlength{\labelsep}{\propQ@labelsep}\fi
+ \ifx\propQ@labelwidth\@empty
+ \settowidth{\labelwidth}%
+ {\propQ@labelwidthTo\hspace{\labelsep}}\else
+ \settowidth{\labelwidth}{\hspace{\propQ@labelwidth}%
+ \hspace{\labelsep}}\fi
+ \setlength{\topsep}{\propQ@topsep}%
+ \setlength{\partopsep}{\propQ@partopsep}%
+ \ifdim\parskip>\z@\addtolength{\topsep}{-\parskip}\fi
+ \setlength{\parsep}{\propQ@parsep}%
+ \setlength{\itemsep}{\propQ@itemsep}%
+ \setlength{\itemindent}{0pt}%
+ \setlength{\leftmargin}{\labelwidth}%
+ }%
+% \setlength{\labelsep}{\propQ@labelsep}}%
+}{\endlist}
+% \end{macrocode}
+% \begin{macro}{\pushquestions}
+% \begin{macro}{\popquestions}
+% Between \cs{item}s within a question environment, you can execute
+% \cs{pushquestions}, this save the question counter, you are then free
+% to make comments between problem, when finished, executed a \cs{popquestions}
+% to return to questioning where you left off.
+% \begin{macrocode}
+\def\pushquestions{\expandafter\xdef\csname save\@quesctr\endcsname
+ {\expandafter\the\csname c@\@quesctr\endcsname}\end{questions}}
+\def\popquestions{%
+ \begin{questions}[\csname quesOpts\@quesctr\endcsname]%
+ \setcounter{\@quesctr}{\csname save\@quesctr\endcsname}%
+ \@ifnextchar\popquestions{\item[]}{\@ifnextchar\begin{\item[]}{}}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \section{The \texttt{shortquiz} and \texttt{shortquiz*} Environments}
+%
+% This \texttt{shortquiz} environment sets up multiple choice
+% questions, with immediate feedback whether the user clicked on the
+% right or wrong answer. Solutions to the \texttt{shortquiz} may,
+% or may not be included.
+% \begin{environment}{shortquiz}
+% The \texttt{shortquiz} environment, really just a shell to define the
+% \cmd{\Ans} macro and the \texttt{solution} environment that go with
+% the \texttt{shortquiz}
+%\par\medskip\noindent
+% After all the parsing is done, the parameters for this environment are
+%\begin{verbatim}
+% \begin{shortquiz}*[<basename>]
+%\end{verbatim}
+%The `\texttt{*}' is optional and signals that forms should be used instead
+%of links. This option is regressed. The user should use the \texttt{shortquiz*}
+% environment. The \verb![<basename>]! is the basename of any form fields
+% generated. If not present, an base fieldname is generated based on the
+% \cs{@shortquizCnt} macro (not a counter). The actual name is given in \cs{@sqGenBaseName}.
+%\par\medskip\noindent
+% \DescribeMacro{\priorsqhook}\cmd{\priorsqhook} and \DescribeMacro{\abovesqskip}\cmd{\abovesqskip}
+% are early hooks and skips.
+% \begin{macrocode}
+\newcommand{\priorsqhook}[1]{\def\sq@priorhook{#1}}
+\priorsqhook{}
+\newcommand{\abovesqskip}[1]{\def\sq@aboveskip{#1}}
+\abovesqskip{\par\medskip}
+% \end{macrocode}
+%\changes{v6.4a}{2011/05/11}{%
+% Added \cs{sq@afterhook} for use by \textsf{eqexam}, but may be useful elsewhere.
+%}
+%\DescribeMacro\endsqhook\cmd\endsqhook is a late hook
+% \begin{macrocode}
+\long\def\endsqhook#1{\def\sq@afterhook{#1}}
+\endsqhook{}
+\def\@shortquizCnt{0}
+\def\@sqGenBaseName{eqSqBn\@shortquizCnt}
+% \end{macrocode}
+%\DescribeMacro\sqhspace\cmd\sqhspace\ is the space that follows \cmd\sqlabel
+% \begin{macrocode}
+\let\sqhspace\space
+\newenvironment{shortquiz}
+{%
+% \end{macrocode}
+% (06/08/10) The next two lines initialize the macros for registering the
+% question label, i.e., \texttt{2(a)(ii)}. These two lines are repeated for
+% the \texttt{oQuestion} and \texttt{quiz} environments.
+% \begin{macrocode}
+ \xdef\eq@pageThisQ{\the\c@page}%
+ \let\@currentQues\@empty
+ {\count0=\@shortquizCnt \advance\count0by1\relax
+ \xdef\@shortquizCnt{\the\count0}}%
+ \goodbreak\@ifstar{\sqForms\@shortquiz}%
+ {\if\aeb@FLOverride\eq@f\def\sqstar{*}\else
+ \def\sqstar{}\sqLinks\fi\@shortquiz}%
+}{\aeb@endshortquiz}
+% \end{macrocode}
+% \end{environment}
+% \begin{environment}{shortquiz*}
+% The \texttt{shortquiz*} is a short quiz that uses forms.
+%\par\medskip\noindent
+% The parameter for this environment is
+%\begin{verbatim}
+% \begin{shortquiz}[<basename>]
+%\end{verbatim}
+% The \verb![<basename>]! is the basename of any form fields
+% generated. If not present, an base fieldname is generated based on the
+% \cs{@shortquizCnt} macro (not a counter). The actual name is given in \cs{@sqGenBaseName}.
+% \begin{macrocode}
+\newenvironment{shortquiz*}
+{%
+ \xdef\eq@pageThisQ{\the\c@page}%
+ {\count0=\@shortquizCnt\advance\count0by1\relax
+ \xdef\@shortquizCnt{\the\count0 }}%
+ \sqForms\@shortquiz
+}{\aeb@endshortquiz}
+% \end{macrocode}
+% Determines if the next argument is optional, if yes, we pass to
+% \cs{@@shortquiz}, else, we supply a automated form name, then
+% continue to \cs{@@shortquiz}.
+% \begin{macrocode}
+\def\@shortquiz{\@ifnextchar[%
+ {\@@shortquiz}{\@@shortquiz[\@sqGenBaseName]}}
+% \end{macrocode}
+% \end{environment}
+% \cs{@@shortquiz} continues the parsing of \texttt{shortquiz} and \texttt{shortquiz*}.
+% Here we take in the basename for any fields generated. The basename is passed
+% as a delimited parameter \texttt{\#1}.
+% \begin{macrocode}
+\def\sq@setCLN#1{\ifx\aebTitleQuiz\@empty
+ \protected@edef\@currentlabelname{#1}\else
+ \protected@edef\@currentlabelname{\@currentlabelname}\fi
+}
+% \end{macrocode}
+% (2013/09/29) Added \cs{isQZ} and \cs{isSQZ}
+% \begin{macrocode}
+\let\isQZ=q \let\isSQZ=s
+%</package|eqexam>
+%<*package>
+\def\sq@IDTxtField{\makebox[0pt][l]{\textField[\autoCenter{n}\BC{}\BG{}
+ \S{S}\textSize{0}\Ff{\FfReadOnly}
+ \AA{\AAFormat{%
+ var \oField=new Object;\r
+ \oField.Grp={};
+ \ifx\defaultColorJSLoc\@empty\else\r
+ \oField.DefaultColorJSLoc=\defaultColorJSLoc;\fi
+ \ifx\rghtColorJSLoc\@empty\else\r
+ \oField.RightColorJSLoc=\rghtColorJSLoc;\fi
+ \ifx\wrngColorJSLoc\@empty\else\r
+ \oField.WrongColorJSLoc=\wrngColorJSLoc;\fi
+ \ifx\rghtAnsSymbJSLoc\@empty\else\r
+ \oField.RightAnsSymbJSLoc=\rghtAnsSymbJSLoc;\fi
+ \ifx\wrngAnsSymbJSLoc\@empty\else\r
+ \oField.WrongAnsSymbJSLoc=\wrngAnsSymbJSLoc;\fi
+ }}]{sqID\oField}{0bp}{0bp}}%
+}
+%</package>
+%<*package|eqexam>
+\def\@@shortquiz[#1]{%\begingroup
+ \gdef\oField{#1}\gdef\curr@quiz{#1}\gdef\currQuiz{#1}%
+% \end{macrocode}
+% We try to support {\LaTeX}'s cross-referencing system by defining
+% \cs{@currentlabel}, \cs{@currentHlabel}, and \cs{@currentlabelname}.
+% \begin{macrocode}
+ \global\let\eqQzQuesList\@empty
+ \let\eq@AddProbToQzQuesList\relax
+ \edef\@currentlabel{\@shortquizCnt}%
+ \edef\@currentHref{shortquiz.\@shortquizCnt}%
+ \global\let\eqQuizType\isSQZ\let\@qzsolndest\@empty
+ \if\sqstar*\relax
+ \let\@Ans\Ans@sq@f
+ \ifx\oField\@empty
+ \typeout{^^JExerquiz: Base field name required when using
+ shortquiz with '*' option}%
+ \PackageInfo{exerquiz}{Assuming link style^^J}%
+ \let\@Ans\Ans@sq@l
+ \fi
+ \else
+ \let\@Ans\Ans@sq@l
+ \fi
+ \setcounter{questionno}{0}%
+ \let\answers\answers@sq
+ \let\endanswers\endanswers@sq
+ \let\manswers\manswers@sq
+ \let\endmanswers\endmanswers@sq
+ \let\solution\solution@sq
+ \let\endsolution\endsolution@sq
+% \end{macrocode}
+% Lay down the question header. \cs{sqlabel} defaults to a red ``Quiz''.
+% \begin{macrocode}
+%</package|eqexam>
+% \end{macrocode}
+% The next segment is for \textsf{exerquiz} only, and not for eqexam.
+% \begin{macrocode}
+%<*package>
+ \let\ifstaroption\eq@ifstaroption
+ \if\eq@tq@star*%
+% \end{macrocode}
+% The next code lines supports the \cs{titleQuiz*} option.
+% If its the star option, we define \cs{sqlabel}, and finished up with
+% a \cs{@gobbletwo}, this eats up the next two tokens that immediately
+% follow \cs{sqlabel} in the beginning of the \texttt{shortquiz} environment.
+% \begin{macrocode}
+ \def\sqlabel{\aebtitleQuiz\@gobbletwo}%
+ \fi
+% \end{macrocode}
+% When the online (or email) options are used in eqexam, the \cs{hypertarget}
+% command is adding vertical space. Normally \cs{sqlabel} is empty, so we don't
+% need \cs{hypertarget} in this case here.
+% \begin{macrocode}
+ \sq@aboveskip\sq@priorhook
+ \@ifundefined{PointsOnLeft}%
+ {\sq@setCLN{\eq@defaultShortQuizLabelName}%
+ \ifx\sqlabel\@empty\else\noindent\fi
+ \hypertarget{sqH\@currentHref}{}\sq@IDTxtField
+ \ifx\sqlabel\@empty\else\expandafter
+ \sqlabel\expandafter\sqhspace\fi
+ {\set@typeset@protect\aebtitleQuiz}}{}\ignorespaces
+%</package>
+%<eqexam> \sq@aboveskip\sq@priorhook\ignorespaces
+%<*package|eqexam>
+}
+% \end{macrocode}
+% \begin{macro}{\aeb@endshortquiz}
+% \begin{macro}{\aftershortquizskip}
+% We reset the labels to the default in case the author
+% of the document has redefined them temporarily. The author can
+% avoid this reset, by redefining the global variables.
+% \begin{macrocode}
+\newcommand\belowsqskip[1]{\def\aftershortquizskip{#1}}
+\belowsqskip{\medskip}
+\def\aeb@endshortquiz{\setcounter{quizno}{0}%
+ \sq@afterhook
+%</package|eqexam>
+%<*package>
+ \global\let\aebtitleQuiz\@empty
+ \global\let\aebTitleQuiz\@empty
+ \global\let\eq@tq@star\relax
+%</package>
+%<*package|eqexam>
+ \global\let\sqlabel\eq@sqlabel
+ \global\let\sqslrtnlabel\eq@sqslrtnlabel
+ \global\let\sqsllabel\eq@sqsllabel
+ \par\aftershortquizskip
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\sqLinks}
+% \begin{macro}{\sqForms}
+% (01/01/05) Use these two commands to locally change the style of multiple choice
+% questions: link or form.
+% \begin{macrocode}
+\def\sqLinks{\def\sqstar{}}\sqLinks
+\def\sqForms{\def\sqstar{*}}
+\let\eq@tq@star\relax
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macrocode}
+%</package|eqexam>
+%<*package>
+% \end{macrocode}
+% The \texttt{shortquiz} contains two other environments, each nested inside
+% the next: The \texttt{answers} environment and the \texttt{solution}
+% environment. The latter environment is optional.
+%
+% \smallskip\noindent\textbf{Basic Usage for the \texttt{shortquiz} environment}
+%\begin{verbatim}
+%No solutions included With Solutions
+%\begin{shortquiz} \begin{shortquiz}
+%The question The question
+%\begin{answers} \begin{answers}[qz:mysoln]
+%\Ans1 ... &\Ans0 &... &\Ans0 ... \Ans1 ... &\Ans0 &... &\Ans0 ...
+%\end{answers} \begin{solution}
+%\end{shortquiz} .....
+% \end{solution}
+% \end{answers}
+% \end{shortquiz}
+%\end{verbatim}
+% To further complicate matters, the \texttt{shortquiz} can be
+% used with the \texttt{questions} environment to create a series of
+% numbered short question quizzes. See the manual for examples.
+% \texttt{solution} environment is defined next.
+% \begin{macro}{solution}
+% The \texttt{solution} environment does double duty, it is used by both
+% the \texttt{shortquiz} and \texttt{quiz} environments.
+% The macro \cmd{\solution@sq} is the one that actually does the work
+% of \cmd{\solution}: It writes the solutions to the file
+% \cmd{\jobname.qsl}. This macro obeys the \texttt{forpaper}
+% option. In this case, solutions are separated by a
+% \cmd{\medskip} rather then put on a separate page. It also
+% obeys the \texttt{solutionsafter} option
+% \changes{v6.4s}{2012/06/03}{Added hooks \cmd{\sqPostHeaderHook} and
+% \cmd{\qPostHeaderHook}}
+%\par\medskip\noindent
+% Hooks \DescribeMacro\sqPostHeaderHook\cmd{\sqPostHeaderHook},
+% \DescribeMacro\qzPriorSolutionAfterHook\cmd\qzPriorSolutionAfterHook,
+% \DescribeMacro\qPostHeaderHook\cmd{\qPostHeaderHook}
+% \begin{macrocode}
+%</package>
+%<*package|eqexam>
+\def\qzPriorSolutionAfterHook{\smallskip}
+\let\sqPostHeaderHook\@empty
+\let\qPostHeaderHook\@empty
+% \end{macrocode}
+% Private versions of the two above. Used by the \texttt{contsolns} option
+% \begin{macrocode}
+\let\eq@sqPostHeaderHook\@empty
+\let\eq@qPostHeaderHook\@empty
+\let\prior@eqQt\@empty
+\let\prior@eqSQt\@empty
+% \end{macrocode}
+% \DescribeMacro\sqsolafterhspace The space after the solution label
+% \begin{macrocode}
+\def\sqsolafterhspace{\space}
+\def\solution@sq{\let\eq@next\relax
+ \ifx\@qzsolndest\@empty
+ \PackageWarning{exerquiz}%
+ {* Solutions unexpected here, will *\MessageBreak
+ * assume solutionsafter option *}%
+ \eq@solutionsaftertrue
+ \fi
+ \ifeq@solutionsafter
+ \par\qzPriorSolutionAfterHook\noindent
+ \if!\sqsolafter!\else
+ \sqsolafter\sqsolafterhspace\fi\ignorespaces
+ \else
+ \global\therearequizsolutionstrue\let\verbatim@out=\quiz@solns
+ \set@display@protect
+ \immediate\write\verbatim@out{%
+% \end{macrocode}
+% Mark in the solutions files whether this is a quiz or a shortquiz solution.
+% \begin{macrocode}
+ \if\eqQuizType\isQZ
+ \ifx\prior@eqQt\@empty\else\prior@eqQt\fi
+ \protect\eqQt{\eqFilterArg}\else
+ \ifx\prior@eqSQt\@empty\else\prior@eqSQt\fi
+ \protect\eqSQt{\eqFilterArg}\fi
+ \protect\quizSolnHeader\if\eqQuizType\isQZ\ifx\allow@peek\eq@NO
+ [{\curr@quiz}{\currQuizStartPage}]\fi\fi
+ {\@qzsolndest}{\sqsllabel}\protect\eqterminex
+ \if\eqQuizType\isQZ\expandafter\eq@qPostHeaderHook
+ \expandafter\qPostHeaderHook\else
+ \expandafter\eq@sqPostHeaderHook
+ \expandafter\sqPostHeaderHook\fi}%
+ \set@typeset@protect
+ \expandafter\verbatimwrite\fi
+}
+\let\qzSolutionsAfterHook\@empty
+\def\endsolution@sq
+{%
+ \ifeq@solutionsafter
+ \eq@fititin{\mbox{\sqslrtnlabel}}\par\qzSolutionsAfterHook
+ \aftergroup\ignorespaces
+ \else
+ \endverbatimwrite
+ \ifx\@qzsolndest\@empty\else\set@display@protect
+ \immediate\write\verbatim@out{\eqSqSolnTrailer}%
+ \set@typeset@protect
+ \fi
+ \fi
+ \global\let\@qzsolndest\@empty
+}
+%</package|eqexam>
+%<*package>
+% \end{macrocode}
+% \DescribeMacro{\promoteNewPageHere}\cmd{\promoteNewPageHere} promotes
+% a new page. The argument is a vertical skip. If there is \texttt{\#1}
+% or more space remaining on the page, the command does nothing, otherwise
+% it issues a \cs{newpage}.
+% \changes{v6.4s}{2012/06/03}{Added \cs{promoteNewPageHere}}
+% \changes{v6.8a}{2014/01/01}{Made an optional argument, but test for required argument as swell.}
+% \begin{macrocode}
+\newcommand\pnphDflt{.1\textheight}
+\newcommand{\promoteNewPageHere}[1][\pnphDflt]{%
+ \@ifnextchar\bgroup{\eq@promoteNewPageHere}
+ {\eq@promoteNewPageHere{#1}}%
+}
+\def\eq@promoteNewPageHere#1{\par
+ \bgroup\@nobreakfalse\addpenalty{-500}%
+ \setlength{\@tempdimb}{#1}%
+ \@tempdima \pagegoal \advance \@tempdima -\pagetotal
+ \ifdim \@tempdima<\@tempdimb\ifnum\col@number>\@ne\columnbreak
+ \else\newpage\penalty1\fi\fi\egroup
+}
+% \end{macrocode}
+% \begin{macro}{\saveDest}
+% \begin{macro}{\useDest}
+% These two macros are used, as needed to save the destination name of a solution, then
+% re-emitting it later, just prior to the solution. Useful for grouped questions.
+% \begin{macrocode}
+\newcommand{\saveDest}[1][]{%
+ \def\sd@arg{#1}\ifx\sd@arg\@empty
+ \xdef\holdDest{\@qzsolndest}\else
+ \xdef\@qzsolndest{#1}\xdef\holdDest{#1}\fi}
+\def\useDest{\def\@qzsolndest{\holdDest}}
+\let\holdDest\@empty
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macrocode}
+%</package>
+%<*package|eqexam>
+\def\fpAfterSolutionsSkip{\par\medskip}
+\let\eqSqSolnTrailerHook\@empty
+\let\eqQzSolnTrailerHook\@empty
+\newcommand\eqSqSolnTrailer{%
+ \if\eqQuizType\isQZ
+ \eqQzSolnTrailerHook
+ \protect\ReturnTo{page.\eq@pageThisQ}%
+ {\protect\mbox{\sqslrtnlabel}}\string\endeqQt
+ \else
+ \eqSqSolnTrailerHook
+ \protect\ReturnTo{page.\eq@pageThisQ}%
+ {\protect\mbox{\sqslrtnlabel}}\string\endeqSQt%
+ \fi
+ \ifeqforpaper\protect\fpAfterSolutionsSkip\fi^^J%
+}
+%</package|eqexam>
+%<*package>
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\eqQt}
+% \begin{macro}{\endeqQt}
+% \begin{macro}{\eqSQt}
+% \begin{macro}{\endeqSQt}
+% The \cmd{\eqQt} and \cmd{\eqSQt} are markers at the beginning of each
+% quiz (short quiz, respectively) solution. These markers, along with
+% ``end'' versions, \cmd{\endeqQt} and \cmd{\endeqSQt}, respectively, can be used to filter out the quiz solutions or the
+% short quiz solutions. The following example removes all short quizzes.
+%\begin{verbatim}
+%\long\def\eqSQt#1\endeqSQt{}
+%\begin{document}
+%\input{mydoc.qsl}
+%\end{document}
+%\end{verbatim}
+% \begin{macrocode}
+%</package>
+%<*package|eqexam>
+\let\eqSQt\@gobble
+\let\endeqSQt\relax
+\let\eqQt\@gobble
+\let\endeqQt\relax
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\quizSolnHeader}
+% Each solution begins with \cmd{\quizSolnHeader}. This can be redefined
+% for whatever reason. It takes three arguments, one of which is optional.
+% \#1 is the \cmd{\noPeek} parameters; \#2 is the named destination to this
+% solution; \#3 is the \cmd{\sqsllabel}.
+%
+% If you want to typeset solutions separately, you can redefine
+% \cmd{\quizSolnHeader} as desired, and used in conjunction with
+% \cmd{eqQt}.
+% \changes{v6.7q}{2013/12/15}{Added this hook for use by \textsf{contsolns.dtx}}
+% \begin{macrocode}
+\let\prior@quizSolnHeaderHook\@empty
+\newcommand\quizSolnHeader[3][]{%
+ \prior@quizSolnHeaderHook
+ \ifeqforpaper\else\webnewpage\fi\noindent
+%</package|eqexam>
+%<*package>
+ \def\eq@argi{#1}%
+ \ifx\eq@argi\@empty\else\noPeek#1\fi
+ \hypertarget{#2}{#3}\relax
+%</package>
+%<*eqexam>
+ #2%
+%</eqexam>
+%<*package|eqexam>
+ \solnspace
+}
+%</package|eqexam>
+%<*package>
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\NoPeeking}
+% \begin{macro}{\AllowPeeking}
+% A \texttt{quiz} solution has an additional (optional) feature. If
+% \cmd{\NoPeeking} is executed, then an open action is placed on the opening
+% page of each solution. This open action simply changes the page back to
+% the page of the quiz. This is an attempt at keeping students from ``peeking''
+% at the solutions before, or while they are taking a quiz. \cmd{\AllowPeeking}
+% is the default.
+% \begin{macrocode}
+\def\AllowPeeking{\global\let\allow@peek\eq@YES}\AllowPeeking
+\def\NoPeeking{\global\let\allow@peek\eq@NO}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\noPeekAction}
+% The default definition of \cmd{quizSolnHeader} contains a macro called
+% \cmd{\noPeek}. This is the action that \cmd{\noPeek} performs. The actual
+% definition of \cmd{\noPeek} is driver dependent, and is listed elsewhere.
+% An open page action will be created with a JavaScript action, which calls
+% a DLJS function \texttt{noPeek("\#1",\#2)}. The first parameter is the base
+% name of the quiz; the second parameter is the page number the quiz starts from
+% (so that we can return to that page when the student tries to view the solution
+% when he is not authorized to).
+% \begin{macrocode}
+\def\noPeekAction#1#2{%
+ /AA <</O<</S/JavaScript/JS(noPeek("#1",#2))>> >>
+}
+% \end{macrocode}
+% \end{macro}
+% \subsection{The \texttt{shortquiz} Solutions}
+% When the first solution is written, \cmd{\therearequizsolutions} is
+% made true. When the solutions are input back into the file, and
+% this switch is still false, then no quiz header is typeset;
+% this avoids an empty quiz solutions section with only the header.
+% \begin{macrocode}
+%</package>
+%<*package|eqexam>
+\newif\iftherearequizsolutions \therearequizsolutionsfalse
+\let\aeb@FLOverride\relax
+% \end{macrocode}
+% \begin{macro}{\includequizsolutions}
+% This macro inserts the solutions to the short quizzes, if there are
+% any solutions. If a user uses this macro to insert the solutions
+% elsewhere, \cmd{\include@quizsolutions} is called, then put is to
+% \cmd{\relax}.
+% \begin{macrocode}
+\def\includequizsolutions{\@ifstar
+ {\let\resetQZtsolns\relax\includequizsolutionsi}
+ {\def\resetQZtsolns{\global\let\include@quizsolutions\relax}%
+ \includequizsolutionsi}%
+}
+\newcommand{\includequizsolutionsi}[1][]{%
+ \filterFor{#1}\includequizsolutionsii
+}
+\def\includequizsolutionsii{%
+ \include@quizsolutions
+ \resetQZtsolns
+ \let\eqFilterArg\@empty
+}
+%</package|eqexam>
+%<*package>
+% \end{macrocode}
+% \end{macro}
+% \DescribeMacro{\eqqzsolutionshook}\DescribeMacro{\priorsqslsectitle}
+% \DescribeMacro{\priorsqslinput} are commands executed at the beginning of the page of quiz solutions.
+% These may be defined by the document author.
+% \begin{macrocode}
+\let\eqqzsolutionshook\@empty
+\let\priorsqslsectitle\@empty
+\let\priorsqslinput\@empty
+% \end{macrocode}
+% \DescribeMacro{\quizSolnsHeadnToc} sets up the quiz solution title.
+% \begin{macrocode}
+\def\quizSolnsHeadnToc{\section*{\sqslsectitle}%
+ \addcontentsline{toc}{section}{%
+ \@ifundefined{web@latextoc}{}{%
+ \ifx\web@latextoc\eq@YES\else
+ \protect\numberline{}\fi}\sqslsectitle}}
+% \end{macrocode}
+% \DescribeMacro{\quizSolnInput} is the command that actually inputs
+% the solutions file \cmd{\jobname.qsl}.
+% \begin{macrocode}
+\newcommand{\quizSolnInput}
+{%
+ \let\webnewpage\relax
+ \immediate\closeout\quiz@solns
+ \ifeq@noquizsolutions\else
+% \end{macrocode}
+% If there are quiz solutions, we start a new page, and clear the right mark.
+% We execute \cmd{\eq@normallheader} which sets the running left header,
+% except on the page with a section head. We set the right mark as
+% \cmd{\eq@sqslsecrunhead}. (2013/09/23) replaced \cmd{\eq@sqslsecrunhead}
+% with \cmd{\sqslsecrunhead}, makes it easier to define running headers
+% when solutions are filtered.
+% \begin{macrocode}
+ \iftherearequizsolutions\newpage\markright{}%
+ \eq@normallheader\markright{\sqslsecrunhead}%
+ \ifx\webnewpage\relax
+ \def\webnewpage{\let\webnewpage\newpage}\fi
+% \end{macrocode}
+% Here we have various prior commands, and the setting of the
+% section title.
+% \begin{macrocode}
+ \priorsqslsectitle\quizSolnsHeadnToc\priorsqslinput
+% \end{macrocode}
+% Now input the solution file \cmd{\jobname.qsl}.
+% \begin{macrocode}
+ \InputIfFileExists{\jobname.qsl}{}%
+ {!!! Solutions to quizzes not found}
+% \end{macrocode}
+% A hook for hanging things
+% \begin{macrocode}
+ \eqqzsolutionshook
+% \end{macrocode}
+% Reset the running header cleanly
+% \begin{macrocode}
+ \newpage\eq@defaultlheader
+ \fi
+ \fi
+}
+% \end{macrocode}
+% The internal command that insert solutions. This command
+% appears at the end of document, where it will insert the
+% solutions, unless it has been redefined to \cmd{\relax} by
+% \cmd{\includequizsolutions}.
+% \begin{macrocode}
+\def\include@quizsolutions{\quizSolnInput}
+% \end{macrocode}
+%
+% \section{The \texttt{quiz} and \texttt{quiz*} Environments}
+%
+% In this section we introduce the \texttt{quiz} environment, and all its
+% supporting elements.
+%
+% \subsection{Define the \texttt{quiz} Environment}
+% \DescribeMacro{\priorqhook}\DescribeMacro{\aboveqskip}
+% \DescribeMacro{\endqhook}\DescribeMacro{\belowqskip} These are hooks and skip
+% before and after the \texttt{quiz} environment.
+% \begin{macrocode}
+\newcommand{\priorqhook}[1]{\def\q@priorhook{#1}}
+\priorqhook{}
+\newcommand{\aboveqskip}[1]{\def\q@aboveskip{#1}}
+\aboveqskip{\par\medskip}
+\newcommand{\qhspace}{\space}
+\def\endqhook#1{\def\eq@prior@endQuiz{#1}}
+\endqhook{}
+\newcommand{\belowqHooknSkip}[1]{\def\eq@belowqskip{#1}}
+\belowqHooknSkip{\medskip}
+\def\belowqskip{\belowqHooknSkip}
+% \end{macrocode}
+% \begin{macrocode}
+\let\eq@initializeServerSubmit\@empty
+% \end{macrocode}
+% \begin{macro}{\quiztype}
+% \begin{macro}{\defaultquiztype}
+% The command \cs{quiztype} can be used to force subsequent quizzes to be link
+% style or form style, independent of the environment. Recognized values are
+% \texttt{f} and \texttt{l}. Once the override \cs{quiztype} has been used,
+% you can recover the default behavior of the quizzes by expanding
+% \cs{defaultquiztype}.
+% \begin{macrocode}
+\newcommand{\quiztype}[1]{%
+ \def\@quiztype{#1}\def\aeb@FLOverride{#1}}
+\let\@quiztype\@empty
+\newcommand{\defaultquiztype}{\let\@quiztype\@empty
+ \let\aeb@FLOverride\relax}
+\let\aeb@FLOverride\relax
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macrocode}
+\def\@setFormLinkType{%
+ \if\qstar*%
+ \ifx\aeb@FLOverride\relax%
+ \def\@@quiztype{f}%
+ \else
+ \if\aeb@FLOverride l\def\@@quiztype{l}\else
+ \def\@@quiztype{f}\fi
+ \fi
+ \else
+ \ifx\aeb@FLOverride\relax
+ \def\@@quiztype{l}%
+ \else
+ \if\aeb@FLOverride f\def\@@quiztype{f}\else
+ \def\@@quiztype{l}\fi
+ \fi
+ \fi
+}
+\def\setdefault@Ans{\@setFormLinkType
+ \expandafter\global\expandafter
+ \let\expandafter\@Ans\expandafter=\csname Ans@\@@quiztype\endcsname
+}
+% \end{macrocode}
+% \begin{macro}{\useForms}
+% \begin{macro}{\useLinks}
+% \begin{macro}{\restoreFLTypeDefault}
+% For multiple choice questions, here we give the option of using a mixture of links
+% and forms.
+% \begin{macrocode}
+%</package>
+%<*package|eqexam>
+\newcommand\useForms{\def\aeb@FLOverride{f}}
+\newcommand\useLinks{\def\aeb@FLOverride{l}}
+\newcommand\restoreFLTypeDefault{\global\let\aeb@FLOverride\relax}
+\let\aeb@FLOverride\relax
+%</package|eqexam>
+%<*package>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{environment}{quiz}
+% The \texttt{quiz} environment takes an optional `\texttt*'
+% and one required argument. There are two styles of quizzes:
+% links or checkboxes. Beginning with v6.08, the use of the \texttt*-option
+% is discouraged, use the quiz* environment instead.
+%\begin{verbatim}
+%\begin{quiz}[*]{<base_name>}
+% ...
+%\end{quiz}
+%\end{verbatim}
+% \begin{itemize}
+% \item optional \texttt{*} $=$ use checkboxes, otherwise use links
+% \item \texttt{<base\_name>}: required argument $=$ base name of quiz.
+% \end{itemize}
+%
+% Note that I set \verb!\tabcolsep=0pt! in preparation for a tabular environment.
+% If authors wants to use a tabular environment within a question, he/she must
+% reset this value to its default, \verb!\setlength{\tabcolsep}{6pt}!.
+% \begin{macrocode}
+\newenvironment{quiz}
+{\goodbreak\@ifstar{\gdef\qstar{*}\@quiz*f}{\gdef\qstar{x}\@quiz*l}}
+ {\aeb@endquiz}
+\def\@quizCnt{0}
+\def\@quiz*#1#2{%
+% \end{macrocode}
+% (06/08/10) The next two lines initialize the macros for registering the
+% question label, i.e., \texttt{2(a)(ii)}. These two lines are repeated for
+% the \texttt{oQuestion} and \texttt{shortquiz} environments.
+% \begin{macrocode}
+ \xdef\eq@pageThisQ{\the\c@page}%
+ \let\@currentQues\@empty
+ \global\let\eqQzQuesList\@empty
+ \global\let\pointValuesArray\@empty
+% \end{macrocode}
+% Initialize \texttt{ptypeArray} to track problem types better
+% \changes{v7.7m}{2016/07/04}{Initialize \string\texttt{ptypeArray} to track problem types better}
+% \begin{macrocode}
+ \global\let\ptypeArray\@empty
+% \end{macrocode}
+% Initialize \texttt{corrAnsArray} to track the correct answers
+% \changes{v7.7n}{2016/07/06}{Initialize \string\texttt{ptypeArray} to track problem types better}
+% \begin{macrocode}
+ \global\let\corrAnsArray\@empty
+% \end{macrocode}
+% Update the internal quiz counter.
+% \begin{macrocode}
+ {\count0=\@quizCnt\advance\count0by1\relax
+ \xdef\@quizCnt{\the\count0 }}%
+% \end{macrocode}
+% We try to support {\LaTeX}'s cross-referencing system by defining
+% \cs{@currentlabel}, \cs{@currentHlabel}, and \cs{@currentlabelname}.
+% \begin{macrocode}
+ \edef\@currentlabel{\@quizCnt}%
+ \edef\@currentHref{quiz.\@quizCnt}%
+ \sq@setCLN{\eq@defaultQuizLabelName}%
+ \setcounter{eqpointvalue}{0}\setcounter{questionno}{0}%
+ \eq@initializeServerSubmit
+ \global\let\eqQuizType\isQZ %\tabcolsep=0pt
+ \gdef\eqPTs{1}\global\let\eqQT\eq@na
+% \end{macrocode}
+% \changes{v6.3u}{2010/11/04}{%
+% Added \cs{xdef}\cs{oField}\texttt{\{\#2\}}, this is
+% needed for \textsf{apb.dtx}.
+%}
+% \begin{macrocode}
+ \gdef\quiz@total{#2}\xdef\curr@quiz{#2}\xdef\oField{#2}%
+ \xdef\currQuiz{#2}\xdef\currQuizStartPage{\thepage}%
+ \xdef\aPointType{0}%
+% \end{macrocode}
+% (2013/12/20) Pass \cs{bqlabelISO} through \cs{pdfstringdef}.
+% \begin{macrocode}
+ \def\fieldJSStr@CMD{\fieldJSStr*[noquotes]\bqlabelISO}%
+ \expandafter\fieldJSStr@CMD\expandafter{\bqlabelISO}%
+ \ifx\@quiztype\@empty\gdef\@@quiztype{#1}\else
+ \xdef\@@quiztype{\@quiztype}\fi
+ \let\@qzsolndest\@empty
+ \let\answers\answers@q\let\endanswers\endanswers@q
+ \let\manswers\manswers@q\let\endmanswers\endanswers@q
+ \let\solution\solution@sq\let\endsolution\endsolution@sq
+ \expandafter%
+ \xdef\csname titleOf\currQuiz\endcsname{\aebTitleQuiz}%
+% \end{macrocode}
+% Modified the destination name of \cs{hypertarget} to avoid deplicate
+% destinations. Did the same thing for the \texttt{shortquiz}.
+% \changes{v7.8a}{2016/12/07}{Modified destination name of \string\cs{hypertarget}}
+% \begin{macrocode}
+ \q@aboveskip\q@priorhook\noindent\hypertarget{qzH\@currentHref}{}%
+ \eq@beginQuiz\qhspace{\set@typeset@protect\aebtitleQuiz}%
+ \ignorespaces
+}
+% \end{macrocode}
+% Here is the end for the \texttt{quiz} and \texttt{quiz*} environments. The
+% \cs{eq@prior@endQuiz} can be used for whatever purposes a
+% developer wants.
+% \begin{macrocode}
+\def\aeb@endquiz
+{%
+ \eq@prior@endQuiz\noindent\eq@endQuiz
+ \global\let\eqQuizType\relax
+ \global\let\aebtitleQuiz\@empty
+ \global\let\aebTitleQuiz\@empty
+ \global\let\bqlabel\eq@bqlabel % reset beginning label to default
+ \global\let\eqlabel\eq@eqlabel % reset ending label to default
+% \end{macrocode}
+% (2013/10/18) Added \cs{sqsllabel} to list of commands that are reset.
+% \begin{macrocode}
+ \global\let\sqsllabel\eq@sqsllabel
+ \global\let\sqslrtnlabel\eq@sqslrtnlabel
+ \global\let\bqlabelISO\eq@bqlabelISO
+ \eq@belowqskip
+}
+% \end{macrocode}
+% \end{environment}
+%
+% \subsection{Define the \texttt{quiz*} Environment}
+%
+% \begin{environment}{quiz*}
+% This environment is more latexy, \texttt{quiz*} environment is for quizzes with forms. Equivalent
+% to \verb!\begin{quiz}*...\end{quiz}!/
+% \begin{macrocode}
+\newenvironment{quiz*}{\goodbreak\gdef\qstar{*}\@quiz*f}{\aeb@endquiz}
+% \end{macrocode}
+% \end{environment}
+%
+% \subsection{Begin/End Quiz with Link or Buttons}
+%
+% Redefine this macro to \cmd{\eq@BeginQuizButton} to get a form button
+% for the \texttt{quiz} environment. Pressing on the link or button
+% initializes the quiz. The default is `link': \cmd{\eq@BeginQuizLink}.
+% \begin{macrocode}
+\newcommand\eq@beginQuiz{\eq@BeginQuizLink}
+% \end{macrocode}
+% Redefine this macro to |\eq@EndQuizButton| to get a form button
+% for the \texttt{quiz} environment. Pressing on the link or button
+% will score the quiz. The default is `link': |\eq@EndQuizLink|.
+% \begin{macrocode}
+\newcommand\eq@endQuiz{\eq@EndQuizLink}
+% \end{macrocode}
+% \begin{macro}{\useBeginQuizButton}
+% Use a button instead of a link for begin quiz
+% \begin{macrocode}
+\newcommand\useBeginQuizButton[1][]
+ {\renewcommand\eq@beginQuiz{\eq@BeginQuizButton[#1]}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\useEndQuizButton}
+% Use a button instead of a link for end quiz
+% \begin{macrocode}
+\newcommand\useEndQuizButton[1][]
+ {\renewcommand\eq@endQuiz{\eq@EndQuizButton[#1]}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\useBeginQuizLink}
+% Use a link begin quiz (the default)
+% \begin{macrocode}
+\newcommand\useBeginQuizLink
+ {\renewcommand\eq@beginQuiz{\eq@BeginQuizLink}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\useEndQuizLink}
+% Use a link end quiz (the default)
+% \begin{macrocode}
+\newcommand\useEndQuizLink
+ {\renewcommand\eq@endQuiz{\eq@EndQuizLink}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macrocode}
+\def\listOfQuizzes{}
+\def\listOfSubmitQuizzes{}
+\def\initializeAllSubmitQuizzes{}
+% \end{macrocode}
+% \begin{macro}{\@initQuiz}
+% \begin{macro}{\priorInitQuiz}
+% \begin{macro}{\postInitQuiz}
+% \cs{@initQuiz} is executed when you click on `Begin Quiz'. Included here are some
+% macro hooks for insert code prior to, and after the quiz initialization. This
+% command appears in the commands \cs{eq@@BeginQuizLinkActions} and \cs{eq@@BeginQuizButtonActions} below.
+%\changes{v7.0}{2014/11/05}{Added some JS: lstOfQuizzes is an associative array
+% listing all quizzes in the document, the value is the quiz object. We add properties
+% isSubmitted and initializeWith to the quiz object.}
+% \begin{macrocode}
+\newcommand\@initQuiz{%
+ var \curr@quiz=new Object();\jsR
+ lstOfQuizzes["\curr@quiz"]=\curr@quiz;\jsR
+ \curr@quiz.oAlertCheck={bAfterValue:false};\jsR
+ \curr@quiz.Grp={};
+ \ifx\defaultColorJSLoc\@empty\else\jsR
+ \oField.DefaultColorJSLoc=\defaultColorJSLoc;\fi
+ \ifx\rghtColorJSLoc\@empty\else\jsR
+ \oField.RightColorJSLoc=\rghtColorJSLoc;\fi
+ \ifx\wrngColorJSLoc\@empty\else\jsR
+ \oField.WrongColorJSLoc=\wrngColorJSLoc;\fi
+ \ifx\partialColorJSLoc\@empty\else\r
+ \oField.PartialColorJSLoc=\partialColorJSLoc;\fi
+ \ifx\rghtAnsSymbJSLoc\@empty\else\jsR
+ \oField.RightAnsSymbJSLoc=\rghtAnsSymbJSLoc;\fi
+ \ifx\wrngAnsSymbJSLoc\@empty\else\jsR
+ \oField.WrongAnsSymbJSLoc=\wrngAnsSymbJSLoc;\fi
+ \ifx\corrAnsSymbJSLoc\@empty\else\jsR
+ \oField.CorrAnsSymbJSLoc=\corrAnsSymbJSLoc;\fi
+ \ifx\eqGradeScaleLoc\@empty\else\jsR
+ \oField.GradeScaleLoc=new Array(\eqGradeScaleLoc);\fi
+ \ifx\priorInitQuiz\@empty\else\jsR\priorInitQuiz\fi\jsR
+ InitializeQuiz("\curr@quiz",\ifnocorrections0\else1\fi);
+ \ifx\eq@CGI\@empty\jsR\curr@quiz.isSubmitted=false;\else
+ \jsR\curr@quiz.isSubmitted=true;\fi
+ \jsR\curr@quiz.initializeWith=%
+'InitializeQuiz("\curr@quiz",\ifnocorrections0\else1\fi);'
+ \ifx\postInitQuiz\@empty\else\jsR\postInitQuiz\fi
+}
+% \end{macrocode}
+% \cs{priorInitQuiz} and \cs{postInitQuiz} are hooks that allow a document author to
+% execute JavaScript just prior to initializing the quiz and just after. These appear in
+% \cs{eq@@BeginQuizLinkActions} and \cs{eq@@BeginQuizButtonActions} below.
+% \begin{macrocode}
+\newcommand{\priorInitQuiz}{}
+\newcommand{\postInitQuiz}{}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% Here are a couple of macros used with `End Quiz', and are used for
+% submitting quiz results to a web server.
+% \begin{macrocode}
+\let\eq@submitURL\@empty
+\let\eq@insertHiddenFields\@empty
+% \end{macrocode}
+%
+% \subsubsection{With Links}
+%
+% \begin{macro}{\eq@BeginQuizLink}
+% Begin quiz with links
+% \begin{macrocode}
+\def\eq@@BeginQuizLinkActions
+{%
+ \A{\JS{%
+% \ifx\priorInitQuiz\@empty\else\priorInitQuiz\jsR\fi
+ \@initQuiz
+% \ifx\postInitQuiz\@empty\else\jsR\postInitQuiz\fi
+ }}%
+}
+\def\eq@BeginQuizLinkDefaults{\Border{0 0 0}}
+\let\bqlabelFmt\@empty
+\def\eq@BeginQuizLink
+{%
+ \set@@Link{}{}{}{\color{\@linkcolor}\bqlabelFmt\bqlabel}{}%
+ {\eq@setWidgetProps\setLink@driver}%
+ {\eq@BeginQuizLinkDefaults\eq@@BeginQuizLinkActions\every@Link}%
+ \space\ignorespaces
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\eq@EndQuizLink}
+% Code the the link version of `End Quiz'.
+% \begin{macrocode}
+\newcommand\priorSubmitQuiz{}
+\newcommand\postSubmitQuiz{}
+\def\eq@@EndQuizLinkActions
+{%
+ \A{\JS{%
+ if (!isQuizInitialized("\curr@quiz"))\jsR\jsT
+ eqAppAlert(InitMsg("\bqlabelISO"),3);\jsR
+ else {\jsR\jsT
+ if (\minQuizResp(\thequestionno)) {\jsR\jsT\jsT
+ \curr@quiz.PtValues=new %
+Array(\pointValuesArray);\jsR\jsT\jsT
+ ProbType = [\ptypeArray];\jsR\jsT\jsT
+\if@inclkey
+ \curr@quiz.CorrAns=(new %
+Array(\corrAnsArray));\jsR\jsT\jsT
+\fi
+ DisplayQuizResults("\curr@quiz",\theeqpointvalue,%
+\thequestionno);\jsR\jsT\jsT
+% \priorSubmitQuiz
+ \eq@submitURL
+ \postSubmitQuiz
+ resetQuiz("\curr@quiz");\jsR\jsT
+ }\jsR
+ }}}%
+}
+\def\eq@EndQuizLinkDefaults{\Border{0 0 0}}
+\let\eqlabelFmt\@empty
+\def\eq@EndQuizLink
+{%
+ \ifx\eq@CGI\@empty
+ \let\eq@submitURL\@empty
+ \let\eq@insertHiddenFields\@empty
+ \fi
+ \set@@Link{}{}{}{\color{\@linkcolor}\eqlabelFmt\eqlabel}{}%
+ {\eq@setWidgetProps\setLink@driver}%
+ {\eq@EndQuizLinkDefaults\eq@@EndQuizLinkActions\every@Link}%
+ \makebox[0pt][r]{\textField[\BC{}\autoCenter{n}]%
+ {htxtfld.\curr@quiz}{0bp}{0bp}}%
+ \makebox[0pt][r]{\eq@insertHiddenFields}\global\let\eq@CGI\@empty
+ \ignorespaces
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{With Buttons}
+%
+% \begin{macro}{\eq@BeginQuizButton}
+% This is the button when the user wants button rather than link for the
+% \texttt{quiz} environment.
+% \begin{macrocode}
+\def\BeginQuizButtonDefaults
+{%
+ \CA{\bqlabel}\H{P}\F{\FPrint}
+ \BC{1 0 0}\BG{.7529 .7529 .7529}\W{1}\S{B}
+}
+\def\eq@@BeginQuizButtonActions
+{%
+ \A{\JS{%
+% \ifx\priorInitQuiz\@empty\else\priorInitQuiz\r\fi
+ \@initQuiz
+% \ifx\postInitQuiz\@empty\else\r\postInitQuiz\fi
+ }}%
+}
+\newcommand\eq@BeginQuizButton[1][]
+{%
+ \mbox{\push@@Button{#1}{beginQuiz.\curr@quiz}{}%
+ {\DefaultHeightOfWidget}{\eq@protect\A}%
+ {\eq@setButtonProps\eq@Button@driver}%
+ {\BeginQuizButtonDefaults\eq@@BeginQuizButtonActions
+ \every@ButtonField\every@BeginQuizButton}}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\eq@EndQuizButton}
+% The `End Quiz' code for Links
+% \begin{macrocode}
+\def\EndQuizButtonDefaults
+{%
+ \CA{\eqlabel}\F{\FPrint}\BC{1 0 0}
+ \BG{.7529 .7529 .7529}\W{1}\S{B}\H{P}
+}
+\def\eq@@EndQuizButtonActions
+{%
+ \A{\JS
+ {if (!isQuizInitialized("\curr@quiz"))\jsR\jsT
+ eqAppAlert(InitMsg("\bqlabelISO"),3);\jsR
+ else {\jsR\jsT
+ if (\minQuizResp(\thequestionno)&&_ModalNotOn){\jsR\jsT\jsT
+ \curr@quiz.PtValues=(new %
+Array(\pointValuesArray));\jsR\jsT\jsT
+ ProbType=[\ptypeArray];\jsR\jsT\jsT
+\if@inclkey
+ \curr@quiz.CorrAns=(new %
+Array(\corrAnsArray));\jsR\jsT\jsT
+\fi
+ DisplayQuizResults("\curr@quiz",\theeqpointvalue,%
+\thequestionno);\jsR\jsT\jsT
+ \eq@submitURL
+ \postSubmitQuiz
+ resetQuiz("\curr@quiz");\jsR\jsT
+ }\jsR
+ }}%
+ }
+}
+\newcommand\eq@EndQuizButton[1][]
+{%
+ \ifx\eq@CGI\@empty
+ \let\eq@submitURL\@empty
+ \let\eq@insertHiddenFields\@empty
+ \fi
+ \mbox{\push@@Button{#1}{endQuiz.\curr@quiz}{}%
+ {\DefaultHeightOfWidget}{\eq@protect\A}%
+ {\eq@setButtonProps\eq@Button@driver}%
+ {\EndQuizButtonDefaults\eq@@EndQuizButtonActions
+ \every@ButtonField\every@EndQuizButton}}%
+ \makebox[0pt][r]{\eq@insertHiddenFields}\global\let\eq@CGI\@empty
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\databaseName}
+% \begin{macro}{\tableName}
+% \begin{macro}{\eqCGI}
+% \begin{macro}{\eqSubmit}
+% These four commands give general support for submitting quiz data
+% to a web server for storage in a database. Use in my \textsf{eq2db} Package
+% which I have not completed yet. (2014/09/14) Sanitized first argument of \cs{eqSubmit}.
+% \begin{macrocode}
+\newcommand\databaseName[1]{\gdef\db@Name{#1}}\def\db@Name{}
+\newcommand\tableName[1]{\gdef\db@Table{#1}}\def\db@Table{}
+\newcommand\eqCGI{\definePath{\eq@CGI}}\def\eq@CGI{}
+\newcommand\eqSubmit{\hyper@normalise\eqSubmiti}
+\def\eqSubmiti#1{\xdef\eq@CGI{"#1"}\eqSubmitii}
+\def\eqSubmitii#1#2{\databaseName{#1}\tableName{#2}}
+\providecommand{\rtnURL}{\definePath{\thisRtnURL}}
+\let\thisRtnURL\@empty
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% The next two commands are used in the \textsf{eq2db} package. We make the
+% definitions here so that they can be used even if the package is not loaded.
+% In this way, a self-contained quiz can be submitted just by loading the
+% package.
+% \begin{macrocode}
+\newcommand\addHiddenTextField[3][]{}
+\newcommand\populateHiddenField[2]{}
+% \end{macrocode}
+% \subsection{Correcting the Quiz}
+%
+% \begin{macro}{\eqButton}
+% Use this button to correct the quiz. Can be customize with
+% optional arguments.
+% section.
+%\begin{verbatim}
+% #1 = optional attributes of button
+% #2 = title of textfield that contains the score.
+%\end{verbatim}
+% \begin{macrocode}
+\def\eqButtonDefaults
+{%
+ \CA{\eq@local@CA}\AC{}\H{P}\W{1}\S{B}
+ \BC{1 0 0}\BG{.7529 .7529 .7529}
+}
+\def\@@eqButtonActions
+{%
+ \A{\JS{if (isEndQuizPushed("\eqBaseName")){\jsR\jsT%
+ correctQuiz("\eqBaseName",\thequestionno);%
+ \ifusesumrytbls\jsR\jsT\else\jsR\fi
+% \end{macrocode}
+% (06/13/10) Added the quiz summary table, and the function
+% \texttt{correctSumryTbl}. If a summary table is not present
+% the function does nothing.
+% \begin{macrocode}
+ if (typeof correctSumryTbl == "function")\jsR\jsT\jsT
+ correctSumryTbl("\eqBaseName",\thequestionno);\jsR
+ }
+ }}%
+}
+\newcommand\eqButton[2][]
+{%
+% \end{macrocode}
+% If nocorrections is true, then this button does not appear.
+% \begin{macrocode}
+ \ifnocorrections\else
+ \def\eqBaseName{#2}%
+ \mbox{\push@@Button{#1}{correct.#2}{}{\DefaultHeightOfWidget}%
+ {\eq@protect\A}{\eq@setButtonProps\eq@Button@driver}%
+ {\eqButtonDefaults\@@eqButtonActions\every@ButtonField
+ \every@eqButton}}%
+ \fi
+}
+% \end{macrocode}
+% \changes{v6.7n}{2013/09/17}{\cs{CorrButton} is now an alias for \cs{eqButton}}
+% \DescribeMacro{\CorrButton} is a name better suited for the task of this button
+% than the \cs{eqButton} name.
+% \begin{macrocode}
+\def\CorrButton{\eqButton}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\rbMarkup}
+% An optional element for quizzes. Place just after a response box (perhaps, before the
+% \cs{CorrAnsButton}. When the correct button is pressed, this check box will show a
+% green check or a red cross (by default).
+% \begin{macrocode}
+\def\rbMarkup@Defaults
+{%
+ \BC{}\F{\FHidden}\Ff{\FfReadOnly}\textSize{12}
+ \textColor{0 g}\symbolchoice{check}\W{}
+}
+\newcommand\rbMarkup[1][]{%
+ \ifx\grpquestions\eq@One
+ \def\Fld@name{%
+ \oField.\thequestionno.\thegrpquestionno}\else
+ \def\Fld@name{\oField.\thequestionno}\fi
+ \mbox{\check@@Box{#1\V{Yes}\DV{Yes}}%
+ {rbmarkup.\Fld@name}%
+% {rbmarkup.\curr@quiz.\thequestionno}%
+ {\RadioFieldSize}{\RadioFieldSize}{Yes}{}%
+ {\eq@setWidgetProps\eq@RadioCheck@driver}%
+ {\rbMarkup@Defaults\every@CheckBox\every@rbMarkup}}}%
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Measuring Quiz Results}
+%
+% \begin{macro}{\minQuizResp}
+% Define the threshold level. The two permissible values are \texttt{lowTreshold}
+% and \texttt{highThreshold}. These are names of DLJS. New threshold functions
+% can be defined and specified.
+% \begin{macrocode}
+\newcommand\minQuizResp{lowThreshold}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\PTs}
+% Use this macro to assign weights to the quiz questions. Use only within
+% the \texttt{questions} environment, just after an \cmd{\item}. If
+% \cmd{\PTs} does not appear, then a weight of $1$ is assumed.
+%\par\noindent|#1 = number of points for the current question.|
+% The star-form records the points but does not display the points.
+% \begin{macrocode}
+\newcommand\PTs{\@ifstar{\def\eq@star{*}\@PTs}{\def\eq@star{x}\@PTs}}
+\def\@PTs#1{\gdef\eq@PTs{#1}\ifx\eq@PTs\@empty\gdef\eq@PTs{1}\fi
+ \global\let\eqPTs\eq@PTs\global\let\eq@PTs\@empty
+ \if\eq@star*\else\PTs@Hook\fi}
+\def\eq@PTs{0} % initialize this variable
+% \end{macrocode}
+% \begin{macro}{\QT}
+% \cs{QT} is used for entering the ``question type'' for the question (optional).
+% This question type is entered into the ``\texttt{tagged}'' data, and is meant to be
+% used for classifying and in tracking the problem types. Example: \verb+\QT{limits}+.
+% \begin{macrocode}
+\newcommand\QT[1]
+{%
+ \gdef\eq@qT{#1}\ifx\eq@qT\@empty\global\let\eq@qT\eq@na\fi
+% \end{macrocode}
+% \cs{eqQT} saves the value, then we put \cs{eq@qT} back to its default.
+% \begin{macrocode}
+ \global\let\eqQT\eq@qT\global\let\eq@qT\eq@na
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macrocode}
+\def\eq@na{na} % not applicable
+\let\eq@qT\eq@na
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\PTsHook}
+% Used to typeset the number of points.
+% \begin{macrocode}
+\newcommand\PTsHook[1]{\def\PTs@Hook{#1}}
+\let\PTs@Hook\@empty
+\let\eq@PTs\@empty
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\eqGradeScale}
+% This is an array of letter grades and grade ranges. This macro is use as the argument
+% of the JS function \texttt{GetGrade}.
+% \begin{macrocode}
+\newcommand\eqGradeScale{%
+ "A",[90, 100],"B",[80,90],"C",[70,80],"D",[60,70],"F",[0,60]}
+\let\eqGradeScaleLoc\@empty
+\newcommand{\resetGradeScaleLoc}{\global\let\eqGradeScaleLoc\@empty}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\DefaultHeightOfWidget}
+% \begin{macro}{\RBW}
+% \begin{macro}{\SFW}
+% \begin{macro}{\GFW}
+% \begin{macro}{\PtW}
+% \begin{macro}{\PcW}
+% \cmd{\DefaultHeightOfWidget} is the default height of all form
+% fields (except radio fields and checkboxes). \cmd{\RBW} is the
+% default width of the \cmd{\RespBox}; and \cmd{\SFW} is the
+% default width of the \cmd{\ScoreField}. \cs{GFW} is the default
+% width of a grade field button; \cs{PtFW} is the default width
+% of a points field button; and \cs{PcFW} is the default width
+% of the percent field button.
+% \begin{macrocode}
+\def\tallywidth#1{\def\TBW{#1}}
+\def\TBW{15bp}
+\def\DefaultHeightOfWidget{11bp}
+\def\RadioFieldSize{11bp}
+\def\RBW{2in} % Response Box width (math,txt, txtpc, answer field)
+\def\SFW{1.5in} % Score Field Width
+\def\GFW{20pt} % Grade Field Width
+\def\PtFW{1.5in} % Point Field Width
+\def\PcFW{1.5in} % Percent Field Width
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\ScoreField}
+% This text field will receive the scores
+% of a quiz. The command \cmd{\eqScore} was defined
+% in Section~\ref{ss:ldm}. This command takes an optional
+% argument and a required argument.
+%\begin{verbatim}
+%#1 = one or more commands that will customize the design of the
+% field. See the manual for examples.
+%#2 = Base name of the quiz
+%\end{verbatim}
+% \begin{macrocode}
+\def\ScoreFieldDefaults
+{%
+ \Ff{\FfReadOnly}\BC{1 0 0}\BG{}\S{S}
+ \DV{\eqScore}\V{\eqScore}\W{1}
+}
+\newcommand\ScoreField[2][]
+{%
+ \mbox{\text@@Field{#1}{ScoreField.#2}{\SFW}%
+ {\DefaultHeightOfWidget}{}{\eq@setWidgetProps\eq@TextField}%
+ {\ScoreFieldDefaults\every@eqTextField\every@ScoreField}}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\GradeField}
+% This command creates a text field that shows the letter grade of the user's
+% effort on the current quiz.
+% \begin{macrocode}
+\def\GradeFieldDefaults
+{%
+ \textColor{0 0 1 rg}\BC{1 0 0}\BG{1 1 1}\S{S}
+ \Ff{\FfReadOnly}\Q{1}\W{1}
+}
+\newcommand\GradeField[2][]
+{%
+ \mbox{\text@@Field{#1}{GradeField.#2}{\GFW}%
+ {\DefaultHeightOfWidget}{}{\eq@setWidgetProps\eq@TextField}%
+ {\GradeFieldDefaults\every@eqTextField\every@GradeField}}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\AnswerField}
+% This command creates a text field to receive the answers to the
+% fill-in questions.
+% \begin{macro}{\resetAnsFieldOnClose}
+% When expanded, the \cs{AnswerField}s will be reset whenever the user changes pages.
+% \begin{macro}{\noResetAnsFieldOnClose}
+% When expanded, the \cs{AnswerField}s will not be reset, this is the default behavior.
+% \begin{macrocode}
+\def\AnswerFieldDefaults
+{%
+ \BC{0 0 0}\S{S}\Ff{\FfReadOnly}\W{1}%
+ \presets{\eq@resetAnsFieldOnClose}%
+}
+\let\eq@resetAnsFieldOnClose\@empty
+\newcommand{\noResetAnsFieldOnClose}{%
+ \global\let\eq@resetAnsFieldOnClose\@empty}
+\newcommand{\resetAnsFieldOnClose}{%
+ \gdef\eq@resetAnsFieldOnClose{%
+ \AApageclose{this.resetForm(["\Fld@name"]);}}}
+\newcommand\AnswerField[2][]
+{%
+ \mbox{\text@@Field{#1}{Ans.#2}{\RBW}{\DefaultHeightOfWidget}%
+ {}{\eq@setWidgetProps\eq@TextField}%
+ {\AnswerFieldDefaults\every@eqTextField\every@AnswerField}}%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\autoAnswerField}
+% An attempt at putting \cs{AnswerField} in the left running footer on each page where there
+% is a response box.
+% \begin{macrocode}
+%
+\newcommand\autoAnswerField{%
+ \@ifundefined{lfooter}{\def\eq@next{\eq@autoAnswerFieldgobble}%
+ \PackageError{exerquiz}{The \string\autoAnswerField\space
+ command\MessageBreak requires the web package}{Use web package}
+ }{%
+ \PackageInfo{exerquiz}{%
+ For this auto answer field feature to run\MessageBreak
+ the webheadings pagestyle of the web package\MessageBreak
+ is required}\def\eq@next{\eq@autoAnswerField}%
+ \ifx\web@lfoot\@empty\else
+ \PackageWarning{exerquiz}{The left running footer already in
+ use\MessageBreak Will overwrite what is there now.
+ Better fix it.}\fi
+ }%
+ \eq@next
+}
+\newcommand\eq@autoAnswerFieldgobble[1][]{\relax}
+\newcommand\autoAnsFldRaiseBox[1]{\def\ef@aAFRB{#1}}
+\autoAnsFldRaiseBox{0pt}
+\let\autoAFOpts\@empty
+\newcommand\eq@autoAnswerField[1][]{\gdef\autoAFOpts{#1}%
+ \def\eq@insertAnswerField{\AnswerField[#1]{\currQuiz}}%
+ \eq@@autoAnswerField
+}
+\newcommand\eq@@autoAnswerField{\lfooter{\ifIsRespBox
+ \raisebox{\ef@aAFRB}{\eq@insertAnswerField}%
+ \global\IsRespBoxfalse\fi}%
+}
+\newcommand\manualAnswerField[1][\autoAFOpts]{%
+ \expandafter\AnswerField\expandafter[#1]{\currQuiz}}
+% \end{macrocode}
+% \end{macro}
+% Now let's define some additional text fields for the quiz environment.
+% \begin{macro}{\PointsField}
+% This command creates a text field which displays the number of points in the
+% quiz scored by the user of the \texttt{quiz}.
+% \begin{macrocode}
+\def\PointsFieldDefaults
+{%
+ \rawPDF{}\BC{1 0 0}\BG{}\W{1}\S{S}\Ff{\FfReadOnly}
+ }
+\newcommand\PointsField[2][]
+{%
+ \mbox{\text@@Field{#1}{PointsField.#2}{\PtFW}%
+ {\DefaultHeightOfWidget}{}{\eq@setWidgetProps\eq@TextField}%
+ {\PointsFieldDefaults\every@eqTextField\every@PointsField}}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\PercentField}
+% This command creates a text field which displays user's score in percent
+% form.
+% \begin{macrocode}
+\def\PercentFieldDefaults
+{%
+ \rawPDF{}\BC{1 0 0}\BG{}\W{1}\S{S}\Ff{\FfReadOnly}%
+}
+\newcommand\PercentField[2][]
+{%
+ \mbox{\text@@Field{#1}{PercentField.#2}{\PcFW}%
+ {\DefaultHeightOfWidget}{}{\eq@setWidgetProps\eq@TextField}%
+ {\PercentFieldDefaults\every@eqTextField\every@PercentField}}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\RestoreScoreField}
+% Reset the score field to its default, in case some author
+% changed things.
+% \begin{macrocode}
+\newcommand\RestoreScoreField
+{%
+ \global\let\eqScore\eq@Score
+ \global\let\eqOutOf\eq@OutOf
+}
+% \end{macrocode}
+% \end{macro}
+% \subsection{Floating and Docking a Quiz}
+%
+% \begin{macro}{\DeclareQuiz}
+% A convenience macro for setting the name of the quiz. This command defines the
+% text macro \cs{currQuiz} which contains the quiz name. Can be used in conjunction
+% with \cs{floatQuiz} and \cs{startQuizHere}.
+% \changes{v6.05c}{2006/05/19}
+% {
+% Added a convenience macro for setting the name of the quiz. This command defines the
+% text macro \cs{currQuiz} which contains the quiz name. Can be used in conjunction
+% with \cs{floatQuiz} and \cs{startQuizHere}.
+% }
+% \begin{macrocode}
+\def\DeclareQuiz#1{%
+ \edef\thisQuiz{#1}%
+ \edef\curr@quiz{#1}%
+ \edef\currQuiz{#1}%
+ \edef\curr@quiz{#1}%
+}
+\let\Quiz\DeclareQuiz
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\floatQuiz}
+% \begin{macro}{\dockQuiz}
+% Use \cs{floatQuiz} to create commands \cs{startQuizHere} and \cs{endQuizHere}. These commands expand to the
+% `Begin Quiz' button or link (`End Quiz' button or link). But these commands can be placed anywhere before the
+% \texttt{quiz} environment (after the \texttt{quiz} environment). Use \cs{dockQuiz} to return to the default behavior of the
+% \texttt{quiz} environment.
+% \changes{v6.05c}{2006/05/19}
+% {
+% Added \cs{floatQuiz}, \cs{dockQuiz} and \cs{startQuizHere} to start a quiz in an
+% arbitrary place prior to the beginning of the quiz.
+% }
+%\par\medskip\noindent Usage:
+%\begin{verbatim}
+%\Quiz{myQuiz}
+%\floatQuiz
+%........
+%\begin{center}
+%\startQuizHere
+%\end{center}
+%....
+%\begin{quiz*}{\thisQuiz}
+%....
+%\end{quiz*}
+%....
+%\endQuizHere
+% ...
+%\docQuiz
+%\begin{quiz}{anotherQuiz}
+%....
+%\end{verbatim}
+% \begin{macrocode}
+\def\aeb@noindgobble{\noindent\@gobbletwo}
+\let\startQuizHere\relax
+\let\endQuizHere\relax
+\let\dockQuiz\relax
+\newcommand\floatQuiz{%
+ \global\let\eq@beginQuiz@saved\eq@beginQuiz
+ \global\let\eq@endQuiz@saved\eq@endQuiz
+ \global\let\startQuizHere\eq@beginQuiz
+ \global\let\endQuizHere\eq@endQuiz
+ \global\let\eq@beginQuiz\aeb@noindgobble
+ \global\let\eq@endQuiz\@empty
+ \global\let\dockQuiz\eq@dockQuiz
+}
+\newcommand\eq@dockQuiz{%
+ \global\let\eq@beginQuiz\eq@beginQuiz@saved
+ \global\let\eq@endQuiz\eq@endQuiz@saved
+ \global\let\startQuizHere\relax
+ \global\let\endQuizHere\relax
+ \global\let\eq@beginQuiz@saved\relax
+ \global\let\eq@endQuiz@saved
+ \global\let\dockQuiz\relax
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{\texorpdfstring{\protect\cs{titleQuiz} and \protect\cs{fancyQuizHeaders}}
+% {\textbackslash{titleQuiz} and \textbackslash{fancyQuizHeaders}}}
+%
+% \begin{macro}{\fancyQuizHeaders}
+% \begin{macro}{\restoreDefaultQuizHeaders}
+% \begin{macro}{\dfltFncyQHdrsFmt}
+% \begin{macro}{\dclrFncyQzHdrsFmt}
+% \begin{macro}{\dclrFncySqHdrsFmt}
+% The commands for \cs{fancyQuizHeaders}: \cs{restoreDefaultQuizHeaders} restores
+% solution headers to the old style; \cs{eq@fancyQuizHeadersfmt} determines the
+% formatting for quizzes; and \cs{eq@fancyShrtQuizHeadersfmt} does the same for
+% short quizzes.
+% \begin{macrocode}
+\def\fancyQuizHeaders{%
+ \global\let\eq@sqsllabel@fancy@save\eq@sqsllabel
+ \gdef\eq@sqsllabel{\eq@fancyQuizHeaders}}
+\def\eq@fancyQuizHeaders{%
+ \if\eqQuizType\isQZ\expandafter\eq@fancyQuizHeadersfmt\else
+ \expandafter\eq@fancyShrtQuizHeadersfmt\fi
+}
+\let\eq@sqsllabel@fancy@save\@empty
+% \end{macrocode}
+% We set \cs{eq@sqsllabel} back to its value when \cs{fancyQuizHeaders} was last
+% invoked.
+% \begin{macrocode}
+\def\restoreDefaultQuizHeaders{%
+ \global\let\eq@sqsllabel\eq@sqsllabel@fancy@save}
+% \end{macrocode}
+% Here is the definition of the format for quizzes. This can be redefined, a few
+% suggestions are made in the documentation. \DescribeMacro{\dfltFncyQHdrsFmt}
+% \cmd{\dfltFncyQHdrsFmt} is the common format for both \texttt{quiz} and \texttt{shortquiz}.
+% \begin{macrocode}
+\newcommand\fncyQHdrsColor{blue}
+% \end{macrocode}
+% (2016/12/21) Localized some text strings in \cs{dfltFncyHdrsFmt}.
+% \changes{v7.8c}{2016/12/21}{Localized some text strings in \string\cs{dfltFncyHdrsFmt}}
+% \begin{macrocode}
+\newcommand\FncyHdrsFmtNoTitleQuiz{Solution to Quiz:}
+\newcommand\FncyHdrsFmtQuestion{Question}
+\newcommand\dfltFncyQHdrsFmt{%
+ \protect\bfseries\protect\color{\fncyQHdrsColor}%
+ \ifx\aebTitleQuiz\@empty
+ \ifnum\@eqquestiondepth>0\relax\FncyHdrsFmtNoTitleQuiz\fi
+ \else\aebTitleQuiz:\ifnum\@eqquestiondepth=0\else\protect\ %
+ \FncyHdrsFmtQuestion\fi\fi\ifcase\@eqquestiondepth
+ \ifx\aebTitleQuiz\@empty\FncyHdrsFmtNoTitleQuiz\fi
+ \or\space\arabic{eqquestionnoi}.%
+ \or\space\arabic{eqquestionnoi}(\alph{eqquestionnoii})%
+ \or\space\arabic{eqquestionnoi}(\alph{eqquestionnoii})%
+ (\roman{eqquestionnoiii})\fi
+}
+% \end{macrocode}
+% \DescribeMacro{\dclrFncyQzHdrsFmt}\cmd{\dclrFncyQzHdrsFmt} is used to declare the formatting for quizzes.
+% \begin{macrocode}
+\newcommand\dclrFncyQzHdrsFmt[1]{%
+ \def\eq@fancyQuizHeadersfmt{{#1}}%
+}
+\dclrFncyQzHdrsFmt{\dfltFncyQHdrsFmt}
+% \end{macrocode}
+% \DescribeMacro{\dclrFncySqHdrsFmt}\cmd{\dclrFncySqHdrsFmt} is for short quizzes, we make the formatting the same as that for quizzes.
+% re-defined.
+% \begin{macrocode}
+\newcommand\dclrFncySqHdrsFmt[1]{%
+ \def\eq@fancyShrtQuizHeadersfmt{{#1}}%
+}
+\dclrFncySqHdrsFmt{\dfltFncyQHdrsFmt}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\titleQuiz}
+% \begin{macro}{\titleQuizfmt}
+% \begin{macro}{\ifQuizType}
+% \begin{macro}{\ifstaroption}
+% \begin{macro}{\eq@ifstaroption}
+% The \cs{titleQuiz} command adds a title to the quiz or short quiz, using
+% a format, as defined in \cs{titleQuizfmt}. The switches \cs{ifQuizType}
+% and \cs{eq@ifstaroption} allows you to distinguish between quizzes and
+% short quizzes, a \texttt{*} option or non-\texttt{*} option.
+%
+%\cs{titleQuiz} takes two parameters: an optional \texttt{*} and the
+%text for the title of the quiz. When \texttt{*} is used---for short
+%quizzes only---the title of the quiz is used for the definition of
+%\cs{sqlabel}. Note that \cs{makeatletter} is invoked before the
+% parameters are read.
+% \changes{v6.7o}{2013/11/25}{Changed \cs{aeb@@titleQuzi} to \cs{aebTitleQuiz}}
+% \changes{v6.7p}{2013/12/11}{Added optional parameter to \cs{titleQuiz}
+% to execute a command, such as incrementing a counter.}
+% \begin{macrocode}
+\let\tqhspace\space
+\newcommand\titleQuiz[1][]{#1\@titleQuizi}
+\def\@titleQuizi{\makeatletter
+ \@ifstar{\def\eq@tq@star{*}\eq@titleQuiz}%
+{\def\eq@tq@star{x}\eq@titleQuiz}}
+\def\eq@titleQuiz#1{%
+ \gdef\aebTitleQuiz{#1}\def\@currentlabelname{#1}%
+ \gdef\aeb@@titleQuiz{#1}%
+ \gdef\aebtitleQuiz{\mbox{\titleQuizfmt{#1}}\tqhspace}%
+\makeatother}
+%</package>
+%<package|eqexam>\let\aebtitleQuiz\@empty
+%<package|eqexam>\let\aebTitleQuiz\@empty
+%<*package>
+% \end{macrocode}
+% The command to format the \cs{titleQuiz}.
+% \begin{macrocode}
+\newcommand\titleQuizfmt{\bfseries}
+% \end{macrocode}
+% A user interface to distinguish between quizzes and short quizzes.
+% \begin{macrocode}
+\def\ifQuizType#1#2{\if\eqQuizType\isQZ\def\qt@next{#1}%
+ \else\def\qt@next{#2}\fi\qt@next}
+% \end{macrocode}
+% Used to distinguish between whether \cs{titleQuiz} was invoked with
+% the \texttt{*} option. In the short quiz environment, this command
+% is let equal to \cs{ifstaroption}, which is the user-access to this command.
+% Outside the \texttt{shortquiz} environment, \cs{ifstaroption} is \cs{@gobbletwo}
+% \begin{macrocode}
+\def\eq@ifstaroption#1#2{\if\eq@tq@star*\def\sq@next{#1}%
+ \else\def\sq@next{#2}\fi\sq@next}
+\let\eq@tq@star\relax
+\def\ifstaroption{\PackageWarning{exerquiz}
+ {\protect\ifstaroption\space is only defined within the\MessageBreak
+ shortquiz environment. Gobbling up its two\MessageBreak
+ arguments, sorry. This occurred}%
+ \@gobbletwo
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Showing Partial Credit Markup}
+%
+% \begin{macro}{\aeb@creditmarkup}
+% \begin{macro}{\aeb@creditmarkupfmt}
+% \begin{macro}{\ptsLabel}
+% \begin{macro}{\ptLabel}
+% \begin{macro}{\multipartquestion}
+% \begin{macro}{\hideCreditMarkup}
+% \begin{macro}{\showCreditMarkup}
+% \cs{showCreditMarkup} will show points assigned to individual questions in a quiz.
+% \cs{showCreditMarkup} turns off this feature. Should be placed before the next quiz,
+% not within a quiz. The command \cs{multipartquestion} is placed just prior to a question
+% that introduces a problem with sub-parts. See the demo file \texttt{pc\_test.tex} for examples.
+% The other two commands \cs{aeb@creditmarkup} and \cs{aeb@creditmarkupfmt} can be redefined
+% to suite your tastes.
+%
+%\changes{v6.2c}{2007/11/14}
+%{
+% Added the commands \cs{showCreditMarkup} and \cs{hideCreditMarkup} to show partial credit markup
+%}
+%\changes{v6.3k}{2008/01/09}
+%{
+% Added \cs{ptsLabel} and \cs{ptLabel} to localize the markup in the margin of a quiz
+%}
+% \begin{macrocode}
+\newcounter{qMarkCnt}
+\def\multipartquestion{\global\let\aeb@multipart\eq@One}
+% \end{macrocode}
+% The labeling for the partial credit markup. These two commands are
+% are defined (identically) in the \textsf{eqexam} package, hence the
+% use of \cs{providecommand}.
+% \begin{macrocode}
+\providecommand{\ptsLabel}[1]{\def\eqptsLabel{#1}}\ptsLabel{pts}
+\providecommand{\ptLabel}[1]{\def\eqptLabel{#1}}\ptLabel{pt}
+\let\aeb@multipart\eq@Zero
+% \end{macrocode}
+% \DescribeMacro{\pcMarkupColor} is the named color in RGB color space to
+% use for the color of the partial credit markup. (2013/09/14).
+% \begin{macrocode}
+\newcommand\pcMarkupColor{red}
+% \end{macrocode}
+% \cs{aeb@creditmarkup} creates a small text fields that holds the partial
+% credit markup. The command may be redefined, perhaps to changes the dimensions
+% of the rectangular bounding box, set at \texttt{12bp} by \texttt{8bp}.
+%
+% We supply basic controls for the text field, width (\DescribeMacro{\markupWidth}\cmd\markupWidth),
+% height (\DescribeMacro{\markupHeight}\cmd{\markupHeight}), and text size
+% (\DescribeMacro{\markupTextSize}\cmd{\markupTextSize})
+% \begin{macrocode}
+\def\markupWidth{12bp}\def\markupHeight{8bp}\def\markupTextSize{0}
+% \end{macrocode}
+% \cmd\aeb@creditmarkup creates the text field that appears in the margins.
+% \begin{macrocode}
+\newcommand{\aeb@creditmarkup}{%
+ \textField[\Ff\FfReadOnly\BC{}\F\FHidden
+ \textColor{\pcMarkupColor}\textSize{\markupTextSize}\autoCenter{n}%
+ \DV{0 \eqptsLabel}\V{0 \eqptsLabel}]%
+ {qMark.\currQuiz.\thequestionno.\arabic{qMarkCnt}}%
+ {\markupWidth}{\markupHeight}%
+}
+% \end{macrocode}
+% The \cs{showCreditMarkup} command defines \cs{qMark} and \cs{qMark@Hook}.
+% \begin{macrocode}
+\def\showCreditMarkup{%
+% \end{macrocode}
+% \cs{qMark} makes the decision whether to place a mark or not. If
+% the command \cs{multipartquestion} has been expanded, \cs{aeb@multipart} is one, otherwise
+% it is zero. If zero we do place the markup, otherwise, no.
+% \begin{macrocode}
+ \def\qMark{\if\aeb@multipart\eq@Zero\aeb@creditmarkup
+ \stepcounter{qMarkCnt}\else\global\let\aeb@multipart\eq@Zero\fi}%
+% \end{macrocode}
+% \cs{qMark@Hook} is a hook that is normally \cs{@empty}. The hook is strategically
+% placed at the beginning of each question \cs{item}. Here we define it to be
+% \cs{aeb@creditmarkupfmt}.
+% \begin{macrocode}
+ \def\qMark@Hook{\aeb@creditmarkupfmt}%
+}
+% \end{macrocode}
+% Turn off partial credit markup by putting \cs{qMark@Hook} back to its default.
+% \begin{macrocode}
+\def\hideCreditMarkup{\global\let\qMark@Hook\@empty}
+% \end{macrocode}
+% A simple command to place the \cs{qMark} in a \cs{makebox[0pt][r]}, with
+% a little adjustment to please the eye.
+% \begin{macrocode}
+\newcommand{\aeb@creditmarkupfmt}{\makebox[0pt][r]{\qMark\hspace{-2bp}}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%\subsection{Filtering solutions to quizzes}
+% The \cs{eqQt} and \cs{eqSQt} commands have one argument designed to be used to filter
+% solutions to quizzes. The demo document is \texttt{filter\_quizzes.tex},
+% but basically, we can include the solutions several times, once for each set filtered set.
+% \begin{macrocode}
+\long\def\gobbleToEndQt#1\endeqQt{\ifeqforpaper\expandafter\@gobble\fi}
+\long\def\gobbleToEndSQt#1\endeqSQt{%
+ \ifeqforpaper\expandafter\@gobble\fi}
+% \end{macrocode}
+% The \DescribeMacro{\inclQtFilter}\cmd{\inclQtFilter} operates on the quizzes. If the argument \texttt{\#1}
+% matches the optional argument of \cs{filterFor}, we include, otherwise, we gobble
+% up everything to the end of the quiz, including the token that follows
+% \cmd{\gobbleToEndQt}.
+% \begin{macrocode}
+\newcommand\inclQtFilter[1]{\def\eqarg{#1}\ifx\eqarg\eqFilterArg
+ \else\expandafter\gobbleToEndQt\fi}
+% \end{macrocode}
+% The \DescribeMacro{\exclQt}\cmd{\exclQt} command exclude all quiz solutions.
+% \begin{macrocode}
+\newcommand{\exclQt}[1]{\gobbleToEndQt}
+% \end{macrocode}
+% The \DescribeMacro{\useQtFilter}\cmd{\useQtFilter} command \cs{let}s \cs{eqQt} to
+% \cs{inclQtFilter}, and it also \cs{let}s \cs{eqSQt} to
+% \cs{exclSQt}.
+% \begin{macrocode}
+\newcommand{\useQtFilter}{%
+ \let\eqQt\inclQtFilter\let\eqSQt\exclSQt
+}
+% \end{macrocode}
+% Now we repeat the same sequence of construct for short quizzes.
+% The command \DescribeMacro{\inclSQtFilter}\cmd{\inclSQtFilter} includes a short quiz
+% solution if it meets the filter criteria.
+% \begin{macrocode}
+\newcommand\inclSQtFilter[1]{\def\eqarg{#1}\ifx\eqarg\eqFilterArg
+ \else\expandafter\gobbleToEndSQt\fi}
+% \end{macrocode}
+% The \DescribeMacro{\exclSQt}\cmd{\exclSQt} command excludes all short quiz solutions.
+% \begin{macrocode}
+\newcommand{\exclSQt}[1]{\gobbleToEndSQt}
+% \end{macrocode}
+% The \DescribeMacro{\useSQtFilter}\cmd{\useSQtFilter} \cs{let}s \cs{eqSQt} to
+% \cs{inclSQtFilter}.
+% \begin{macrocode}
+\newcommand{\useSQtFilter}{\let\eqSQt\inclSQtFilter\let\eqQt\exclQt}
+% \end{macrocode}
+%
+%\section{Bookmarking the Quizzes}
+%
+% \begin{macro}{\sqbookmarkfmt}
+% \begin{macro}{\qzbookmarkfmt}
+% \begin{macro}{\quizpdfbookmark}
+% Support for bookmarking the quizzes and shortquizzes. Unlike the bookmarking
+% of the exercises, there is no support for bookmarking individual questions
+% within a quiz.
+%\changes{v6.2a}{2007/11/10}
+%{
+% Added \cs{quizpdfbookmark} to bookmark quizzes.
+%}
+% \begin{macrocode}
+\newcommand{\sqbookmarkfmt}{Short Quiz \@shortquizCnt.\space}
+\newcommand{\qzbookmarkfmt}{Quiz \@quizCnt.\space}
+\newcommand{\quizpdfbookmark}[1]{\relax\def\argi{#1}%
+ \if\eqQuizType\isSQZ\edef\aeb@bmmrkdest{sqbm.\@shortquizCnt}%
+ \def\aeb@thisbkmrkfmt{\sqbookmarkfmt}\else
+ \edef\aeb@bmmrkdest{qzbm.\@quizCnt}%
+ \def\aeb@thisbkmrkfmt{\qzbookmarkfmt}\fi
+ \def\quizpdfbookmarktitle{#1}%
+ \def\eqex@next{\belowpdfbookmark{\aeb@thisbkmrkfmt#1}%
+ {\aeb@bmmrkdest}}%
+ \ifx\aebTitleQuiz\@empty\else\ifx\argi\@empty
+ \def\quizpdfbookmarktitle{\aebTitleQuiz}%
+ \def\eqex@next{\belowpdfbookmark{\aebTitleQuiz}%
+ {\aeb@bmmrkdest}}\fi\fi
+ \eqex@next\ignorespaces
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \section{Multiple Choice Alternatives}
+% \subsection{For \texttt{shortquiz}}
+% \subsubsection{The \texttt{answers} Environment}
+% \begin{macro}{answers}
+% The alternatives of a multiple choice question are enclosed in
+% the \texttt{answers} environment.
+% This environment takes an optional argument, and one
+% required argument. The required parameter is the number of
+% columns to construct in the underlying \texttt{tabular}
+% environment; the presence of the optional argument means the author
+% wants to include the solution to this quiz question. The value of
+% the optional parameter is the named destination of the solution.
+% The optional parameter for the named destination can also be a
+% `\texttt*', in which case a name of \texttt{\string\curr@quiz.\string\thequestionno}
+% is assigned.
+% \begin{macrocode}
+%</package>
+%<*package|eqexam>
+\def\pushEnvir{\xdef\eq@currenvir{\@currenvir}\endgroup}
+\def\popEnvir{\begingroup\@endpefalse
+ \edef\@currenvir{\eq@currenvir}%
+ \edef\@currenvline{\on@line}%
+}
+\def\answers@sq{\parindent0pt
+% \end{macrocode}
+% The \texttt{answers} environment needs to go into horizontal mode for the
+% \cs{linelength} to be correct when using \cs{leadinitem}.
+% \begin{macrocode}
+ \ifx\solutionparshape\@empty\else
+% ?? remove the \par, why is it there to begin with?
+ \pushEnvir\par\noindent\expandafter\popEnvir\fi
+% \pushEnvir\par\noindent\expandafter\popEnvir\fi
+ \stepcounter{questionno}%
+ \if\sqstar*\relax
+ \if\aeb@FLOverride\eq@l
+ \let\@Ans\Ans@sq@l\else
+ \let\@Ans\Ans@sq@f\fi
+ \else
+ \if\aeb@FLOverride\eq@f
+ \let\@Ans\Ans@sq@f\else
+ \let\@Ans\Ans@sq@l\fi
+ \fi
+ \def\aeb@answerType{r}\@ifnextchar[{\answers@@sq}%
+ {\@ifstar{\answers@@sq[\curr@quiz.\thequestionno]}{\answers@@sq[]}}}
+\def\manswers@sq{\parindent0pt
+% \end{macrocode}
+% \cs{ifuserectforms} is defined in \textsf{eqexam},
+% \begin{macrocode}
+ \@ifundefined{ifuserectforms}{}
+ {\if\aeb@FLOverride\eq@f\ifuserectforms
+ \useRectForMC\else\useCircForMC\fi\fi}%
+ \ifx\solutionparshape\@empty\else
+ \pushEnvir\par\noindent\expandafter\popEnvir\fi
+ \stepcounter{questionno}%
+ \if\sqstar*\relax
+ \if\aeb@FLOverride\eq@l
+ \let\@Ans\Ans@ck@sq@l\else
+ \let\@Ans\Ans@ck@sq@f\fi
+% \if\aeb@FLOverride l\let\@Ans\Ans@ck@sq@f\fi
+ \else
+ \if\aeb@FLOverride\eq@f
+ \let\@Ans\Ans@ck@sq@f\else
+ \let\@Ans\Ans@ck@sq@l\fi
+ \fi
+ \def\aeb@answerType{c}\@ifnextchar[{\answers@@sq}%
+ {\@ifstar{\answers@@sq[\curr@quiz.\thequestionno]}{\answers@@sq[]}}}
+% \end{macrocode}
+% \end{macro}
+%\begin{verbatim}
+% #1 = named destination to be associated with solution
+% #2 = number of columns in the tabular environment
+%\end{verbatim}
+% If the number of columns specified, then we use a list environment.
+% \begin{macrocode}
+\let\sq@hwdest\@empty % hard-wired destination
+\def\answers@@sq[#1]#2{%
+ \xdef\aeb@numCols{#2}%
+ \ifx\sq@hwdest\@empty
+ \xdef\@qzsolndest{#1}\else
+ \gdef\@qzsolndest{\sq@hwdest}\fi
+ \if\aeb@numCols1\gdef\eq@listType{1}\expandafter\answers@sq@list
+ \else
+ \gdef\eq@listType{0}\expandafter\answers@@sq@tabular
+ \fi{\aeb@numCols}%
+}
+% \end{macrocode}
+% \begin{macro}{\setMClabelsep}
+% \changes{v6.05e}{2006/18/06 v6.05e}
+% {
+% Added control over the separation between the MC label and subsequent text:
+% \cs{setMClabelsep} and \cs{resetMClabelsep}.
+% }
+% \begin{macro}{\resetMClabelsep}
+% \begin{macro}{\eq@hspanner}
+% \begin{macro}{\eq@hspanner@default}
+% Some convenience macros for computing the width of labels. The command \cs{setMClabelsep}
+% can be used to set the separation between the MC label and the beginning of text. The
+% argument for this command is anything that takes up horizontal space. The command sets
+% the value of \cs{eq@hspanner}. The default value % of the separation is given by \cs{eq@hspanner@default}.
+% The default value can be restored by executing \cs{resetMClabelsep}.
+% \begin{macrocode}
+\def\setMClabelsepDefault#1{\def\eq@hspanner@default{#1}}
+\def\setMClabelsep#1{\def\eq@hspanner{#1}}
+\setMClabelsep{\ }\setMClabelsepDefault{\ }
+\def\resetMClabelsep{\expandafter\setMClabelsep\expandafter
+ {\eq@hspanner@default}}
+\def\eq@lw@l{\eq@l@l\eq@hspanner}
+% \end{macrocode}
+% For the link-style MC question, the default width, \cs{eq@l@l}, of the label is the normalsize width of
+% `(d)'. For a form checkbox or radiobutton bux, the default width, cs{eq@lw@f}, is \cs{RadioFieldSize},
+% normally defined as \texttt{11bp}.
+% \begin{macrocode}
+\def\eq@l@l{\normalsize\normalfont(d)}
+\def\eq@lw@f{\kern\RadioFieldSize\eq@hspanner}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% This macro will pick up the arguments of the \cs{Ans} command.
+%\begin{verbatim}
+% [#1] = points to be awarded if problem is false (partial credit)
+% #2 = 1 (for true) or 0 (for false)
+%\end{verbatim}
+% In a list, each time the \cs{item} is executed, \cs{@Ans}
+% is executed as the default label.
+%
+% These parameters are saved in the commands \cs{eq@pPTs} and
+% \cs{Ans@choice}.
+% \begin{macrocode}
+\@ifundefined{ifwithsoldoc}{\newif\ifwithsoldoc\withsoldocfalse}{}
+\let\eq@ansChoiceArray\@empty
+\def\eq@recordAnsChoice{%
+ \ifx\eq@ansChoiceArray\@empty
+ \edef\tmp@exp{\noexpand\g@addto@macro
+ \noexpand\eq@ansChoiceArray{"\alph{quizno}"}}\else
+ \edef\tmp@exp{\noexpand\g@addto@macro
+ \noexpand\eq@ansChoiceArray{,"\alph{quizno}"}}\fi
+ \tmp@exp
+}
+\newcommand\Ans@list[2][0]{\gdef\eq@pPTs{#1}%
+ \xdef\Ans@choice{#2}\item\relax\noindent\if\eq@listType\eq@One
+ \addtocounter{quizno}{-1}\@ifundefined{ifwithsoldoc}
+ {\refstepcounter{quizno}}{\ifwithsoldoc\stepcounter{quizno}\else
+ \refstepcounter{quizno}\fi}\fi
+ \ignorespaces}
+% \end{macrocode}
+% Answers environment for a list environment.
+% \begin{macrocode}
+\newenvironment{answers@sq@list}[1]
+{%
+ \ifx\aeb@answerType\eq@r
+ \let\endanswers\endanswers@sq@list\else
+ \let\endmanswers\endanswers@sq@list\fi
+ \list{\strut\@Ans}{%
+ \if\sqstar*\relax
+ \settowidth{\labelwidth}{\eq@lw@f}\else
+ \settowidth{\labelwidth}{\eq@lw@l}\fi
+% \end{macrocode}
+% (2013/05/17) Incorporated \cs{aboveanswersSkip} into \cs{topsep}
+% \begin{macrocode}
+ \setlength{\topsep}{-\parskip+\aboveanswersSkip}%
+ \setlength{\parsep}{0pt}\setlength{\itemindent}{0pt}%
+% \end{macrocode}
+% (2014/04/05) Added a specification for \cs{itemsep} so that the
+% \cs{rowsep} acts identically for tabular and list.
+% \begin{macrocode}
+ \setlength{\itemsep}{0pt}\setlength{\partopsep}{0pt}%
+ \setlength{\listparindent}{\parindent}%
+% \end{macrocode}
+% (2013/05/17) When inside the parts environment in tabular-mode,
+% we need to add in \cs{eqemargin}. For \textsf{exerquiz} defaults
+% to 0pt; when \textsf{eqexam} is used, it has a nonzero value.
+% \begin{macrocode}
+ \ifnum\exerwparts@cols>1\relax
+ \ifx\itsExerParts\eq@YES % dps17
+ \setlength{\leftmargin}{\labelwidth}\else
+ \setlength{\leftmargin}{\labelwidth+\eqemargin}\fi
+ \else
+% \end{macrocode}
+% (2013/05/17) Some adjustments depending on whether \cs{solutionparshape}
+% is empty or not. If empty, \cs{leftmargin} is its usual value; otherwise
+% we add in \cs{eqemargin} (0pt in \textsf{exerquiz}, nonzero in \textsf{eqexam}).
+% \begin{macrocode}
+ \ifx\solutionparshape\@empty
+ \setlength{\leftmargin}{\labelwidth}\else
+ \setlength{\leftmargin}{\labelwidth+\eqemargin}\fi\fi
+% \end{macrocode}
+% (2013/10/10) I'm changing the \cs{labelsep}, one definition for \texttt{eqexam}
+% another for \texttt{exerquiz}.
+% to the following.
+% \begin{macrocode}
+%</package|eqexam>
+%<package> \setlength{\labelsep}{0pt}%
+%<package>% \settowidth{\labelsep}{\eq@hspanner}%
+%<eqexam> \setlength{\labelsep}{0pt}%
+%<*package|eqexam>
+ \def\Ans{\Ans@list}%
+ }%
+}%
+{\endlist\setcounter{quizno}{0}\eq@answersEndHook}
+% \end{macrocode}
+% Answers environment for a tabular environment. This command picks
+% up the arguments of \cs{Ans}, then passes on the \cs{@Ans}
+%\begin{verbatim}
+% [#1] = points to be awarded if problem is false (partial credit)
+% #2 = 1 (for true) or 0 (for false)
+%\end{verbatim}
+% These parameters are saved in the commands \cs{eq@pPTs} and
+% \cs{Ans@choice}.
+% \begin{macrocode}
+\newcommand\Ans@tabular[2][0]{\gdef\eq@pPTs{#1}%
+ \xdef\Ans@choice{#2}\leavevmode\@Ans
+}
+% \end{macrocode}
+% (2013/05/17) \DescribeMacro{\sqtabsep} sets the \cs{tabsep} between columns.
+% \DescribeMacro{\sqTabPos} \cs{sqTabPos} allows you to set the positioning
+% optional parameter (t,c,b) on the tabular env. The default is no optional parameter.
+% \begin{macrocode}
+\newcommand\sqtabsep[1]{\def\eq@argi{#1}\ifx\eq@argi\@empty
+ \def\sq@tabsep{1.5pt}\else\def\sq@tabsep{#1}\fi}
+\sqtabsep{1.5pt}
+\def\sqTabPos#1{\def\sq@TabPos{[#1]}}\sqTabPos{}
+\def\answers@@sq@tabular#1{%
+% \ifinner\else\par\vskip-\parskip\vspace{\aboveanswersSkip}\fi
+ \ifinner % dps17
+ \ifx\itsExerParts\eq@YES\par\removelastskip
+ \removelastparskip\vskip\aboveanswersSkip\fi
+ \else\par\removelastskip\removelastparskip
+ \vskip\aboveanswersSkip\fi
+% \end{macrocode}
+% (2013/05/17) If within a parts environment in tabular mode, the tab env
+% needs to be shifted over by an amount of \cs{eqemargin}, for
+% \textsf{exerquiz} this is 0pt, nonzero for \textsf{eqexam}.
+% \begin{macrocode}
+ \noindent\ifnum\exerwparts@cols>1\relax\parshape=0\fi
+ \tabcolsep=0pt
+% \end{macrocode}
+%\begin{verbatim}
+% n=#1
+% width=(\linewidth-2*(n-1)*\tabcolsep)/n
+%\end{verbatim}
+% In the next line, we adjust \cs{linewidth}, \cs{eqemargin} is \texttt{0pt}
+% in \textsf{exerquiz} and nonzero otherwise.
+% \begin{macrocode}
+% \setlength{\linewidth}{\linewidth-\eqemargin}%
+ \eq@tmpdima=\linewidth
+ \@tempcnta#1\relax
+% n-1
+ \advance\@tempcnta-1\relax
+% 2(n-1)
+ \multiply\@tempcnta by2
+ \@tempdima\sq@tabsep\relax
+% 2*(n-1)*\eq@partstabcolsep
+ \multiply\@tempdima\@tempcnta
+% \linewidth-(n-1)*\sq@tabsep
+ \advance\eq@tmpdima-\@tempdima
+% (\linewidth-(n-1)*\sq@tabsep)/n
+ \divide\eq@tmpdima by#1
+ \def\Ans{\Ans@tabular}%
+ \tabcolsep\sq@tabsep\relax
+% \end{macrocode}
+% (2013/05/17) We allow the position argument (t,b,c). It changed
+% through \cs{sqTabPos} defined above.
+% \begin{macrocode}
+ \expandafter\tabular\sq@TabPos{@{}*{#1}{p{\eq@tmpdima}}@{}}}%
+% \end{macrocode}
+% \changes{v7.4}{2015/03/23}{added \cmd{\reset@doendpe}}
+% \DescribeMacro{\reset@doendpe} attempts to restore the \cs{parshape}
+% following a list environment. It appears in several locations, includeing
+% \cs{endanswers}, \cs{endmanswers}, and \cs{setTabulrSolnEnv}.
+% \par\medskip\noindent We begin by saving the core definition of \cs{@doendpe},
+% it is restored after each usage of \cs{reset@doendpe}.
+% \begin{macrocode}
+\let\eq@save@doendpe\@doendpe
+% \end{macrocode}
+% The argument \texttt{\#1} consists of the \cs{parshape} parameters to be restored
+% following the closing of any environment that uses \cs{doendpe}
+% \begin{macrocode}
+\def\reset@doendpe#1{\global\eq@scratchtoks=\expandafter{#1}%
+ \gdef\@doendpe{\par\@endpetrue\global\let\@doendpe\eq@save@doendpe
+ \def\par{\@restorepar
+ \expandafter\everypar
+ \expandafter{\the\eq@scratchtoks}\par\@endpefalse}%
+ \everypar{{\setbox\z@\lastbox}%
+ \everypar{}\@endpefalse}\the\eq@scratchtoks
+ }%
+}
+% \end{macrocode}
+%
+% \begin{macro}{\endanswers}
+% Close off \texttt{tabular} environment, and reinitialize the
+% \texttt{quizno} counter. Added \cs{answersEndHook}.
+% \begin{macrocode}
+\newcommand\answersEndHook[1]{\def\eq@answersEndHook{#1}}
+\let\eq@answersEndHook\@empty
+\def\endanswers@sq{\endtabular\setcounter{quizno}{0}%
+ \eq@answersEndHook\reset@doendpe{\the\everypar}%
+ \ifinner\else%\par
+ \removelastskip
+% \removelastparskip
+ \vspace{\aboveanswersSkip}\@endpetrue\fi
+}
+\def\endmanswers@sq{\endtabular\setcounter{quizno}{0}%
+ \eq@answersEndHook\reset@doendpe{\the\everypar}%
+ \ifinner\else%\par
+ \removelastskip
+% \removelastparskip
+ \vspace{\aboveanswersSkip}\@endpetrue\fi
+}
+\def\popiiictm{\special{CTM: pop pop pop}}
+%</package|eqexam>
+%<*package>
+% \end{macrocode}
+% \end{macro}
+% \subsubsection{Link Style}
+% \begin{macro}{\Ans@sq@l}
+% For the link multiple choice type question. The driver independent stuff starts
+% here, then goes to |\Ans@sq@l@driver| the rest of the code that depends on the
+% driver.
+% \begin{macrocode}
+\def\sqWrongRespJS{OnBlurRespBox( false, "\oField" );}
+\def\sqRightRespJS{OnBlurRespBox( true, "\oField" );}
+\def\Ans@sq@l@Actions
+{%
+ \A{\if\Ans@choice1
+ \JS{\sqRightRespJS}
+ \ifx\@qzsolndest\@empty\else
+ \ifeq@solutionsafter\else
+ /Next <</S/GoTo/D(\@qzsolndest)>>
+ \fi
+ \fi
+ \else
+ \JS{\sqWrongRespJS\jsR
+ \ifx\oField\@empty\else
+ updateTally("\oField.\thequestionno");
+ \fi}%
+ \fi
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macrocode}
+\def\linkContentFormat{\alph{quizno}}
+\def\aebChoiceAltFmt{\noexpand\ifaebshowgrayletters
+ \Alph{quizno}\noexpand\else\linkContentFormat\noexpand\fi}
+%</package>
+%<*eqexam>
+\def\aebChoiceAltFmt{\noexpand\ifaebshowgrayletters
+ \Alph{quizno}\noexpand\else\linkContentFormat\noexpand\fi}
+\def\linkContentFormat{%
+ \if\probstar*\Alph{quizno}\else\alph{quizno}\fi}
+%</eqexam>
+%<*package|eqexam>
+\def\linkContentWrapper{(\hfil\linkContentFormat\hfil)}%
+\def\Ans@sq@l{%
+ \leavevmode\if\eq@listType\eq@One\stepcounter{quizno}\else
+ \@ifundefined{ifwithsoldoc}{\refstepcounter{quizno}}
+ {\ifwithsoldoc\stepcounter{quizno}\else
+ \refstepcounter{quizno}\fi}\fi\PBS\raggedright
+ \settowidth{\eq@tmplength}{\eq@lw@l}\sbox{\eq@tmpbox}{\eq@l@l}%
+ \eq@tmpdima=\wd\eq@tmpbox
+ \def\link@@Content{\linkContentWrapper}%
+ \hangindent=\eq@tmplength\hangafter=1\relax
+%</package|eqexam>
+%<*eqexam>
+ \Ans@sq@l@driver
+%</eqexam>
+%<*package>
+ \set@@Link{}{}{}%
+ {\makebox[\eq@tmpdima]{\color{\@linkcolor}\link@@Content}}
+ {\eq@protect\A}{\eq@setWidgetProps\setLink@driver}%
+ {\set@LinkTextDefaults\Ans@sq@l@Actions\every@Link}%
+ \Ans@proofing{\eq@tmpdima}%
+%</package>
+%<*package|eqexam>
+\eq@hspanner\ignorespaces}
+%</package|eqexam>
+%<*package>
+% \end{macrocode}
+% \begin{macro}{\Ans@ck@sq@l}
+% Created in support of eqExam to give multiple selection for the
+% online and email options. Otherwise, it defaults to a radio button field.
+% \begin{macrocode}
+\def\Ans@ck@sq@l{\Ans@ck@sq@f}
+%</package>
+%<*eqexam>
+% dps 4/16/05
+\let\Ans@ck@sq@l\Ans@sq@l
+%</eqexam>
+%<*package>
+% \end{macrocode}
+% \end{macro}
+% \subsubsection{Form Style}
+% \begin{macro}{\Ans@sq@f}
+% For the link multiple choice type question. The driver independent stuff starts
+% here, then goes to |\Ans@sq@f@driver| the rest of the code that depends on the
+% driver.
+% \changes{v7.7d}{2015/11/15}{Changed mc.\cs{oFields} so it is printable}
+% \begin{macrocode}
+\def\@@Ans@sq@f@Defaults
+{%
+ \BC{0 0 0}\Ff{\FfNoToggleToOff}\W{1}
+ \F{\FPrint}\textSize{12}\textColor{0 g}
+}
+% \end{macrocode}
+% For short quizzes, refine the type of responses: turn off the alert
+% message (the default is on); or have a (red) `\texttt{x}' make an
+% incorrect answer, and a (green) check mark a correct answer.
+% \begin{macrocode}
+\def\sqTurnOffAlerts{\let\@sqTurnOffAlerts\eq@Zero}
+\def\sqTurnOnAlerts{\let\@sqTurnOffAlerts\eq@One}
+\sqTurnOnAlerts
+% \end{macrocode}
+% This feature was discontinued sometime between version 5.x and 6.x.
+% \begin{macrocode}
+\def\sqNoCorrections{\let\@sqAlertsOnly\eq@One}
+\def\sqCorrections{\let\@sqAlertsOnly\eq@Zero}
+\sqNoCorrections
+% \end{macrocode}
+% The actions for the form version of a multiple choice question of a \texttt{shortquiz}.
+% \begin{macrocode}
+\def\Ans@sq@f@Actions
+{%
+ \A{\if\Ans@choice\eq@One
+ \JS{%
+% \end{macrocode}
+%\changes{v6.7d}{2013/05/27}{removed JS control of checks and color, they
+% are hardwired instead.}
+% \begin{macrocode}
+ \if\@sqTurnOffAlerts1OnBlurRespBox(true,"\oField");\jsR\fi
+ \ifx\@qzsolndest\@empty\else
+ \ifeq@solutionsafter\else
+ jmpToNamedDest("\oField","\@qzsolndest",%
+\if\@sqTurnOffAlerts00\else1\fi);\fi
+ \fi}%
+ \else
+ \JS{%
+ \if\@sqTurnOffAlerts1OnBlurRespBox( false, %
+"\oField" );\jsR\fi
+ \ifx\oField\@empty\else
+ updateTally("\oField.\thequestionno");
+ \fi}%
+ \fi%
+ }%
+ \AA{\AAMouseDown{\JS{%
+ updateTally.downState=!!event.target.isBoxChecked%
+(\arabic{quizno}-1);}}}%
+}
+\def\Ans@proofing
+#1{%
+ \ifeq@proofing\if\Ans@choice1\relax
+ \llap{\@proofingsymbol\,\hskip#1\relax}%
+ \fi\fi
+}
+% \end{macrocode}
+%\DescribeMacro{\sqRghtSymbChoice}\DescribeMacro{\sqRghtSymbColor} for the \texttt{shortquiz}
+% environment, these first two commands assign the right symbol (default check) and
+% color (default webgreen). The second two\DescribeMacro{\sqWrngSymbChoice}\DescribeMacro{\sqWrngSymbColor}
+% does the same thing for the wrong answer.
+% \begin{macrocode}
+\def\sqRghtSymbChoice#1{\chooseJSsymbol*{#1}%
+ \ifx\eq@retnStyle\@empty
+ \edef\sq@corrsymch{\sqRghtSymbChoiceDef}\else
+ \edef\sq@corrsymch{#1}\fi}
+\def\sqRghtSymbColor#1{\edef\eq@arg{#1}\ifx\eq@arg\@empty
+ \edef\sq@corrsymcol{\sqRghtSymbColorDef}\else
+ \edef\sq@corrsymcol{#1}\fi}
+\def\sqWrngSymbChoice#1{\chooseJSsymbol*{#1}%
+ \ifx\eq@retnStyle\@empty
+ \edef\sq@wrgsymch{\sqWrngSymbChoiceDef}\else
+ \edef\sq@wrgsymch{#1}\fi}
+\def\sqWrngSymbColor#1{\edef\eq@arg{#1}\ifx\eq@arg\@empty
+ \edef\sq@wrgsymcol{\sqWrngSymbColorDef}\else
+ \edef\sq@wrgsymcol{#1}\fi}
+\def\sqRghtSymbChoiceDef{check}
+\def\sqRghtSymbColorDef{0 .6 0 rg}
+\def\sqWrngSymbChoiceDef{cross}
+\def\sqWrngSymbColorDef{1 0 0 rg}
+\edef\sq@corrsymch{\sqRghtSymbChoiceDef}
+\edef\sq@corrsymcol{\sqRghtSymbColorDef}
+\edef\sq@wrgsymch{\sqWrngSymbChoiceDef}
+\edef\sq@wrgsymcol{\sqWrngSymbColorDef}
+\def\sqResetSymbToDef{%
+ \sqRghtSymbChoice{}\sqRghtSymbColor{}%
+ \sqWrngSymbChoice{}\sqWrngSymbColor{}%
+}
+% \end{macrocode}
+%\DescribeMacro{\qChoiceSymb}\DescribeMacro{\qChoiceColor} for the \texttt{quiz}
+% environment, these two commands assign the selection symbol (default check) and the
+% color (default webgreen).
+% \begin{macrocode}
+\def\qChoiceSymb#1{\chooseJSsymbol*{#1}%
+ \ifx\eq@retnStyle\@empty
+ \edef\qz@chksymb{\qChoiceSymbDef}\else
+ \edef\qz@chksymb{#1}\fi}
+\def\qChoiceColor#1{\edef\eq@arg{#1}\ifx\eq@arg\@empty
+ \edef\qz@chksymbcol{\qChoiceColorDef}\else
+ \edef\qz@chksymbcol{#1}\fi}
+\def\qChoiceSymbDef{check}
+\def\qChoiceColorDef{0 0 0 rg}
+\edef\qz@chksymb{\qChoiceSymbDef}
+\edef\qz@chksymbcol{\qChoiceColorDef}
+%</package>
+%<*package|eqexam>
+\let\rbf@Opts\@empty
+\def\Ans@sq@f{%
+ \if\eq@listType\eq@One\stepcounter{quizno}\else
+ \@ifundefined{ifwithsoldoc}{\refstepcounter{quizno}}
+ {\ifwithsoldoc\stepcounter{quizno}\else
+ \refstepcounter{quizno}\fi}\fi\PBS\raggedright
+%</package|eqexam>
+% \end{macrocode}
+%\changes{v6.7d}{2013/05/27}{added \cs{rbf@Opts} to hardwire choices.}
+% \begin{macrocode}
+%<*package>
+ \if\Ans@choice\eq@One
+ \def\rbf@Opts{\symbolchoice{\sq@corrsymch}%
+ \textColor{\sq@corrsymcol}}\else
+ \def\rbf@Opts{\symbolchoice{\sq@wrgsymch}%
+ \textColor{\sq@wrgsymcol}}\fi
+%</package>
+%<*package|eqexam>
+ \settowidth{\eq@tmplength}{\eq@lw@f}%
+ \eq@tmpdima=\wd\eq@tmpbox%
+ \hangindent=\eq@tmplength\hangafter=1\relax
+ \insertGrayLetters % 6.3d
+%</package|eqexam>
+%<*eqexam>
+ \Ans@sq@f@driver
+%</eqexam>
+%<*package>
+% \end{macrocode}
+%\changes{v6.7d}{2013/05/27}{new \cs{rbf@Opts} option.}
+% \begin{macrocode}
+ \mbox{\expandafter\radio@@Button\expandafter{\rbf@Opts}%
+ {mc.\oField.\thequestionno}%
+ {\RadioFieldSize}% 11/16/05 changed from \oField to mc.\oField
+ {\RadioFieldSize}{\Ans@choice\alph{quizno}}{\eq@protect\A}%
+ {\eq@setWidgetProps\eq@RadioCheck@driver}%
+ {\@@Ans@sq@f@Defaults\Ans@sq@f@Actions\every@RadioButton
+ \every@sqRadioButton}}%
+ \Ans@proofing{\RadioFieldSize}%
+%</package>
+%<*package|eqexam>
+\eq@hspanner\ignorespaces}
+%</package|eqexam>
+%<*package>
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\Ans@ck@sq@f}
+% Created in support of \textsf{eqExam} to give multiple selection for the
+% online and email options. Otherwise, it defaults to a radio button field.
+% \begin{macrocode}
+%
+%</package>
+%<*eqexam>
+% dps 4/16/05
+\let\Ans@ck@sq@f\Ans@sq@f
+%</eqexam>
+%<*package>
+\def\@@Ans@ck@sq@f@Defaults
+{%
+ \BC{0 0 0}\Ff{\FfNoToggleToOff}
+ \F{\FPrint}\textSize{12}\textColor{0 g}\W{1}
+}
+\begingroup
+\catcode`\&=12
+\gdef\eq@AND{&&}
+\endgroup
+\def\Ans@ck@sq@f@Actions
+{%
+ \A{\if\Ans@choice1%
+ \JS{%
+var fName=event.target.name;\jsR
+var g=this.getField("mc.\oField.\thequestionno");\jsR
+var a=g.getArray();\jsR
+for (var i=0; i<a.length; i++)\jsR\jsT
+ if ( a[i].isBoxChecked(0) \eq@AND\space
+a[i].value.charAt(0)==0)\jsR\jsT\jsT
+ a[i].checkThisBox(0,false);\jsR
+ \if\@sqTurnOffAlerts1OnBlurRespBox( %
+ true, "\oField" );\jsR\fi
+ \ifx\@qzsolndest\@empty\else
+ \ifeq@solutionsafter\else
+% if all correct answers are check, jump to solution
+for (var i=0; i<a.length; i++){\jsR\jsT
+ if ( a[i].exportValues[0].charAt(0)==1 \eq@AND\space
+!a[i].isBoxChecked(0) )\jsR\jsT\jsT
+ break;\jsR
+}\jsR
+ if (i>=a.length) jmpToNamedDest("\oField","\@qzsolndest",%
+ \if\@sqTurnOffAlerts00\else1\fi);
+ \fi
+ \fi}%
+ \else%
+ \JS{%
+var fName=event.target.name;\jsR
+var g=this.getField("mc.\oField.\thequestionno");\jsR
+var a=g.getArray();\jsR
+for (var i=0; i<a.length; i++)\jsR
+{\jsR\jsT
+ if (a[i].value.charAt(0)==0) {\jsR\jsT\jsT
+ if ( fName != a[i].name )\jsR\jsT\jsT\jsT
+ a[i].checkThisBox(0,false);\jsR\jsT
+ }\jsR
+}\jsR
+ \if\@sqTurnOffAlerts1OnBlurRespBox( false, "\oField" );\fi%
+ \ifx\oField\@empty\else%
+ updateTally("\oField.\thequestionno");
+ \fi}%
+ \fi%
+ }%
+ \AA{\AAMouseDown{%
+\JS{updateTally.downState=!!event.target.isBoxChecked(0);}}}
+}
+\def\Ans@ck@sq@f{%
+ \if\eq@listType\eq@One\stepcounter{quizno}\else
+ \@ifundefined{ifwithsoldoc}{\refstepcounter{quizno}}
+ {\ifwithsoldoc\stepcounter{quizno}\else
+ \refstepcounter{quizno}\fi}\fi\PBS\raggedright
+ \if\Ans@choice1%
+ \def\rbf@Opts{\symbolchoice{\sq@corrsymch}%
+ \textColor{\sq@corrsymcol}}\else
+ \def\rbf@Opts{\symbolchoice{\sq@wrgsymch}%
+ \textColor{\sq@wrgsymcol}}\fi
+ \settowidth{\eq@tmplength}{\eq@lw@f}%
+ \eq@tmpdima=\wd\eq@tmpbox%
+ \hangindent=\eq@tmplength\hangafter=1\relax
+ \insertGrayLetters % 6.3d
+ \mbox{\expandafter\check@@Box\expandafter{\rbf@Opts}%
+ {mc.\oField.\thequestionno.\arabic{quizno}}%
+ {\RadioFieldSize}{\RadioFieldSize}
+ {\Ans@choice\alph{quizno}}{\eq@protect\A}%
+ {\eq@setWidgetProps\eq@RadioCheck@driver}%
+ {\@@Ans@ck@sq@f@Defaults\Ans@ck@sq@f@Actions\every@CheckBox
+ \every@sqCheckBox}}%
+ \Ans@proofing{\RadioFieldSize}%
+\eq@hspanner\ignorespaces}
+% \end{macrocode}
+% \end{macro}
+% \subsection{For \texttt{quiz}}
+% \subsubsection{The \texttt{answers} and \texttt{manswers} Environment}
+% \begin{macro}{answers}
+% This is the answers environment for the \texttt{quiz}
+% environment. The \texttt{quiz} environment states
+% \verb+\let\answers=\answers@q+. This is to avoid a conflict
+% with \texttt{shortquiz}, which also as an \texttt{answers}
+% environment.
+%
+% The following parameters are recognized:
+%\begin{verbatim}
+% [#1]|* = named destination to be associated with solution;
+% with *, the destination is automatically generated
+% #2 = number of columns in the tabular environment
+%\end{verbatim}
+% If the number of columns is $1$, then we use a list environment,
+% else, we use a tabular environment.
+% \begin{macrocode}
+%</package>
+%<*package|eqexam>
+\newskip\aboveanswersSkip
+\setlength\aboveanswersSkip{3pt}
+%</package|eqexam>
+%<*package>
+\let\q@hwdest\@empty % hard-wired destination
+\let\pointValuesArray\@empty
+\newif\ifeqshowmarkup\eqshowmarkupfalse
+\newif\ifeqshowOutOf \eqshowOutOffalse
+\def\showOutOfinSmryTbl{false}
+\def\eq@recordThesePTs{%
+ \ifx\pointValuesArray\@empty
+ \edef\ptsValue{\showOutOfinSmryTbl,\eqPTs}\else
+ \edef\ptsValue{,\eqPTs}\fi
+ \expandafter\g@addto@macro\expandafter\pointValuesArray
+ \expandafter{\ptsValue}}
+% \end{macrocode}
+% \changes{v7.7m}{2016/07/04}{Added \string\texttt{ptypeArray} to track problem types better}
+% \begin{macrocode}
+\let\ptypeArray\@empty
+\def\eq@recordProbType{%
+ \ifx\ptypeArray\@empty
+ \edef\tmp@exp{\noexpand\g@addto@macro
+ \noexpand\ptypeArray{null,"\eqQT"}}\else
+ \edef\tmp@exp{\noexpand\g@addto@macro
+ \noexpand\ptypeArray{,"\eqQT"}}\fi
+ \tmp@exp
+}
+\let\corrAnsArray\@empty
+\def\eq@recordCorrAns#1{%
+ \ifx\corrAnsArray\@empty
+ \edef\tmp@exp{\noexpand\g@addto@macro
+ \noexpand\corrAnsArray{null,#1}}\else
+ \edef\tmp@exp{\noexpand\g@addto@macro
+ \noexpand\corrAnsArray{,#1}}\fi
+ \tmp@exp
+}
+\def\aeb@answerType@r{r}
+\def\aeb@answerType@c{c}
+\newcommand\answers@q{%
+ \eq@AddProbToQzQuesList
+ \def\aeb@answerType{r}\setdefault@Ans\eq@recordThesePTs
+ \eq@recordProbType
+ \addtocounter{eqpointvalue}{\eqPTs}\stepcounter{questionno}%
+ \def\aeb@thisType{"mc"}\@ifnextchar[{\answers@@q}%
+ {\@ifstar{\answers@@q[\curr@quiz.\thequestionno]}{\answers@@q[]}}%
+}
+\def\answers@@q[#1]#2{\global\let\eq@ansChoiceArray\@empty
+ \xdef\aeb@numCols{#2}\edef\eqtmp{\aPointType}%
+ \xdef\aPointType{\eqtmp,[\eqPTs,\aeb@thisType]}%
+ \ifx\q@hwdest\@empty
+ \xdef\@qzsolndest{#1}\else
+ \gdef\@qzsolndest{\q@hwdest}\fi
+ \ifnum\aeb@numCols=1
+ \gdef\eq@listType{1}\expandafter\answers@q@list\else
+ \gdef\eq@listType{0}\expandafter\answers@q@tabular\fi{\aeb@numCols}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{manswers}
+% The \texttt{manswers} environment is used for multiple selection questions for the quiz
+% environment only. Within this environment, the \cs{Ans} command (\cs{@Ans} actually) is let equal to
+% \cs{Ans@ck@f} or \cs{Ans@ck@l} for forms or links respectively. These commands are defined
+% in the sections that follow.
+% \changes{v6.2}{2007/11/08 }
+%{
+% Added the \texttt{manswers} environment, and supporting elements, both {\LaTeX}
+% and JavaScript. This \texttt{manswers} environment is for the \texttt{quiz} environment
+% only. There is a \texttt{manswers} environment for the \texttt{shortquiz} environment, but
+% this is used by \textsf{eqExam} only.
+%}
+%
+% The following parameters are recognized
+%\begin{verbatim}
+% [#1]|* = named destination to be associated with solution;
+% with *, the destination is automatically generated
+% #2 = number of columns in the tabular environment
+%\end{verbatim}
+% \begin{macrocode}
+\newcommand\manswers@q
+{%
+ \eq@AddProbToQzQuesList
+ \def\aeb@answerType{c}\@setFormLinkType
+ \global\expandafter\let\expandafter\@Ans
+ \expandafter=\csname Ans@ck@\@@quiztype\endcsname
+ \eq@recordThesePTs\eq@recordProbType
+ \addtocounter{eqpointvalue}{\eqPTs}\stepcounter{questionno}%
+ \def\aeb@thisType{"ms"}\@ifnextchar[{\answers@@q}%
+ {\@ifstar{\answers@@q[\curr@quiz.\thequestionno]}{\answers@@q[]}}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macrocode}
+\newenvironment{answers@q@list}[1]{%
+ \ifx\aeb@answerType\eq@r
+ \let\endanswers\endanswers@q@list\else
+ \let\endmanswers\endanswers@q@list\fi
+ \list{\strut\@Ans}{%
+ \if\qstar*\relax
+ \if\aeb@FLOverride\eq@l
+ \settowidth{\labelwidth}{\eq@lw@l}\else
+ \settowidth{\labelwidth}{\eq@lw@f}\fi
+ \else
+ \if\aeb@FLOverride\eq@f
+ \settowidth{\labelwidth}{\eq@lw@f}\else
+ \settowidth{\labelwidth}{\eq@lw@l}\fi
+ \fi
+ \setlength{\topsep}{-\parskip+\aboveanswersSkip}%
+ \setlength{\parsep}{0pt}\setlength{\itemindent}{0pt}%
+ \setlength{\listparindent}{\parindent}%
+ \setlength{\leftmargin}{\labelwidth}%
+ \setlength{\labelsep}{0pt}%
+ \def\Ans{\Ans@list}%
+ }%
+}{\endlist\setcounter{quizno}{0}%
+ \eq@answersEndHook
+ \setdefault@Ans
+ \ifx\aeb@answerType\aeb@answerType@r
+% \end{macrocode}
+% If this is a MC question, we record the author's correct answer
+% \begin{macrocode}
+ \eq@recordCorrAns{\eq@ansChoiceArray}\ifwithinMCFI
+% \end{macrocode}
+% If within a \cs{bMCFI}/\cs{eMCFI} command pair, we also record
+% the author's correct answer.
+% \begin{macrocode}
+ \eq@recordCorrAns{\s@veCorrAnsMCFI}\fi\else
+% \end{macrocode}
+% If this is a MS question, we record the author's correct answer as an array
+% \begin{macrocode}
+ \eq@recordCorrAns{[\eq@ansChoiceArray]}\fi
+ \global\let\eqlimselTo\@empty
+}
+% \end{macrocode}
+% \begin{macrocode}
+\newcommand\qztabsep[1]{\def\eq@argi{#1}\ifx\eq@argi\@empty
+ \def\qz@tabsep{1.5pt}\else\def\qz@tabsep{#1}\fi}
+\qztabsep{1.5pt}
+\def\qzTabPos#1{\def\qz@TabPos{[#1]}}\qzTabPos{}
+\def\answers@q@tabular#1{%
+ \ifinner\else\par\removelastparskip\vspace{\aboveanswersSkip}\fi
+ \eq@tmpdima=\linewidth
+ \@tempcnta#1\relax
+% n-1
+ \advance\@tempcnta-1\relax
+% 2(n-1)
+ \multiply\@tempcnta by2
+ \@tempdima\qz@tabsep\relax
+% 2*(n-1)*\qz@tabsep
+ \multiply\@tempdima\@tempcnta
+% \linewidth-(n-1)*\qz@tabsep
+ \advance\eq@tmpdima-\@tempdima
+% (\linewidth-(n-1)*\qz@tabsep)/n
+ \divide\eq@tmpdima by#1
+% \begin{macrocode}
+ \tabcolsep\qz@tabsep\relax
+ \def\Ans{\Ans@tabular}%
+ \ifx\aeb@answerType\eq@r
+ \let\endanswers\endanswers@q@tabular\else
+ \let\endmanswers\endanswers@q@tabular\fi
+ \noindent\expandafter
+ \tabular\qz@TabPos{@{}*{#1}{p{\eq@tmpdima}}@{}}%
+}
+% \end{macrocode}
+% \begin{macro}{\endanswers}
+% Again, we put \verb+\let\endanswers=\endanswers@q+.
+% \begin{macrocode}
+\def\endanswers@q@tabular
+{%
+ \endtabular\setcounter{quizno}{0}%
+ \eq@answersEndHook
+ \setdefault@Ans
+ \ifx\aeb@answerType\aeb@answerType@r
+% \end{macrocode}
+% If this is a MC question, we record the author's correct answer
+% \begin{macrocode}
+ \eq@recordCorrAns{\eq@ansChoiceArray}\ifwithinMCFI
+% \end{macrocode}
+% If within the MCFI command pair, we record the author's fill-in as well.
+% \begin{macrocode}
+ \eq@recordCorrAns{\s@veCorrAnsMCFI}\fi\else
+% \end{macrocode}
+% If this is a MS question, we record the author's correct answer as an array
+% \begin{macrocode}
+ \eq@recordCorrAns{[\eq@ansChoiceArray]}\fi
+ \global\let\eqlimselTo\@empty
+}
+% \end{macrocode}
+% \end{macro}
+% \subsubsection{Link Style}
+% \begin{macro}{\Ans@l}
+% For the forms version of the \texttt{quiz} environment.
+% dps 12/19/03 removed the notify because we are not embedding a radio button field
+% \begin{macrocode}
+\let\qRadionActionsHook\@empty
+\def\Ans@@l@Actions{\A{\JS{%
+ this.getField("mc.\curr@quiz.\thequestionno").value
+ = "\Ans@choice\alph{quizno}";\jsR
+ RecordPointValue([0,\eqPTs,\eq@pPTs],\thequestionno);\jsR
+ RecordProblemType("\eqQT",\thequestionno);\jsR
+ ProcessQuestion(\Ans@choice,"\alph{quizno}",\thequestionno,%
+\arabic{quizno},"\curr@quiz",0,\ifnocorrections0\else1\fi,%
+"\bqlabelISO"\if\eqQuizType\isQZ\ifx\eq@online\eq@YES
+\ifeq@noquizsolutions\else,1\fi\fi\fi);\qRadionActionsHook}}%
+}
+\def\Ans@r@l@Defaults
+{%
+ \BC{}\S{S}\W{1}\Ff{\FfNoToggleToOff}\F{\FPrint}
+ \textSize{12}\textColor{0 g}\Ff{\FfReadOnly}
+}
+\def\Ans@l{\leavevmode\if\eq@listType1\stepcounter{quizno}%
+ \else\refstepcounter{quizno}\fi\PBS\raggedright
+ \settowidth{\eq@tmplength}{\eq@lw@l}\sbox{\eq@tmpbox}{\eq@l@l}%
+ \hangindent=\eq@tmplength\hangafter=1\relax
+ \eq@tmpdima=\wd\eq@tmpbox
+ \def\link@@Content{(\hfil\linkContentFormat\hfil)}%
+% begin dps changes 12/19/03
+% \end{macrocode}
+% (2013/10/24) Imperative that radio button has no boundary line.
+% \begin{macrocode}
+ \def\late@options{\BC{}}%
+\if\Ans@choice1\relax\eq@recordAnsChoice\fi
+ \makebox[0pt][l]{\radio@@Button{}{mc.\curr@quiz.\thequestionno}%
+ {\eq@tmpdima}{\RadioFieldSize}{\Ans@choice\alph{quizno}}%
+ {\eq@protect\A}{\eq@setWidgetProps\eq@l@check@driver}%
+ {\Ans@r@l@Defaults\every@RadioButton
+ \every@qRadioButton\late@options}}%
+% end dps changes 12/19/03
+ \set@@Link{}{}{}%
+ {\makebox[\eq@tmpdima]{\color{\@linkcolor}\link@@Content}}%
+ {\eq@protect\A}{\eq@setWidgetProps\setLink@driver}%
+ {\set@LinkTextDefaults\Ans@@l@Actions\every@Link}%
+ \ifnocorrections\else
+ \if\Ans@choice1\relax
+ \edef\Ans@c@l@Choice{\noexpand\DV{Yes}%
+ \ifx\@qzsolndest\@empty
+ \noexpand\Ff{\FfReadOnly}%
+ \else % there is a solution
+ \ifeq@noquizsolutions
+ \noexpand\Ff{\FfReadOnly}%
+ \else
+ \noexpand\A{\noexpand\quiz@SolutionActionHook}%
+ \fi
+ \fi
+ }%
+ \else
+ \def\Ans@c@l@Choice{\Ff{\FfReadOnly}\BC{}}%
+ \fi
+ \def\late@options{\BC{}}%
+ \if\Ans@choice1\relax
+ \ifx\@qzsolndest\@empty\else
+ \ifeq@noquizsolutions\else
+ \edef\late@options{\noexpand\BC{\solution@Color}}%
+ \fi
+ \fi
+ \fi
+ \makebox[0pt][r]{\check@@Box{}%
+ {mcq.\curr@quiz.\thequestionno.\arabic{quizno}}%
+ {\eq@tmpdima}{0pt}{Yes}{}% \@tempdimb
+ {\eq@setWidgetProps\eq@l@check@driver}%
+ {\Ans@c@f@Defaults\Ans@c@l@Choice\every@RadioButton
+ \every@qRadioButton\late@options}}%
+ \fi
+ \Ans@proofing{\eq@tmpdima}%
+\eq@hspanner\ignorespaces}
+% \end{macrocode}
+% \end{macro}
+% Now for the code to support the \texttt{manswers} environment for link style.
+% \begin{macro}{\Ans@ck@l}
+% Below is \cs{Ans@ck@l} and its supporting default appearances and actions. The command \cs{Ans@ck@l} defines
+% a checkbox, on top of that a link (that the user interacts with) and on top another check box.
+% \begin{macrocode}
+\def\Ans@ck@@l@Actions{\A{\JS{%
+ var ckfName="mck.\curr@quiz.\thequestionno.\arabic{quizno}";\jsR
+ var ckf = this.getField(ckfName);\jsR
+ ckf.checkThisBox(0,!ckf.isBoxChecked(0));\jsR
+ var _bOK=true;\jsR
+\ifx\eqlimselTo\@empty\else _bOK = LimitSelection(\eqlimselTo,%
+"mck.\curr@quiz.\thequestionno","\arabic{quizno}");\jsR\fi
+if (_bOK) {\jsR\jsT
+ var aPMSretn=ProcessMultiSelection(\Ans@choice,"\alph{quizno}",%
+\thequestionno,\arabic{quizno},"\curr@quiz",\eqPTs,\eq@pPTs);\jsR\jsT
+ RecordProblemType("\eqQT",\thequestionno);\jsR\jsT
+ ProcessQuestion(aPMSretn[0],aPMSretn[1],\thequestionno,%
+\arabic{quizno},"\curr@quiz",0,\ifnocorrections0\else1\fi,%
+"\bqlabelISO"\if\eqQuizType\isQZ\ifx\eq@online\eq@YES
+\ifeq@noquizsolutions\else,1\fi\fi\fi);\jsR
+}
+ }}
+}
+\def\Ans@ck@l@Defaults
+{%
+ \BC{}\S{S}\W{1}\H{N}\Ff{\FfNoToggleToOff}
+ \textSize{12}\textColor{0 g}\Ff{\FfReadOnly}
+}
+\def\Ans@ck@l{%
+ \leavevmode\if\eq@listType1\stepcounter{quizno}%
+ \else\refstepcounter{quizno}\fi
+ \if\Ans@choice1\eq@recordAnsChoice\fi\PBS\raggedright
+ \settowidth{\eq@tmplength}{\eq@lw@l}\sbox{\eq@tmpbox}{\eq@l@l}%
+ \hangindent=\eq@tmplength\hangafter=1\relax
+ \eq@tmpdima=\wd\eq@tmpbox
+ \def\link@@Content{(\hfil\linkContentFormat\hfil)}%
+% begin dps changes 12/19/03
+ \makebox[0pt][l]{%
+ \check@@Box{}{mck.\curr@quiz.\thequestionno.\arabic{quizno}}%
+ {\eq@tmpdima}{\RadioFieldSize}{\Ans@choice\alph{quizno}}%
+ {\eq@protect\A}{\eq@setWidgetProps\eq@l@check@driver}%
+ {\Ans@ck@l@Defaults\every@RadioButton
+ \every@qckCheckbox}}%
+% end dps changes 12/19/03
+ \set@@Link{}{}{}%
+ {\makebox[\eq@tmpdima]{\color{\@linkcolor}\link@@Content}}%
+ {\eq@protect\A}{\eq@setWidgetProps\setLink@driver}%
+ {\set@LinkTextDefaults\Ans@ck@@l@Actions\every@Link}%
+ \ifnocorrections\else
+ \if\Ans@choice1\relax
+ \edef\Ans@c@l@Choice{\noexpand\DV{Yes}%
+ \ifx\@qzsolndest\@empty\noexpand\BC{}%
+ \noexpand\Ff{\FfReadOnly}%
+ \else % there is a solution
+ \ifeq@noquizsolutions
+ \noexpand\BC{}\noexpand\Ff{\FfReadOnly}%
+ \else
+ \noexpand\BC{\solution@Color}%
+ \noexpand\A{\noexpand\quiz@SolutionActionHook}%
+ \fi
+ \fi
+ }%
+ \else
+ \def\Ans@c@l@Choice{\Ff{\FfReadOnly}\BC{}}%
+ \fi
+ \makebox[0pt][r]{\check@@Box{}%
+ {mcq.\curr@quiz.\thequestionno.\arabic{quizno}}%
+ {\eq@tmpdima}{0pt}{Yes}{}%
+ {\eq@setWidgetProps\eq@l@check@driver}%
+ {\Ans@c@f@Defaults\Ans@c@l@Choice\every@RadioButton
+ \every@qRadioButton}}%
+ \fi
+ \Ans@proofing{\eq@tmpdima}%
+\eq@hspanner\ignorespaces}
+% \end{macrocode}
+% \end{macro}
+% \subsubsection{Form Style}
+% \begin{macro}{\Ans@f}
+% For the form button multiple choice type question. The driver independent stuff starts
+% here, then goes to |\Ans@f@driver| the rest of the code that depends on the
+% driver.
+% \begin{macrocode}
+\def\Ans@f{\leavevmode\if\eq@listType1\stepcounter{quizno}%
+ \else\refstepcounter{quizno}\fi
+ \PBS\raggedright\Ans@@f}
+\def\Ans@r@f@Defaults
+{%
+ \BC{0 0 0}\S{S}\W{1}\Ff{\FfNoToggleToOff}
+ \F{\FPrint}\textSize{12}\textColor{0 g}
+}
+% Action of the radio button field
+\def\Ans@r@f@Actions{\A{\JS{%
+ RecordPointValue([0,\eqPTs,\eq@pPTs],\thequestionno);\jsR
+ RecordProblemType("\eqQT",\thequestionno);\jsR
+ ProcessQuestion(\Ans@choice,"\alph{quizno}",\thequestionno,%
+ \arabic{quizno},"\curr@quiz",0,\ifnocorrections0\else1\fi,%
+ "\bqlabelISO"\if\eqQuizType\isQZ\ifx\eq@online\eq@YES
+ \ifeq@noquizsolutions\else,1\fi\fi\fi);\qRadionActionsHook}}
+}
+% Action of the check box underlying the radio button field
+\def\quiz@SolutionActionHook{%
+ /S/GoTo/D(\@qzsolndest)/Next<<\JS{this.resetForm(%
+ ["mcq.\curr@quiz.\thequestionno.\arabic{quizno}"]);}>>
+}
+\def\Ans@c@f@Defaults
+{%
+ \BC{0 0 0}\S{S}\W{1}\F{\FHidden}\textSize{12}
+ \textColor{0 g}\symbolchoice{circle}
+}
+% \end{macrocode}
+% \changes{v6.05d}{2007/04/14}
+% {
+% Added the command \cs{insertGrayLetters}. This can be defined to place symbols under
+% the multiple choice form boxes. The command \cs{bottomOfAnsfStack} is there as a
+% hook for whatever purposes are desired.
+% }
+% \begin{macrocode}
+\let\bottomOfAnsfStack\relax
+%</package>
+%<*package|eqexam>
+% \end{macrocode}
+% \changes{v7.7}{2015/06/04}{Added \cs{graylettersColor}}
+% \DescribeMacro\graylettersColor sets the color of the gray letters, the default is
+% \texttt{gray}.
+% \begin{macrocode}
+\providecommand\graylettersColor{gray}
+\def\insertGrayLetters{\ifaebshowgrayletters
+ \rlap{\makebox[\RadioFieldSize]%
+ {\textcolor{\graylettersColor}{\Alph{quizno}}}}\else\relax\fi}
+%</package|eqexam>
+%<*package>
+\def\Ans@@f
+{%
+ \settowidth{\eq@tmplength}{\eq@lw@f}%
+ \hangindent=\eq@tmplength\hangafter=1
+ \bottomOfAnsfStack\insertGrayLetters
+% dps add
+ \edef\rbf@Opts{\ifaeb@usecircles\else
+ \noexpand\symbolchoice{\qz@chksymb}\fi
+ \noexpand\textColor{\qz@chksymbcol}}%
+ \if\Ans@choice1\eq@recordAnsChoice\fi
+ \mbox{\expandafter\radio@@Button\expandafter{\rbf@Opts}%
+ {mc.\curr@quiz.\thequestionno}%
+ {\RadioFieldSize}{\RadioFieldSize}{\Ans@choice\alph{quizno}}%
+ {\eq@protect\A}{\eq@setWidgetProps\eq@RadioCheck@driver}%
+ {\Ans@r@f@Defaults\Ans@r@f@Actions\every@RadioButton
+ \every@qRadioButton\insert@circlesymbol}}%
+ \let\late@options\@empty
+ \ifnocorrections\else
+ \if\Ans@choice1\relax
+ \edef\Ans@c@f@Choice{\noexpand\DV{Yes}%
+ \ifx\@qzsolndest\@empty\noexpand\Ff{\FfReadOnly}%
+ \else
+ \ifeq@noquizsolutions
+ \noexpand\Ff{\FfReadOnly}%
+ \else
+ \noexpand\A{\noexpand\quiz@SolutionActionHook}%
+ \fi
+ \fi
+ }%
+ \else
+ \def\Ans@c@f@Choice{\Ff{\FfReadOnly}}%
+ \fi
+% \end{macrocode}
+% \changes{v6.7h}{2013/08/19}{When the \cs{useMCCircles} is used, the boundary
+% color is transparent. We try a fix for this to show the colored solution
+% boundary. The fix uses the \cs{late@options} commands.}
+% \begin{macrocode}
+ \ifaeb@usecircles\def\late@options{\BC{}}\fi
+ \if\Ans@choice1\relax
+ \ifx\@qzsolndest\@empty\else
+ \ifeq@noquizsolutions\else
+ \edef\late@options{\noexpand\BC{\solution@Color}}%
+ \fi
+ \fi
+ \fi
+ \makebox[0pt][r]{\check@@Box{}%
+ {mcq.\curr@quiz.\thequestionno.\arabic{quizno}}%
+ {\RadioFieldSize}{\RadioFieldSize}{Yes}{}%
+ {\eq@setWidgetProps\eq@RadioCheck@driver}%
+ {\Ans@c@f@Defaults\Ans@c@f@Choice\every@CheckBox
+ \every@qCheckBox\late@options}}%
+ \fi
+ \Ans@proofing{\RadioFieldSize}%
+\eq@hspanner\ignorespaces}
+% \end{macrocode}
+% \DescribeMacro{\limitSelectionTo} limits the selection to the number specified
+% by its argument for multiple selection questions.
+% \begin{macrocode}
+\def\limitSelectionTo#1{\def\eqlimselTo{#1}}
+\let\eqlimselTo\@empty
+% \end{macrocode}
+% \begin{macro}{\Ans@ck@f}
+% The support for multiple selection answers within the \texttt{manswers} environment.
+% \begin{macrocode}
+\def\Ans@ck@f{\leavevmode\if\eq@listType1\stepcounter{quizno}%
+ \else\refstepcounter{quizno}\fi
+ \if\Ans@choice1\eq@recordAnsChoice\fi
+ \PBS\raggedright\Ans@@ck@f}
+\def\Ans@ck@f@Defaults
+{%
+ \BC{0 0 0}\S{S}\W{1}\Ff{\FfNoToggleToOff}
+ \textSize{12}\textColor{0 g}
+}
+% Action of the radio button field
+\def\Ans@ck@f@Actions
+{%
+ \A{\JS{%
+% \end{macrocode}
+% Here is limit the number of selections. If \cs{eqlimselTo} is nonempty,
+% we call \texttt{LimitSelection()} to count the number of checks in this
+% current field. If too many, we uncheck the current effort and inform the
+% user.
+% \begin{macrocode}
+ var _bOK=true;\jsR
+\ifx\eqlimselTo\@empty\else _bOK = LimitSelection(\eqlimselTo,%
+"mck.\curr@quiz.\thequestionno","\arabic{quizno}");\jsR\fi
+% \end{macrocode}
+% As a result of the previous changes, we make this a condition:
+% if the JavaScript function \texttt{LimitSelection()} returns false, we do not execute. The default
+% value is \texttt{\_bOK=true}.
+% \begin{macrocode}
+if (_bOK) {\jsR\jsT
+ var aPMSretn=ProcessMultiSelection(\Ans@choice,"\alph{quizno}",%
+\thequestionno,\arabic{quizno},"\curr@quiz",\eqPTs,\eq@pPTs);\jsR\jsT
+ RecordProblemType("\eqQT",\thequestionno);\jsR\jsT
+ ProcessQuestion(aPMSretn[0],aPMSretn[1],\thequestionno,%
+\arabic{quizno},"\curr@quiz",0,\ifnocorrections0\else1\fi,%
+"\bqlabelISO"\if\eqQuizType\isQZ\ifx\eq@online\eq@YES
+\ifeq@noquizsolutions\else,1\fi\fi\fi);\jsR
+}}}%
+}
+% Action of the check box underlying the radio button field
+\def\quiz@SolutionActionHook{%
+ /S/GoTo/D(\@qzsolndest)/Next<<\JS{this.resetForm(%
+["mcq.\curr@quiz.\thequestionno.\arabic{quizno}"]);}>>
+}
+% \end{macrocode}
+% \cs{Ans@@ck@f} is the definition of the \cs{Ans} command within the
+% \texttt{manswers} environment.
+% \begin{macrocode}
+\def\Ans@@ck@f
+{%
+ \settowidth{\eq@tmplength}{\eq@lw@f}%
+ \hangindent=\eq@tmplength\hangafter=1
+ \bottomOfAnsfStack\insertGrayLetters
+% \end{macrocode}
+% The bottom most checkbox
+% \begin{macrocode}
+ \bottomOfAnsfStack\insertGrayLetters
+% dps add
+\def\cbf@Opts{\symbolchoice{\qz@chksymb}%
+ \textColor{\qz@chksymbcol}}%
+ \mbox{\expandafter\check@@Box\expandafter{\cbf@Opts}%
+ {mck.\curr@quiz.\thequestionno.\arabic{quizno}}%
+ {\RadioFieldSize}{\RadioFieldSize}{\Ans@choice\alph{quizno}}%
+ {\eq@protect\A}{\eq@setWidgetProps\eq@RadioCheck@driver}%
+ {\Ans@ck@f@Defaults\Ans@ck@f@Actions\every@RadioButton
+ \every@qckCheckbox}}%
+ \ifnocorrections\else
+ \if\Ans@choice1\relax
+ \edef\Ans@c@f@Choice{\noexpand\DV{Yes}%
+ \ifx\@qzsolndest\@empty\noexpand\Ff{\FfReadOnly}%
+ \else
+ \ifeq@noquizsolutions
+ \noexpand\Ff{\FfReadOnly}%
+ \else
+ \noexpand\A{\noexpand\quiz@SolutionActionHook}%
+ \fi
+ \fi
+ }%
+ \else
+ \def\Ans@c@f@Choice{\Ff{\FfReadOnly}}%
+ \fi
+ \let\late@options\@empty
+ \if\Ans@choice1\relax
+ \ifx\@qzsolndest\@empty\else
+ \ifeq@noquizsolutions\else
+ \edef\late@options{\noexpand\BC{\solution@Color}}%
+ \fi
+ \fi
+ \fi
+% \end{macrocode}
+% The top most checkbox
+% \begin{macrocode}
+ \makebox[0pt][r]{\check@@Box{}%
+ {mcq.\curr@quiz.\thequestionno.\arabic{quizno}}%
+ {\RadioFieldSize}{\RadioFieldSize}{Yes}{}%
+ {\eq@setWidgetProps\eq@RadioCheck@driver}%
+ {\Ans@c@f@Defaults\Ans@c@f@Choice\every@CheckBox
+% \end{macrocode}
+% (2012/12/22) Replace \cs{every@qRadioButton} with \cs{every@qCheckBox}.
+% \begin{macrocode}
+ \every@qCheckBox\late@options}}%
+ \fi
+ \Ans@proofing{\RadioFieldSize}%
+\eq@hspanner\ignorespaces}
+% \end{macrocode}
+% \end{macro}
+% \begin{macrocode}
+%</package>
+%<*package|eqexam>
+% \end{macrocode}
+%\subsection{The \texorpdfstring{\protect\cs{bChoices}/\protect\cs{eChoices}}
+% {\textbackslash{bChoices}/\textbackslash{eChoices}} Pair}
+% (2/15/05) This pair of macros is not really an environment, the
+% \cs{eChoices} really does nothing other than to act as an ending marker. The idea
+%behind this pair of macros twofold: (1) To provide a convenient way of listing
+%alternate choices for a multiple choice questions, the ``environment'' makes it
+%easy to change the number of columns, or to change from tabular to list (or visa-versa);
+%(2) Laying out the alternatives in a list style, makes it easy to develop techniques
+%of randomizing the alternatives. Here is an example of usage:
+%\begin{verbatim}
+%\begin{answers}{4}
+%\bChoices[2]
+% \Ans0 a choice\eAns
+% \Ans1 another choice\eAns
+% \Ans0 still another choice\eAns
+% \Ans0 another\eAns
+% \Ans0 incoming\eAns
+% \Ans0 more choices\eAns
+% \Ans0 another still\eAns
+% \Ans0 too many\eAns
+% \Ans0 choices\eAns
+%\eChoices
+%\end{answers}
+%\end{verbatim}
+%\noindent The argument of the \texttt{answers} environment is $4$ which means we are
+%going to use the tabular environment with $4$ columns. Now within those $4$ we are going
+%to only use the first $2$ columns ( this is the optional argument of \cs{bChoices}.
+%
+% If the optional argument is removed from \cs{bChoices}, the choices are typeset
+% in the with $4$ columns. If the argument of \cs{answers} is changed to $1$, then the
+% optional argument of \cs{bChoices} is ignored, and the alternatives are typeset in a
+% one column list environment.
+%
+% By changing the two parameters (one for \cs{answers} and one for \cs{bChoices})
+% you can easily modify how the alternatives are typeset.
+%\par\medskip\noindent
+% This counter tracts the column number we are in.
+% \begin{macrocode}
+\newcount\eq@tabColCnt
+% \end{macrocode}
+% \begin{macro}{\bChoices}
+% This command has one optional argument, the number of columns to use.
+%
+% When the answer environment sets the number of columns, the answers are set in
+% tabular form. If you say \verb!\begin{answers}[4]!, four columns are used.
+% If you then say \IndexKey{nCols}\verb!\Choices[nCols=2]!, only the first two columns are used.
+% To maintain backward compatibility, you can also say \verb!\Choices[2]!
+% \begin{macrocode}
+\define@key{bchoice}{nCols}{\def\bChoiceNumCols{#1}}
+\@for\eqi:=1,2,3,4,5,6,7,8,9,10 \do{\edef\temp@expand@def{%
+ \noexpand\define@key{bchoice}{\eqi}[\eqi]{%
+ \noexpand\def\noexpand\bChoiceNumCols{\eqi}}%
+ }\temp@expand@def
+}
+% \end{macrocode}
+% The number of columns specified in the answers environment is saved as the value
+% of \cs{aeb@numCols}. This the default value of \cs{bChoiceNumCols}.
+% \begin{macrocode}
+\def\bChoiceNumCols{\aeb@numCols}
+% \end{macrocode}
+% This is the definition of the random key\IndexKey{random}, a boolean.
+% \begin{macrocode}
+\define@key{bchoice}{random}[true]{%
+ \csname if#1\endcsname\eq@randomizeChoicestrue
+ \else\eq@randomizeChoicesfalse\fi
+}
+% \end{macrocode}
+% \changes{v6.3x}{2011/04/05}{%
+% Added \texttt{label} parameter to \cs{bChoices}.
+%}
+% A new key, \IndexKey{label}\texttt{label}, if this label is specified, then we keep track of all the
+% correct alternatives, put them into a commands to make them accessible by the user.
+% \begin{macrocode}
+\define@key{bchoice}{label}[]{\xdef\bChoiceLabel{#1}}
+% \end{macrocode}
+% The \cs{bChoices} command is now processed by the \texttt{keyval} package. There
+% are two keys: \texttt{nCols} and \texttt{random}. The first key
+% sets the number of columns we are limited to; the second one obviously declares
+% that this list of choices should be randomized, a boolean. The \texttt{random}
+% key is ignored unless the document author has use the \texttt{allowrandomize} option.
+% \begin{macrocode}
+\def\bChoices{\@ifnextchar[{\@ansChoices}{\@ansChoices[\aeb@numCols]}}
+% \end{macrocode}
+% If \cs{numCols} is $1$, we use a list environment, otherwise, a tabular is used.
+% \begin{macrocode}
+\def\@ansChoices[#1]%
+{%
+% \end{macrocode}
+% We initialize some variables that the new label option uses.
+% \begin{macrocode}
+ \global\let\@tempholdSaveAns\@empty %4/5
+ \global\let\@tempholdSaveChoice\@empty %4/5
+ \global\let\bChoiceLabel\@empty %4/5
+ \setkeys{bchoice}{#1}%
+ \global\eq@tabColCnt=0
+ \ifnum\aeb@numCols=1 % list mode
+ \def\eq@next{\@layoutListAns}\else % tabular mode
+ \def\eq@next{\@layoutTabularAns{\bChoiceNumCols}}\fi
+ \eq@next
+}
+\let\eChoices\relax
+% \end{macrocode}
+% \end{macro}
+% If the next token is \cs{Ans} we grab its all stuff between
+% \cs{Ans} and \cs{eAns} and typeset it. We continue until the
+% next token is not \cs{Ans}. (This last token
+% should be \cs{eChoices}.)
+% \begin{macrocode}
+\def\@layoutListAns{\@ifnextchar\Ans{\@getListAns}%
+ {\@lookforendansChoices{\@layoutListAns}}%
+}
+% \end{macrocode}
+% \changes{v6.3x}{2011/04/05}{%
+% Supporting commands that use the value of the \texttt{label} parameter
+% of \cs{bChoices}: \cs{eq@saveAns}, \cs{eq@displayAns}, \cs{eq@displayAlts}, etc.
+%}
+% \texttt{4/5} We begin an experimental series of commands. The idea is to be able to
+% conveniently reference a multiple choice problem when the
+% \texttt{vspacewithsolns} option is in effect (\textsf{eqexam}).
+%
+% \cs{eq@saveAns} is an internal macro, it gathers up the first two
+% arguments of \cs{Ans}, if the second arg is a 1, it passes the flow
+% to \cs{@@@SaveAns}; otherwise, it gobbles all leftovers.
+% \begin{macrocode}
+\newcommand{\eq@saveAns}[2][]{%
+ \let\eq@next\@@@SaveAnsGobbleAns
+ \ifx\bChoiceLabel\@empty\else
+ \def\eq@savedAnsOpt{#1}\def\eq@savedAnsZO{#2}%
+ \if\eq@savedAnsZO1 \let\eq@next\@@@SaveAns\fi
+ \fi\eq@next
+}
+% \end{macrocode}
+% \cs{@@@SaveAns} collects the answer to the problem, and placed
+% it in the holding command \cs{@tempholdSaveAns}, it also saves
+% the alternative letter as well in \cs{@tempholdSaveChoice}.
+% \begin{macrocode}
+\long\def\@@@SaveAns#1\eAns{% 4/5
+ \g@addto@macro\@tempholdSaveAns{\\{\ignorespaces#1}}%
+% \end{macrocode}
+% This code is expanded before the \cs{Ans} command is, so we'll simulate
+% incrementing the \texttt{quizno} counter, \dots
+% \begin{macrocode}
+ \addtocounter{quizno}{1}%
+ \edef\temp@expand{\noexpand\g@addto@macro\noexpand
+ \@tempholdSaveChoice{%
+ \noexpand\\{\ifx\sqstar\@empty\aebChoiceAltFmt\else
+ \ifaebshowgrayletters\Alph{quizno}\else
+ \linkContentFormat\fi\fi}}}\temp@expand
+% \end{macrocode}
+% and decrement when we are finished adding to the token list.
+% \begin{macrocode}
+ \addtocounter{quizno}{-1}%
+}
+% \end{macrocode}
+% \cs{eq@displayAns} is \cs{let} to \verb!\\!. Definition and name may change.
+% \cs{useSaveAns} is a simple interface to accessing the list of all correct
+% answers. Probably this definition will change.
+%
+% \cs{eq@insertComma} is a simple way of delimiting the list. We put a comma
+% before each expression, except for the first one.
+%
+% (2016/11/21) The \DescribeMacro{\oxfordCommaOn}\cs{oxfordCommaOn} is on by default, while
+% \DescribeMacro{\oxfordCommaOn}\cs{oxfordCommaOff} turns off the Oxford comma. The
+% Oxford comma comes into play only with the star-forms of \cs{useSavedAns},
+% \cs{useSavedAlts}, and \cs{useSavedAltsAns}.
+% \changes{v7.8}{2016/11/21}{Added star option to each of the \string\cs{useSaved...} commands}
+% \begin{macrocode}
+\newif\ifoxfordcomma \oxfordcommatrue
+\def\oxfordCommaOn{\oxfordcommatrue}
+\def\oxfordCommaOff{\oxfordcommafalse}
+\def\eq@insertComma{%
+ \ifx\eq@comma\@empty
+ \ifnum\@nameuse{NumAns\eq@namearg}>2\relax
+ \def\eq@comma{,}\fi
+ \else\ifx\eq@insertAnd\@empty\eq@comma\space
+ \else\ifnum\@tempcnta=\@nameuse{NumAns\eq@namearg}%
+ \ifoxfordcomma\eq@comma\fi\else\eq@comma\fi\space
+ \fi
+ \fi
+}
+\newcommand\eqAnd{and}\def\eq@insertAnd{%
+ \ifnum\@nameuse{NumAns\eq@namearg}<2\relax\else
+ \ifnum\@nameuse{NumAns\eq@namearg}>2\relax
+ \else\leavevmode\space\fi\eqAnd\space\fi}
+\long\def\eq@displayAns#1{\advance\@tempcnta1\relax
+ \eq@insertComma
+ \ifnum\@tempcnta=\@nameuse{NumAns\eq@namearg}\eq@insertAnd\fi#1}
+\def\eq@displayAlts#1{\advance\@tempcnta1
+ \eq@insertComma
+ \ifnum\@tempcnta=\@nameuse{NumAns\eq@namearg}\eq@insertAnd\fi
+ \savedAltFmt{#1}}
+\def\eq@displayAltsAns#1{\advance\@tempcnta1\relax
+ \eq@insertComma
+ \ifnum\@tempcnta=\@nameuse{NumAns\eq@namearg}\eq@insertAnd\fi#1}
+% \end{macrocode}
+% \begin{macro}{\useSavedAns}
+% \begin{macro}{\useSavedAlts}
+% \begin{macro}{\useSavedAltsAns}
+% \begin{macro}{\useSavedNumAns}
+% \changes{v6.3x}{2011/04/05}{%
+% Added \cs{useSavedAns}, \cs{useSavedAlts}, and \cs{useSavedAltsAns}.
+%}
+% These three commands hold the correct alternatives and answers to a multiple choice
+% or multiple selection problem. The optional first argument allows you to display
+% a particular result, the second argument is the value of the \texttt{label} key-value,
+% given in the enclosing \cs{bChoices}/\cs{eChoices} ``environment.''
+% \begin{macrocode}
+\newcommand{\savedAltFmt}[1]{(#1)}
+\newcommand{\useSavedAns}{\bgroup\@ifstar{\useSavedAns@i}
+ {\let\eq@insertAnd\@empty\useSavedAns@i}}
+\newcommand{\useSavedAns@i}[2][]{\@tempcnta=0\relax
+ \def\eq@namearg{#2}\let\label\@gobble
+ \def\eq@argi{#1}\ifx\eq@argi\@empty
+ \let\eq@comma\@empty
+ \let\\\eq@displayAns\@nameuse{SavedAns#2}\else
+ \@nameuse{SavedAns#2-Idx#1}\fi
+ \egroup
+}
+\newcommand{\useSavedAlts}{\bgroup\@ifstar{\useSavedAlts@i}
+ {\let\eq@insertAnd\@empty\useSavedAlts@i}}
+\newcommand{\useSavedAlts@i}[2][]{\@tempcnta=0\relax
+ \def\eq@namearg{#2}\@nameuse{caseFor#2}%
+ \def\eq@argi{#1}\ifx\eq@argi\@empty
+ \let\eq@comma\@empty
+ \let\\\eq@displayAlts\@nameuse{SavedAlts#2}\else
+ \savedAltFmt{\@nameuse{SavedAlts#2-Idx#1}}\fi
+ \egroup
+}
+\newcommand{\useSavedAltsAns}{\bgroup\@ifstar{\useSavedAltsAns@i}
+ {\let\eq@insertAnd\@empty\useSavedAltsAns@i}}
+\newcommand{\useSavedAltsAns@i}[2][]{\@tempcnta=0\relax
+ \def\eq@namearg{#2}\@nameuse{caseFor#2}\let\label\@gobble
+ \def\eq@argi{#1}\ifx\eq@argi\@empty
+ \let\eq@comma\@empty
+ \let\\\eq@displayAltsAns\@nameuse{SavedAltsAns#2}\else
+ \savedAltFmt{\@nameuse{SavedAlts#2-Idx#1}}
+ \@nameuse{SavedAns#2-Idx#1}\fi
+ \egroup
+}
+\newcommand{\useSavedNumAns}[1]{\@nameuse{NumAns#1}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macrocode}
+\long\def\@@@SaveAnsGobbleAns#1\eAns{} % 4/5
+% \end{macrocode}
+% This command gets, and sets the list of alternatives
+% \begin{macrocode}
+\long\def\@getListAns\Ans#1\eAns{%\@@par %start new paragraph
+% \end{macrocode}
+% We record the list as we process each item.
+% \begin{macrocode}
+ \eq@saveAns#1\eAns % 4/5
+ \Ans#1\vspace{\@rowskip}%
+ \@layoutListAns
+}
+\long\def\@lookforendansChoices#1{%
+ \@ifnextchar\eChoices{\rowsep{\rowsep@default}%
+ \expandafter\@findendans\@gobble}{\expandafter#1\@gobble}%
+}
+% \end{macrocode}
+% The argument is the number of columns to typeset, this number
+% is forced to be \texttt{<=} to the number of columns specified in the \texttt{answers}
+% environment.
+% \begin{macrocode}
+\def\@layoutTabularAns#1{%
+ \let\eq@tabSep\@empty
+ \xdef\numShortCols{#1}%
+ \ifnum#1>\aeb@numCols \xdef\numShortCols{\aeb@numCols}\fi
+ \@@layoutTabularAns
+}
+% \end{macrocode}
+% If the next token is \cs{Ans} we grab its all stuff between
+% \cs{Ans} and \cs{eAns} and typeset it and insert the appropriate
+% token, either \texttt{\&} or \texttt{\string\cr}.
+% We continue until the next token is not \cs{Ans}. (This last token
+% should be \cs{eChoices}.)
+% \begin{macrocode}
+\def\@@layoutTabularAns{%
+ \@ifnextchar\Ans{\@getTabAns}%
+ {\@lookforendansChoices{\@@layoutTabularAns}}%
+}
+\def\rowsep#1{\gdef\@rowsep{[#1]}\gdef\@rowskip{#1}}%
+\rowsep{\rowsep@default}
+\def\rowsepDefault#1{\def\rowsep@default{#1}}
+\def\rowsep@default{0pt}
+\long\def\@getTabAns\Ans#1\eAns{%
+ \eq@saveAns#1\eAns
+ \global\advance\eq@tabColCnt1
+ \let\@save@tabSep=\eq@tabSep
+ \ifnum\eq@tabColCnt=\numShortCols
+ \global\eq@tabColCnt=0
+ \xdef\eq@tabSep{\noexpand\\\noalign{\kern\@rowskip\relax}}%
+ \else
+ \gdef\eq@tabSep{&}%
+ \fi
+ \@ifnextchar\eChoices{\@save@tabSep\Ans#1\rowsep{\rowsep@default}
+ \expandafter\@findendans\@gobble}%
+ {\@save@tabSep\Ans#1\@@layoutTabularAns}%
+}
+% \end{macrocode}
+% This command, I think, is executed after we've found the \cs{eChoices}.
+% \begin{macrocode}
+\def\@findendans{\@ifnextchar\end{% 4/5
+% \end{macrocode}
+% If there is a \cs{bChoiceLabel} we process the alternatives.
+% \begin{macrocode}
+ \ifx\bChoiceLabel\@empty\else
+ \processLabeledAns\fi
+ }{\expandafter\@findendans\@gobble}}%
+% \end{macrocode}
+% The command that processes the alternatives.
+% \changes{v6.7g}{2013/08/09}{Changed \texttt{\#1} to \cs{the}\cs{@temptokena} Fixing
+% a nasty bug. Reported by Christopher C.}
+% \begin{macrocode}
+\def\defineEachAns#1{\advance\count0by1\relax
+ \@temptokena={#1}\csarg\xdef
+ {SavedAns\bChoiceLabel-Idx\the\count0}{\the\@temptokena}%
+ \ifsolutionsonly\else
+ {\let\\\relax\eq@IWDefs{\string
+ \csarg\string\gdef{SavedAns\bChoiceLabel-Idx\the\count0}%
+ {\the\@temptokena}}}\fi
+}
+\def\defineEachChoice#1{\advance\count0by1\relax
+ \@temptokena={#1}\csarg\xdef
+ {SavedAlts\bChoiceLabel-Idx\the\count0}%
+ {\the\@temptokena}\ifsolutionsonly\else
+ {\let\\\relax\eq@IWDefs{\string
+ \csarg\string\gdef{SavedAlts\bChoiceLabel-Idx\the\count0}%
+ {\the\@temptokena}}}\fi
+}
+\def\processLabeledAns{%
+ \bgroup
+ \let\label\@gobble
+% \end{macrocode}
+% \changes{v7.7c}{2015/10/08}{Added memory for the case}
+% \begin{macrocode}
+\if\aeb@FLOverride\eq@l
+ \global\@namedef{caseFor\bChoiceLabel}{\graylettersOff}\else
+ \ifaebshowgrayletters
+ \global\@namedef{caseFor\bChoiceLabel}{\graylettersOn}\else
+ \global\@namedef{caseFor\bChoiceLabel}{\graylettersOff}\fi
+\fi
+ \toks@=\expandafter{\@tempholdSaveAns}\csarg
+ \xdef{SavedAns\bChoiceLabel}{\the\toks@}%
+ \ifsolutionsonly\else{\let\\\relax\eq@IWDefs{\string
+ \csarg\string\gdef{SavedAns\bChoiceLabel}{\the\toks@}}}\fi
+ \count0=0\relax\let\\\defineEachAns\the\toks@
+ \xdef\@currNCntAns{\the\count0 }\csarg
+ \xdef{NumAns\bChoiceLabel}{\@currNCntAns}%
+ \ifsolutionsonly\else{\eq@IWDefs{\string
+ \csarg\string\gdef{NumAns\bChoiceLabel}{\the\count0 }}}\fi
+ \toks@=\expandafter{\@tempholdSaveChoice}\csarg
+ \xdef{SavedAlts\bChoiceLabel}{\the\toks@}%
+ \ifsolutionsonly\else{\let\\\relax\eq@IWDefs{\string
+ \csarg\string\gdef{SavedAlts\bChoiceLabel}{\the\toks@}}}\fi
+ \count0=0\relax\let\\\defineEachChoice\the\toks@
+ \count0=1\relax\toks@={}%{\ignorespaces\@gobble}%
+ \loop
+ \edef\temp@exp{\the\toks@\noexpand\\{%
+ \noexpand\useSavedAlts[\the\count0]{\bChoiceLabel}
+ \noexpand\useSavedAns[\the\count0]{\bChoiceLabel}}}%
+ \toks@=\expandafter{\temp@exp}%
+ \ifnum\count0<\@currNCntAns
+ \advance\count0by1
+ \repeat
+ \csarg\xdef{SavedAltsAns\bChoiceLabel}{\the\toks@}%
+ \ifsolutionsonly\else{\let\\\relax\eq@IWDefs{\string
+ \csarg\string\gdef{SavedAltsAns\bChoiceLabel}{\the\toks@}}}\fi
+ \egroup
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macrocode}
+%</package|eqexam>
+% \end{macrocode}
+% \begin{macrocode}
+%<*randomize>
+% \end{macrocode}
+%
+% \subsection{Randomizing the Order of the Multiple Choices}\label{randomize}
+%
+% When the author wants to randomize the multiple choices, we require the \texttt{keyval}
+% package and the \texttt{random.tex} macro file. This works only when using \cs{bChoices}
+% and \cs{eChoices}. The use of \cs{bChoices} and \cs{eChoices} is limited to non-verbatim
+% items.
+%
+% \changes{v6.7f}{2013/08/03}{Added conditional input of random.tex}
+% The \texttt{random.tex}, by Donald Arseneau, provides the random number support.
+% \begin{macrocode}
+\@ifundefined{nextrandom}{\input{random.tex}}{}
+% \end{macrocode}
+% We redefine \cs{nextrandom} from \texttt{random.tex} to save the initializing seed.
+% \begin{macrocode}
+\def\nextrandom{\begingroup
+ \ifnum\randomi<\@ne % then initialize with time
+ \global\randomi\time
+ \global\multiply\randomi388 \global\advance\randomi\year
+ \global\multiply\randomi31 \global\advance\randomi\day
+ \global\multiply\randomi97 \global\advance\randomi\month
+ \message{Randomizer initialized to \the\randomi.}%
+ \nextrandom \nextrandom \nextrandom
+% \end{macrocode}
+% Save the initial seed value to \cs{eqInitSeedValue}.
+% \changes{v6.7f}{2013/08/03}{Save the initial seed value to \cs{eqInitSeedValue}.}
+% \begin{macrocode}
+ \xdef\InitSeedValue{\the\randomi}%
+ \fi
+ \count@ii\randomi
+ \divide\count@ii 127773 % modulus = multiplier * 127773 + 2836
+ \count@\count@ii
+ \multiply\count@ii 127773
+ \global\advance\randomi-\count@ii % random mod 127773
+ \global\multiply\randomi 16807
+ \multiply\count@ 2836
+ \global\advance\randomi-\count@
+ \ifnum\randomi<\z@ \global\advance\randomi 2147483647\relax\fi
+ \endgroup
+}
+% \end{macrocode}
+% The \cs{bChoices} command is now processed by the \texttt{keyval} package. There
+% are two keys: \texttt{nCols} and \texttt{random}. The first key
+% sets the number of columns we are limited to; the second one obviously declares
+% that this list of choices should be randomized, a boolean.
+%
+% We redefine \cs{@ansChoices} above to take key-value optional arguments.
+% We allow for a global override of the random key. If random is true, we
+% call \cs{@@bChoices}, which begins the process of randomization; otherwise
+% we call \cs{@@ansChoices} which is roughly equal to the earlier
+% \cs{@ansChoices}.
+% \changes{v6.1}{2007/10/28}
+% {%
+% Added support for randomizing the multiple choices, requires the use of \cs{bChoices}
+% and \cs{eChoices}.
+% }
+% \begin{macrocode}
+\def\@ansChoices[#1]%
+{%
+ \global\let\@tempholdSaveAns\@empty % 5/24
+ \global\let\@tempholdSaveChoice\@empty % 5/24
+ \global\let\bChoiceLabel\@empty % 5/24
+ \ifeq@randomizeallChoices
+ \setkeys{bchoice}{#1,random=true}\else
+ \setkeys{bchoice}{#1}\fi
+ \global\eq@tabColCnt=0
+ \ifeq@randomizeChoices\expandafter\@@bChoices
+ \else\expandafter\@@ansChoices\fi
+}
+% \end{macrocode}
+% This is actually the old \cs{@ansChoices} only slightly modified.
+% \begin{macrocode}
+\def\@@ansChoices{%
+ \ifnum\aeb@numCols=1 % list mode
+ \def\eq@next{\@layoutListAns}%
+ \else % tabular mode
+ \edef\eq@next{\noexpand\@layoutTabularAns{\bChoiceNumCols}}%
+ \fi
+ \eq@next
+}
+% \end{macrocode}
+% The following are some registers to hold integers and tokens.
+% \begin{macrocode}
+\newcount\aeb@numChoices
+\newcount\aeb@ranChoice
+\newtoks\aeb@hold\aeb@hold={}
+% \end{macrocode}
+% This is the command that begins the randomization of the alternatives.
+% First we initialize some scratch macros to hold the choices, then
+% we look for the next token, if it is \cs{Ans} we then execute \cs{@getAns}
+% otherwise, we're finished.
+% \begin{macrocode}
+\def\@@bChoices{\gdef\@temphold{}\gdef\@tempholdrandom{}%
+ \gdef\@tempholdfreeze{}\aeb@searchfortoken{\@getAns}%
+}
+\def\aeb@searchfortoken#1{%
+ \@ifnextchar\Ans{\advance\aeb@numChoices1\relax#1}
+ {\@ifnextchar\eFreeze{\expandafter\@getFreezeAns\@gobble}
+ {\@ifnextchar\par{\def\@@temp{\aeb@searchfortoken{#1}}%
+ \expandafter\@@temp\@gobble}{\@eChoices}}}%
+}
+% \end{macrocode}
+% The non-frozen questions will be held in the macro \cs{@temphold}.
+% We keep track of the number of choices using the counter \cs{aeb@numChoices}.
+% \begin{macrocode}
+\long\def\@getAns\Ans#1\eAns{%
+ \g@addto@macro\@temphold{{\Ans#1\eAns}}%
+ \aeb@searchfortoken{\@getAns}%
+}
+% \end{macrocode}
+% We've encountered \cs{eFreeze}, if the next token is \cs{Ans}, go get the
+% choices, otherwise, we are finished.
+% \begin{macrocode}
+\def\@getFreezeAns{\aeb@searchfortoken{\@@getFreezeAns}}
+% \end{macrocode}
+% Get the frozen choice, then look for another. Hold these frozen choices
+% in the macro \cs{@tempholdfreeze}.
+% \begin{macrocode}
+\long\def\@@getFreezeAns\Ans#1\eAns{%
+ \g@addto@macro\@tempholdfreeze{\Ans#1\eAns}%
+ \aeb@searchfortoken{\@@getFreezeAns}%
+}
+% \end{macrocode}
+% When we are finished finding all the choices, we come here to randomize the choices.
+% \begin{macrocode}
+\long\def\@eChoices#1\eChoices{%
+ \aeb@randomizeChoices{\the\aeb@numChoices}%
+}
+% \end{macrocode}
+% The routine that randomizes the choices. Basically, we use \texttt{random.tex} to get
+% a random number between one and \cs{aeb@numChoices}, inclusive. Then we search through
+% the list of choices (\cs{@temphold}, moved to \cs{aeb@hold}). The one selected at random
+% is moved to \cs{@tempholdrandom}, and the rest of the choices are moved to \cs{@temphold},
+% here \cs{aeb@hold} is used as a scratch token register.
+% \begin{macrocode}
+\def\aeb@randomizeChoices#1{%
+ \setrannum{\aeb@ranChoice}{1}{#1}
+ \count0=0 \aeb@hold=\expandafter{\@temphold}\def\@temphold{}%
+ \expandafter\@tfor\expandafter
+ \@temp\expandafter:\expandafter=\the\aeb@hold \do {%
+ \advance\count0by1
+ \ifnum\count0=\aeb@ranChoice
+ \aeb@hold=\expandafter\expandafter\expandafter
+ {\expandafter\@tempholdrandom\@temp}%
+ \edef\@tempholdrandom{\the\aeb@hold}%
+ \else
+ \aeb@hold=\expandafter\expandafter\expandafter
+ {\expandafter\@temphold\expandafter{\@temp}}%
+ \edef\@temphold{\the\aeb@hold}%
+ \fi
+ }%
+% \end{macrocode}
+% We repeat this process a total of \cs{aeb@numChoices}, the original count of the number
+% of choices. Once finished, we go to \cs{aeb@finishedRandomizing} to lay out the
+% randomized choices for typesetting.
+% \begin{macrocode}
+ \aeb@numChoices=#1
+ \advance\aeb@numChoices-1
+ \ifnum\aeb@numChoices=0\relax
+ \def\aeb@next{\aeb@finishedRandomizing}\else
+ \def\aeb@next{\aeb@randomizeChoices{\the\aeb@numChoices}}\fi
+ \aeb@next
+}
+% \end{macrocode}
+% This command assembles the questions held in random order in the command \cs{@tempholdrandom} and
+% the frozen ones held in \cs{@tempholdfreeze}, and lays out the choices for typesetting.
+% \begin{macrocode}
+\def\aeb@finishedRandomizing{%
+ \aeb@hold=\expandafter\expandafter\expandafter
+ {\expandafter\@tempholdrandom\@tempholdfreeze}%
+ \gdef\@temphold{}\gdef\@tempholdrandom{}\gdef\@tempholdfreeze{}%
+ \edef\finished@Randomizing{%
+ \noexpand\@@ansChoices
+ \the\aeb@hold
+ \noexpand\eChoices}%
+ \finished@Randomizing
+}
+% \end{macrocode}
+% \begin{macro}{\saveRandomSeed}
+% \begin{macro}{\inputRandomSeed}
+% \begin{macro}{\useRandomSeed}
+%
+% \cs{saveRandomSeed} causes \texttt{exerquiz/eqexam} to save the last random seed used.
+%
+% When you have labels, as we might have in a list of multiple choices, the save feature
+% needs to be turned off for several runs of latex until the label reference
+% becomes up to date.
+%
+% \cs{inputRandomSeed} causes \texttt{exerquiz/eqexam} to input the last random seed used, if
+% one exists, to re-seed the randomization so a new random sequence
+% will be generated. This allows you to get a new sequence every time
+% you latex.
+%
+% (2013/09/17) Made a number of changes so that the randomization of \cs{bChoices}
+% and \cs{eChoices} works well with the \textsf{ran\_toks}. There is a lot of common
+% code, and commands with the same name. I've also change from using the aux file
+% \cs{jobname\_ran.sav} to \cs{jobname\_rt.sav}, the latter being the aux file used
+% by \textsf{ran\_toks}. Now, there share a common aux file and common initial and final
+% seeds.
+% \begin{macrocode}
+%\def\saveRandomSeed{\AtEndDocument{\eq@writeRandomData}}
+\def\saveRandomSeed{\PackageInfo{exerquiz}
+ {The command \string\saveRandomSeed\space
+ is deprecated.\MessageBreak Seed automatically saved}}
+% \end{macrocode}
+% I \cs{let} the commands in this file to the companion commands in \textsf{ran\_toks} file.
+% The user can use either set of commands \cs{inputRandomSeed} or \cs{useLastSeed} as one
+% pair and \cs{useRandomSeed} and \cs{useThisSeed} as the other pair.
+% \begin{macrocode}
+\@ifpackageloaded{ran_toks}{%
+ \let\inputRandomSeed\useLastAsSeed
+ \let\useRandomSeed\useThisSeed
+}{%
+ \def\inputRandomSeed{\eq@readRandomData}%
+ \def\useRandomSeed#1{\saveseedfalse\randomi=#1}%
+}
+\def\InitSeedValue{\the\randomi} % dps
+\@ifundefined{ifsaveseed}{\newif\ifsaveseed\saveseedtrue}{} % dps
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macrocode}
+\def\eq@writeRandomData
+{%
+ \ifsaveseed
+ \@ifundefined{saveseedinfo}{\newwrite\saveseedinfo}{}
+ \immediate\openout \saveseedinfo \jobname_rt.sav
+ \let\verbatim@out\saveseedinfo
+ \def\eqrt@msgi{initializing seed value}%
+ \def\eqrt@msgii{last random number used}%
+ \uccode`c=`\%\uppercase{%
+ \immediate\write\verbatim@out
+ {\InitSeedValue\space c \eqrt@msgi}%
+ \immediate\write\verbatim@out
+ {\the\randomi\space c \eqrt@msgii}%
+ }\immediate\closeout\saveseedinfo
+ \fi
+}
+\AtEndDocument{\eq@writeRandomData}
+% \end{macrocode}
+% Save the data to the file \cs{jobname\_ran.sav}.
+% \begin{macrocode}
+\def\eq@readRandomData{\IfFileExists{\jobname_rt.sav}{%
+ \PackageInfo{exerquiz}{Inputting \jobname_rt.sav}%
+ \@ifundefined{readsavfile}{\newread\readsavfile}{}%
+ \openin\readsavfile=\jobname_rt.sav
+ \read\readsavfile to \InitSeedValue
+ \read\readsavfile to \eqlastRandomNum
+ \closein\readsavfile
+ \randomi=\eqlastRandomNum
+ \xdef\InitSeedValue{\the\randomi}%
+ \immediate\closeout\readsavfile
+}{%
+ \PackageInfo{exerquiz}{\jobname_rt.sav cannot
+ be found, \MessageBreak
+ using the random initializer}%
+}}
+% \end{macrocode}
+% \begin{macrocode}
+%</randomize>
+% \end{macrocode}
+%\subsection{In Support of showgrayletters}
+%
+% This is a hack to reference multiple choice questions when the
+% \texttt{showgrayletters} option is in effect. We define \cs{REF} to
+% return the uppercase version of the letters.
+% \begin{macrocode}
+%<*package|eqexam>
+% \end{macrocode}
+% \begin{macro}{\graylettersOn}
+% \begin{macro}{\graylettersOff}
+% Convenience commands for turning on or off the gray letter feature
+% \begin{macrocode}
+\def\graylettersOn{\aebshowgrayletterstrue}
+\def\graylettersOff{\aebshowgraylettersfalse}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macrocode}
+\def\aeb@exiii{\expandafter\expandafter\expandafter}
+% \end{macrocode}
+% \begin{macro}{\REF}
+% Same syntax as \cs{ref}, including a \texttt{*} option. the
+% \texttt{*} version does not create a link. If
+% \texttt{showgrayletters} is not in effect, then \cs{REF} is
+% equivalent to \cs{ref}.
+%\changes{v6.06c}{2007/04/26}
+%{
+% Added \cs{REF} in support of the \texttt{showgrayletters} option.
+%}
+%\changes{v6.4d}{2011/07/14}{%
+% Correct \cs{REF} so that a link is created.
+%}
+% \begin{macrocode}
+\def\REF{\@ifstar{\let\isREFstar\eq@One\aeb@REFstar}
+ {\let\isREFstar\eq@Zero\aeb@REF}}
+\def\aeb@REFstar#1{\@ifundefined{r@#1}{\hbox{\reset@font\bfseries ??}}
+ {\ifaebshowgrayletters\aeb@buildUpperCaseRef{#1}%
+ \else\ref*{#1}\fi}%
+}
+\def\aeb@REF#1{\@ifundefined{r@#1}{\hbox{\reset@font\bfseries ??}}
+ {\ifaebshowgrayletters\aeb@buildUpperCaseRef{#1}%
+ \else\ref{#1}\fi}%
+}
+%</package|eqexam>
+%<*eqexam>
+\def\aeb@buildUpperCaseRef#1{%
+ \xdef\tmp@expand{\aeb@exiii\@firstoftwo\csname r@#1\endcsname}%
+ \xdef\tmp@expand{\uppercase{\tmp@expand}}\tmp@expand
+}
+%</eqexam>
+%<*package>
+\def\aeb@buildUpperCaseRef#1{%
+ \xdef\tmp@expand{\aeb@exiii\@firstoffive\csname r@#1\endcsname}%
+ \xdef\tmp@expand{\uppercase{\tmp@expand}}%
+ \if\isREFstar\eq@One\tmp@expand\else\hyperref[#1]{\tmp@expand}\fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Circles instead of Rectangles}
+%
+% For quizzes only, there is now an way to use circles for the radio button
+% fields for multiple choice questions (not for multiple selection questions, however).
+%
+% \begin{macro}{\useMCCircles}
+% Execute this command prior to the quiz you want to use circular radio buttons. The command
+% saves the values of \cs{every@qRadioButton} and \cs{every@qCheckBox}, then uses the
+% every mechanism to set the all radio buttons created in a quiz to a circle symbol, we also
+% set all check boxes used in multiple choice question to a transparent border.
+%
+%\changes{v6.3j}{2008/12/08}
+%{
+% Added \cs{useMCCircles} and \cs{useMCCRects}.
+%}
+% \par\medskip\noindent We use a switch to keep track of ``circle mode.'' If the
+% document author invokes \cs{useMCCircles} when we are already in circle mode,
+% \cs{useMCCircles} does nothing.
+% \begin{macrocode}
+\newif\ifaeb@usecircles\aeb@usecirclesfalse
+% \end{macrocode}
+% \begin{macrocode}
+\let\insert@circlesymbol\@empty
+\def\useMCCircles{\useForms
+ \ifaeb@usecircles\else
+ \global\aeb@usecirclestrue
+ \gdef\insert@circlesymbol{\symbolchoice{circle}}%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\useMCRects}
+% We can restore the default behavior by executing \cs{useMCRects} prior to the next quiz.
+% The command restores the state of \cs{every@qRadioButton} and \cs{every@qCheckBox}
+% to their values prior to the last invocation of \cs{useMCCircles}.
+% \begin{macrocode}
+\def\useMCRects{\useForms
+ \ifaeb@usecircles\global\aeb@usecirclesfalse
+ \global\let\insert@circlesymbol\@empty
+ \fi
+}
+\let\useMCCRects\useMCRects
+% \end{macrocode}
+% \end{macro}
+%
+% \section{Objective Style Questions}
+%
+% The code for objective style questions is very simple. The
+% evaluation of the user's response is done by JavaScript. The
+% JavaScript is inserted into the PDF file through DLJS. For
+% authors using \textsf{pdftex} or \textsf{dvipdfm}, this process
+% is automatic; for authors using the distiller (hence, would use
+% the \texttt{dvips} or \texttt{dvipsone} option), the solution is
+% also automatic if you use \textbf{Acrobat 5.0}. If you do not have
+% the latest version of Acrobat, the DLJS must be inserted
+% manually using the \texttt{Document > Insert Pages} menu item. See
+% paragraphs below for a little more detail, or see the manual.
+%
+% There are two kinds of questions that can be posed (actually only one type):
+% (1) a question that has a numerical answer;
+% (2) a question that has a symbolic answer in one variable,
+% $x$. The symbolic answer must reduce, however, to a numerical value when
+% $x$ is given a numerical value. Thus, only questions whose answers can
+% be reduced to numerical values can be posed.
+%
+% If the author has Acrobat 5.0, the \textsf{exerquiz} package should be
+% built using the \texttt{Acrobatv} option in the
+% \textsf{exerquiz.ins} file. In this case, Document level
+% Javascript will be input when the newly distilled file is
+% first opened in the Acrobat Viewer. If the function ``CkBalP'' is
+% undefined, the we input the FDF file contained the Doc Level JS.
+% The file needs to be saved (Save As) for the Doc Level JS to
+% remain in the PDF file.
+%
+% In the case of the author using Acrobat 4.0, he/she needs to load
+% manually insert the \texttt{eq\_DLJS.pdf} file. If only exercises
+% are used, this insertion is not needed.
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+% \begin{environment}{oQuestion}
+% This was my first attempt and I have not deleted it from the package yet.
+% Useful for posing a single question only. The argument is the (unique) name
+% of this question. This name is used to define the macro \cmd{\oField} which is used
+% by support macros. The \texttt{shortquiz} environment can also be used for
+% single/multiple questions as well.
+% \begin{macrocode}
+\let\oqpriorhook\@empty
+\newenvironment{oQuestion}[1]{%
+% \end{macrocode}
+% (06/08/10) The next two lines initialize the macros for registering the
+% question label, i.e., \texttt{2(a)(ii)}. These two lines are repeated for
+% the \texttt{shortquiz} and \texttt{quiz} environments.
+% \begin{macrocode}
+ \let\@currentQues\@empty
+ \xdef\eq@pageThisQ{\the\c@page}%
+ \global\let\eqQzQuesList\@empty
+ \xdef\oField{#1}\xdef\curr@quiz{#1}\xdef\currQuiz{#1}%
+ \let\@qzsolndest\@empty
+ \stepcounter{questionno}%
+ \let\eqQuizType\isSQZ\gdef\eqPTs{1}\global\let\eqQT\eq@na
+ \let\answers\answers@sq
+ \let\endanswers\endanswers@sq
+ \let\manswers\manswers@sq
+ \let\endmanswers\endmanswers@sq
+ \let\solution\solution@sq
+ \let\endsolution\endsolution@sq
+ \noindent\oqpriorhook\sq@IDTxtField\ifx\aebTitleQuiz\@empty
+ \else\aebtitleQuiz\fi\ignorespaces
+}{%
+ \global\let\aebtitleQuiz\@empty
+ \global\let\aebTitleQuiz\@empty
+ \global\let\eq@tq@star\relax
+}
+\def\oSolution#1{\edef\@qzsolndest{#1}}
+% \end{macrocode}
+% \end{environment}
+% \begin{macro}{\replaceExclPt}
+% When processing a mathematical expression, replace \texttt{n!} or \texttt{(n)!} with
+% \texttt{fact(n)}. Used with the \texttt{combinatorics} option of \textsf{dljslib} package.
+% \begin{macrocode}
+\def\replaceExclPt#1{\def\replaceexclaim{#1}}
+\replaceExclPt{false}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\negPointsAllowed}
+% Used with the \texttt{ProcessMultiSelection} when processing \texttt{manswers} environments.
+% The default is not to allow the score to go below 0. By executing \cs{negPointsAllowed}
+% in the preamble, we allow the score to go below zero.
+%\changes{v6.3i}{2008/10/22}
+%{
+% Added \cs{negPointsAllowed} to allow negative scores on quizzes. This is only relevant
+% when the quiz has a \texttt{manswers} environment.
+%}
+% \begin{macrocode}
+\def\negPointsAllowed{\def\negpointsallowed{true}}
+\@onlypreamble{\negPointsAllowed}
+\def\negpointsallowed{false}
+\def\negPointsMarkupAllowed{\def\negpointsmarkupallowed{true}}
+\def\negpointsmarkupallowed{false}
+\@onlypreamble{\negPointsMarkupAllowed}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\requireAlertBox}
+% Turn off the ``Do not show this message again'' checkbox for objective questions
+% and multiple choice questions.
+%\changes{v6.3m}{2010/01/27}
+%{
+% Added \cs{requireAlertBox} to turn off the ``Do not show this message again'' checkbox for objective questions.
+%}
+%The alert box displays the message \cs{doNotShowAgainMsg} which by default is
+%``Do not show this message again''
+% \begin{macrocode}
+\def\requireAlertBox{\def\bcheckboxused{false}}
+\def\allowNoAlertBox{\def\bcheckboxused{true}}
+\allowNoAlertBox
+% \end{macrocode}
+% \end{macro}
+% \subsection{Math Fill-In Questions}
+% \begin{macro}{\RespBox}
+% \begin{macro}{\RespBoxMath}
+% \begin{macro}{\RespBoxNT}
+% \cmd{\RespBox} and \cmd{\RespBoxNT} lay out a text box, into which the
+% user enters his/her response to the question. \cmd{\RespBox} expects the presence
+% of \cmd{\sqTallyBox}, whereas \cmd{\RespBoxNT} does not (NT = No Tally ).
+%\par\medskip
+% Usage: |\RespBox[#1]#2(#3)[#4]#5#6#7#8[#9]*#10|
+% \begin{description}
+% \item[\ttfamily\#1 :] Optional parameter used to modify the appearance of the
+% text field.
+% \item[\ttfamily\#2 :] The correct answer to the question.
+% This must be a numerical value, or a function of one variable.
+% JavaScript Note:
+% In JavaScript, functions such as \texttt{sin(x)} and \texttt{cos(x)} are
+% methods of the \texttt{Math} object. It is not necessary, however, to
+% type \texttt{Math.sin(x)} or \texttt{Math.cos(x)}; this is done by inserting
+% the expression into a \texttt{with(Math)} group.
+% \item[\ttfamily\#3 :] An optional parameter, \textit{delimited by parentheses},
+% that defines the independent variable; \texttt{x}, is the default value. Note
+% that this parameter is set off by parentheses. For a multivariate question, just
+% list the variables in juxtaposition, \texttt{(xyz)}. An alternate method is to
+% delimit with commas \texttt{(x,y,n)} and include the type of the variables
+% \texttt{(r:x,r:y,i:n)}, where \texttt{"r"} means a real variable and \texttt{"i"}
+% means an integer variable. The variables must be either of the old style (no commas, no typing)
+% or the new style. Do not mix the styles.
+% \item[\ttfamily\#4 :] Optional, a named destination to the solution to the
+% question. If this parameter appears, then a solution must follow the
+% question, enclosed in a \texttt{solution} environment.
+% Alternately, the fourth parameter can be a `\texttt*', in which case, we have
+% automatic naming of the destination, namely, \texttt{[\string\curr@quiz.\string\thequestionno]}
+% \item[\ttfamily\#5 :] The number of samples points to be used, usually $3$ or $4$ is
+% sufficient.
+% \item[\ttfamily\#6 :] Precision required, the $\epsilon$ value, if you will.
+% \item[\ttfamily\#7 :] Parameters \#7 and \#8 are used to define the interval from
+% which to draw the sample points. There are two forms: (1) \#7 is the left-hand endpoint
+% of the interval and \#8 is the right-hand endpoint (the use of \#7 and \#8 in this form
+% is deprecated); (2) the interval is defined by standard interval notation, \texttt{[a,b]}.
+% For a multivariate question---one where parameter \#2 lists more than one variable,
+% separate the intervals for each variable by a `x', \texttt{[0,2]x[1,2]x[3,4]}.
+% \item[\ttfamily\#8 :] (1) \#8 is the right-hand endpoint of the interval (the use of this
+% parameter is deprecated); (2) in the second
+% case, \#8 is not used.
+% \item[\ttfamily\#9 :] This optional parameter is either the name of a customized
+% comparison function \textit{or} a JavaScript object with at most two properties:
+% \texttt{priorParse} and \texttt{comp}. See the demo file \texttt{integer\_tst.tex} for
+% examples of usage.
+% \item[\ttfamily\#10:] (Only detected if following an asterisk, `\texttt*')
+% The name of a JavaScript function that is to be used to process the user input.
+% \end{description}
+% Example:
+%\begin{flushleft}\footnotesize
+%|\RespBoxMath{<exp(t), 2*t, sin(t)>}(t)[soln]{3}{.0001}{[0,1]}[compare]*{ProcVec}|
+%\end{flushleft}
+% or (the deprecated form)
+%\begin{flushleft}\footnotesize
+%|\RespBoxMath{<exp(t), 2*t, sin(t)>}(t)[soln]{3}{.0001}{0}{1}[compare]*{ProcVec}|
+%\end{flushleft}
+% \begin{macrocode}
+\newcommand\RespBoxNT{\def\rbFlag{0}\@RespBox}
+\newcommand\RespBox{\def\rbFlag{0}\@RespBox}
+\newcommand\RespBoxMath{\def\rbFlag{0}\@RespBox}
+% \end{macrocode}
+% These commands can be used define the default appearance of the \cs{RespBoxMath},
+% \cs{RespBoxTxt} et al. This first set controls all standard text fields.
+% \begin{macrocode}
+% \end{macrocode}
+% Get any changes in the appearance of the text box
+% \changes{v6.4c}{2011/07/01}{\cs{RespBoxMath} now records its lists of
+% independent variables under the global variable \texttt{\_mathVars}.}
+% \begin{macrocode}
+\begin{defineJS}[%
+ \catcode`\%=14\relax\catcode`\@=0\relax]{\AAKqRespBoxMath}
+if(event.willCommit){
+ RecordPointValue(@eqPTs,@thequestionno@ifx@grpquestions1,%
+@thegrpquestionno,@grpPointValue,@grpTotalWeight,%
+"@grpEvalFunction"@fi);
+ RecordProblemType("@eqQT",@thequestionno);
+ _mathVars=@indepVar;
+ var retn = @processJSfunc(@rbArgs,@compareJSfunc);
+ ProcUserResp(retn,event.value,@thequestionno,%
+0@ifx@grpquestions1,@thegrpquestionno@fi);
+}
+if (!isQuizInitialized("@currQuiz")) {
+ @eqObjAlert@space eqAppAlert(InitMsg("@bqlabelISO"),3);
+ event.rc = false;
+}
+\end{defineJS}
+\def\RespBoxMathDefaults
+{%
+ \BC{0 0 0}\S{S}\textColor{0 g}\F{\FPrint}\W{1}
+}
+\def\moreRespBoxMathDefaults
+{%
+ \edef\@moreRespBoxMathDefaults{%
+ \if\eqQuizType\isQZ\ifx\eq@online\eq@YES
+ \ifeq@noquizsolutions
+ \else\noexpand\Ff{\FfReadOnly}\fi\fi\fi
+ }%
+}
+\let\eqFormatArg\@empty
+\def\@@RespBoxMathActions
+{%
+ \AA{\if\eqQuizType\isQZ
+ \AAKeystroke{\AAKqRespBoxMath\eqAAKeystrokeArg}
+ \AAFormat{\eqFormatArg}
+ \else
+ \AAKeystroke{if(event.willCommit) {\r\t
+ _mathVars=\indepVar;\r\t
+ retn=\processJSfunc(\rbArgs,\compareJSfunc);\r
+\if\@sqTurnOffAlerts1
+ \t OnBlurRespBox(%
+ \if\@sqTurnOffAlerts1retn\else null\fi,"\curr@quiz");
+ \eqAAKeystrokeArg\r
+\fi
+ }%
+ }
+ \AAFormat{\eqFormatArg}%
+ \AAOnFocus{\JS{var retn = null;}}%
+ \AAOnBlur{\JS{OnBlurRespBox(null,"\curr@quiz");}}%
+ \fi
+ }
+}
+\newcommand\@RespBox[1][]
+{%
+ \eq@AddProbToQzQuesList
+ \smallskip\ifx\grpquestions\eq@Zero
+ \addtocounter{eqpointvalue}{\eqPTs}\fi
+ \if\eqQuizType\isQZ
+ \def\rbFlag{1}\global\IsRespBoxtrue
+ \ifx\grpquestions\eq@One
+ \stepcounter{grpquestionno}%
+ \def\Fld@name{%
+ grpobj.\curr@quiz.\thequestionno.\thegrpquestionno}%
+ \else
+ \eq@recordThesePTs\eq@recordProbType
+ \edef\eqtmp{\aPointType}%
+ \xdef\aPointType{\eqtmp,[\eqPTs,"math"]}%
+ \stepcounter{questionno}%
+ \def\Fld@name{obj.\curr@quiz.\thequestionno}%
+ \fi
+ \else % shortquiz
+ \ifx\grpquestions\eq@One
+ \stepcounter{grpquestionno}%
+ \def\Fld@name{%
+ grpobj.\oField.\thequestionno.\thegrpquestionno}%
+ \else
+ \stepcounter{questionno}%
+ \def\Fld@name{%
+ obj.\oField.\thequestionno}%
+ \fi
+ \fi
+% \end{macrocode}
+% Changed (v6.3f, 2008/10/08) the command \cs{array} to \cs{Array} to avoid clashing with the
+% array command defined in \texttt{amsmath}.
+% \begin{macrocode}
+ \let\Array\aeb@array
+ \moreRespBoxMathDefaults
+% \end{macrocode}
+% (2014/01/23) This is tricky, I'm enclosing \cs{text@@Field} in an \cs{mbox}, beginning here
+% \begin{macrocode}
+ \leavevmode\hbox\bgroup\text@@Field{#1}{\Fld@name}%
+ {\RBW}{\DefaultHeightOfWidget}%
+ {\eq@protect\AA}{\eq@setWidgetProps\eq@RespBox}%
+ {\RespBoxMathDefaults\@moreRespBoxMathDefaults
+ \@@RespBoxMathActions\every@eqTextField\every@RespBoxMath}%
+}
+% \end{macrocode}
+% Get the second parameter, which is the correct answer to the question, and
+% test to see if there is a specification for the optional third parameter,
+% which is the variable list, `\texttt x' is the default.
+% \begin{macrocode}
+\def\eq@RespBox#1{\gdef\eqCorrectAns{#1}\if\grpquestions\eq@Zero
+% \end{macrocode}
+% If not within a \texttt{mathGrp} environment, if within a MCFI command pair we save the author's
+% answer as \cs{s@veCorrAnsMCFI}; otherwise, we record the author's answer. If within
+% \texttt{mathGrp} environment, we record is as part of the group array to be use later.
+% \begin{macrocode}
+ \ifwithinMCFI\gdef\s@veCorrAnsMCFI{"#1"}\else
+% \eq@recordCorrAns{"#1"}
+\fi\else\eq@recordGrpAnsArray{"#1"}\fi
+ \@ifnextchar({\@eq@RespBox{#1}}{\@eq@RespBox{#1}(x)}}
+% \end{macrocode}
+% Pick up the optional third parameter, then test whether the optional fourth parameter is there.
+% There are two forms: the [mydest] an explicit destination for the solution to the problem, or
+% a `\texttt*', in which case, we have automatic naming, the name is
+% \texttt{[\string\curr@quiz.\string\thequestionno]}.
+% \begin{macrocode}
+\def\@eq@RespBox#1(#2){\@ifnextchar[{\@eq@RespB@x{#1}(#2)}%
+ {\@ifstar{\@eq@RespB@x{#1}(#2)[\curr@quiz.\thequestionno]}%
+ {\@eq@RespB@x{#1}(#2)[]}}}
+% \end{macrocode}
+% Now get the next three parameters: the number of samples, the precision, and the first of the
+% two interval parameters.
+% \begin{macrocode}
+\def\eq@ZERO{0}
+\def\defaultRDPrecision#1{\def\eq@defaultRDPrecision{#1}}
+\defaultRDPrecision{1E-14}
+% \end{macrocode}
+% dps/change 02/23/07 Here we try to implement a suggest of Bruce Wagner. If the tolerance
+% is set to zero, then use \texttt{reldiffCompare} as the default compare, and set the tolerance
+% to some small value. Here, the small value is the value of the command
+% \cs{eq@defaultRDPrecision} which can be set by \cs{defaultRDPrecision}. The default definition
+% is \verb!\defaultRDPrecision{1E-14}!.
+% \begin{macrocode}
+\def\@eq@RespB@x#1(#2)[#3]#4#5#6{\xdef\@qzsolndest{#3}%
+ \def\indepVar{"#2"}\def\eq@precision{#5}%
+ \ifx\eq@precision\eq@ZERO
+ \def\eq@defaultCompare{reldiffCompare}%
+% \end{macrocode}
+% (2017/01/11) Replace \texttt{\#1} by \cs{eqCorrectAns} to delay expansion
+% \changes{v7.8d}{2017/01/11}{Replace \string\texttt{\#1} by \string\cs{eqCorrectAns} to delay expansion}
+% \begin{macrocode}
+ \def\rbArgstmp{%
+ \rbFlag,"\eqCorrectAns",#4,\eq@defaultRDPrecision}\else
+ \def\eq@defaultCompare{diffCompare}%
+ \def\rbArgstmp{\rbFlag,"\eqCorrectAns",#4,#5}\fi
+% \end{macrocode}
+% We have arrived at the first of possibly two parameters that define the interval(s)
+% from which to sample random points. There are two forms, the old style (deprecated)
+% and the new style. We must detect which form this is.
+% \par\medskip\noindent
+% (10/10/11) To support \cs{viidna}, we expand \texttt{\#6} first before passing it
+% to the command \cs{@checkforInterval}.
+% \begin{macrocode}
+ \edef\eq@ixparam{#6}%
+ \expandafter\@checkforInterval\eq@ixparam\\%
+}
+% \end{macrocode}
+% \DescribeMacro{\viidna} is used with the \texttt{satisfyEq} for the seventh parameter,
+% these routines do not use the ninth, but there needs to be something that does not
+% stop compilation.
+% \begin{macrocode}
+\def\viidna{[]}
+% \end{macrocode}
+% If the next token is a `\texttt[', then that signals the beginning of an interval
+% such as \texttt{[a,b]}, must be the new style. The second parameter is not
+% needed, and not expected in this case. It would be a mistake to include it.
+% \begin{macrocode}
+\def\@checkforInterval{%
+ \@ifnextchar[{\@checkforIntervali}{\@checkforIntervalii}}
+% \end{macrocode}
+% This is the case of the new style of defining the interval. We insert it into the
+% arguments list, and continue on to the next stage.
+%
+% I have detected a problem when the ninth parameters is a JavaScript object and the left brace
+% is next to the left bracket. Somehow, the left brace and right brace get absorbed. We do a
+% work around, and insert a space after the left bracket.
+% \begin{macrocode}
+\def\@checkforIntervali#1\\{%
+ \def\rbArgs{\rbArgstmp,"#1",\indepVar}%
+ \@ifnextchar[{\@eq@@RespBox[ \expandafter\@gobble}%
+ {\@eq@@RespBox[\eq@defaultCompare]}%
+}
+% \end{macrocode}
+% This is assumed to be the old style for defining the interval. In this case, the next
+% token is the right-hand endpoint of the interval, we need it. It would be a mistake
+% \texttt{not} to include it. We also test for the presence of the optional
+% of a customized comparison function, parameter \texttt{\#9}
+% \begin{macrocode}
+\def\@checkforIntervalii#1\\#2{%
+ \def\rbArgs{\rbArgstmp,"[#1,#2]",\indepVar}%
+ \@ifnextchar[{\@eq@@RespBox}{\@eq@@RespBox[\eq@defaultCompare]}%
+}
+% \end{macrocode}
+% Finally, we see if there will be a 10th parameter by seeing if `\texttt*' comes
+% next. We change the catcodes here, so we can have a left and right brace in the
+% optional argument \#9. Hope it works. dps 12/30/03
+%\changes{v6.4g}{2011/07/21}{%
+% Changing the definition of \cs{@eq@@RespBox}, removing the change
+% in \cs{catcode}s. If this causes problems, can restore the
+% old definition.
+%}
+% \begin{macrocode}
+%\def\@eq@@RespBox{\begingroup\catcode`\<=1\relax\catcode`\>=2\relax
+% \catcode`\{=12\relax\catcode`\}=12\relax\@eq@@@RespBox}
+%\def\@eq@@@RespBox[#1]{\endgroup\@ifstar{\jsRespBox[#1]}%
+% {\jsRespBox[#1]{ProcResp}}}
+% \end{macrocode}
+% Below is an alternate (and obvious) definition for \cs{@eq@@RespBox}. Whatever
+% reason I had to change the catcodes, I don't remember, and things seem to work
+% without it. But, will keep things as they are.
+% \begin{macrocode}
+\def\@eq@@RespBox{\@eq@@@RespBox}
+\def\@eq@@@RespBox[#1]{\@ifstar{\jsRespBox[#1]}%
+ {\jsRespBox[#1]{ProcResp}}}
+\def\eq@ProcRespIntervals{ProcRespIntervals}
+\def\jsRespBox[#1]#2{\def\compareJSfunc{#1}%
+ \def\processJSfunc{#2}\gdef\g@processJSfunc{#2}% 01/11
+% \end{macrocode}
+% (2017/01/11) Run answer through \cs{pdfstringdef} if
+% \texttt{ProcRespIntervals} is used to avoid unbalanced parentheses.
+% \changes{v7.8d}{2017/01/11}{Run answer through \string\cs{pdfstringdef} if
+% \string\texttt{ProcRespIntervals} is used.}
+% \begin{macrocode}
+ \ifx\eq@ProcRespIntervals\g@processJSfunc
+% \end{macrocode}
+% When the response function is \texttt{ProcRespIntervals} there is no `real' math, no subscripts,
+% no superscripts. We turn of the math mode warning before \cs{pdfstringdef}.
+% \begin{macrocode}
+ \let\@inmathwarn@SAVE\@inmathwarn\let\@inmathwarn\@gobble
+% \end{macrocode}
+% When the response function is \texttt{ProcRespIntervals}, there may be unbalanced parentheses, we'll
+% pass \cs{eqCorrectAns} through \cs{pdfstringdef} to escape them.
+% \begin{macrocode}
+ \pdfstringdef{\eqCorrectAns}{\eqCorrectAns}%
+ \let\@inmathwarn\@inmathwarn@SAVE\fi
+ \eq@recordCorrAns{"\eqCorrectAns"}% 01/11
+ \ifeq@proofing\makebox[0pt][l]{\space\math@correctAnswer}\fi
+ \eq@TextField % send to the driver-dependent macro
+% \end{macrocode}
+% (2014/01/23) Closing the \cs{hbox} here, begun at the opening of \cs{text@@Field} above.
+% \begin{macrocode}
+ \egroup
+}
+% \end{macrocode}
+% The primitive \cs{meaning} is used to get a typeset version of the answer for the \texttt{proofing}
+% option. I found it a difficult problem because once the answer is scanned, it has catcodes attached.
+% Once that is done, it is impossible to use standard methods to make a typeset the answer in
+% verbatim mode. This trick appears in the \TeX book. \cs{meaning} inserts additional spaces on occasion,
+% for example, following a period (`.'). Oh, well.
+% \begin{macrocode}
+\def\gobbleMacro#1>{}
+\gdef\math@correctAnswer{%
+ \ttfamily\color{\@proofingsymbolColor}\spaceskip=2pt\xspaceskip=2pt%
+ \expandafter\gobbleMacro\meaning\eqCorrectAns
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%\subsection{Text Fill-In}
+% \begin{macro}{\RespBoxTxt}
+% \begin{macro}{\RespBoxTxtNT}
+% These two macros process open-ended questions that require a text response.
+% There are several ways to customize these macros; as described below.
+% \par\medskip
+% \noindent Usage: |\RespBoxTxt[#1]#2#3[#4]#5<plus listing of alternatives>|
+% \begin{description}
+% \item[\ttfamily\#1 :] Optional parameter used to modify the appearance of the
+% text field.
+% \item[\ttfamily\#2 :] This required parameter is a number that indicates
+% the filtering method to be used. Permissible values of this parameter are
+% \begin{description}
+% \item[\ttfamily -1: ] (The default) The author's and user's answers are not filtered
+% in any way. (Spaces, case, and punctuation are preserved.)
+% \item[\ttfamily 0: ] The author's and user's answers are converted to
+% lower case, any white space and non-word characters are removed.
+% \item[\ttfamily 1: ] The author's and user's answers are converted to
+% lower case, any white space is removed.
+% \item[\ttfamily 2: ] The author's and user's answers are stripped of any
+% white space.
+% \end{description}
+% \item[\ttfamily\#3 :] This parameter a number that indicates the compare
+% method to be used. Permissible values of this parameter are
+% \begin{description}
+% \item[\ttfamily 0: ] (The default) The author's and user's answers are
+% compared for an exact match. (These answers are filtered before they are
+% compared.)
+% \item[\ttfamily 1: ] The user's response is searched in an attempt to
+% get a substring match with the author's alternatives. Additional comparison
+% methods may be added.
+% \end{description}
+% \item[\ttfamily\#4 :] Optional, a named destination to the solution to the
+% question. If this parameter appears, then a solution must follow the
+% question, enclosed in a \texttt{solution} environment.
+% \item[\ttfamily\#5 :] This required parameter is the number of alternative
+% answers that are acceptable. The alternative answers are listed
+% immediately after this parameter. (The example above specified
+% that $4$ alternatives follow.)
+% \end{description}
+% \begin{macrocode}
+\newcommand\RespBoxTxtNT{\def\rbFlag{0}\@RespBoxTxt}
+\newcommand\RespBoxTxt{\def\rbFlag{0}\@RespBoxTxt}
+% \end{macrocode}
+% Pick up any parameters that would modify the appearance of this text field.
+% \begin{macrocode}
+\def\RespBoxTxtOnBlur{OnBlurRespBox(%
+ \if\@sqTurnOffAlerts1retn\else null\fi,"\curr@quiz");}
+\def\eqObjAlert{%
+ \ifx\eqQuizType\isQZ\ifx\eq@online\eq@YES\ifeq@noquizsolutions
+ \else if (false)\fi\fi\fi}
+\begin{defineJS}[%
+ \catcode`\@=0\relax\catcode`\%=14\relax]{\AAKqRespBoxTxt}
+if(event.willCommit){
+ RecordPointValue(@eqPTs,@thequestionno@ifx@grpquestions1,%
+@thegrpquestionno,@grpPointValue,@grpTotalWeight,%
+"@grpEvalFunction"@fi);
+ RecordProblemType("@eqQT",@thequestionno);
+ var retn = ProcRespTxt(@rbTxtAlt);
+ ProcUserResp(retn,event.value,@thequestionno,%
+0@ifx@grpquestions1,@thegrpquestionno@fi);
+}
+if (!isQuizInitialized("@currQuiz")) {
+ @eqObjAlert@space eqAppAlert(InitMsg("@bqlabelISO"),3);
+ event.rc = false;
+}
+\end{defineJS}
+\def\RespBoxTxtDefaults
+{%
+ \BC{0 0 0}\W{1}\S{S}\textColor{0 g}\F{\FPrint}%
+}
+\def\moreRespBoxTxtDefaults
+{%
+ \edef\@moreRespBoxTxtDefaults{%
+ \if\eqQuizType\isQZ\ifx\eq@online\eq@YES
+ \ifeq@noquizsolutions\else
+ \noexpand\Ff{\FfReadOnly}\fi\fi\fi
+ }%
+}
+\def\@@RespBoxTxtActions
+{%
+ \AA{\if\eqQuizType\isQZ
+ \AAKeystroke{\AAKqRespBoxTxt}
+ \else
+ \AAKeystroke{%
+ if(event.willCommit) {\r\t
+ retn = ProcRespTxt(\rbTxtAlt);\r
+\if\@sqTurnOffAlerts1
+ \t\RespBoxTxtOnBlur\r
+\fi
+ }%
+ }
+ \AAOnFocus{\JS{var retn = null;}}
+% \end{macrocode}
+% dps 2/12/05 A fix for Acro7.0, a change in the blur event, must
+% move this event to keystroke so behavior is the same as in previous
+% versions.
+% \begin{macrocode}
+\if\@sqTurnOffAlerts0
+ \AAOnBlur{\JS{\RespBoxTxtOnBlur}}%
+\fi
+ \fi
+ }
+}
+\newcommand\@RespBoxTxt[1][]
+{%
+ \eq@AddProbToQzQuesList
+% \smallskip
+ \ifx\grpquestions\eq@Zero\addtocounter{eqpointvalue}{\eqPTs}\fi
+ \if\eqQuizType\isQZ
+ \def\rbFlag{1}\global\IsRespBoxtrue
+ \ifx\grpquestions\eq@One
+ \stepcounter{grpquestionno}%
+ \def\Fld@name{%
+ grpobj.\curr@quiz.\thequestionno.\thegrpquestionno}%
+ \else
+ \eq@recordThesePTs\eq@recordProbType
+ \edef\eqtmp{\aPointType}%
+ \xdef\aPointType{\eqtmp,[\eqPTs,"text"]}%
+ \stepcounter{questionno}%
+ \def\Fld@name{obj.\curr@quiz.\thequestionno}%
+ \fi
+ \else
+ \stepcounter{questionno}%
+ \def\Fld@name{obj.\oField.\thequestionno}%
+ \fi
+ \moreRespBoxTxtDefaults
+ \leavevmode\hbox\bgroup\text@@Field{#1}{\Fld@name}%
+ {\RBW}{\DefaultHeightOfWidget}%
+ {\eq@protect\AA}{\eq@setWidgetProps\@@RespBoxTxt}%
+ {\RespBoxTxtDefaults\@moreRespBoxTxtDefaults
+ \@@RespBoxTxtActions\every@eqTextField\every@RespBoxTxt}%
+}
+% \end{macrocode}
+% Now get the next two required parameters. Also, see if there is going to be a solution.
+% This can be specified in two ways: (1) By inserting an explicit named destination \texttt{[mydest]}
+% or (2) by specifying a `\texttt*', in which case, automatic naming is performed. The name is
+% \texttt{\string\curr@quiz.\string\thequestionno}, \texttt{[\string\curr@quiz.\string\thequestionno]]} is inserted
+% as the parameter.
+% \medskip\noindent
+% |#1 = filter|, |#2 = comp|
+% \begin{macrocode}
+\def\@@RespBoxTxt#1#2{%
+ \@ifnextchar[{\@@@RespBoxTxt{#1}{#2}}
+ {\@ifstar{\@@@RespBoxTxt{#1}{#2}[\curr@quiz.\thequestionno]}%
+ {\@@@RespBoxTxt{#1}{#2}[]}}}
+% \end{macrocode}
+% |#1 = filter|, |#2 = comp|, |#3 = dest|, |#4 = num_alts|
+% \begin{macrocode}
+\def\eq@ZERO{0}\def\eq@ONE{1}\def\eq@TWO{2}
+\def\@@@RespBoxTxt#1#2[#3]#4{%
+ \xdef\@qzsolndest{#3}%
+ \def\eq@argi{#1}\ifx\eq@argi\eq@ZERO\else
+ \ifx\eq@argi\eq@ONE\else\ifx\eq@argi\eq@TWO\else
+ \def\eq@argi{-1}\fi\fi\fi
+ \def\eq@argii{#2}\ifx\eq@argii\eq@ONE\else\def\eq@argii{0}\fi
+ \begingroup
+ \ifnum\eq@argii=1\relax
+% \end{macrocode}
+% local definitions: \DescribeMacro{\rexpStr}\cs{rexpStr},
+% \DescribeMacro{\\<RegEXP>}|\\|, and \DescribeMacro{\word}\cs{word}.
+% \begin{macrocode}
+ \def\rexpStr##1{\eqbs\eqbs\eqbs\eqbs##1}%
+ \def\\##1{\eqbs\eqbs\eqbs\eqbs##1}%
+ \def\word##1{\\b##1\\b}\def\any{@any@}\fi
+ \xdef\rbTxtAlt{\rbFlag,\eq@argi,\eq@argii}%
+ \global\let\txtAltList\@empty
+ \count0=#4 \ifnum\count0 > 0 \expandafter\@argRead\else
+ \PackageError{exerquiz}{%
+ The fourth required parameter of \string\RespBoxTxt\MessageBreak
+ is required to be a positive integer. You entered\MessageBreak
+ #4\space instead}{Enter a positive integer.}\fi
+}
+\def\@argRead#1{\xdef\jsTempArgs{\txtAltList}%
+ \ifx\txtAltList\@empty\xdef\txtAltList{"#1"}\else
+ \xdef\txtAltList{\jsTempArgs,"#1"}\fi\@@argRead}
+\def\@@argRead{\advance\count0 by-1\relax
+ \ifnum\count0=0\relax
+ \def\eq@next{\endgroup
+ \xdef\rbTxtAlt{\rbTxtAlt,\txtAltList}%
+ \if\grpquestions\eq@Zero
+ \ifwithinMCFI
+ \xdef\s@veCorrAnsMCFI{[\txtAltList]}\else
+ \eq@recordCorrAns{[\txtAltList]}\fi
+ \else
+% \end{macrocode}
+% \changes{v7.8a}{2016/11/18}{Fixed a typo, \string\texttt{...AnsArrayi} should be
+% \string\texttt{...AnsGrpAnsArray}}
+% Fixed typo, changed \cs{eq@recordGrpAnsArrayi} to \cs{eq@recordGrpAnsArray}.
+% \begin{macrocode}
+ \eq@recordGrpAnsArray{[\txtAltList]}%
+ \fi
+ \eq@@RespBoxTxt
+ }%
+ \else
+ \def\eq@next{\@argRead}%
+ \fi\eq@next
+}
+\def\eq@@RespBoxTxt{%
+ \ifeq@proofing\makebox[0pt][l]{\space\txt@correctAnswer}\fi
+ \eq@TextField
+% \end{macrocode}
+% Closing of the \cs{hbox} begun above.
+% \begin{macrocode}
+ \egroup
+}
+% \end{macrocode}
+% If the \texttt{proofing} option is specified, then we type out the author's list of
+% acceptable answers. Again, we use \cs{meaning}, probably not needed here.
+% \begin{macrocode}
+\def\gobbleTxt#1>#2,#3,#4,{}
+\gdef\txt@correctAnswer{\ttfamily\color{\@proofingsymbolColor}%
+ \spaceskip=2pt\xspaceskip=2pt
+ \expandafter\gobbleTxt\meaning\rbTxtAlt
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\RespBoxTxtPC}
+% This is pretty much a copy of \cs{RespBoxTxt}, with slight modifications. Here,
+% we attempt to award partial credit for words that appear in the answer.
+% This is a feature request of Kate of Kenya.
+% \par\medskip
+% \noindent Usage:
+%\begin{verbatim}
+% \RespBoxTxt[#1]#2[#3]#4[<num1>]{<word1>}...[<num_n>]{<word_n>}
+%\end{verbatim}
+% \begin{description}
+% \item[\ttfamily\#1 :] Optional parameter used to modify the appearance of the
+% text field.
+% \item[\ttfamily\#2 :] This required parameter is a number that indicates
+% the filtering method to be used. Permissible values of this parameter are
+% \begin{description}
+% \item[\ttfamily -1: ] (The default) The author's and user's answers are not filtered
+% in any way. (Spaces, case, and punctuation are preserved.)
+% \item[\ttfamily 0: ] The author's and user's answers are converted to
+% lower case, any white space and non-word characters are removed.
+% \item[\ttfamily 1: ] The author's and user's answers are converted to
+% lower case, any white space is removed.
+% \item[\ttfamily 2: ] The author's and user's answers are stripped of any
+% white space.
+% \item[\ttfamily 3: ] The author's and user's answers are converted to
+% lower case only. \emph{This is the recommended value for this function.}
+% \end{description}
+% \item[\ttfamily\#3 :] Optional, a named destination to the solution to the
+% question. If this parameter appears, then a solution must follow the
+% question, enclosed in a \texttt{solution} environment.
+% \item[\ttfamily\#4 :] This required parameter is the number of alternative
+% answers that are acceptable. The alternative answers are listed
+% immediately after this parameter. (The example above specified
+% that $4$ alternatives follow.)
+% \end{description}
+% \begin{macrocode}
+\begin{defineJS}[%
+ \catcode`\@=0\relax\catcode`\%=14\relax]{\AAKqRespBoxTxtPC}
+if(event.willCommit){
+ RecordPointValue(@eqPTs,@thequestionno@ifx@grpquestions1,%
+@thegrpquestionno,@grpPointValue,@grpTotalWeight,%
+"@grpEvalFunction"@fi);
+ RecordProblemType("@eqQT",@thequestionno);
+ var retn = ProcRespTxtPC(@rbTxtAlt);
+@ifx@grpquestions1%
+ ProbValue[@thequestionno][3+@thegrpquestionno]%
+=ProcRespTxtPC.txtPCpCr;@else%
+ ProbValue[@thequestionno]=ProcRespTxtPC.txtPCpCr;@fi
+ ProcUserResp(retn,event.value,@thequestionno,0%
+@ifx@grpquestions1,@thegrpquestionno@fi);
+}
+if (!isQuizInitialized("@currQuiz")) {
+ @eqObjAlert@space eqAppAlert(InitMsg("@bqlabelISO"),3);
+ event.rc = false;
+}
+\end{defineJS}
+\def\@@RespBoxTxtPCActions
+{%
+ \AA{\if\eqQuizType\isQZ
+ \AAKeystroke{\AAKqRespBoxTxtPC}
+ \else
+ \AAKeystroke{%
+ if(event.willCommit) {\r\t
+ retn = ProcRespTxtPC(\rbTxtAlt);\r
+\if\@sqTurnOffAlerts1%
+ \t\RespBoxTxtOnBlur\r
+\fi
+ }%
+ }
+ \AAOnFocus{\JS{var retn = null;}}
+\if\@sqTurnOffAlerts0%
+ \AAOnBlur{\JS{\RespBoxTxtOnBlur}}%
+\fi
+ \fi
+ }
+}
+% \end{macrocode}
+% Here is the beginning of \cs{RespBoxTxtPC}.
+% \begin{macrocode}
+\newcommand{\RespBoxTxtPC}{\def\rbFlag{0}\@RespBoxTxtPC}
+\newcommand\@RespBoxTxtPC[1][]
+{%
+ \eq@AddProbToQzQuesList
+ \smallskip\ifx\grpquestions\eq@Zero
+ \addtocounter{eqpointvalue}{\eqPTs}\fi
+ \if\eqQuizType\isQZ\def\rbFlag{1}\global\IsRespBoxtrue
+ \ifx\grpquestions\eq@One
+ \stepcounter{grpquestionno}%
+ \def\Fld@name{%
+ grpobj.\curr@quiz.\thequestionno.\thegrpquestionno}%
+ \else
+ \eq@recordThesePTs\eq@recordProbType
+ \edef\eqtmp{\aPointType}%
+ \xdef\aPointType{\eqtmp,[\eqPTs,"text"]}%
+ \stepcounter{questionno}%
+ \def\Fld@name{obj.\curr@quiz.\thequestionno}%
+ \fi
+ \else
+ \stepcounter{questionno}%
+ \def\Fld@name{obj.\oField.\thequestionno}%
+ \fi
+ \moreRespBoxTxtDefaults
+ \leavevmode\hbox\bgroup\text@@Field{#1}{\Fld@name}%
+ {\RBW}{\DefaultHeightOfWidget}%
+ {\eq@protect\AA}{\eq@setWidgetProps\@@RespBoxTxtPC}%
+ {\RespBoxTxtDefaults\@moreRespBoxTxtDefaults
+ \@@RespBoxTxtPCActions\every@eqTextField\every@RespBoxTxt}%
+}
+\def\@@RespBoxTxtPC#1{\@ifnextchar[{\@@@RespBoxTxtPC{#1}}
+ {\@ifstar{\@@@RespBoxTxtPC{#1}[\curr@quiz.\thequestionno]}%
+ {\@@@RespBoxTxtPC{#1}[]}}}
+\def\@@@RespBoxTxtPC#1[#2]#3{\xdef\@qzsolndest{#2}%
+ \begingroup
+% \end{macrocode}
+% We make special definitions for retrieving the parameters.
+% \begin{macrocode}
+ \def\rexpStr##1{\eqbs\eqbs\eqbs\eqbs##1}%
+ \def\\##1{\eqbs\eqbs\eqbs\eqbs##1}%
+ \def\word##1{\\b##1\\b}\def\any{@any@}
+ \gdef\rbTxtAlt{\rbFlag,#1,1}% force sub-string match
+ \global\let\txtAltList\@empty
+ \count0=#3 \ifnum\count0>0 \expandafter\@argReadPC\else
+ \PackageError{exerquiz}{%
+ The third required parameter of
+ \string\RespBoxTxtPC\MessageBreak
+ is required to be a positive integer.
+ You entered\MessageBreak #3\space instead}
+ {Enter a positive integer.}\fi
+}
+% \end{macrocode}
+% \texttt{\#1=<num>}, partial credit for this answer, \texttt{\#2=word}.
+% \begin{macrocode}
+\newcommand\@argReadPC[2][0]{\xdef\jsTempArgs{\txtAltList}%
+ \ifx\txtAltList\@empty\xdef\txtAltList{["#2",#1]}\else
+ \xdef\txtAltList{\jsTempArgs,["#2",#1]}\fi\@@argReadPC}
+\def\@@argReadPC{\advance\count0 by-1\relax
+ \ifnum\count0=0\relax
+ \def\eq@next{\endgroup
+ \xdef\rbTxtAlt{\rbTxtAlt,\txtAltList}%
+ \if\grpquestions\eq@Zero
+ \ifwithinMCFI
+ \xdef\s@veCorrAnsFCFI{[\txtAltList]}\else
+ \eq@recordCorrAns{[\txtAltList]}\fi
+ \else
+ \eq@recordGrpAnsArray{[\txtAltList]}%
+ \fi
+ \eq@@RespBoxTxtPC
+ }%
+ \else
+ \def\eq@next{\@argReadPC}%
+ \fi\eq@next
+}
+\def\eq@@RespBoxTxtPC{%
+ \ifeq@proofing\makebox[0pt][l]{\space\txt@correctAnswer}\fi
+ \eq@TextField
+% \end{macrocode}
+% Closing of the \cs{hbox} begun above.
+% \begin{macrocode}
+ \egroup
+}
+% \end{macrocode}
+% \end{macro}
+%\subsection{Essay Fill-In}
+% \begin{macro}{\RespBoxEssay}
+% Here is a simple text field with a multi-line attribute for entering
+% essay-type questions. This question will not be graded by JavaScript,
+% of course; ideally, the response will be submitted to a CGI for storage
+% in a database. The instructor can later bring up the student's response
+% and assign a grade.
+% \begin{macrocode}
+\def\RespBoxEssayDefaults
+{%
+ \BC{0 0 0}\W{1}\S{S}\Ff{\FfMultiline}\rawPDF{}%
+}
+\def\@@RespBoxEssayActions
+{%
+ \AA{\if\eqQuizType\isQZ
+ \AAKeystroke{%
+ if(event.willCommit){\jsR\jsT
+ RecordPointValue(\eqPTs,\thequestionno);\jsR\jsT
+ RecordProblemType("\eqQT",\thequestionno);\jsR\jsT
+ }\jsR
+ if (!isQuizInitialized("\curr@quiz")) {\jsR\jsT
+ @eqObjAlert\space eqAppAlert(%
+ InitMsg("\bqlabelISO"),3);\jsR\jsT
+ event.rc = false;\jsR
+ }%
+ }%
+ \fi
+ }
+}
+\newcommand\RespBoxEssay[3][]
+{%
+ \smallskip\addtocounter{eqpointvalue}{\eqPTs}%
+ \stepcounter{questionno}%
+ \mbox{\text@@Field{#1}{essay.\curr@quiz.\thequestionno}{#2}{#3}%
+ \edef\eqtmp{\aPointType}\xdef\aPointType{\eqtmp,[\eqPTs,"essay"]}%
+ {\eq@protect\AA}{\eq@setWidgetProps\@@RespBoxEssayActions
+ \eq@TextField}{\RespBoxEssayDefaults\every@eqTextField}}%
+}
+% \end{macrocode}
+% \end{macro}
+%\subsection{Fields that Support the Fill-Ins}
+% \begin{macro}{\sqTallyBox}
+% The \cmd{\sqTallyBox} holds the number of incorrect responses to the
+% question. This box is not required to appear. If it does not
+% appear, use \cmd{\RespBoxNT} to prevent the doc level JavaScript
+% from trying to write a nonexistent text field.
+% \begin{macrocode}
+\let\@@sqTallyBoxActions\@empty
+\@ifundefined{calcOrder}{%
+\ifpdf\def\@@sqTallyBoxActions{%
+ \AA{\AAValidate{getTotalTally("\oField");}}}\fi}{}
+\def\sqTallyBoxDefaults
+{%
+ \BC{0 0 0}\W{1}\textColor{1 0 0 rg}\S{I}\Q{2}\Ff{\FfReadOnly}
+}
+\ifpdf\def\@@sqTallyBoxActions{%
+ \AA{\AAValidate{getTotalTally("\oField");}}}\else
+ \let\@@sqTallyBoxActions\@empty
+\fi
+\newcommand\sqTallyBox[1][]
+{%
+ \mbox{\text@@Field{#1}{tally.\oField.\thequestionno}%
+ {\TBW}{\DefaultHeightOfWidget}%
+ {}{\eq@setWidgetProps\eq@TextField}%
+ {\sqTallyBoxDefaults\@@sqTallyBoxActions\every@eqTextField
+ \every@sqTallyBox}}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\sqTallyTotal}
+% This text field stores the tally total. Only used within the
+% \texttt{shortquiz} environment. Takes on optional parameter; this
+% parameter can be used to modify the appearance of the fields.
+% \begin{macrocode}
+\def\sqTallyTotalDefaults
+{%
+ \rawPDF{}\W{1}\BC{0 0 0}\S{I}\textColor{1 0 0 rg}%
+ \Q{2}\Ff{\FfReadOnly}%
+}
+\def\@@sqTallyTotalActions
+{%
+ \AA{%
+ \AAKeystroke{AFNumber_Keystroke(0,0,0,0,"",true);}
+ \AAFormat{AFNumber_Format(0,0,0,0,"",true);}
+ \AACalculate{%
+ AFSimple_Calculate("SUM",new Array("tally.\oField"));
+ }}
+}
+\newcommand\sqTallyTotal[1][]
+{%
+ \mbox{\text@@Field{#1}{tallytotal.\oField}{\TBW}%
+ {\DefaultHeightOfWidget}{\eq@protect\AA}%
+% {\eq@setWidgetProps\eq@calcTextField}%
+ {\eq@setWidgetProps\eq@TextField}%
+ {\sqTallyTotalDefaults\@@sqTallyTotalActions\every@eqTextField
+ \every@sqTallyTotal}}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\CorrAnsButton}
+% The \cmd{\CorrAnsButton} is a button macro which, when pressed, will
+% display the correct answer for the user. This button is again
+% optional. This macro takes one parameter and one optional parameter
+%\begin{verbatim}
+%#1 : the correct answer as the user should enter it.
+%\end{verbatim}
+% The value if \texttt{\#1} may be different from the parameter
+% \texttt{\#2} in \cmd{\RespBox}; for example, if the answer is
+% $x^2$, then \texttt{\#2} of \cmd{\RespBox} would be
+% \texttt{pow(x,2)}; but the user would enter |x^2|.
+%
+% The optional parameter is specified by a star * followed by a
+% name of a JavaScript function. The arguments of this JS function
+% is the same as that of DisplayAnswer. For example,
+%\begin{verbatim}
+%\CorrAnsButton{convertFrac('#1','#2')}*{EvalCorrAnsButton}}
+%\end{verbatim}
+% The JavaScript function might be
+%\begin{verbatim}
+%function EvalCorrAnsButton(fieldname,theanswer)
+%{
+% theanswer = eval(theanswer);
+% DisplayAnswer(fieldname,theanswer);
+%}
+%\end{verbatim}
+% Here, we call a function to evaluate the answer for us.
+% \begin{macrocode}
+\def\CorrAnsButtonDefaults
+{%
+ \CA{\eq@local@CorrAnsButton}\W{1}\S{S}
+ \BC{0 0 0}\BG{.7529 .7529 .7529}\H{P}
+}
+\def\normalCABtnBC{0 0 0}
+ \def\qCorrAnsButtonActionHook
+ {%
+ \JS{%
+ \ifx\@qzsolndest\@empty\else
+ if (event.shift)\jsR\jsT
+ this.gotoNamedDest("\@qzsolndest");\jsR
+ else\jsR\jsT
+ \fi
+ \processJSfunc("Ans.\curr@quiz","\CorrectAns",\currQuiz);
+ }%
+ }
+ \def\sqCorrAnsButtonActionHook
+ {%
+ \JS{%
+% \end{macrocode}
+% Allow local definition the reset color for response boxes. The reset color
+% is normally black (\cs{eqDefaultColor}). Now if \cs{sqCorrAnsResetBC} is none
+% empty, we put it in as a property of the \cs{oField} object.
+% \begin{macrocode}
+ \ifx\@qzsolndest\@empty\else
+ if (event.shift)\jsR\jsT
+ this.gotoNamedDest("\@qzsolndest");\jsR
+ else\jsR\jsT
+ \fi
+ \processJSfunc("obj.\oField.\thequestionno","\CorrectAns",%
+\currQuiz);
+ }%
+ }
+\newcommand\CorrAnsButton[1][]{\eq@@CorrAnsButton{#1}}
+\def\eq@@CorrAnsButton#1#2{\bgroup\makeJSspecials % 1/12
+ \@ifstar{\eq@@@CorrAnsButton{#1}{#2}}{%
+ \eq@@@CorrAnsButton{#1}{#2}{DisplayAnswer}}%
+}
+\def\eq@@@CorrAnsButton#1#2#3{\gdef\CorrectAns{#2}%
+ \def\processJSfunc{#3}%
+ \ifx\eq@ProcRespIntervals\g@processJSfunc % 01/11
+ \let\@inmathwarn@SAVE\@inmathwarn\let\@inmathwarn\@gobble
+% \end{macrocode}
+% When the response function is \texttt{ProcRespIntervals}, there may be unbalanced parentheses, we'll
+% pass \cs{CorrectAns} through \cs{pdfstringdef} to escape them.
+% \begin{macrocode}
+ \pdfstringdef{\CorrectAns}{\CorrectAns}%
+ \let\@inmathwarn\@inmathwarn@SAVE\fi
+ \if\eqQuizType\isQZ\def\Fld@name{corr.\curr@quiz.\thequestionno}%
+ \else\def\Fld@name{corr.\oField.\thequestionno}\fi
+ \if\eqQuizType\isQZ
+ \edef\@@CorrAnsButtonActions{\noexpand\F{\FHidden}%
+ \ifx\@qzsolndest\@empty%\noexpand\BC{\normalCABtnBC}%
+ \else\noexpand\BC{\solution@Color}\fi
+ \noexpand\A{\noexpand\qCorrAnsButtonActionHook}}%
+ \ifeq@noquizsolutions\else
+ \mbox{\push@@Button{#1}{\Fld@name}{}{\DefaultHeightOfWidget}%
+ {\eq@protect\A}{\eq@setButtonProps\eq@Button@driver}%
+ {\CorrAnsButtonDefaults\@@CorrAnsButtonActions
+ \every@ButtonField\every@CorrAnsButton}}%
+ \fi
+ \else
+ \edef\@@CorrAnsButtonActions{%
+ \ifx\@qzsolndest\@empty%\noexpand\BC{\normalCABtnBC}
+ \else\noexpand\BC{\solution@Color}\fi
+ \noexpand\A{\noexpand\sqCorrAnsButtonActionHook}}%
+ \mbox{\push@@Button{#1}{\Fld@name}{}{\DefaultHeightOfWidget}%
+ {\eq@protect\A}{\eq@setButtonProps\eq@Button@driver}%
+ {\CorrAnsButtonDefaults\@@CorrAnsButtonActions
+ \every@ButtonField\every@CorrAnsButton}}%
+ \fi
+ \egroup
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\sqClearButton}
+% This button will clear the tallyfields and change the color of
+% the \cmd{\RespBox} back to \cmd{\defaultColorJS}. The button clears the fields
+% based on the current value of \cmd{\oField}. This text macro is
+% given its value when the optional parameter in the
+% \texttt{shortquiz} environment is specified.
+%\changes{v6.3g}{2008/10/13 }
+%{%
+% Fixed a problem with the clear button not setting the boundary color
+% back to the default. I must have changed the name of an objective field,
+% now, we say \texttt{this.getField("obj.\cs{oField}")}.
+%}
+% \begin{macrocode}
+\def\sqClearButtonDefaults
+{%
+ \CA{\eq@local@sqClearButton}\textColor{0 g}\F{\FPrint}
+ \BC{0 0 0}\BG{.7529 .7529 .7529}\W{1}\S{B}\Ff{\FfNoExport}
+}
+% \end{macrocode}
+% In an attempt to supply some custom colors for the shortquiz, we
+% define \cmd{\sqRespBoxResetColor}. It determines the clear
+% \begin{macrocode}
+\def\@@sqClearButtonActions
+{%
+ \A{\JS{ProcessIt = false;\jsR
+ if ( typeof \oField\space== "undefined" )\jsR\jsT
+ \oField\space= new Object;\jsR
+ if (typeof appAlerts["\oField"] == "undefined")\jsR\jsT
+ appAlerts["\oField"] = new Object;\jsR
+ this.resetForm(new Array("mc.\oField","obj.\oField",%
+ "tally.\oField","grpobj.\oField"));\jsR
+ var f = this.getField("obj.\oField");\jsR
+% \end{macrocode}
+% Here, we give the user an opportunity to designate the color
+% of the response boxes when they are reset by the \cs{sqClearButton}.
+% The default is to use \cs{eqDefaultColor}.
+% \begin{macrocode}
+ if ( f != null ) f.strokeColor=\ifx\defaultColorJSLoc\@empty
+\defaultColorJS\else\defaultColorJSLoc\fi;\jsR
+ f = this.getField("grpobj.\oField");\jsR
+ if ( f != null ) f.strokeColor=\ifx\defaultColorJSLoc\@empty
+\defaultColorJS\else\defaultColorJSLoc\fi;\jsR
+ f = this.getField("rbmarkup.\oField");\jsR
+ if ( f != null ) f.display=display.hidden;\jsR
+ \oField.Grp = {};\jsR
+ appAlerts["\oField"].bAfterValue=false;\jsR
+ ProcessIt=true;}%
+ }
+}
+\newcommand\sqClearButton[1][]
+{%
+ \mbox{\push@@Button{#1}{clear.\oField}{}{\DefaultHeightOfWidget}%
+ {\eq@protect\A}{\eq@setButtonProps\eq@Button@driver}%
+ {\sqClearButtonDefaults\@@sqClearButtonActions\every@ButtonField
+ \every@sqClearButton}}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\@PromptButton}
+% The \cs{@PromptButton} is used to create a ``progressive-style'' question (for math fill-in).
+% Some series of questions build on one another. You can use this button to show the solution
+% for one problem, so the student can try the next problem. On clicking on the prompt button,
+% the student cannot enter another answer in the text field, and the input that is already
+% there will be the one that is counted has the student's response.
+% \begin{macrocode}
+\def\PromptButtonDefaults
+{%
+ \CA{\eq@local@CorrAnsButton}\W{1}\S{S}\BC{0 0 0}
+ \BG{.7529 .7529 .7529}\H{P}
+}
+\newcommand{\promptButtonMsg}{%
+ "Would you like to see the correct answer at this time? "\r\t\t
+ + "Your current answer will be the one that will be scored. "\r\t\t
+ + "If you click on \\"Yes\\",
+ you will not be able to change your answer."
+}
+\newcommand{\AnsPromptBtnStr}{Answer:\space}
+\def\PromptButtonActionHook
+{%
+ \JS{%
+ if (!isQuizInitialized("\currQuiz")) {\r\t
+ eqAppAlert(InitMsg("\bqlabelISO"),3);\r\t
+ event.rc=false;\r
+ } else {\r\t
+ if ( !\currQuiz.oAlertCheck.bAfterValue ) {\r\t
+ var resp=eqAppAlert({\r\t\t
+ cMsg:\promptButtonMsg,\r\t\t
+ nIcon: 2, nType: 2,\r\t\t
+ cTitle: ("AcroTeX Prompt Message"),\r\t\t
+ oCheckbox: \currQuiz.oAlertCheck\r\t
+ });\r\t
+ }\r
+% \end{macrocode}
+% Correction to the if condition below
+% \changes{v7.8d}{2017/01/11}{Correction to the if condition in \string\cs{PromptButtonActionHook}}
+% \begin{macrocode}
+ if ( promptQuiz.oAlertCheck.bAfterValue || resp==4 )\r\t
+ {\r\t\t
+ var field=this.getField(%
+ "obj.\currQuiz.\thequestionno");\r\t\t
+ field.readonly=true;\r\t\t
+ field=this.getField("Ans.\currQuiz");\r\t\t
+ if (field!=null)
+ field.value = "\AnsPromptBtnStr\PromptAns";\r\t
+ }\r
+ }
+ }%
+}
+% \end{macrocode}
+% This button takes the standard two arguments
+% \begin{flushleft}
+% \texttt{\#1}: Optional parameters to change the appearance of the field\\
+% \texttt{\#2}: Prompt answer
+% \end{flushleft}
+% \begin{macrocode}
+\newcommand\@PromptButton[2][]
+{%
+ \def\PromptAns{#2}\if\eqQuizType\isQZ
+ \def\Fld@name{promptButton.\curr@quiz.\thequestionno}%
+ \else\def\Fld@name{promptButton.\oField.\thequestionno}\fi
+ \if\eqQuizType\isQZ
+ \def\@@PromptButtonActions{%
+ \A{\PromptButtonActionHook}}%
+ \mbox{\push@@Button{#1}{\Fld@name}{}%
+ {\DefaultHeightOfWidget}{\eq@protect\A}%
+ {\eq@setButtonProps\eq@Button@driver}%
+ {\PromptButtonDefaults\@@PromptButtonActions
+ \every@ButtonField\every@CorrAnsButton}}%
+ \else\PackageWarning{exerquiz}{The \string\PromptButton
+ is for quiz questions only.}
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+% \DescribeMacro{\PromptButton} is the default definition of the \cs{PromptButton},
+% it can be redefined. The \cs{CorrectAns} command is defined in the
+% \cs{CorrAnsButton} as the answer provided by the author.
+% \begin{macrocode}
+\newcommand{\PromptButton}{\makebox[0pt][r] % assumes xcolor
+ {\@PromptButton[\textColor{1 0 0 rg}]{\CorrectAns}}}
+% \end{macrocode}
+% \begin{environment}{mathGrp}
+% An environment for enclosing a collection of math/text fill-ins that are to be grouped
+% together. This grouping should not cross a begin or end of another environment, or include more
+% an \cs{item}. This environment has two optional arguments:
+%\begin{description}
+% \item[\texttt{[\#1]}] : total weight (needed when sum of weight is greater than total number of points
+% \item[\texttt{[\#2]}] : evaluation function, a JavaScript function to evaluate the user's responses.
+% The default evaluation function is \texttt{groupEval}.
+%\end{description}
+% The way the parsing of the parameters works out, to specify \texttt{\#1}, you must specify
+%\texttt{\#2}.
+% \begin{macrocode}
+\let\eq@ansGrpArray\@empty
+\def\eq@recordGrpAnsArray#1{%
+ \ifx\eq@ansGrpArray\@empty
+ \edef\tmp@exp{\noexpand\g@addto@macro
+ \noexpand\eq@ansGrpArray{#1}}\else
+ \edef\tmp@exp{\noexpand\g@addto@macro
+ \noexpand\eq@ansGrpArray{,#1}}\fi
+ \tmp@exp
+}
+\let\grpquestions\eq@Zero
+\def\mathGrp{\global\let\eq@ansGrpArray\@empty
+ \@ifnextchar[{\@imathGrp}{\@imathGrp[groupEval]}}
+\def\@imathGrp[#1]{\def\argi{#1}%
+ \@ifnextchar[{\@iimathGrp}{\@iimathGrp[]}}
+\def\@iimathGrp[#1]{\def\argii{#1}%
+ \eq@AddProbToQzQuesList
+ \global\let\grpquestions\eq@One
+ \setcounter{grpquestionno}{0}%
+ \stepcounter{questionno}%
+ \xdef\beginGrp{\thequestionno}%
+ \xdef\grpPointValue{\eqPTs}%
+ \eq@recordThesePTs\eq@recordProbType
+ \if\eqQuizType\isQZ
+ \edef\eqtmp{\aPointType}%
+ \xdef\aPointType{\eqtmp,[\eqPTs,"grp"]}\fi
+ \addtocounter{eqpointvalue}{\eqPTs}%
+ \ifx\argii\@empty
+ \xdef\grpTotalWeight{\eqPTs}%
+ \xdef\grpEvalFunction{\argi}%
+ \else
+ \xdef\grpTotalWeight{\argi}%
+ \xdef\grpEvalFunction{\argii}%
+ \fi
+}
+\def\endmathGrp{\global\let\grpquestions\eq@Zero
+ \eq@recordCorrAns{[\eq@ansGrpArray]}%
+ \xdef\endGrp{\thequestionno}}
+% \end{macrocode}
+% \end{environment}
+% \begin{macro}{\CorrAnsButtonGrp}
+% The correct answer button for grouped questions.
+% \begin{macrocode}
+\def\CorrAnsButtonGrpDefaults
+{%
+ \CA{\eq@local@CorrAnsButton}\W{1}\S{S}\BC{0 0 0}
+ \BG{.7529 .7529 .7529}\H{P}
+}
+\def\CorrAnsButtonGrpActionHook{\JS{%
+\ifx\@qzsolndest\@empty\else
+ if (event.shift)\jsR\jsT
+ this.gotoNamedDest("\@qzsolndest");\jsR
+ else\jsR
+\fi
+ {\jsR\jsT
+ var aCorrectAns=\CorrectAns;\jsR\jsT
+ var beginGrp = 1;\jsR\jsT
+ grpOffset = beginGrp;\jsR\jsT
+% if ( typeof \currQuiz == "undefined" ) {\jsR\jsT\jsT
+% \currQuiz = new Object;\jsR\jsT\jsT
+% \currQuiz.Grp = {};\jsR\jsT
+% }\jsR\jsT
+ if ( \currQuiz.Grp==null ) \currQuiz.Grp = {};\jsR\jsT
+ if (typeof \currQuiz.Grp["\thequestionno"]=="undefined")\jsR\jsT
+ {\jsR\jsT\jsT
+ \currQuiz.Grp["\thequestionno"] = {offset: 0};\jsR\jsT\jsT
+ var f = this.getField(%
+ "grpobj.\curr@quiz.\thequestionno."
+ + grpOffset)\jsR\jsT\jsT
+% \end{macrocode}
+% When the field is readonly, then we cannot set the focus. We'll remove the readonly, set focus, then
+% reset readonly to true again; however, we must wait a little for \texttt{setFocus} to finish.
+% \begin{macrocode}
+ if ( f.readonly ) {\jsR\jsT\jsT
+ f.readonly = false;\jsR\jsT\jsT
+ f.setFocus();\jsR\jsT\jsT
+ eqDelay = app.setTimeOut(%
+ "f.readonly = true;
+ app.clearTimeOut(eqDelay);",10);\jsR\jsT
+ } else f.setFocus();\jsR\jsT
+ }\jsR\jsT
+ else \jsR\jsT
+ {\jsR\jsT\jsT
+ \currQuiz.Grp["\thequestionno"].offset =
+ ++\currQuiz.Grp["\thequestionno"].offset
+ \% aCorrectAns.length;\jsR\jsT\jsT
+ grpOffset = beginGrp
+ + \currQuiz.Grp["\thequestionno"].offset;\jsR\jsT\jsT
+ var f = this.getField("grpobj.\curr@quiz.\thequestionno."
+ + grpOffset);\jsR\jsT\jsT
+ if ( f.readonly ) {\jsR\jsT\jsT
+ f.readonly = false;\jsR\jsT\jsT
+ f.setFocus();\jsR\jsT\jsT
+ eqDelay = app.setTimeOut("f.readonly = true;
+ app.clearTimeOut(eqDelay);",10);\jsR\jsT
+ } else f.setFocus();\jsR\jsT
+ }\jsR\jsT
+\if\eqQuizType\isQZ
+ DisplayAnswer("Ans.\curr@quiz",
+ aCorrectAns[\currQuiz.Grp["\thequestionno"].offset],%
+\currQuiz);
+%\ifx\sqCorrAnsResetBC\@empty\else,\currQuiz\fi);\jsR
+\else
+% \end{macrocode}
+% Allow local definition the reset color for response boxes. The reset color
+% is normally black (\cs{eqDefaultColor}). Now if \cs{sqCorrAnsResetBC} is none
+% empty, we put it in as a property of the \cs{oField} object.
+% \begin{macrocode}
+%\ifx\sqCorrAnsResetBC\@empty\else
+% if ( typeof \oField=="undefined")\jsR\jsT\jsT
+% var \oField = new Object;\jsR\jsT
+% \oField.CorrAnsResetBC=\sqCorrAnsResetBC;\jsR\jsT
+%\fi
+ DisplayAnswer("grpobj.\oField.\thequestionno."+ grpOffset,
+ aCorrectAns[\currQuiz.Grp["\thequestionno"].offset],%
+\oField);\jsR
+\fi
+ }
+}}
+\newcommand\CorrAnsButtonGrp[2][]
+{%
+ \makeStringArray{#2}%
+ \edef\CorrectAns{\stringArray}%
+ \if\eqQuizType\isQZ\def\Fld@name{corr.\curr@quiz.\thequestionno}%
+ \else\edef\currQuiz{\oField}%
+ \def\Fld@name{corr.\oField.\thequestionno}\fi
+ \if\eqQuizType\isQZ
+ \edef\@@CorrAnsButtonGrpActions{\noexpand\F{\FHidden}%
+ \ifx\@qzsolndest\@empty%\noexpand\BC{\normalCABtnBC}
+ \else\noexpand\BC{\solution@Color}\fi
+ \noexpand\A{\noexpand\CorrAnsButtonGrpActionHook}}%
+ \ifeq@noquizsolutions\else
+ \mbox{\push@@Button{#1}{\Fld@name}{}{\DefaultHeightOfWidget}%
+ {\eq@protect\A}{\eq@setButtonProps\eq@Button@driver}%
+ {\CorrAnsButtonGrpDefaults\@@CorrAnsButtonGrpActions
+ \every@ButtonField\every@CorrAnsButton}}%
+ \fi
+ \else
+ \edef\@@CorrAnsButtonGrpActions{%
+ \ifx\@qzsolndest\@empty%\noexpand\BC{\normalCABtnBC}
+ \else\noexpand\BC{\solution@Color}\fi
+ \noexpand\A{\noexpand\CorrAnsButtonGrpActionHook}}%
+ \mbox{\push@@Button{#1}{\Fld@name}{}{\DefaultHeightOfWidget}%
+ {\eq@protect\A}{\eq@setButtonProps\eq@Button@driver}%
+ {\CorrAnsButtonGrpDefaults\@@CorrAnsButtonGrpActions
+ \every@ButtonField\every@CorrAnsButton}}%
+ \fi
+}
+\def\makeStringArray#1{\def\stringArray{[}\@makeStringArray#1,\@nil}
+\def\@makeStringArray#1,#2\@nil{%
+ \edef\eq@temp{\stringArray}\def\argii{#2}%
+ \ifx\argii\@empty
+ \edef\stringArray{\eq@temp"#1"]}%
+ \def\eq@next{}%
+ \else
+ \edef\stringArray{\eq@temp"#1",}%
+ \def\eq@next{\@makeStringArray#2\@nil}%
+ \fi
+ \eq@next
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \section{Quiz Summary Tables}
+%
+% This code is designed for use with a \texttt{quiz}, as opposed to a
+% \texttt{shortquiz}. Insert the command \cs{displaySumryTbl} after the
+% end of the quiz, but before \verb!\end{quiz}!. The expansion of
+% \cs{displaySumryTbl} is a table summarizing the user's effort on the
+% quiz, indicating which questions had responses, and which did not.
+%\par\medskip\noindent
+% (06/08/10) We define \cs{eq@AddProbToQzQuesList}, which adds the current question label to
+% the list \cs{eqQzQuesList}. The command \cs{@eqListExp} is initially defined
+% to be \cs{relax} and is redefined just before \cs{eqQzQuesList} is expanded.
+% \begin{macrocode}
+\let\@eqListExp\relax
+\let\@currentQues\@empty
+\let\eqQzQuesList\@empty
+\def\eq@AddProbToQzQuesList{%
+ \edef\eq@tmpExp{\noexpand\g@addto@macro%
+ \noexpand\eqQzQuesList{%
+ \noexpand\@eqListExp{\@currentQues}{\thepage}}}%
+% \end{macrocode}
+% We add to the list only if we are not within a \texttt{mathGrp} environment.
+% \begin{macrocode}
+ \ifx\grpquestions\eq@Zero\eq@tmpExp\fi
+}
+% \end{macrocode}
+% \begin{macrocode}
+%</package>
+%<*sumrytbls>
+% \end{macrocode}
+% The command below is convenience command to concatenate the current quiz with
+% another string. The reason the parameter is enclosed in parenthesis is that
+% the command is (sometimes) executed in a limited verbatim environment were the
+% catcodes of our friendly braces have been changed.
+% \begin{macrocode}
+\def\ccatCurrQzWith(#1){\currQuiz#1}
+% \end{macrocode}
+% This is the JavaScript action for the push button \cs{pbPopulateSumTable}.
+% The code is activated when the page becomes visible. The code reads through
+% the Responses array and determines which questions were answered, and checks
+% the appropriate box. (Version 6 or greater)
+% \begin{macrocode}
+% \end{macrocode}
+% This zero width/height push button is hidden at the top of the table. When
+% the page that contains the button, the JS is executes.
+% \begin{macrocode}
+\def\pbPopulateSumTable{\pushButton[\W0\BG{}\BC{}\S{S}\autoCenter{n}
+ \TU{\thequestionno}\Ff{\FfReadOnly}
+ \AA{\AAPageVisible{try{popVisitsTbl("\currQuiz",\thequestionno)}%
+ catch(e){}}}]{\currQuiz activateSC}{0pt}{0pt}}
+% \end{macrocode}
+% (2013/12/29) Here are some ideas to think about. Each change in the response to a question
+% can execute the following code. I've put the needed information in the tooltip
+% above, the code below extracts this information and calls \texttt{popVisitsTbl}
+% in this way, the summary need to be required to appear on separate page.
+%\begin{verbatim}
+%f=this.getField("\currQuiz activateSC");
+%v=f.userName
+%v=v.split(",")
+%popVisitsTbl.apply(null,v)
+%\end{verbatim}
+% \begin{macrocode}
+\def\pbDoNoCorrectSumryTbl{\makebox[0pt][l]{\pushButton[\F{\FHidden}]%
+ {\currQuiz NoCorrections}{0pt}{0pt}}}
+% \end{macrocode}
+% A scratch counter to count the number of row entries we have created.
+% \begin{macrocode}
+\newcount\eq@rowcnt
+% \end{macrocode}
+% \begin{macro}{\sumryTblQ}
+% \begin{macro}{\sumryTblR}
+% \begin{macro}{\sumryTblP}
+% Through these commands, the author can change the title headings of the summary table.
+% \begin{macrocode}
+\newcommand{\sumryTblQ}{Question}
+\newcommand{\sumryTblR}{Responded}
+\newcommand{\sumryTblP}{Page}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\displaySumryTbl}
+% Place this command between the end of the quiz \textbf{on a new page} (after the closing of the
+% last \texttt{questions} environment and before \verb!\end{quiz}!.
+%
+% The \cs{displaySumryTbl} takes two parameters, one optional and one required.
+%\begin{description}
+% \item[{[\texttt{\#1}]}] is optional and takes key-value pairs
+% \begin{itemize}
+% \item \texttt{ntables}\IndexKey{ntables} is a key that has a value of 1, 2, or 3, the default is determined by
+% \cs{smrytbl@ntables}, which is set to 2 in this package. If
+% \texttt{ntables=1} only one table is created, and if \texttt{ntables=2}
+% two tables are created, each containing half the information.
+% \item \texttt{showmarkup}\IndexKey{showmarkup}: If this switch is true, then markup fields are
+% created that will hold the number of points the student received for
+% each problem. The default is there is no markup. Entering
+% \texttt{showmarkup} in the option list will generate the markup fields.
+% \item \texttt{nocorrections}\IndexKey{nocorrections}: If this switch is true, corrections will not
+% be shown when the user presses the `End Quiz' button.
+% \item \texttt{showOutOf}\IndexKey{showOutOf}: if taken the point and total points for the problem are displayed.
+% For example, `2 of 5 pts'.
+% \item \texttt{setDimens}\IndexKey{setDimen} is a key to pass its value within group created by
+% the command \cs{displaySumryTbl}. Use it to use the conditional switches to set the
+% dimensions of the markup text fields, color declarations, font declarations, etc.
+% None of it should take up space of any kind.
+% \end{itemize}
+% \item[\texttt{\#2}] is the quiz this table represents, usually this is \cs{currQuiz}.
+%\end{description}
+% \begin{macrocode}
+\define@key{smrytbl}{ntables}{%
+ \@tempcntb=#1
+ \ifnum\@tempcntb<1 \@tempcntb=1 \fi
+ \ifnum\@tempcntb>3 \@tempcntb=3 \fi
+ \edef\smrytbl@ntables{\the\@tempcntb}%
+}
+\def\smrytbl@ntables{2}
+\define@key{smrytbl}{showmarkup}[true]{%
+ \csname if#1\endcsname\eqshowmarkuptrue
+ \else\eqshowmarkupfalse\fi
+}
+\newif\ifsmrytbl@corrections\smrytbl@correctionstrue
+\define@key{smrytbl}{nocorrections}[true]{%
+ \csname if#1\endcsname\smrytbl@correctionsfalse
+ \else\smrytbl@correctionstrue\fi
+}
+\define@key{smrytbl}{showOutOf}[true]{%
+ \csname if#1\endcsname\eqshowOutOftrue\def\stfmtType{OO}%
+ \gdef\showOutOfinSmryTbl{true}\let\stmarkupbox\relax
+ \else
+ \eqshowOutOffalse\let\stfmtType\@empty
+ \gdef\showOutOfinSmryTbl{false}%
+ \fi
+}
+\let\stfmtType\@empty
+\define@key{smrytbl}{setDimens}[]{#1}
+\def\showOutOfinSmryTbl{false}
+\def\stmarkupbox{\makebox[0pt][l]}
+% \end{macrocode}
+% Finally we come to the definition of \cs{displaySumryTbl}.
+% \begin{macrocode}
+\newcommand{\displaySumryTbl}[2][]{%
+ \begingroup\edef\currQuiz{#2}\edef\oField{#2}\edef\curr@quiz{#2}%
+ \setkeys{smrytbl}{#1}%
+ \count0=\smrytbl@ntables
+% \end{macrocode}
+% We accept only 1 or 2 as an argument, we put it in \cs{count0},
+% if not an integer, we'll stop the compile. If the argument is not 1,
+% we force a value of 2.
+% \begin{macrocode}
+% \ifnum\count0=1\relax\else\count0=2\relax\fi
+ \eq@rowcnt=0\relax\@tempcntb=\value{questionno}%
+% \end{macrocode}
+% We calculate the number of rows in the first column, in case
+% of a two column table. When the number of questions is odd,
+% the the left-hand table will have one more entry than the right-hand
+% column.
+% \begin{macrocode}
+ \ifnum\count\z@=2\relax
+ \divide\@tempcntb2\relax
+ \advance\@tempcntb\ifodd\value{questionno}2\else1\fi
+ \xdef\@beginSecCol{\the\@tempcntb}%
+ \advance\@tempcntb-1\relax
+ \fi
+% \end{macrocode}
+% Three table support
+% \begin{macrocode}
+ \ifnum\count\z@=3
+ \edef\eq@n{\the\@tempcntb}%
+ \divide\@tempcntb\count\z@
+ \edef\eq@q{\the\@tempcntb}%
+ \@tempcnta=\@tempcntb\multiply\@tempcnta3
+ \edef\eq@p{\the\@tempcnta}%
+ \@tempcnta=\eq@n
+ \advance\@tempcnta-\eq@p\relax
+ \ifnum\@tempcnta=0
+ \@tempcntb=\eq@q \advance\@tempcntb1
+ \xdef\@beginSecCol{\the\@tempcntb}%
+ \advance\@tempcntb\eq@q\relax
+ \xdef\@beginThrdCol{\the\@tempcntb}%
+ \else\ifnum\@tempcnta=1
+ \@tempcntb=\eq@q \advance\@tempcntb1
+ \edef\nB@lCols{\the\@tempcntb}%
+ \advance\@tempcntb1\relax
+ \xdef\@beginSecCol{\the\@tempcntb}%
+ \advance\@tempcntb\eq@q\relax
+ \xdef\@beginThrdCol{\the\@tempcntb}%
+ \else\ifnum\@tempcnta=2
+ \@tempcntb=\eq@q \advance\@tempcntb1
+ \edef\nB@lCols{\the\@tempcntb}%
+ \advance\@tempcntb1
+ \xdef\@beginSecCol{\the\@tempcntb}%
+ \advance\@tempcntb\nB@lCols
+ \xdef\@beginThrdCol{\the\@tempcntb}%
+ \fi\fi\fi
+ \@tempcntb=\eq@n
+ \fi
+% \end{macrocode}
+% We \cs{let} \cs{@eqListExp} to \cs{@@eqListExp}, defined below.
+% \begin{macrocode}
+ \let\@eqListExp\@@eqListExp
+% \end{macrocode}
+% \dots and expand the token list \cs{eqQzQuesList}.
+% \begin{macrocode}
+ \eqQzQuesList
+ \endgroup
+}
+% \end{macrocode}
+% \end{macro}
+% \paragraph*{Construction of the table.} The construction is performed by \cs{@eqListExp}.
+% This is a definition of \cs{@eqListExp}. It appears in the
+% token list \cs{eqQzQuesList}. A typical entry in \cs{eqQzQuesList} is
+% of the form
+%\begin{verbatim}
+% \@eqListExp{<question_label>}{\thepage}
+%\end{verbatim}
+% We use the two arguments to construct a table of three columns: Question (consisting
+% of the question label); Responded (a checkbox that is checked if that question was answered);
+% and Page (a hypertext link to the page containing he question). The command may be redefined
+% to as needed.\medskip\par\noindent
+% \textbf{Column headings} are defined by \cmd{\eq@begintab}.
+% This can be redefined. We begin a \texttt{tabular} with
+% headings (may be redefined).
+% \begin{macrocode}
+\def\eq@begintab{%
+ \begin{tabular}[t]{lcc}\sumryTblQ&\sumryTblR&\sumryTblP\\\sthline
+ {\Large\strut}%
+}
+% \end{macrocode}
+% \DescribeMacro{\sthline}\cmd{\sthline}
+% is a user hook to change the appearance of the horizontal line, such
+% as adding color.
+% \begin{macrocode}
+\def\sthline{\hline}
+% \end{macrocode}
+% End of the \texttt{tabular}.
+% \begin{macrocode}
+\def\eq@endtab{\end{tabular}}
+% \end{macrocode}
+% \cs{@@eqListExp} is \cs{let} to \cs{@eqListExp} in \cs{displaySumryTbl}.
+% \begin{macrocode}
+\def\sumrytblCkMUsep{\kern3bp}
+\def\sumrytbllinkHook#1{#1}
+% \end{macrocode}
+% \textbf{First Column.} \DescribeMacro{\sumryTblProbFmt}\cmd{\sumryTblProbFmt}
+% sets the {\LaTeX} formatting for the problem numbers that appear in the
+% first column of the table.
+% \begin{macrocode}
+\newcommand{\sumryTblProbFmt}[1]{\textbf{\textcolor{blue}{#1}}}
+% \end{macrocode}
+% A macro to set the separation between the tables.
+% \begin{macrocode}
+\newcommand{\sumrytablesep}{\space}
+% \end{macrocode}
+% We supply basic controls for the text field, width (\DescribeMacro{\stmarkupWidth}\cmd{\stmarkupWidth}),
+% height (\DescribeMacro{\stmarkupHeight}\cmd{\stmarkupHeight}), and text size
+% (\DescribeMacro{\stmarkupTextSize}\cmd{\stmarkupTextSize})
+% \begin{macrocode}
+\def\stmarkupWidth{12bp}\def\stmarkupHeight{9bp}\def\stmarkupTextSize{0}
+% \end{macrocode}
+% \textbf{Second column.} The second column of the table consisting of a checkbox
+% and stMarkup text field.
+% \begin{macrocode}
+\def\st@scndclmn{%
+ \checkBox[\Ff{\FfReadOnly}]%
+ {\ccatCurrQzWith(SanityCheck).\the\eq@rowcnt}%
+ {\markupHeight}{\markupHeight}{Yes}\ifeqshowmarkup
+ \stmarkupbox{\sumrytblCkMUsep\textField[%
+ \Ff\FfReadOnly\BC{}\textColor{\pcMarkupColor}%
+ \textSize{\stmarkupTextSize}\autoCenter{n}%
+% \end{macrocode}
+% Key to being able to have duplicated summary fields with different \texttt{showOutOf}
+% options is the naming of the text field. If \texttt{showOutOf=false}, the default,
+% the field name is \cs{currQuizSanityCheckPts}, but if \texttt{showOutOf=true}, the
+% text field is named \cs{currQuizSanityCheckOOPts}. When the Correct button is pressed,
+% the JavaScript function \texttt{correctSumryTbl()} checks for the existence of each of
+% these two fields, and populates them properly formatted. The command \cs{stfmtType} is
+% either \cs{empty} or \cs{OO}.
+% \begin{macrocode}
+ ]{\ccatCurrQzWith(SanityCheck\stfmtType Pts).\the\eq@rowcnt}%
+ {\stmarkupWidth}{\stmarkupHeight}}\fi
+}
+% \end{macrocode}
+% \textbf{Third column.} The third column of the table consisting of a link to the
+% page that contains the question.
+% \begin{macrocode}
+\def\st@thrdclmn#1{%
+ \setLink[\linktxtcolor{\@linkcolor}
+ \A{\JS{this.pageNum=(#1-1)}}]{\sumrytbllinkHook{#1}}}
+% \end{macrocode}
+% Now for the definition of \cs{@@eqListExp} which does the work in the table.
+% \begin{macrocode}
+\def\@@eqListExp#1#2{\global\advance\eq@rowcnt1\relax
+% \end{macrocode}
+% If it is the first row, we insert the push button that will activate
+% when the page becomes visible, and we expand \cs{eq@begintab}, which
+% is a \texttt{tabular} environment.
+% \begin{macrocode}
+ \ifnum\eq@rowcnt=1\relax
+ \pbPopulateSumTable\ifsmrytbl@corrections\else
+ \pbDoNoCorrectSumryTbl\fi\expandafter\eq@begintab\fi
+% \end{macrocode}
+% If it is the two table solution, and the row number equals the calculated
+% value of the first row of the second table, we emit another
+% \cs{eq@begintab}.
+% \begin{macrocode}
+ \ifnum\count0>1 \ifnum\eq@rowcnt=\@beginSecCol\relax
+ \eq@endtab\expandafter\sumrytablesep\expandafter\eq@begintab
+ \fi\fi
+ \ifnum\count0=3 \ifnum\eq@rowcnt=\@beginThrdCol\relax
+ \eq@endtab\expandafter\sumrytablesep\expandafter\eq@begintab
+ \fi\fi
+% \end{macrocode}
+% We layout a row of the table, problem label, checkbox, and page.
+% \begin{macrocode}
+ \sumryTblProbFmt{#1}&\st@scndclmn&\st@thrdclmn{#2}\\[1bp]
+% \end{macrocode}
+% We set the \cs{eq@endtab} at the bottom of the first table,
+% and at the bottom of the second table.
+% \begin{macrocode}
+% \ifnum\count0=2 \ifnum\eq@rowcnt=\@tempcntb
+% \expandafter\eq@endtab\fi\fi
+ \ifnum\eq@rowcnt=\thequestionno\relax\expandafter\eq@endtab\fi
+}
+% \end{macrocode}
+%
+% \subsection{Duplicating the Summary Table elsewhere}
+%
+% \begin{macro}{\writeProListAux}
+% This command writes the information essential to the creation of
+% the quiz summary table (\cs{displaySumryTbl}), and should be
+% placed after the final question, and before the `End Quiz'. The purpose
+% is to write the info to the auxiliary file so the table can be
+% constructed elsewhere, for example, at the beginning of the quiz, or
+% wherever desired. The command writes two macros to the aux file,
+% \verb!\csname \currQuiz QzQuesList\endcsname! that contains the token
+% list of problems using by the table, and
+% \verb!\csname \currQuiz nQuestions\endcsname! that contains the
+% total number of questions.
+% \begin{macrocode}
+\def\writeProListAux{%
+ \eq@IWAuxOut{\string\expandafter\string\gdef
+ \string\csname\space\currQuiz QzQuesList\string\endcsname
+ {\eqQzQuesList}}%
+ \eq@IWAuxOut{\string\expandafter\string\gdef
+ \string\csname\space\currQuiz nQuestions\string\endcsname
+ {\thequestionno}}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macrocode}
+\def\setParamSumryTblAux{%
+ \edef\eqQzQuesList{\@nameuse{\currQuiz QzQuesList}}%
+ \@ifundefined{\currQuiz nQuestions}{}{%
+ \value{questionno}=\@nameuse{\currQuiz nQuestions}}%
+}
+% \end{macrocode}
+% \begin{environment}{sumryTblAux}
+% Normally, we use \cs{displaySumryTbl} right after the last question, and before
+% the `End Quiz.' It is possible to display a summary table elsewhere, perhaps at the beginning
+% of the quiz, on the first page, wherever. Assuming \cs{writeProListAux} jas beem
+% inserted after the last question and before `End Quiz', you can then use the
+% \texttt{sumryTblAux} environment to place the same table in another location. For example,
+%\begin{verbatim}
+% \begin{sumryTblAux}{demoQuiz}
+% \begin{center}
+% {\normalsize\sffamily\bfseries Quiz Summary Table}\\[3pt]
+% \displaySumryTbl[showmarkup]{\currQuiz}
+% \end{center}
+% \end{sumryTblAux}
+%\end{verbatim}
+% The environment takes one parameter, the quiz name that this table
+% represents. It uses \cs{setParamSumryTblAux} to set the appropriate
+% variables that \cs{displaySumryTbl} uses.
+%
+% This environment \emph{is required} if the table appears outside the scope of the
+% quiz.
+% \begin{macrocode}
+\newenvironment{sumryTblAux}[1]{%
+ \DeclareQuiz{#1}\setParamSumryTblAux}{}%
+% \end{macrocode}
+% \end{environment}
+% \begin{macrocode}
+%</sumrytbls>
+% \end{macrocde}
+% \subsection{Posing MC/math fill-in questions}
+% \begin{macrocode}
+%<*mcfi>
+\def\bMCFI{%
+ \withinMCFItrue
+ \ifx\qRadionActionsHook\@empty
+ \let\qRadionActionsHook@SAVE\@empty
+ \def\qRadionActionsHook{\jsR
+ qRadioButtonMCFI(\Ans@choice,"\currQuiz",\thequestionno);}\else
+ \let\qRadionActionsHook@SAVE\qRadionActionsHook
+ \def\qRadionActionsHook{\qRadionActionsHook@SAVE\jsR
+ qRadioButtonMCFI(\Ans@choice,"\currQuiz",\thequestionno);}\fi
+ \ifx\every@RespBoxMath\@empty
+ \let\every@RespBoxMath@SAVE\@empty
+ \def\every@RespBoxMath{%
+ \AddAAKeystroke{mcfiKeyStroke("\currQuiz",\thequestionno);}}%
+ \else
+ \let\every@RespBoxMath@SAVE\every@RespBoxMath
+ \expandafter\def\expandafter\every@RespBoxMath\expandafter{%
+ \every@RespBoxMath@SAVE
+ \AddAAKeystroke{mcfiKeyStroke("\currQuiz",\thequestionno);}}%
+ \fi
+}
+\def\eMCFI{%
+ \ifx\qRadionActionsHook@SAVE\@empty
+ \let\qRadionActionsHook\@empty\else
+ \let\qRadionActionsHook\qRadionActionsHook@SAVE\fi
+ \ifx\every@RespBoxMath@SAVE\@empty
+ \let\every@RespBoxMath\@empty\else
+ \let\every@RespBoxMath\every@RespBoxMath@SAVE\fi
+ \withinMCFIfalse
+}
+\def\eqNA{-43252452452}
+\@ifundefined{text}{\let\MCFIMarkup@BOX\mbox}{\let\MCFIMarkup@BOX\text}
+\newcommand\mcfiMarkupfmt{\cgBdry
+ ${}^{\MCFIMarkup@BOX{\aeb@creditmarkup}}$}
+\def\mcfiMarkup{\addtocounter{questionno}{-1}\mcfiMarkupfmt
+ \stepcounter{questionno}}
+%</mcfi>
+%<*package>
+% \end{macrocode}
+% \section{Input Language definitions and JS}
+% Here is were we make the redefinitions of the above commands if
+% a language option is specified.
+% \begin{macrocode}
+\LangRedefinitions
+% \end{macrocode}
+% We introduce the document-level JavaScript for exerquiz at this point.
+% \begin{macrocode}
+\input{aebjs.def}
+% \end{macrocode}
+% If the \texttt{usesumrytbls} option is taken, we input the code.
+% \begin{macrocode}
+\inputSumryTblCode
+% \end{macrocode}
+% If the \texttt{usemcfi} option is taken, we input the code.
+% \begin{macrocode}
+\inputMCFICode
+% \end{macrocode}
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+% \section{eForms Support}
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+% \begin{macro}{\solutionColor}
+% This color is introduced at the pdfmark/rawPDF level. Define
+% the color without commas. For example |\solutionColor{0 .6 0}|
+% \begin{macrocode}
+\newcommand{\solutionColor}[1]{\def\eq@argi{#1}\ifx\eq@argi\@empty
+ \def\solution@Color{\solutionColorDef}\else
+ \def\solution@Color{#1}\fi}
+\newcommand{\solutionColorDef}{0 .6 0}
+\solutionColor{\solutionColorDef}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+%<*eqcolor>
+% \end{macrocode}
+%
+% \subsection{Color support}
+%
+% \begin{macrocode}
+\def\eq@getCmdName#1#2{\edef#1{\expandafter\@gobble\string#2}}
+\def\eq@getfirst#1#2\@nil{\def\eq@argi{#1}}
+\def\eq@checkValidityModel#1{%
+ \if#1g\else\if#1r\else\if#1c\else
+ \PackageError{exerquiz}
+ {JavaScript does not support this model}
+ {Use a named color from one of the models gray, rgb, or cmyk.}
+ \fi\fi\fi
+}
+\def\eq@jsSetColorMsg#1#2{\PackageWarning{exerquiz}
+ {The argument `#2' of \string#1\MessageBreak
+ is not of the right form.\MessageBreak Using the default}}
+\def\eqModelInfo#1#2{%
+ \uppercase{\def\eq@ucmodel{#1}}\def\eq@modelspec{#2}%
+ \eq@getfirst#1\@nil\eq@ResetModelForGray{\eq@argi}%
+ \eq@checkValidityModel{\eq@argi}%
+}
+\def\eq@ResetModelForGray#1{\if#1g\def\eq@ucmodel{G}\fi}
+% \end{macrocode}
+% We test for raw JS color in two ways, look for \texttt{["} or look for \texttt{co}
+% as the first two tokens.
+% \begin{macrocode}
+\def\eq@checkRawJSColor#1{%
+ \edef\eq@argi{#1}\ifx\eq@argi\@empty
+ \def\eq@next{\let\eq@rawJSCol\eq@YES}\else
+ \def\eq@next{\expandafter\eq@@checkRawJSColor#1\@nil}\fi\eq@next
+}
+\def\eq@@checkRawJSColor#1#2#3\@nil{\let\eq@rawJSCol\eq@NO
+ \let\eqpredefineJSCol\eq@NO
+ \if[#1\if#2"\let\eq@rawJSCol\eq@YES\fi\fi
+ \ifx\eq@rawJSCol\eq@NO\if#1c\if#2o\let\eq@rawJSCol\eq@YES
+ \let\eqpredefineJSCol\eq@YES\fi\fi\fi
+}
+\def\eq@jsColorWXColori#1#2{\edef\eq@colorDefn{#2}%
+ \ifx\eq@colorDefn\@empty
+ \ifx\is@Defined\eq@YES
+ \edef\eq@colorDefn{\csname\cmdName Def\endcsname}\else
+ \PackageError{exerquiz}{JS color \string#1 has an
+ empty definition}{}\fi
+ \fi
+ \eq@checkRawJSColor{\eq@colorDefn}%
+ \ifx\eq@rawJSCol\eq@NO
+ \extractcolorspec{\eq@colorDefn}{\eq@tmp@color}%
+ \expandafter\eqModelInfo\eq@tmp@color
+ \edef#1{["\eq@ucmodel",\eq@modelspec]}%
+ \else\edef#1{\eq@colorDefn}\fi
+}
+\def\eq@jsColorWOXColori#1#2{\def\eq@colorDefn{#2}%
+ \ifx\eq@colorDefn\@empty
+ \ifx\is@Defined\eq@YES
+ \edef\eq@colorDefn{\csname cmdName Def\endcsname}\else
+ \PackageError{exerquiz}{JS color \string#1 has an
+ empty definition}{}\fi
+ \fi
+ \eq@checkRawJSColor{\eq@colorDefn}%
+ \ifx\eq@rawJSCol\eq@YES\edef#1{\eq@colorDefn}\else
+ \eq@jsSetColorMsg{#1}{#2}\fi
+}
+% \end{macrocode}
+% \DescribeMacro{\jsColor} General command for defining a JavaScript Color, and support commands for
+% \textsf{xcolor} and w/o \textsf{xcolor}. When \textsf{xcolor} is used, colors
+% can be specified using the usual {\LaTeX} color methods:
+%\begin{verbatim}
+% \jsColor{\rghtColorJS}{blue}
+% \jsColor{\rghtColorJS}{[cmyk]{0,1,0,0}}
+%\end{verbatim}
+% or the \emph{JavaScript format} can be used:
+%\begin{verbatim}
+% \jsColor{\rghtColorJS}{["RGB",0,0,1]}
+% \jsColor{\rghtColorJS}{["CMYK",0,1,0,0}
+%\end{verbatim}
+% When \textsf{xcolor} is not used, only the JavaScript format is allowed.
+% \begin{macrocode}
+\def\jsColor#1#2{\eq@getCmdName{\cmdName}{#1}%
+ \let\is@Defined\eq@YES
+ \expandafter\ifx\csname\cmdName\endcsname\relax
+ \PackageWarning{exerquiz}{\string#1 is not a command used by
+ exerquiz.\MessageBreak Will define it anyway}%
+ \let\is@Defined\eq@NO\fi
+ \HyColor@IfXcolor{\eq@jsColorWXColori{#1}{#2}}%
+ {\eq@jsColorWOXColori{#1}{#2}}%
+}
+% \end{macrocode}
+% \begin{macrocode}
+%</eqcolor>
+%<*package>
+% \end{macrocode}
+% Now input \texttt{eqcolor.def}.
+% \changes{v7.8f}{2017/02/29}{Separated the color stuff into its own segment
+% (\string\texttt{eqcolor})}
+% \begin{macrocode}
+\@ifundefined{jsColor}{%
+ \InputIfFileExists{eqcolor.def}{\PackageInfo{exerquiz}
+ {Inputting eqcolor.def}}
+ {\PackageError{exerquiz}{cannot find eqcolor.def}
+ {Refresh your file name database and try again.}}
+}{}
+% \end{macrocode}
+%
+% \subsection{Default Colors for Checks, Crosses, and Borders}
+%
+% These commands are used to define the colors for the checks,
+% crosses and correct symbols. These are controlled by JavaScript,
+% so use the correct syntax for defining colors here.
+%
+% The default colors for the above defined color declaration commands, the
+% the default definitions of the color commands. The commands appear in pairs
+% and are used in the second and third arguments of \cs{eq@jsColor}.
+% \begin{macrocode}
+\newcommand\rghtColorJSDef{["RGB", 0, .6, 0]}
+\newcommand\rghtColorJS{\rghtColorJSDef}
+\newcommand\wrngColorJSDef{color.red}
+\newcommand\wrngColorJS{\wrngColorJSDef}
+\newcommand\partialColorJSDef{color.blue}
+\newcommand\partialColorJS{\partialColorJSDef}
+\newcommand\defaultColorJSDef{color.black}
+\newcommand\defaultColorJS{\defaultColorJSDef}
+% \end{macrocode}
+% The next command is special, it is used in the quiz environments to allow a localization
+% of the color. Unlike the ones above, this can be specified within the body of the document.
+% \begin{macrocode}
+\let\defaultColorJSLoc\@empty
+\let\defaultColorJSLocDef\@empty
+\let\rghtColorJSLoc\@empty
+\let\rghtColorJSLocDef\@empty
+\let\wrngColorJSLoc\@empty
+\let\wrngColorJSLocDef\@empty
+\let\partialColorJSLoc\@empty
+\let\partialColorJSLocDef\@empty
+% \end{macrocode}
+% \paragraph*{Symbol choice.} This is in support for changing check styles for quizzes
+% These must be declared in the preamble.
+% \begin{macrocode}
+\def\chooseJSsymbol{\@ifstar{\let\eq@isstar\eq@YES\chooseJSsymboli}
+ {\let\eq@isstar\eq@NO\chooseJSsymboli}}
+\def\chooseJSsymboli#1{\lowercase{\edef\eq@arg{#1}}%
+ \def\eq@carg{check}\ifx\eq@arg\eq@carg
+ \def\eq@retnStyle{style.ch}\else
+ \def\eq@carg{cross}\ifx\eq@arg\eq@carg
+ \def\eq@retnStyle{style.cr}\else
+ \def\eq@carg{diamond}\ifx\eq@arg\eq@carg
+ \def\eq@retnStyle{style.di}\else
+ \def\eq@carg{circle}\ifx\eq@arg\eq@carg
+ \def\eq@retnStyle{style.ci}\else
+ \def\eq@carg{star}\ifx\eq@arg\eq@carg
+ \def\eq@retnStyle{style.st}\else
+ \def\eq@carg{square}\ifx\eq@arg\eq@carg
+ \def\eq@retnStyle{style.sq}\else
+ \let\eq@retnStyle\@empty
+ \ifx\eq@isstar\eq@NO\PackageWarning{exerquiz}
+ {Argument `#1' not recognized.\MessageBreak
+ Permissible values are check, cross, diamond,\MessageBreak
+ circle, star, square. Will use the default}\fi
+ \fi\fi\fi\fi\fi\fi
+}
+% \end{macrocode}
+% \begin{macro}{\setRightAnsSymb}
+% The check style when the user is correct. (def: \texttt{style.ch})
+% \begin{macro}{\setCorrAnsSymb}
+% The check style when the user is wrong but you are marking which response is correct.
+% (def: \texttt{style.ci})
+% \begin{macro}{\setWrongAnsSymb}
+% The check style when the use chooses the incorrect answer.
+% (def: \texttt{style.cr})
+% \begin{macrocode}
+%\def\defineAnsStyle#1#2{%
+% \eq@getCmdName{\cmdName}{#1}\let\is@Defined\eq@YES
+%}
+\newcommand\setRghtAnsSymb[1]{\chooseJSsymbol{#1}%
+ \ifx\eq@retnStyle\@empty\else
+ \edef\rghtAnsSymbJS{\eq@retnStyle}%
+ \edef\rghtAnsSymb{\eq@carg}\fi}
+\def\rghtAnsSymbJS{style.ch}
+\def\rghtAnsSymb{check}
+\newcommand\setCorrAnsSymb[1]{\chooseJSsymbol{#1}%
+ \ifx\eq@retnStyle\@empty\else
+ \edef\corrAnsSymbJS{\eq@retnStyle}%
+ \edef\corrAnsSymb{\eq@carg}\fi}
+\def\corrAnsSymbJS{style.ci}
+\def\corrAnsSymb{circle}
+\newcommand\setWrngAnsSymb[1]{\chooseJSsymbol{#1}%
+ \ifx\eq@retnStyle\@empty\else
+ \edef\wrngAnsSymbJS{\eq@retnStyle}%
+ \edef\wrngAnsSymb{\eq@carg}\fi}
+\def\wrngAnsSymbJS{style.cr}
+\def\wrngAnsSymb{cross}
+\def\setRghtAnsSymbLoc#1{\chooseJSsymbol*{#1}%
+ \ifx\eq@retnStyle\@empty
+ \let\rghtAnsSymbJSLoc\@empty\else
+ \edef\rghtAnsSymbJSLoc{\eq@retnStyle}\fi
+}
+\def\setCorrAnsSymbLoc#1{\chooseJSsymbol*{#1}%
+ \ifx\eq@retnStyle\@empty
+ \let\corrAnsSymbJSLoc\@empty\else
+ \edef\corrAnsSymbJSLoc{\eq@retnStyle}\fi
+}
+\def\setWrngAnsSymbLoc#1{\chooseJSsymbol*{#1}%
+ \ifx\eq@retnStyle\@empty
+ \let\wrngAnsSymbJSLoc\@empty\else
+ \edef\wrngAnsSymbJSLoc{\eq@retnStyle}\fi
+}
+\let\rghtAnsSymbJSLoc\@empty
+\let\rghtAnsSymbJSLocDef\@empty
+\let\corrAnsSymbJSLoc\@empty
+\let\corrAnsSymbJSLocDef\@empty
+\let\wrngAnsSymbJSLoc\@empty
+\let\wrngAnsSymbJSLocDef\@empty
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \subsection{``Every'' Definitions}
+% \begin{macrocode}
+\newcommand\everyeqTextField[1]{\def\every@eqTextField{#1}}
+\def\every@eqTextField{}
+\newcommand\everyRespBoxMath[1]{\def\every@RespBoxMath{#1}}
+\def\every@RespBoxMath{}
+\newcommand\everyRespBoxTxt[1]{\def\every@RespBoxTxt{#1}}
+\def\every@RespBoxTxt{}
+\newcommand\everyrbMarkup[1]{\def\every@rbMarkup{#1}}
+\def\every@rbMarkup{}
+\newcommand\everysqTallyBox[1]{\def\every@sqTallyBox{#1}}
+\def\every@sqTallyBox{}
+\newcommand\everysqTallyTotal[1]{\def\every@sqTallyTotal{#1}}
+\def\every@sqTallyTotal{}
+\newcommand\everyScoreField[1]{\def\every@ScoreField{#1}}
+\def\every@ScoreField{}
+\newcommand\everyAnswerField[1]{\def\every@AnswerField{#1}}
+\def\every@AnswerField{}
+\newcommand\everyPointsField[1]{\def\every@PointsField{#1}}
+\def\every@PointsField{}
+\newcommand\everyPercentField[1]{\def\every@PercentField{#1}}
+\def\every@PercentField{}
+\newcommand\everyGradeField[1]{\def\every@GradeField{#1}}
+\def\every@GradeField{}
+% \end{macrocode}
+% \begin{macro}{\AddAAFormat}
+% Here is the definition of \cs{AddAAFormat}. This macro can be used
+% in \cs{RespBoxMath} to add in formatting of the answer. This macro is
+% necessary because the \cs{AA} actions for the \textsf{exerquiz} quiz macros
+% are ``protected''; the document author cannot accidentally overwrite my
+% JavaScript for processing the user's answer.
+% \begin{flushleft}
+% Example: In the preamble
+%\begin{verbatim}
+%\begin{defineJS}{\formatAsSet}
+%if (event.value.replace(/\\s/g,"") != "")
+% event.value = "{ " + event.value + " }";
+%\end{defineJS}
+%\end{verbatim}
+% and in the body of a \texttt{quiz} environment,
+%\begin{verbatim}
+%$x^2 - 3x + 2 = 0$, $S = \RespBoxMath[\AddAAFormat{\formatAsSet}
+% \rectW{.75in}\textSize{0}]{1,2}{1}{.0001}{[0,1]}*{ProcRespSetNum}$
+%\end{verbatim}
+%\end{flushleft}
+% \begin{macrocode}
+\def\@eqAddAAFormat#1{\def\eqFormatArg{#1}}
+\def\eq@AddAAFormat{}
+\def\formatAsSet{try{formatAsSet()}catch(e){}}
+\def\formatAsVector{try{formatAsVector()}catch(e){}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\AddAAKeystroke}
+% The value of this key is JS code that executes after the input box has been processed.
+% Created to use with AcroFleX for showing graphs after the user enters a response.
+%
+%\changes{v6.3b}{2008/06/29}
+%{
+% Added the \cs{AddAAKeystroke} to the recognizable set of keys. This will be obeyed
+% within the optional arguments of \cs{RespBoxMath}.
+%}
+% \begin{macrocode}
+\def\@eqAddAAKeystroke#1{\def\argi{#1}\ifx\argi\@empty
+ \def\eqAAKeystrokeArg{}\else\def\eqAAKeystrokeArg{\r #1}\fi}
+\def\eqAAKeystrokeArg{}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\everysqRadioButton}
+% \begin{macro}{\everyqRadioButton}
+% Here, you can control the appearance of all the standard checkboxes, also
+% effects radio fields of \texttt{shortquiz} and \texttt{quiz}.
+% \begin{macro}{\everyqckCheckBox}
+% (2010/07/30) Added \cs{everyqckCheckBox} to control the appearance
+% of the underlying checkbox for \texttt{manswers} environments.
+% Previously \cs{everyqRadioButton} was used, but this is the same as used by
+% multiple choice. To get control over \texttt{manswers} when \cs{useMCCircles}
+% and \cs{useMCCRects} \texttt{manswers} needs it one ``every'' command.
+% \begin{macrocode}
+\newcommand{\everysqRadioButton}[1]{\def\every@sqRadioButton{#1}}
+\def\every@sqRadioButton{}
+\newcommand{\everyqRadioButton}[1]{\def\every@qRadioButton{#1}}
+\def\every@qRadioButton{}
+\newcommand{\everyqckCheckBox}[1]{\def\every@qckCheckbox{#1}}
+\def\every@qckCheckbox{}
+% \end{macrocode}
+% \begin{macro}{\everyqCheckBox}
+% (12/08/2008) Added \cs{everyqCheckBox}, this is used only for the check boxes
+% that hold the answer of a multiple choice question, not a multiple selection
+% problem. This change is needed to create a circle radio button, in this case
+% we need to make the boundary of the check box to 0 width.
+% \begin{macrocode}
+\newcommand{\everyqCheckBox}[1]{\def\every@qCheckBox{#1}}
+\def\every@qCheckBox{}
+\newcommand{\everysqCheckBox}[1]{\def\every@sqCheckBox{#1}}
+\def\every@sqCheckBox{}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% Here, you can control the appearance of all the standard buttons.
+% \begin{macrocode}
+\let\everyeqButtonField\everyButtonField
+\newcommand\everyCorrAnsButton[1]{\def\every@CorrAnsButton{#1}}
+\def\every@CorrAnsButton{}
+\newcommand\everysqClearButton[1]{\def\every@sqClearButton{#1}}
+\def\every@sqClearButton{}
+\newcommand\everyeqButton[1]{\def\every@eqButton{#1}}
+\newcommand\everyCorrButton{\everyeqButton}
+\def\every@eqButton{}
+\newcommand\everyBeginQuizButton[1]{\def\every@BeginQuizButton{#1}}
+\def\every@BeginQuizButton{}
+\newcommand\everyEndQuizButton[1]{\def\every@EndQuizButton{#1}}
+\def\every@EndQuizButton{}
+% Replace everyeqGenButten with everyPushButton
+\let\everyeqGenButton\everyPushButton
+\let\every@eqGenButton\every@PushButton
+\newcommand\everyeqIcon[1]{\def\every@eqIcon{#1}}
+\def\every@eqIcon{}
+% dps new
+\let\eqGenButton\pushButton
+% \end{macrocode}
+% \begin{macro}{\eqIcon}
+% Create a push button for displaying an icon. I've set this on read only, this
+% can be removed by saying \verb+\Ff{-\FfReadOnly}+/
+%\begin{verbatim}
+% #1 = optional, used to enter any modification of the appearance/actions
+% #2 = the title of the button field
+% #3 = the width of the bounding rectangle
+% #4 = the height of the bounding rectangle
+%\end{verbatim}
+% \begin{macrocode}
+\def\eqIconDefaults
+{%
+ \rawPDF{}\S{}\mkIns{/TP 1}\W{}
+ \CA{}\RC{}\AC{}\BC{}\BG{}\H{N}
+ \textColor{0 g}\Ff{\FfReadOnly}
+}
+\newcommand\eqIcon[4][]
+{%
+ \mbox{\push@@Button{#1}{#2}{#3}{#4}{}{\eq@setButtonProps
+ \eq@Button@driver}{\eqIconDefaults\every@ButtonField
+ \every@eqIcon}}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \section{Document Level JavaScripts}
+%
+% The \texttt{insDLJS} package is used to insert the JavaScript at
+% the document level. This package makes all necessary
+% driver-dependent conversions, we just write the JavaScript code,
+% which is hard enough.
+%
+% \begin{macrocode}
+%<*aebjs>
+% \end{macrocode}
+% \begin{macrocode}
+\def\aeb@array{new Array}
+% \end{macrocode}
+% The following definitions are associated with \texttt{requireForm()}, the JS function
+% defined below.
+% \begin{macrocode}
+%\newcommand{\defaultReqFormMsg}{%
+% "The expression is not in the expected form."}
+% \end{macrocode}
+% (07/16/11) Some definitions that may be used by \texttt{requireForm}, a \cs{RespMathBox} filter
+% \begin{macrocode}
+%\def\refac(#1){\\(#1\\)}\def\regrp(#1){(#1)}\def\rechrclass(#1){[#1]}
+\def\refac#1{\\(#1\\)}\def\regrp#1{(#1)}\def\rechrclass#1{[#1]}
+\def\redm{\\.}\def\remul{\\*}\def\rediv{\\/}\def\repow{\\^}
+\def\redigit{\\d}\def\reany{.}\def\rebstr{\string^}\def\reestr{\string$}
+% \end{macrocode}
+% \begin{macro}{\preDenyForm}
+% \begin{macro}{\preReqForm}
+% \begin{macro}{\postDenyForm}
+% (10/07/11) Some convenience commands to simplifying the use of the \texttt{priorParse}
+% and \texttt{postParse} filters.
+% \begin{macrocode}
+%\def\preDenyForm(#1){\Array(denyForm,#1)}
+%\def\preReqForm(#1){\Array(requireForm,#1)}
+%\def\postDenyForm(#1){\Array(requireFormNot,#1)}
+\def\preReqForm{\Array(requireForm,\@gobble}
+\def\preDenyForm{\Array(denyForm,\@gobble}
+\def\postDenyForm{\Array(requireFormNot,\@gobble}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \DescribeMacro{\noPeekArgs}\cmd{\noPeekArgs} is used to modify the arguments
+% of the no peeking alert box.
+% \begin{macrocode}
+\newcommand{\noPeekArgs}[1]{%
+ \def\NoPeekAlert{eqAppAlert(#1)}}\def\newNoPeekArgs{}
+\def\NoPeekAlert{eqAppAlert(\noPeekMsg,3)}
+% \end{macrocode}
+% \begin{macrocode}
+\newcommand{\dlLibSpecRespJS}{"none","undefined","empty"}
+\begin{insDLJS*}[exerquizLoaded]{exerquiz}
+% \end{macrocode}
+% \subsection{Global Data}
+% Global data and some miscellaneous definitions
+% \begin{macrocode}
+\begin{newsegment}{AeB: AcroTeX eDucation Bundle}
+/*
+ Document Level JavaScript
+ AcroTeX eDucation Bundle
+ D. P. Story copyright 2000-\the\year
+*/
+var exerquizLoaded = true;
+this.disclosed = true;
+app.runtimeHighlight=false;
+\end{newsegment}
+\begin{newsegment}{Eq: Global Data}
+var ok2Continue = true;
+% \end{macrocode}
+% The global variable \texttt{ProcessIt} is really used only once. In the
+% function \texttt{DisplayAnswer()}. The function is called by the correct
+% answer button. It sets \texttt{ProcessIt = false}, then it inserts the correct
+% answer into the text field. A \texttt{false} value of \texttt{ProcessIt}
+% prevents the \texttt{ProcResp} (and others) from from processing the answer.
+%
+% The arrays \texttt{RightWrong}, \texttt{ProbValue}, \texttt{ProbDist} and \texttt{ProbType} maintain quiz information
+% for a quiz. The following are typical values of these arrays. This is a quiz taken
+% from the manswer.tex demo file. Question 1 is a multiple selection question; Question 2
+% is a multiple choice question; Question 3 is a math fill-in question; and Question 4
+% is a grouped question. (The \texttt{undefined} entries indicate an empty or a not used entry.)
+%\begin{verbatim}
+%RightWrong.toSource()
+%[undefined, [0, 1, [undefined, undefined, 0, 1, 1, 0, 1]], 1, 1,
+% [undefined, 1, 1, 1, 0]]
+%
+%Responses.toSource()
+%[undefined, [undefined, undefined, "b", "c", "d", "e", "f"], "a", "cos(x)",
+% [undefined, "0", "4", "1", "9"]]
+%
+%ProbValue.toSource()
+%[undefined, [3, 5, [undefined, undefined, -2, 3, 3, -2, 3]], [0, 3, 0], 3,
+% [1, "groupEval", 4, 4, 1, 1, 1, 1]]
+%
+%ProbDist.toSource()
+%[undefined, 5, 3, 3, 3]
+%
+%ProbType.toSource()
+%[undefined, "na", "na", "na", "na"]
+%
+%aPointType.toSource()
+% [undefined, [2, "mc"], [4, "ms"], [2, "text"], [4, "math"], [4, "grp"]]
+%\end{verbatim}
+% \begin{macrocode}
+var ProcessIt = true;
+var retn;
+var Score=0;
+var ptScore=0;
+var pcScore=0;
+var quizGrade="C";
+var e = Math.E;
+var pi = Math.PI;
+var replaceExclaim = \replaceexclaim;
+var negPointsAllowed = \negpointsallowed;
+var negPointsMarkupAllowed = \negpointsmarkupallowed;
+var aQuizControl = new Array();
+var RightWrong=new Array();
+var ProbValue = new Array();
+var ProbDist = new Array();
+var ProbType = new Array();
+var Responses=new Array();
+var appAlerts = new Object;
+var _mathVars="x";
+var _ModalNotOn=true;
+var GradeScaleDefault=new Array(\eqGradeScale);
+var aDlLibSpecResp=new Array(\dlLibSpecRespJS);
+% \end{macrocode}
+% JSf is an array of supported mathematical functions.
+%\changes{v6.06}{2007/02/23}
+%{
+% Separated the \texttt{JSf} array into \texttt{JSfBuiltIn} and \texttt{JSfCustom}. This
+% allows us to identify the built-in JavaScript functions. I concatenate these two
+% into \texttt{JSf}.
+%}
+% \begin{macrocode}
+var JSfBuiltIn = new Array
+ ( "abs","acos","asin","atan","ceil", "floor","cos","exp",
+ "log","max","min","pow","random","round","sin",
+ "sqrt","tan");
+% \end{macrocode}
+%\changes{v6.3c}{2008/07/03}
+%{
+% Added the hyperbolic functions and inverse hyperbolic functions
+%}
+% Additional function recognized by exerquiz. Note to self, when adding
+% functions, if one function is a substring of another, list the function
+% with the longer name first. Searching is done in the order the functions
+% are listed in this array.
+%\changes{v6.3o}{2010/05/24}
+%{
+% Modification of the array structure for supported JS functions, due to
+% Robert Marik. He writes, ``arcsin(x), arccos(x) and arctan(x) are not
+% recognized properly when implmulti from dljslib is active. I think that
+% the problem is caused by the fact that arcsin(x) follows sin(x) in the
+% field of known functions and converted into arc*sin(x) and then into
+% a*r*c*sin(x). I enclose the patch for the exerquiz.dtx file which in my
+% opinion solves the problem.''
+%}
+% \begin{macrocode}
+var JSfCustomEarly = new Array ("arctan", "arcsin", "arccos")
+var JSfCustomLate = new Array
+ ( "logc", "ln","sec","csc","cot",
+ "asinh", "acosh","atanh","acoth","asech","acsch",
+ "sinh", "cosh","tanh","coth","sech","csch","sgn",
+ "C","P","fact","pi");
+var JSf = new Array().concat(JSfCustomEarly, JSfBuiltIn, JSfCustomLate);
+var JSfCustom = new Array().concat(JSfCustomEarly, JSfCustomLate);
+var JSc = new Array("PI","E")
+% \end{macrocode}
+% Additional functions that I've defined.
+% \begin{macrocode}
+function ln(x) { return Math.log(x); }
+function sec(x) { return 1/Math.cos(x); }
+function csc(x) { return 1/Math.sin(x);}
+function cot(x) { return Math.cos(x)/Math.sin(x); }
+function arctan(x) { return Math.atan(x); }
+function arcsin(x) { return Math.asin(x); }
+function arccos(x) { return Math.acos(x); }
+function logc(x) { return Math.LOG10E * Math.log(x); }
+function C(x,y) {return ch(x,y);}
+function P(x,y) {return perm(x,y);}
+% \end{macrocode}
+% Additional functions that I've defined. (07/03/08)
+% \begin{macrocode}
+function sinh(x) { return ( Math.exp(x) - Math.exp(-x) )/2; }
+function cosh(x) { return ( Math.exp(x) + Math.exp(-x) )/2; }
+function tanh(x) {
+ return (Math.exp(x)-Math.exp(-x))/(Math.exp(x)+Math.exp(-x)); }
+function coth(x) {
+ return ( Math.exp(x)+Math.exp(-x))/(Math.exp(x)-Math.exp(-x)); }
+function sech(x) { return 2/( Math.exp(x) + Math.exp(-x) )/2; }
+function csch(x) { return 2/( Math.exp(x) - Math.exp(-x) )/2; }
+function asinh(x) { return Math.log (x+Math.sqrt(Math.pow(x,2)+1)); }
+function acosh(x) {
+ return Math.log (x+Math.sqrt(Math.pow(x,2)-1)); } // x ge 1
+function atanh(x) { return .5*Math.log ((1+x)/(1-x)); } // -1 < x < 1
+function acoth(x) { return atanh(1/x); } // |x| > 1
+function asech(x) { return acosh(1/x); } // 0 < x le 1
+function asch(x) { return asinh(1/x); } // x ne 0
+function acsch(x) { return asinh(1/x); } // x ne 0
+function sgn(x) { return (x==0?0:(x<0?-1:1)) };
+% \end{macrocode}
+% The aGroup array lists left and right grouping delimiters. This array is
+% used by ParseInput() to call CkBalP().
+% \begin{macrocode}
+var aGroup = new Array
+ ( ["\(","\)",\eqParens],
+ ["[","]",\eqBrackets],
+ ["{","}",\eqBraces]
+ );
+\end{newsegment}
+% \end{macrocode}
+% \subsection{Math Fill-in}
+% This section of the code is primarily dedicated to processing the math fill-in questions.
+% \begin{macrocode}
+\begin{newsegment}{Eq: Support for Math Fill-in}
+% \end{macrocode}
+% A custom alert box that uses \texttt{\_ModalNotOn} to alert when the modal alert
+% box is displayed. When \texttt{!\_ModalNotOn} is true, there is an alert box being
+% displayed.
+%\changes{v6.9}{2014/10/05}{Added eqAppAlert}
+% \begin{macrocode}
+var _mto;
+function eqAppAlert(args) {
+ _ModalNotOn = false;
+ var retn=app.alert(args);
+ _mto= app.setTimeOut("_ModalNotOn = true", 100);
+% \end{macrocode}
+% Add a return to eqAppAlert, needed for the prompt button
+% \changes{v7.8d}{2017/01/11}{Add a return to eqAppAlert}
+% \begin{macrocode}
+ return retn;
+}
+% \end{macrocode}
+% Description: Checks for balanced grouping delimiters.
+% Arguments:
+%\begin{enumerate}
+% \item \texttt{UserInput}: A string
+% \item \texttt{lDelimiter}: left delimiter
+% \item \texttt{rDelimiter}: right delimiter
+%\end{enumerate}
+% Returns: \texttt{true} (if balanced); \texttt{false} (if not)
+% \begin{macrocode}
+function CkBalP(UserInput,lDelimiter,rDelimiter)
+{
+ var Lcount=0, Rcount=0;
+ for (var k=0; k < UserInput.length; k++)
+ {
+ if (UserInput.charAt(k) == lDelimiter) Lcount++;
+ else if (UserInput.charAt(k) == rDelimiter) Rcount++;
+ }
+ return (Lcount==Rcount);
+}
+% \end{macrocode}
+% Description: This function simply determines if there are an even number of
+% `\verb+|+' chars. Used for parsing absolute value.
+% \verb=| x+2 | --> abs(x+2)=.\\
+% Arguments:\\
+% \texttt{UserInput}: a string\\
+% Returns: \texttt{true} (if even); \texttt{false} (if odd)
+% \begin{macrocode}
+function CkBalVert(UserInput)
+{
+ var Lcount=0;
+ for (var k=0; k < UserInput.length; k++)
+ if (UserInput.charAt(k)=="|") Lcount++;
+ return (Lcount \% 2 == 0);
+}
+% \end{macrocode}
+% Description: This function searches for alpha words and matches them against supported
+% mathematical functions.\\
+% Arguments:\\
+% \texttt{UserInput}: a string\\
+% Returns: 1 (if there is a match); 0 (if no match)
+% also sets the global variable \texttt{ok2Continue} to \texttt{false}.
+% \changes{v6.4c}{2011/07/01}{Ckfunc now uses a global variable \texttt{\_mathVars} which
+% holds the variables of the current \cs{RespBoxMath} being processed. We search
+% all substrings containing 2 or more letters; if it consists only of the variables
+% that substring is OK.}
+% \begin{macrocode}
+function Ckfuncs(UserInput)
+{
+ var re, rei, reii;
+ re = /[a-zA-Z]{2,}/g;
+ reii=/r:|i:|,/g
+% \end{macrocode}
+% Get \texttt{\_mathVars}, and remove special formatting, new variable \texttt{\_v}.
+% \begin{macrocode}
+ var _v=_mathVars.replace(reii,"");
+% \end{macrocode}
+% Define a regular expression that will return null if the string
+% contains only letters from the variable list \texttt{\_v}.
+% \begin{macrocode}
+ rei=new RegExp("[^"+_v+"]", "g");
+ aF = UserInput.match(re);
+ if ( aF == null ) return true;
+ for (var i=0; i < aF.length; i++)
+ {
+% \end{macrocode}
+% If the current string contains only variables, move on to the next string
+% \begin{macrocode}
+ if ( rei.exec(aF[i]) == null ) continue;
+ for(var j=0; j < JSf.length; j++)
+ if ( aF[i].indexOf(JSf[j]) != -1 ) break;
+ if (j < JSf.length) continue;
+ for(var j=0; j < JSc.length; j++)
+ if ( aF[i].indexOf(JSc[j]) != -1 ) break;
+ if(j==JSc.length)
+ {
+ eqAppAlert(\eqerrBadMathFunc,3);
+% \end{macrocode}
+% 09/07/09 added the next line, this could change behavior. We try to signal
+% that an alert box has already been displayed, don't display another one.
+% \begin{macrocode}
+ ok2Continue=false;
+ return false;
+ }
+ }
+ return true;
+}
+% \end{macrocode}
+% This function displays the answer.
+% \begin{macrocode}
+function DisplayAnswer(fieldname,theanswer)
+{
+ ProcessIt = false;
+ var oDefault;
+ if (arguments.length > 2 )
+ var oQName = arguments[2];
+ else var oQName = oDefault;
+ if (typeof oQName=="undefined")
+ var oQName = new Object;
+ var defaultColor=(typeof oQName.DefaultColorJSLoc=="undefined")%
+?\defaultColorJS:oQName.DefaultColorJSLoc;
+ try {
+ this.getField(fieldname).value=(theanswer);
+% this.getField(fieldname).strokeColor = defaultColor;
+ } catch(e) {}
+ ProcessIt = true;
+}
+function EvalCorrAnsButton(fieldname,theanswer)
+{
+ theanswer = eval(theanswer);
+ DisplayAnswer(fieldname,theanswer);
+}
+% \end{macrocode}
+% Finds and returns the position of the matching parentheses.
+% \begin{macrocode}
+function FindBalP(UserInput,Poff,Forward)
+{
+ var j,depth;
+ if (Forward)
+ {
+ for (depth=-1, j=Poff+1; depth !=0; j++)
+ {
+ if ( j > UserInput.length) return null;
+ if (UserInput.charAt(j)=="\(") depth--;
+ else if (UserInput.charAt(j)=="\)") depth++;
+ }
+ j--
+ }
+ else
+ {
+ for (depth=-1, j=Poff-1; depth !=0; j--)
+ {
+ if ( j < 1 ) return null;
+ if (UserInput.charAt(j)=="\)") depth--;
+ else if (UserInput.charAt(j)=="\(") depth++;
+ }
+ j++
+ }
+ return j;
+}
+% \end{macrocode}
+% Remove white spaces from \texttt{UserInput}.
+% \begin{macrocode}
+function stripWhiteSpace (UserInput)
+{
+ UserInput = UserInput.replace(/\s/g,"");
+ if(UserInput==null || UserInput.length==0)
+ {
+ ok2Continue = false;
+ return false;
+ } else return UserInput;
+}
+function stripOutMuli (UserInput)
+{
+ UserInput = UserInput.replace(/\*/g,"");
+ return UserInput;
+}
+% \end{macrocode}
+% This function takes its argument, and adds in the suffix of \texttt{Math.}
+% in front of every recognizable JS built-in functions.
+% \begin{macrocode}
+function addMathObject(UserInput)
+{
+ for ( var i=0; i < JSfBuiltIn.length; i++) {
+ var re = new RegExp("\\b("+JSfBuiltIn[i]+")\\b","g");
+ UserInput = UserInput.replace(re,"Math.$1");
+ }
+ re = /\b(PI)\b/g;
+ UserInput = UserInput.replace(re,"Math.$1");
+ return UserInput;
+}
+% \end{macrocode}
+%
+% \paragraph{ParseInput.}
+%
+% This is the very heart of parsing the user's input. This function takes the
+% \texttt{UserInput} and works it over and places it in a proper JavaScript expression
+% for the JavaScript interpreter to evaluate.
+%
+% First get rid of all whitespace. Then
+% check for balanced parentheses followed by checking for known
+% or unknown math functions.
+%
+% The power function is \texttt{pow}; thus, |x^2| is \texttt{pow(x,2)}. Rather than
+% make students write \texttt{pow(x,2)} we try to code things so they can enter
+% |x^2| instead, much easier for them. Now we must scan through for different
+% patterns. The patterns are: |x^n|, |(expr)^n|, |x^(expr)| and |(expr1)^(expr1)|. We
+% search through looking for these patterns and replace them appropriately:
+% |pow(x,n)|, |pow(expr,n)|, |pow(x,expr)| and |pow (expr1,expr2)|. To do this, we
+% must find balanced parentheses.
+%
+% For those who have Acrobat 5.0, you can call this function from the console, something
+% I do quite a lot when developing new scripts. From the console, enter, for example,
+% \verb+ParseInput("xycos(xy^3)")+, and the return value of this function will be
+% displayed in the console. An author can check the syntax of his/her answer.
+%
+% \begin{macrocode}
+function ParseInput(UserInput)
+{
+ var re, repi;
+ UserInput = stripWhiteSpace (UserInput);
+ if (!ok2Continue) return null;
+% \end{macrocode}
+% See if there are matching `\texttt{[]}', `\texttt{\{\}}' and `\texttt{()}'.
+% \begin{macrocode}
+ for(var i=0; i< aGroup.length; i++)
+ {
+ if(!CkBalP(UserInput, aGroup[i][0], aGroup[i][1]))
+ {
+ eqAppAlert(\eqerrDelimNotBal,3);
+ ok2Continue = false;
+ return false;
+ }
+ }
+% \end{macrocode}
+% Replace `\texttt{[]}' and `\texttt{\{\}}' with `\texttt{()}'; only parentheses
+% are used in JavaScript for grouping.
+% \begin{macrocode}
+ UserInput = ChngAllGrpsToParens(UserInput);
+% UserInput = UserInput.replace(/\[|\{/g, "\(");
+% UserInput = UserInput.replace(/\]|\}/g, "\)");
+% \end{macrocode}
+% If the \texttt{fact} function is defined, we attempt to replace user's input of the form
+% \texttt{<number>!} with \texttt{fact(<number>)}.
+% \begin{macrocode}
+ if ( replaceExclaim &&(typeof fact == "function") )
+ UserInput = UserInput.replace(%
+/(?=\()?(\d+)(?=\))?!/g,"fact($1)");
+% \end{macrocode}
+% Check to see if there are an even number of absolute value symbols, `\verb+|+'.
+% \begin{macrocode}
+ if (!CkBalVert(UserInput))
+ {
+ eqAppAlert(\eqerrABS,3);
+ ok2Continue = false;
+ return false;
+ }
+% \end{macrocode}
+% 07/07/08 Before we go further, find all occurrences of the JavaScript function,
+% and enclose each in parentheses. This helps with some of the exponential parsing
+% later. Things of the form \verb!sin^2(x)! will not be enclosed, but will be
+% if the \texttt{ImplMulti} option is used.
+% \begin{macrocode}
+ UserInput=groupJSf(UserInput);
+% \end{macrocode}
+% (01/09/10) We try to identify an expression of the form \verb!e^!, when preceded by a
+% letter or number, in this case we assume multiplication. We also look for
+% the letter \texttt{e} when it is not in the middle of \texttt{sec}, this interpreted
+% as a numerical constant, it is converted to \verb!(e^1)!.
+% \begin{macrocode}
+ re=/(\w)(e)(\^)/g;
+ repi=/(\w)(pi)/g;
+% \end{macrocode}
+% If its a word followed by e, followed by the exponent symbol (\verb!^!), it is
+% multiplication.
+% \begin{macrocode}
+ UserInput=UserInput.replace(re, "$1*$2$3");
+ UserInput=UserInput.replace(repi, "$1*$2");
+% UserInput=UserInput.replace(repE, "$1*$2");
+% \end{macrocode}
+% We mark \texttt{sec} so we don't get a hit on the next search.
+% \begin{macrocode}
+ UserInput=UserInput.replace(/(sec)/g, "s@e@c");
+ re=/(\w)(e)([^\^])?/g;
+% \end{macrocode}
+% If its a word, followed by e, followed by something other than \verb!^!
+% then e must be used in the sense of a constant, so we replace it by
+% \verb!(e^1)!, so subsequence searches within this function will ultimately
+% convert it to \texttt{pow(e,1)}.
+% multiplication.
+% \begin{macrocode}
+ UserInput=UserInput.replace(re,"$1($2\^1)$3");
+ UserInput=UserInput.replace(/(s@e@c)/g, "sec");
+% \end{macrocode}
+% (07/16/11) In support of scientific notation. It is desirable to support E4, for example.
+% So we search for any occurrence of \texttt{E\cs{d}} and replace with \texttt{E+\cs{d}}.
+% Note: the letters \texttt{E} and \texttt{e} are used in JS to represent floating point numbers.
+% In this package \texttt{e} will be used for the natural number. Another problem,
+% JavaScript does not compute something like \texttt{1*E+2}, so we must remove any \texttt{*} between
+% the digit previous to \texttt{E} and \texttt{E}.
+% \begin{macrocode}
+ re=/E(\d)/g;
+ UserInput=UserInput.replace(re,"E+$1");
+ re=/(\d)\*E/g;
+ UserInput=UserInput.replace(re,"$1E");
+% \end{macrocode}
+% We make a rough check of the user input, if it has alpha-words of size two or greater
+% that do not match up against a recognizable function, it must be an error.
+%
+% (09/07/09) Comment this out so we check for function in both cases, get same alert message
+% \begin{macrocode}
+% if (typeof(Ck4Exponents) == "undefined")
+ if(!Ckfuncs(UserInput)) return false;
+% \end{macrocode}
+% Now try to insert the multiplication operator where applicable.
+% \begin{macrocode}
+ if (typeof(Ck4Exponents) != "undefined")
+ UserInput = Ck4Exponents(UserInput);
+ if (typeof(Ck4Products) != "undefined" )
+ UserInput = Ck4Products(UserInput);
+ ok2Continue = true;
+% \end{macrocode}
+% Convert any occurrence of log to log10 (known internally as logc). We are now (12/22/06) going to use log for
+% common log even though log in JS is natural log. This may break a few things.
+% \changes{v6.05f}{2006/12/22 }
+% {
+% Added support for common logarithms. log is now common logs, and ln is
+% natural logs.
+% }
+% \begin{macrocode}
+ re = /\b(log)\b/g;
+ UserInput = UserInput.replace(re, "logc");
+% \end{macrocode}
+% Search for occurrences of \verb!|<exp>|! and replace with \texttt{abs(<exp>)}.
+% \begin{macrocode}
+ while (/\|/.test(UserInput)&&(ok2Continue))
+ {
+ re = /(\|)([^\|]*)(\|)([-\+\/\*\^\)\|])/;
+ if (re.test(UserInput))
+ if (re.exec(UserInput)[4] == '^')
+ UserInput = UserInput.replace(re, "(abs($2))$4");
+ else
+ UserInput = UserInput.replace(re, "abs($2)$4");
+ else
+ {
+ re = /(\|)([^\|]*)(\|$)/;
+ if (re.test(UserInput))
+ UserInput = UserInput.replace(re, "abs($2)");
+ }
+ }
+% \end{macrocode}
+% Replace every instance of \texttt{pi} with \texttt{(pi)} so things like
+% \verb!pi^2! are parsed correctly.
+% \begin{macrocode}
+ re=/\b(pi)\b/g;
+ UserInput=UserInput.replace(re,"($1)")
+% \end{macrocode}
+% We now begin our search for exponents, we search the UserInput from left to right
+% for any of the four strings \texttt{"\string^"},\texttt{")\string^"}, \texttt{"\string^("}, and
+% \texttt{")\string^("}, using the regular expression \texttt{reTstExp}. (07/07/08) I've rewritten
+% this part of the parser to accommodate nested exponents of the form \verb!x^2^3!, which should
+% be interpreted as \verb!(x^2)^2!, something like \verb!2^sin(x)! and \verb!sin(x)^2! work, the latter
+% is interpreted as \verb!(sin(x))^2!. This is why earlier we executed \texttt{groupJSf} to enclose
+% all JS function and their arguments in parentheses; by the time \verb!sin(x)^2! reaches this parser
+% it has already been changed to \verb!(sin(x))^2!, which is correct syntax.
+%
+% These is another change to the parser here. We pass through \texttt{Ck4OddRoots}, which tries,
+% in a crude way, to determine if this exponent is of the form \texttt{a/b}, and if so, whether
+% \texttt{b}, the denominator, is an odd root. If so, we change the calculation of \texttt{Math.pow}
+% to avoid a calculation bug by that JavaScript function.
+% \begin{macrocode}
+ var reTstExp = /(\))?\^(\()?/g;
+ while ( ((aResults=reTstExp.exec(UserInput))!=null)&&(ok2Continue) )
+ {
+ var firstGroup = Number(Boolean(aResults[1])); // 0 or 1
+ var secondGroup = 2*Number(Boolean(aResults[2])); // 0 or 2
+ var caseStudy = firstGroup+secondGroup; // 0,1,2,3
+ switch(caseStudy) {
+ case 0:
+ re=/([a-zA-Z]|\d*\.?\d*)\^([a-zA-Z]|[\+-]?\d+\.?\d*|%
+[\+-]?\d*\.?\d+)/;
+ if (re.test(UserInput))
+ UserInput=Ck4OddRoots(UserInput,re);
+ else ok2Continue=false;
+ break;
+ case 1:
+ aP =/\)\^/.exec(UserInput);
+ LeftP=FindBalP(UserInput,aP.index,0);
+ re = new RegExp("\\((.{"+eval(aP.index-LeftP-1)
+ +"})\\)\\^([a-zA-Z]|[\+-]?\\d+\\.?\\d*|%
+[\+-]?\\d*\\.?\\d+)");
+ if (re.test(UserInput))
+ UserInput=Ck4OddRoots(UserInput,re);
+ else ok2Continue=false;
+ break;
+ case 2:
+ aP = /\^\(/.exec(UserInput);
+ RightP=FindBalP(UserInput,aP.index+1,1);
+ re = new RegExp("([a-zA-Z]|\\d*\\.?\\d*)\\^\\((.{"
+ +eval(RightP-aP.index-2)+"})\\)");
+ if (re.test(UserInput))
+ UserInput=Ck4OddRoots(UserInput,re);
+ else ok2Continue=false;
+ break;
+ case 3:
+ aP = /\)\^\(/.exec(UserInput);
+ LeftP=FindBalP(UserInput,aP.index,0);
+ RightP=FindBalP(UserInput,aP.index+2,1);
+ re = new RegExp("\\((.{"+eval(aP.index-LeftP-1)
+ +"})\\)\\^\\((.{"+eval(RightP-aP.index-3)+"})\\)");
+ if (re.test(UserInput))
+ UserInput=Ck4OddRoots(UserInput,re);
+ else ok2Continue=false;
+ break;
+ default:
+ ok2Continue=false;
+ }
+% console.println("working.."+UserInput);
+ }
+ if (!ok2Continue)
+ {
+ eqAppAlert(\eqerrBadExp,3);
+ return false;
+ }
+ else {
+% \end{macrocode}
+%\changes{v6.06}{2007/02/23}
+%{
+% Now, just before we return the parsed expression, we append all built-in
+% JavaScript functions and constants with \texttt{Math.}, this is to avoid
+% having to use the \texttt{with(Math)} construct. These changes are in support
+% of using scientific notation.
+%}
+% \begin{macrocode}
+ UserInput=addMathObject(UserInput);
+ return UserInput;
+ }
+}
+% \end{macrocode}
+% \DescribeMacro{ChngAllGrpsToParens}(2011/10/04) Separated out the routine to replace `\texttt{[}' and `\verb!{!' with
+% `\texttt{(}'.
+% \begin{macrocode}
+function ChngAllGrpsToParens(UserInput)
+{
+ UserInput = UserInput.replace(/\[|\{/g, "\(");
+ UserInput = UserInput.replace(/\]|\}/g, "\)");
+ return UserInput;
+}
+% \end{macrocode}
+% \DescribeMacro{Ck4OddRoots}The \texttt{Ck4OddRoots} function looks for exponents of the form \texttt{a/b},
+% it checks whether \texttt{b} is an odd integer, if yes, instead of returning
+% the usual of \verb!"(pow($1,$2))"!, it returns something like
+% \verb!(sgn(<base>)^a*(abs(<base>)^a)^(1/b))!. This gives a base that evaluates
+% to a negative number a change of being evaluated, and avoid a bug in the \texttt{Math.pow}
+% function.
+% \begin{macrocode}
+function Ck4OddRoots(UserInput,re) {
+ var a=re.exec(UserInput);
+% \end{macrocode}
+% \texttt{a[2]} should be the exponent
+% try to remove extraneous parentheses
+% \begin{macrocode}
+ while ( a[2].charAt(0)=="\(") {
+ var RightP=FindBalP(a[2],0,1); // forward search
+ if (RightP == a[2].length-1)
+ a[2]=a[2].substring(1,a[2].length-1);
+ else break;
+ }
+ var b=a[2].split("/");
+% \end{macrocode}
+% We are looking for an exponent of the form a/b, if we can't find it
+% we process this power in the usual way. \texttt{b[0]} is our possible numerator
+% and \texttt{b[1]} is our possible denominator.
+% \begin{macrocode}
+ if ( b.length==2 ) {
+ try { _m=eval(b[1])
+% \end{macrocode}
+% We try to evaluate the denominator \texttt{b[1]}. If there are unbalanced
+% parentheses, JavaScript will throw an exception, if \texttt{\_m} is either
+% undefined or not a number, we throw an exception. The expression will be
+% processed in the usual way.
+% \begin{macrocode}
+ if ( _m == undefined || isNaN(_m) ) throw new Error();
+% \end{macrocode}
+% The denominator appears to be numerical, so we'll continue
+% \begin{macrocode}
+ var d = b[1];
+% \end{macrocode}
+% Check for the presence of enclosing parentheses
+% \begin{macrocode}
+ var isEnclosed=(d.charAt(0) == "\(" && d.charAt(d.length-1)=="\)");
+% \end{macrocode}
+% if not enclosed look for arithmetic operations
+% \begin{macrocode}
+ if (!isEnclosed)
+% \end{macrocode}
+% if arithmetic operations of add/sub found, exit. In this case, perhaps the user had an
+% exponent of the form \texttt{x/2 + 3}, and so \texttt{d = 2 + 3}, which is not the desired denominator.
+% We'll throw an exception, and process as usual.
+% \begin{macrocode}
+ if (/.+[\+\-].+/.test(d)) throw new Error();
+% \end{macrocode}
+% remove enclosing parentheses
+% \begin{macrocode}
+ if (isEnclosed) d = s.substring(1,d.length-1);
+% \end{macrocode}
+% now need to do the same thing for the numerator
+% \begin{macrocode}
+ var n = b[0];
+ isEnclosed=(n.charAt(0) == "\(" && n.charAt(d.length-1)=="\)");
+ if (!isEnclosed)
+% \end{macrocode}
+% if arithmetic operations of add/sub found, exit. If numerator was not enclosed
+% in parentheses, and there is either addition or subtraction, we are looking
+% at an exponent of the form \texttt{1 + x/d,} and \texttt{n = 1 + x}. The numerator is not \texttt{1+x}, we
+% process in the usual way.
+% \begin{macrocode}
+ if (/.+[\+\-].+/.test(n)) throw new Error();
+% \end{macrocode}
+% I don't think we need to remove the enclosing parentheses
+% as we did for the denominator.
+%
+% Now check if the denominator, \texttt{d}, is an integer, for that we'll use \texttt{parseInt},
+% If it is an integer, we see if it is odd or even using \verb!d % 2!, which yields
+% a nonzero remainder if d is odd. If \texttt{d} passes all tests, we write
+% \verb!<base>^(n/d)! as \verb!(sgn(<base>))^n! \verb!(abs(<base>)^(n/d))!.
+% \begin{macrocode}
+ if ( d == parseInt(d) && ( Boolean(d \% 2) ) ) {
+ UserInput=UserInput.replace(re,
+ "(pow(sgn($1),"+n+")*(pow(abs($1),$2)))");
+% \end{macrocode}
+% We we have an odd integer as a denominator, we return our result here
+% \begin{macrocode}
+ return UserInput;
+ }
+% \end{macrocode}
+% All exceptions come here, then continue on to the lines that follow.
+% \begin{macrocode}
+ } catch(e) {}
+ }
+% \end{macrocode}
+% If we don't have an odd integer as a denominator, we return here
+% \begin{macrocode}
+ UserInput=UserInput.replace(re,"(pow($1,$2))");
+ return UserInput;
+}
+% \end{macrocode}
+% \DescribeMacro{groupJSf}We enclose all recognizable functions in parentheses. This makes it easier for doing
+% exponents, and avoids parsing errors. We look for functions of the form \texttt{fname(..)},
+% replace that with \texttt{fname@(..)} to avoid an infinite loop, as we search for the function
+% name followed by a left parenthesis. Once finished, we remove the \texttt@ character.
+% \begin{macrocode}
+function groupJSf(UserInput)
+{
+ var re, regexp, aP, RightP;
+ for (var i=0; (i<JSf.length) && (ok2Continue); i++)
+ {
+ re = new RegExp(JSf[i]+"\\\(");
+ while ( re.test(UserInput) && (ok2Continue) )
+ {
+ regexp = new RegExp(JSf[i]+"\\\(", "g");
+ if ( (aP = regexp.exec(UserInput)) != null )
+ {
+ RightP=FindBalP(UserInput,regexp.lastIndex-1,1);
+ offsetArg = RightP - regexp.lastIndex;
+ regexp = new RegExp(%
+"("+JSf[i]+")\\((.{"+offsetArg+"})\\)");
+ regexp.lastIndex=0;
+ if (regexp.test(UserInput))
+ UserInput=UserInput.replace(regexp,"($1@($2))");
+ else ok2Continue=false;
+ continue;
+ }
+ }
+ }
+% \end{macrocode}
+% Remove the \texttt@ marker, and return.
+% \begin{macrocode}
+ UserInput=UserInput.replace(/@/g,"");
+ return UserInput;
+}
+% \end{macrocode}
+% Process the user's response. Here, we randomly choose, $n$,
+% points from the selected interval $[a,b]$. The correct answer (as
+% supplied by the author of the document and the answer provided by
+% the user are evaluated at each of the $n$ points. If any of the
+% evaluations differs by more than \texttt{epsilon}, the answer is
+% considered wrong.
+%
+% The idea for evaluating user input in this way comes from Drs.\
+% Wlodzimierz Bryc and Stephan Pelikan of The University of
+% Cincinnati. These two have developed an \texttt{html} based
+% \textbf{Online Exercise System} which can evaluate objective
+% type questions. This evaluation, however, takes place on the
+% \emph{server-side}. This implementation is on \emph{the client-side}.
+%
+% \begin{macro}{TypeParameters}
+% The argument \texttt{v} is either a comma delimited list of variables \texttt{"x,y,z"} or just a list \texttt{"xyz"}.
+% This function types each untyped variable that is not typed. Currently, there
+% are only two data types: \texttt{"r"} and \texttt{"i"}. \texttt{"r:x"} means \texttt{"x"} is a real variable,
+% \texttt{"i:x"} means \texttt{"x"} is an integer variable.
+% \begin{macrocode}
+function TypeParameters(v)
+{
+ var aV;
+% \end{macrocode}
+% If \texttt{v} has a colon in it, we take that as a signal that the variables are comma
+% delimited.
+% \begin{macrocode}
+ aV = ( (v.indexOf(":") == -1) && (v.indexOf(",") == -1) ) ?
+ v.split("") : v.split(",");
+ for ( var i=0; i < aV.length; i++)
+ if ( aV[i].indexOf(":") == -1 ) aV[i] = "r:"+aV[i];
+ return aV.join(",")
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{ProcResp}
+% This function handles numerical answers or function of a single variable, x,
+% that evaluate to a number.
+% \begin{macrocode}
+function ProcResp(flag,CorrAns,n,epsilon,domain,indepVar,oComp)
+{
+ if (!ProcessIt) return null;
+ var fieldname = event.target.name;
+ var UserAns = event.value;
+ var success = _ProcResp(flag,CorrAns,UserAns,%
+n,epsilon,domain,indepVar,oComp);
+% \end{macrocode}
+% 09/07/09 Added next line to avoid double alert boxes
+% \begin{macrocode}
+ if ( success == -1 || !ok2Continue ) return null;
+ if ( success == null ) { return syntaxError(), null; }
+ return notifyField(success, flag, fieldname);
+}
+// changed name of var comp -> oComp
+function _ProcResp(flag,CorrAns,UserAns,n,epsilon,domain,indepVar,oComp)
+{
+ ok2Continue = true;
+% \end{macrocode}
+% by preprocessing.
+% \begin{macrocode}
+ CorrAns = ParseInput(CorrAns);
+ if (!ok2Continue) {
+ eqAppAlert("Syntax error in author's answer! Check console.",3);
+ return null;
+ }
+% \end{macrocode}
+% If \texttt{oComp} is an object, then see if it has a \texttt{comp} property
+% \begin{macrocode}
+ var comp = ( typeof oComp == "object" ) ?
+ ((typeof oComp.comp == "undefined" ) ?
+ diffCompare : oComp.comp ) : oComp;
+% \end{macrocode}
+% \paragraph*{priorParse} The \texttt{comp} parameter, which has been changed to \texttt{oComp}, can now be
+% an object. One property of this object is \texttt{comp}, handled above. Another
+% property is \texttt{priorParse}, this is a function that returns \texttt{null}
+% or \texttt{true}. This \texttt{priorParse} function allows for additional
+% filtering of the \texttt{UserAns} before parsing. If it returns \texttt{true},
+% we are ok to continue, if \texttt{null}, we don't like something the user has entered,
+% and ask him/her to change it.
+% \begin{macrocode}
+ if ( (typeof(oComp)=="object") %
+&& (typeof(oComp.priorParse)!="undefined") ) {
+ var retn=processSpecialParse(oComp.priorParse,UserAns);
+ if (retn==null) return -1;
+ }
+% \end{macrocode}
+% (2014/01/22) Before we solve Bruce's problem with the commas, we need to allow for the use of
+% the combinatorics functions \texttt{C(x,y)} and \texttt{P(x,y)}.
+% \begin{macrocode}
+ var reCP=/((C|P)\(.+?)(,)(.+?\))/g
+% str="P(12,4)"
+% reCP.exec(str)
+ UserAns=UserAns.replace(reCP,"$1@c@$4");
+% \end{macrocode}
+% (2012/04/13) Bruce Wagner reports a problem with the user enters an answer containing
+% a comma \texttt{"3,2"}, if the correct answer is 2, exerquiz marks the response as correct
+% even though the user has also entered a 3. The comma operator in JS, evaluates its operands
+% one to the left, one to the right, and returns the value of the one on the right. To fix
+% this problem, we scan the \texttt{UserAns} for a comma (,) and set an alert if one is found.
+%
+% For vector- and list-valued answers, the \texttt{ProcResp<name>} procedure should parse
+% the comma-delimited answers and call \texttt{\_ProcResp} once for each answer in the list
+% so there should be no problem with commas in that regard.
+% \changes{v6.4r}{2012/04/13}{Added a warning about commas in an answer.}
+% \begin{macrocode}
+ var reComma=/,/;
+ if ( reComma.test(UserAns) ) {
+ eqAppAlert(\eqSyntaxErrorComma,3);
+ return -1;
+ }
+% \end{macrocode}
+% \begin{macrocode}
+ var reRlCommaSubst=/@c@/g;
+ UserAns=UserAns.replace(reRlCommaSubst,",");
+% \end{macrocode}
+% Parse the user's input.
+% \begin{macrocode}
+ UserAns = ParseInput(UserAns);
+% \end{macrocode}
+% Originally, the value of \texttt{indepVar} is a string of variables \texttt{"xyz"}. You can
+% now have variables of the form \texttt{"r:x,i:n,r:y"}. Where the identifier \texttt{"r:"} indicates a
+% real variable and \texttt{"i:"} indicates an integer variable. \texttt{indepVar} must be either
+% of the old style, or the new style, not a mixture of both, e.g. \texttt{"xyi:n"}.
+% \begin{macrocode}
+ indepVar = TypeParameters(indepVar);
+ if (!ok2Continue) return null;
+ var success=randomPointCompare(n,domain,indepVar,%
+epsilon,CorrAns,UserAns,comp);
+% \end{macrocode}
+% \paragraph*{postParse} (2011/10/05) The beginning of an idea, \texttt{postParse}. After it is determined
+% whether the answer is right or wrong, post-process it here. For example,
+% if the problem is to extract all roots of $\sqrt{72}$, the correct answer
+% is $6\sqrt{2}$, whereas $3\sqrt{8}$ is not correct though it is equal to
+% $\sqrt{72}$
+% \begin{macrocode}
+ if ( success && (typeof(oComp)=="object") %
+&& (typeof(oComp.postParse)!="undefined") )
+ success=processSpecialParse(oComp.postParse,UserAns);
+ return success;
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macrocode}
+function processSpecialParse(oParse,UserAns) {
+ var retn, f, _o
+ if ( typeof(oParse) == "object" ) {
+ for ( var i=0; i < oParse.length; i++) {
+ _o=oParse[i];
+ if (typeof(_o)=="function") {
+% \end{macrocode}
+% If \texttt{oParse} is an object (it should be an array), and the first entry is a function
+% then we have: \texttt{priorParse: [myfunction, optional arguments]}. The function is
+% evaluated with the args \texttt{(UserAns, optional args)}. In the code below, we remove
+% the name of the function at the beginning of the array, and insert the \texttt{UserAns}
+% in its place. Various syntax variations supported.
+%\begin{verbatim}
+% priorParse: nodec,
+% priorParse: [nodec,noBinFac],
+% priorParse: [nodec,noBinFac,[myFunc,arg1, arg2,..]],
+%\end{verbatim}
+% \begin{macrocode}
+% _o=oParse.shift();
+% oParse.unshift(UserAns);
+ retn=_o(UserAns);
+% retn = _o.apply(null,oParse);
+ if (retn==null) return retn;
+% \end{macrocode}
+% In this case, we break out of the loop, we don't expect any more properties
+% for \texttt{priorParse} or \texttt{postParse}.
+% \begin{macrocode}
+% break;
+ } else {
+% \end{macrocode}
+% If \texttt{oComp.priorParse[i]} is not a function, it is required to be an array. The first
+% element of the array is the function, the rest of the entries are the additional arguments
+% (in addition to \texttt{UserAns}).
+% \begin{macrocode}
+% f=_o.shift();
+% _o.unshift(UserAns);
+% retn=f.apply(null,_o);
+ retn=_o[0].apply(null, [ UserAns ].concat(_o.slice(1)));
+ if (retn==null) return null;
+ }
+ }
+ } else {
+% \end{macrocode}
+% The case where \texttt{preParse: myfunction} or \texttt{postParse: myfunction}.
+% Such a function is evaluated with the \texttt{UserAns} argument.
+% \begin{macrocode}
+ retn = oParse(UserAns);
+ }
+ return retn;
+}
+% \end{macrocode}
+% This function randomly selects points from the interval [a,b]
+% and calls the 'comp' function to compare results.
+% Returns: null if the expression is bad, no penalty.
+% true if the error of the random comparison is less than epsilon
+% false if the error of the random comparison is greater than epsilon
+% \begin{macrocode}
+function randomPointCompare (n,domain,indepVar,epsilon,%
+CorrAns,userAns,comp)
+{
+ var error, i, j, k;
+ var aXY = new Array();
+ domain = domain.replace(/[\[\]\s]/g, "");
+ var aIntervals = domain.split("&");
+ for (k=0; k < aIntervals.length; k++)
+ {
+ var aInterval = aIntervals[k].split("x");
+ nI = aInterval.length;
+ with (Math) {
+ for (j=0; j < n; j++)
+ {
+ for (i=0; i < nI; i++)
+ {
+ var endpoints = aInterval[i].split(",");
+ aXY[i] = eval(endpoints[0])-0+(eval(endpoints[1])%
+-eval(endpoints[0]))*Math.random();
+ }
+ var cXY = aXY.toString();
+ error = comp(domain,cXY,indepVar,CorrAns,userAns);
+ if (error == null) return null;
+ if ( (error == -1) || (error > epsilon) ) {j=-1; break;}
+ }
+ }
+ if (j!=n) return false;
+ }
+ return true;
+}
+% \end{macrocode}
+% \texttt{diffCompare}: A simple comparison function, we evaluate the two input function `\texttt{\_F}'
+% and `\texttt{\_G}' and the point `\texttt{\_c}' and return the absolute difference.
+%
+% Returns: Absolute difference between `\texttt{\_F}' and `\texttt{\_G}'
+% null if expression was not valid
+% -1 if expression is not a number
+% \begin{macrocode}
+function diffCompare(_a,_c,_v,_F,_G) {
+ var aXY = _c.split(",");
+ var _V = _v.split(","); // e.g. _V[0] = "i:x"
+ var _n = aXY.length;
+% \end{macrocode}
+% For each of the independent variables, we set them equal to a randomly chosen value
+% from the specified interval.
+% \begin{macrocode}
+ for (var _i=0; _i < _n; _i++)
+ {
+ if (_V[_i].charAt(0) == "r" )
+ eval ("var "+_V[_i].charAt(2)+"="+aXY[_i]+";");
+ else // assume type "i"
+ eval ("var "+_V[_i].charAt(2)+"="+Math.ceil(aXY[_i])+";");
+ }
+% \end{macrocode}
+% The \texttt{\_F} is the author's answer, we assume this is well formed JavaScript
+% and do not test it for possible errors. The author can correct before s/he distributes
+% the document.
+% \begin{macrocode}
+ _F = eval(_F);
+% \end{macrocode}
+% Now we try to protect our code from bad input. We use \texttt{try/catch} to try and
+% thrown exceptions. However, \texttt{try/catch} is not valid in any version of the
+% Acrobat Reader prior to version 5.
+% \begin{macrocode}
+ if ( app.viewerVersion >= 5)
+ {
+% \end{macrocode}
+% This code, which uses \texttt{eval()} and \texttt{try/catch} is an attempt to write
+% code that both works for Acro5 (or higher) and Acro4.05/4.0. In Acro4.x, \texttt{try/catch}
+% are reserved words, so we can't use them even in a conditional. However, within a string
+% the JavaScript interpreter does not see them. The other complication is that Acro5 objects
+% to having a \texttt{return} within an \texttt{eval()}, so we work around that with a
+% \texttt{rtnCode}. The returns are executed outside the \texttt{eval()}.
+% \begin{macrocode}
+ var rtnCode = 0;
+ eval("try {if(isNaN(_G = eval(_G))) rtnCode=-1; }"
+ +"catch (e) { rtnCode=1; }");
+ switch(rtnCode)
+ {
+ case 0: break;
+ case 1: return null;
+ case -1: return -1;
+ }
+ }
+ else
+% \end{macrocode}
+% For Acro4/4.05, all we can do is detect whether \texttt{\_G} is a number or not. If the user
+% enters an undefined symbol, for example, we cannot catch this as we can with Acro5. Oh, well.
+% \begin{macrocode}
+ if(isNaN(_G = eval(_G))) return -1;
+% \end{macrocode}
+%
+% The function \texttt{G} is the user's input expression. There may be syntax errors
+% that prevent the successful numerical evaluation of the expression. We try to
+% prevent problems.
+%
+% If the user enters a function such as \texttt{sqrt( 1 - x )}, and this function is
+% evaluated at a x = 2, for example, we are outside the domain of the function. The \texttt{isNaN}
+% function will catch this type of error. A return of \texttt{-1} signals an error
+% at this of this type. This is considered to be an error by the user, and will be scored as an
+% incorrect answer.
+%
+% The error described above does not throw an exception. What will throw an exception
+% is if the users function has some undefined variables in it. For example, suppose
+% we are expecting a response that is a function of \texttt{x} and the user enters a
+% function of \texttt{t} instead. This will throw an exception as \texttt{t} is undefined.
+% In this case, we do not treat this as an error, and expect the user to correct the
+% input. This kind of error is signaled by returning a \texttt{null}.
+%
+% \begin{macrocode}
+ return Math.abs ( _F - _G );
+}
+% \end{macrocode}
+% This function is the same as above, but returns the relative absolute error.
+% \begin{macrocode}
+function reldiffCompare(_a,_c,_v,_F,_G) {
+ var aXY = _c.split(",");
+ var _V = _v.split(","); // e.g. _V[0] = "i:x"
+ var _n = aXY.length
+ for (var _i=0; _i < _n; _i++)
+ {
+ if (_V[_i].charAt(0) == "r" )
+ eval ("var "+_V[_i].charAt(2)+"="+aXY[_i]+";");
+ else // assume type "i"
+ eval ("var "+_V[_i].charAt(2)+"="+Math.ceil(aXY[_i])+";");
+ }
+ _F = eval(_F);
+ if ( app.viewerVersion >= 5)
+ {
+ var rtnCode = 0;
+ eval("try { if(isNaN(_G = eval(_G))) rtnCode=-1; }"
+ +"catch (e) { rtnCode=1; }");
+ switch(rtnCode)
+ {
+ case 0: break;
+ case 1: return null;
+ case -1: return -1;
+ }
+ }
+ else
+ if(isNaN(_G = eval(_G))) return -1;
+ return Math.abs ( (_F - _G)/_G );
+}
+% \end{macrocode}
+% \DescribeMacro{requireForm}(07/16/11) The JS function \texttt{requireForm} is an example of a filter function. It is
+% of such a general nature we put it in the \textsf{exerquiz} code, rather than the \textsf{dljslib} code.
+% The function takes two or three arguments, the second one is an regular expression or an array
+% of regular expressions to test \texttt{UserAns} against. The third, optional argument is a text message to
+% be displayed if the \texttt{UserAns} is not of the required form.
+%\changes{v6.4f}{2011/07/16}{Added \texttt{requireForm} filtering function}
+%\par\medskip\noindent Usage: Factor: $-36z^5 - 96z^4 - 64z^3.$
+%\begin{verbatim}
+%\RespBoxMath{-4z^3(3z+4)^2}(z)*{3}{.0001}{[0,1]}[ { priorParse:
+% \Array( \Array( requireForm, \Array(%
+% /.*(\refac\repow|\refac\refac)/,%
+% /.*\refac\refac\repow\redigit+/,%
+% /.*\refac\repow\redigit+\refac/,%
+% /.*\refac\refac\refac/%
+% ), \myCustomMsg ) ) }
+% ]\CorrAnsButton{-4z^3(3z+4)^2}
+%\end{verbatim}
+% where \cs{refac}, \cs{repow}, \cs{redigit}, and \cs{rediv} are convenience macros defined
+% earlier in \texttt{exerquiz.dtx}. The regular expression describe the form of the answer
+% acceptable.
+%
+% There seems to be a redundancy in the usage of \cs{Array}, but this is by design.
+% The first \cs{Array} is there so the function \texttt{\_ProcResp} does not misinterpret
+% the second \cs{Array}.
+% \begin{macrocode}
+function requireForm(UserAns, regexpr) {
+ var msg=\defaultReqFormMsg;
+ UserAns = stripWhiteSpace (UserAns);
+ if (!ok2Continue) return null;
+% UserAns = stripOutMuli(UserAns);
+ UserAns = ChngAllGrpsToParens(UserAns);
+ if (arguments.length>2) msg=arguments[2];
+ if (typeof(regexpr.length)=="undefined") {
+ if (regexpr.test(UserAns)) return true;
+ else { eqAppAlert(msg,3); return null; }
+% \end{macrocode}
+% \texttt{regexpr} is an array of regular expressions.
+% \begin{macrocode}
+ } else {
+ for (var i=0; i<regexpr.length; i++)
+ if (regexpr[i].test(UserAns)) break;
+ if ( i < regexpr.length ) return true;
+ else { eqAppAlert(msg,3); return null; }
+ }
+}
+% \end{macrocode}
+% \DescribeMacro{denyForm}Same type of function as \texttt{requireForm}.
+% If the regular expression is found, we return \texttt{null}
+% and emit an alert.
+% \begin{macrocode}
+function denyForm(UserAns, regexpr) {
+ var msg=\defaultReqFormMsg;
+ UserAns = stripWhiteSpace (UserAns);
+ if (!ok2Continue) return null;
+% UserAns = stripOutMuli(UserAns);
+ UserAns = ChngAllGrpsToParens(UserAns);
+ if (arguments.length>2) msg=arguments[2];
+ if (typeof(regexpr.length)=="undefined") {
+ if (regexpr.test(UserAns)) { eqAppAlert(msg,3); return null; }
+ else return true;
+% \end{macrocode}
+% \texttt{regexpr} is an array of regular expressions.
+% \begin{macrocode}
+ } else {
+ for (var i=0; i<regexpr.length; i++)
+ if (regexpr[i].test(UserAns)) break;
+ if ( i < regexpr.length ) { eqAppAlert(msg,3); return null; }
+ else return true;
+ }
+}
+% \end{macrocode}
+% \DescribeMacro{requireFormNot} does the opposite of
+% \texttt{requireForm}. If the regular expression is found,
+% we return \texttt{false}. \texttt{postParse} does not emit any messages.
+% \begin{macrocode}
+function requireFormNot(UserAns, regexpr) {
+ UserAns = stripWhiteSpace (UserAns);
+ if (!ok2Continue) return null;
+ UserAns = stripOutMuli(UserAns);
+ UserAns = ChngAllGrpsToParens(UserAns);
+ if (typeof(regexpr.length)=="undefined") {
+% \end{macrocode}
+% If the regular expression is found, we return false
+% this is opposite to what \texttt{requireForm} returns
+% \begin{macrocode}
+ if (regexpr.test(UserAns)) return false;
+ else return true;
+% \end{macrocode}
+% \texttt{regexpr} is an array of regular expressions.
+% \begin{macrocode}
+ } else {
+ for (var i=0; i<regexpr.length; i++)
+ if (regexpr[i].test(UserAns)) break;
+ if ( i < regexpr.length ) return false;
+ else return true;
+ }
+}
+\end{newsegment}
+% \end{macrocode}
+% \subsection{Text Fill-in}
+% Now the JS functions that process text fill-in questions.
+% \begin{macrocode}
+\begin{newsegment}{Eq: Support Text Fill-in}
+% \end{macrocode}
+% This function processes fill-in problems that require only a text
+% response. It takes a variable number of arguments, which are retrieved
+% using the \texttt{arguments[]} array
+% \begin{macrocode}
+function ProcRespTxt() {
+ var i, success, authorAnswer, userAnswer = event.value;
+ var fieldname=event.target.name;
+ var flag = arguments[0];
+ var filterMethod = arguments[1];
+ var compareMethod = arguments[2];
+ if ( !ProcessIt || userAnswer == "" ) return null;
+ for (i = 3; i < arguments.length; i++)
+ if ( success = compareTxt(userAnswer,arguments[i],%
+filterMethod, compareMethod)) break;
+ return notifyField(success, flag, fieldname);
+}
+% \end{macrocode}
+% This is for text fill-in problems with partial credit. It takes a variable
+% number of arguments. \texttt{arguments[i]=["<word>", part\_credit]}. This
+% function has a property attached to it \texttt{ProcRespTxtPC.txtPCpCr}
+% is the credit received for this problem. This function is called by
+% \cs{RespBoxTxtPC}.
+% \begin{macrocode}
+function ProcRespTxtPC() {
+ var i, success, authorAnswer, userAnswer = event.value;
+ ProcRespTxtPC.txtPCpCr=0;
+ var fieldname=event.target.name;
+ var flag = arguments[0];
+ var filterMethod = arguments[1];
+ var compareMethod = arguments[2];
+ if ( !ProcessIt || userAnswer == "" ) return null;
+% \end{macrocode}
+% Unlike \texttt{ProcRespTxt}, we do not break at our first success. We go through
+% all \texttt{<words>}, each having partial credit associated with it. For each
+% success returned by \texttt{compareTxt}, we add in the credit to the total.
+% \begin{macrocode}
+ for (i=3;i<arguments.length;i++)
+ if(compareTxt(userAnswer,arguments[i][0],%
+filterMethod,compareMethod))
+ ProcRespTxtPC.txtPCpCr+=(arguments[i][1]);
+% \end{macrocode}
+% success if at least one of the words were used, partial credit awarded.
+% \begin{macrocode}
+ success=(ProcRespTxtPC.txtPCpCr>0);
+ return notifyField(success,flag,fieldname);
+}
+% \end{macrocode}
+%
+% \texttt{compareTxt} actually compares the \texttt{userAnswer} with the \texttt{authorAnswer}.
+% there are options for various types of comparisons.
+% Returns true or false.
+% \begin{macrocode}
+function compareTxt(userAnswer,authorAnswer,filterMethod,compareMethod)
+{
+ var caseSensitive = ( compareMethod==3 ) ? "" : "i";
+ var reSwitches = "g"+caseSensitive;
+ userAnswer = new String(userAnswer).filter(filterMethod);
+ switch(compareMethod) {
+ case 1:
+ var AuthorAnswer;
+ var aAuthorAnswer = authorAnswer.split(/\s+/);
+ for (var j=0; j < aAuthorAnswer.length; j++) {
+ AuthorAnswer = new String(%
+aAuthorAnswer[j]).filter(filterMethod);
+% \end{macrocode}
+% When using \cs{RespBoxTxtPC}, if the author wants to use the
+% character class . (period, meaning match anything newline or another unicode line terminator)
+% we define in \cs{RespBoxTxtPC} a local command \cs{any} which expands to \texttt{@any@}.
+% After we replace any occurrence of . (period) with \verb!\\.!, we then replace \texttt{@any@}
+% with \texttt{.}.
+% \begin{macrocode}
+ AuthorAnswer = AuthorAnswer.replace(/\./g,"\\.");
+ AuthorAnswer = AuthorAnswer.replace(/@any@/g,".");
+ var re = new RegExp(AuthorAnswer, reSwitches);
+ if (!re.test(userAnswer)) return false;
+ }
+ return true;
+ default:
+ authorAnswer=new String(authorAnswer).filter(filterMethod);
+ return (userAnswer == authorAnswer) ? true : false;
+ }
+}
+% \end{macrocode}
+% Various string prototypes. This function is called by compareTxt.
+% The function returns the 'filtered' string.
+% \begin{macrocode}
+String.prototype.filter = eqFilter;
+function eqFilter(filterMethod) {
+ switch (filterMethod) {
+ case 0:
+ var re = /\W/g;
+ return this.replace(re,"").toLowerCase();
+ case 1:
+ var re = /\s/g;
+ return this.replace(re,"").toLowerCase();
+ case 2:
+ var re = /\s/g;
+ return this.replace(re,"");
+% \end{macrocode}
+% If filter method 3 is used, a case-insensitive search is used in the
+% \texttt{compareTxt} method. Added 04/21/09.
+% \begin{macrocode}
+ case 3:
+ default:
+% \end{macrocode}
+%\changes{v6.4k}{2011/08/17}{Within the function eqFilter, changed \texttt{this} to
+% \texttt{this.toString()}. The comparisons were returning false when they shouldn't
+% this is because in this case, we were comparing objects to objects}
+% \begin{macrocode}
+ return this.toString();
+ }
+}
+\end{newsegment}
+% \end{macrocode}
+% \subsection{Multiple Choice Questions}
+% These are the routines for processing multiple choice questions.
+% \begin{macrocode}
+\begin{newsegment}{Eq: Quiz Management}
+function InitMsg(msg) { return (\eqInitQuizMsg) }
+function syntaxError() { eqAppAlert(\eqSyntaxErrorUndefVar,3); }
+% \end{macrocode}
+% \begin{macrocode}
+var lstOfQuizzes=new Array();
+% \end{macrocode}
+% There are four required parameters, if there is a fifth, that means
+% we have a grouped question, parameter 5 will be the group sub-problem number.
+% \begin{macrocode}
+var reExtractBaseName=/^.+?\.(.+?)\..+$/;
+function ProcUserResp(key,userresp,probno,notify)
+{
+ if (key==null) {
+ ProcUserNoResp.apply(null,arguments);
+ return;
+ }
+ if ( arguments.length > 4 ) {
+ if ( typeof RightWrong[probno] == "undefined" ) {
+ RightWrong[probno] = new Array();
+ RightWrong[probno][0] = "grp";
+ Responses[probno] = new Array();
+ }
+ RightWrong[probno][arguments[4]] = (!!key) ? 1 : 0;
+ Responses[probno][arguments[4]] = userresp;
+ } else {
+% \end{macrocode}
+% If key is an array, we are processing a multiple selection problem. The
+% actual key is the first entry. The second entry, not used here, is 1
+% if user has selected at least one correct answer, zero otherwise.
+% \begin{macrocode}
+ if ( typeof key == "object" ) {
+ RightWrong[probno][0] = key[0];
+ RightWrong[probno][1] = key[1];
+ Responses[probno] = userresp;
+ if (Responses[probno].length==0)
+ Responses[probno]=undefined;
+ } else {
+ RightWrong[probno] = (!!key)?1:0;
+ Responses[probno] = userresp;
+ }
+ }
+% \end{macrocode}
+% \texttt{ProcUserResp()} is also called by a link, so we'll skip this code.
+% \texttt{fieldPopTbl()} is executed later in \texttt{ProcessQuestions()}
+% \begin{macrocode}
+ if ( (typeof fieldPopTbl == "function")&&(event.type != "Link") ) {
+ var a=reExtractBaseName.exec(event.target.name);
+ fieldPopTbl(a[1]);
+ }
+}
+function ProcUserNoResp(key,userresp,probno,notify)
+{
+ if ( arguments.length > 4 ) {
+ RightWrong[probno][arguments[4]] = undefined;
+ Responses[probno][arguments[4]] = undefined;
+ var bVoidArray=true;
+ for (var i=0; i<Responses[probno].length; i++) {
+ if ( typeof Responses[probno][i] != "undefined") {
+ bVoidArray=false;
+ break;
+ }
+ }
+ if (bVoidArray) {
+ Responses[probno]=undefined;
+ RightWrong[probno]=undefined;
+ ProbValue[probno]=undefined;
+ }
+ } else {
+ RightWrong[probno] = undefined;
+ Responses[probno] = undefined;
+ }
+ if ( typeof fieldPopTbl == "function" ) {
+ var a=reExtractBaseName.exec(event.target.name);
+ fieldPopTbl(a[1]);
+ }
+}
+function InitializeQuiz(qtfield,mark) {
+ var oQName=eval(qtfield);
+ Score=0;
+ retn = null;
+ if (!isQuizInitialized(qtfield)&&!isAQuizUnfinished()) return null;
+ neutralizeQuizzes();
+ ProcessIt = false;
+ aQuizControl[qtfield] = 1;
+ this.resetForm(["ScoreField." + qtfield,"mc."+qtfield,
+ "obj."+qtfield,"mck."+qtfield,"Ans."+qtfield,
+ "PointsField."+qtfield,"PercentField."+qtfield,
+ "essay."+qtfield,"GradeField."+qtfield,
+ "grpobj."+qtfield,"qMark."+qtfield, qtfield+"SanityCheck",
+ qtfield+"SanityCheckPts",qtfield+"SanityCheckOOPts",
+ "rbmarkup."+qtfield]);
+ ProcessIt = true;
+ var f = this.getField("qMark."+qtfield);
+ if ( f != null ) f.display = display.hidden;
+ f = this.getField("promptButton."+qtfield);
+ if (f != null) f.display=display.visible;
+% \end{macrocode}
+% We create a special parameter for Oa.Sys. Then the arguments.length is
+% 3 (or greater) we do not set the objective text fields to readonly=false.
+% Oa.Sys already creates a readonly field for the solutions, we don't want
+% to mess with that.
+% \begin{macrocode}
+ if (arguments.length<3) {
+ f = this.getField("obj." + qtfield);
+ if ( f != null ) f.readonly = false;
+ }
+ RightWrong=new Array();
+ Responses=new Array();
+ ProbValue=new Array();
+ ProbDist=new Array();
+ ProbType=new Array();
+ if (mark==1)
+ {
+% \end{macrocode}
+% The next few lines support local symbol and color assignment.
+% \begin{macrocode}
+ var defaultColor=(typeof oQName.DefaultColorJSLoc=="undefined")%
+?\defaultColorJS:oQName.DefaultColorJSLoc;
+ var rightColor=(typeof oQName.RightColorJSLoc=="undefined")%
+?\rghtColorJS:oQName.RightColorJSLoc;
+ var corrAnsSymb=(typeof oQName.CorrAnsSymbJSLoc=="undefined")%
+?\corrAnsSymbJS:oQName.CorrAnsSymbJSLoc;
+ var f = this.getField("mcq." + qtfield);
+ if (f != null) {
+ f.delay=true;
+ f.display=display.hidden;
+ this.resetForm([f.name]);
+% \end{macrocode}
+% (2013/10/27) Removed legacy code for version prior to 4.0
+% \begin{macrocode}
+ f.textColor = rightColor;
+ var a = f.getArray();
+ for (var i=0; i<a.length; i++) a[i].style=corrAnsSymb;
+ f.delay=false;
+ }
+ f = this.getField("obj." + qtfield);
+ if ( f != null ) f.strokeColor = defaultColor;
+ f = this.getField("grpobj." + qtfield);
+ if ( f != null ) f.strokeColor = defaultColor;
+ f = this.getField("corr." + qtfield);
+ if ( f != null ) f.display = display.hidden;
+ f = this.getField(qtfield+"SanityCheck");
+ if ( f != null ) f.strokeColor=defaultColor;
+ f = this.getField("rbmarkup."+qtfield);
+ if ( f != null ) f.display = display.hidden;
+ }
+ return null;
+}
+function neutralizeQuizzes()
+{
+ for ( var qtfield in aQuizControl ) aQuizControl[qtfield] = 0;
+}
+isAQuizUnfinished.check=true;
+function isAQuizUnfinished()
+{
+ if (!isAQuizUnfinished.check) return true;
+ for ( var qtfield in aQuizControl )
+ if ( aQuizControl[qtfield] == 1 )
+ {
+ eqAppAlert(\eqerrUnfinishQuiz, 3);
+ return false;
+ }
+ return true;
+}
+function isQuizInitialized(qtfield)
+{
+ if (typeof (aQuizControl[qtfield]) == "undefined")
+ return false;
+ else
+ return (aQuizControl[qtfield] == 1);
+}
+function isEndQuizPushed(qtfield)
+{
+ if (typeof (aQuizControl[qtfield]) == "undefined")
+ return false;
+ else
+ return (aQuizControl[qtfield] == -1);
+}
+function resetQuiz(qtfield)
+{
+ aQuizControl[qtfield] = -1;
+}
+% \end{macrocode}
+% The function RecordPointValue has two required parameters. For a grouped question,
+% there are three more parameters, they are, in order (2) grpquestionno (3) grpPointValue
+% (4) total weight (5) grpEvalFunction, a JS function that evaluates the group.
+% The elements of the ProbValue array are as follows:
+%\begin{enumerate}
+% \item If multiple choice, then the entry is \texttt{[0, point value, partial credit]}
+% \item If objective type question that is not part of a group, the entry is a number \texttt{point value}
+% \item total weight of the group, significant only if greater than point value
+% \item If objective grouped-type question, the entry is\\
+% \texttt{[1, EvalJS, grpPointValue, <list of points for each part>]}
+%\end{enumerate}
+% \begin{macrocode}
+function RecordPointValue(ptvalue,probno)
+{
+ if (arguments.length > 2) {
+ if ( typeof ProbValue[probno] == "undefined" ) {
+ ProbValue[probno]=[1,arguments[5],arguments[3],arguments[4]];
+ ProbValue[probno][3+arguments[2]] = ptvalue;
+ } else ProbValue[probno][3+arguments[2]] = ptvalue;
+ }
+ else {
+ ProbValue[probno]=ptvalue;
+ }
+}
+function RecordProblemType(qType,probno)
+{
+ ProbType[probno]=qType;
+}
+function GrpRight( a, nProb, qtfield )
+{
+ var f = this.getField("grpobj."+qtfield+"."+nProb);
+ var l = f.getArray().length
+ var prod = 1;
+ for ( var i=1; i <= l; i++) prod *= !!a[i];
+ return prod;
+
+}
+function DisplayQuizResults(qtfield,nPointTotal,nQuestions)
+{
+ Score = 0; ptScore = 0;
+ for (var i=1; i < RightWrong.length; i++)
+ {
+ if ( (typeof RightWrong[i] == "object" ) %
+ && ( RightWrong[i][0] == "grp" ) ) {
+ // grouped question
+ Score += GrpRight(RightWrong[i], i, qtfield);
+ var aWeights = ProbValue[i].slice(2);
+ var evalGrpJS = eval(ProbValue[i][1]);
+ var evalGrpJSValue = evalGrpJS(this,qtfield,i,
+ RightWrong[i],aWeights);
+ ProbDist[i] = evalGrpJSValue;
+ ptScore = ptScore + evalGrpJSValue;
+ } else {
+ if (typeof RightWrong[i] == "object") {
+ if ( RightWrong[i][0] == 1 ) {
+ Score++;
+ ProbDist[i]=(typeof ProbValue[i] == "object") ?
+ 1*ProbValue[i][1] : 1*ProbValue[i];
+ ptScore += (1*ProbDist[i]);
+ } else {
+ if (RightWrong[i][1] == 1)
+ ProbDist[i]=(typeof ProbValue[i]=="object") ?
+ 1*ProbValue[i][1] : 1*ProbValue[i];
+ else
+ ProbDist[i]=(typeof ProbValue[i] == "object") ?
+ 1*ProbValue[i][1] : 0;
+ ptScore += (1*ProbDist[i]);
+ }
+ } else {
+ if (RightWrong[i]==1) {
+ Score++;
+ ProbDist[i] = ( typeof ProbValue[i] == "object") ?
+ 1*ProbValue[i][1] : 1*ProbValue[i];
+ ptScore += (1*ProbDist[i]);
+ }
+ else {
+ ProbDist[i] = ( typeof ProbValue[i] == "object") ?
+ 1*ProbValue[i][2] : 0;
+ ptScore += (1*ProbDist[i]);
+ }
+ }
+ }
+ }
+if ( !negPointsAllowed && (ptScore < 0) ) ptScore = 0;
+ if (ptScore == nPointTotal) pcScore = 100;
+ else pcScore = util.printf("\%.1f", (100 * ptScore) / nPointTotal);
+ var oQName=eval(qtfield);
+ var gradeScale=%
+(typeof oQName.GradeScaleLoc=="undefined")%
+?GradeScaleDefault:oQName.GradeScaleLoc;
+ quizGrade = GetGrade.apply(null,gradeScale);
+% quizGrade = GetGrade(\eqGradeScale);
+ var f = this.getField("ScoreField."+qtfield);
+ if ( f != null ) f.value=(\eqQuizTotalMsg);
+ f = this.getField("PointsField."+qtfield);
+ if ( f != null) f.value=(\eqQuizPointsMsg);
+ f = this.getField("PercentField."+qtfield);
+ if ( f != null) f.value=(\eqQuizPercentMsg);
+ f = this.getField("GradeField."+qtfield);
+ if ( f != null) f.value=(\eqQuizGradeMsg);
+}
+function GetGrade()
+{
+ var cGrade, aRange;
+ var l = arguments.length/2;
+ if (pcScore >=100) return arguments[0];
+ if (pcScore < 0 ) return arguments[arguments.length-2];
+ for (var i=0; i < l; i++)
+ {
+ cGrade = arguments[2*i];
+ aRange = arguments[2*i+1];
+ if ( (pcScore >= arguments[2*i+1][0])
+ && (pcScore < arguments[2*i+1][1])) return cGrade;
+ }
+ return null;
+}
+function ProcessQuestion (key,letterresp,probno,
+ quizno,qtfield,notify,mark,msg) {
+ var silent = ( arguments.length > 8 ) ? true : false;
+ if (!isQuizInitialized(qtfield))
+ {
+ if (!silent) eqAppAlert(InitMsg(msg),3);
+ this.resetForm(["mc."+qtfield+"."+probno,
+ "mck."+qtfield+"."+probno]);
+ }
+ else
+ {
+ ProcUserResp(key,letterresp,probno,notify);
+ if (mark==1)
+ {
+ var oQName=eval(qtfield);
+ var defaultColor=%
+(typeof oQName.DefaultColorJSLoc=="undefined")%
+?\defaultColorJS:oQName.DefaultColorJSLoc;
+ var rightColor=%
+(typeof oQName.RightColorJSLoc== "undefined")%
+?\rghtColorJS:oQName.RightColorJSLoc;
+ var wrongColor=%
+(typeof oQName.WrongColorJSLoc=="undefined")%
+?\wrngColorJS:oQName.WrongColorJSLoc;
+ var rightAnsSymb=%
+(typeof oQName.RightAnsSymbJSLoc=="undefined")%
+?\rghtAnsSymbJS:oQName.RightAnsSymbJSLoc;
+ var wrongAnsSymb=%
+(typeof oQName.WrongAnsSymbJSLoc=="undefined")%
+?\wrngAnsSymbJS:oQName.WrongAnsSymbJSLoc;
+ var corrAnsSymb=%
+(typeof oQName.CorrAnsSymbJSLoc=="undefined")%
+?\corrAnsSymbJS:oQName.CorrAnsSymbJSLoc;
+% \end{macrocode}
+% MC or MS questions
+% \begin{macrocode}
+ var f = this.getField("mcq."+qtfield+"."+probno);
+ var fck = this.getField("mck."+qtfield+"."+probno);
+ var bMultiSelect = ( fck != null ) ? true : false;
+ f.delay=true;
+ this.resetForm([f.name]);
+ var a = f.getArray();
+ var l = a.length;
+ if ( bMultiSelect ) {
+ var ack = fck.getArray();
+ for ( var i=0; i<l; i++) {
+ if ( ack[i].isBoxChecked(0) ) {
+ a[i].style = ( a[i].isDefaultChecked(0) ) ?
+ rightAnsSymb : wrongAnsSymb;
+ a[i].textColor = ( a[i].isDefaultChecked(0) ) ?
+ rightColor : wrongColor;
+ a[i].value = "Yes";
+ } else {
+ a[i].style = ( a[i].isDefaultChecked(0) ) ?
+ corrAnsSymb : wrongAnsSymb;
+ a[i].textColor = ( a[i].isDefaultChecked(0) ) ?
+ rightColor : wrongColor;
+ a[i].value = ( a[i].isDefaultChecked(0) ) ?
+ "Yes" : "Off";
+ }
+ }
+ } else {
+ for (var i=0; i < a.length; i++)
+ if (a[i].style == rightAnsSymb)
+ {
+ a[i].style = corrAnsSymb;
+ a[i].textColor = rightColor;
+ }
+ var qr=this.getField(%
+"mcq."+qtfield+"."+probno+"."+quizno);
+% \end{macrocode}
+% (2013/10/27) removed legacy code for versions prior to 4.0.
+% \begin{macrocode}
+ qr.textColor = key ? rightColor :wrongColor;
+ qr.style = key ? rightAnsSymb : wrongAnsSymb;
+ qr.value="Yes"; // gr.checkThisBox(0); // ver 5.0
+ }
+ this.getField("mcq."+qtfield+"."+probno).delay=false;
+ }
+ }
+ if ( typeof fieldPopTbl == "function" ) fieldPopTbl(qtfield);
+}
+% \end{macrocode}
+% Dependencies: \texttt{RightWrong}, \texttt{ProbDist} (if \texttt{qMark} is present).
+% \begin{macrocode}
+function correctQuiz(qtfield,nQuestions)
+{
+ var oQName=eval(qtfield);
+ var defaultColor=(typeof oQName.DefaultColorJSLoc=="undefined")%
+?\defaultColorJS:oQName.DefaultColorJSLoc;
+ var rightColor=(typeof oQName.RightColorJSLoc=="undefined")%
+?\rghtColorJS:oQName.RightColorJSLoc;
+ var wrongColor=(typeof oQName.WrongColorJSLoc=="undefined")%
+?\wrngColorJS:oQName.WrongColorJSLoc;
+ var rightAnsSymb=(typeof oQName.RightAnsSymbJSLoc=="undefined")%
+?\rghtAnsSymbJS:oQName.RightAnsSymbJSLoc;
+ var wrongAnsSymb=(typeof oQName.WrongAnsSymbJSLoc=="undefined")%
+?\wrngAnsSymbJS:oQName.WrongAnsSymbJSLoc;
+% \end{macrocode}
+% MC or MS questions
+% \begin{macrocode}
+ var f = this.getField("mcq." + qtfield);
+ if ( f != null) f.display = display.visible;
+ f = this.getField("obj." + qtfield);
+ if ( f != null ) {
+ var a = f.getArray();
+ var re=/^obj\./;
+ for (var i = 0; i < a.length; i++) {
+ var probno = a[i].name.replace(/.*\./g,"");
+ var rbmuname = a[i].name.replace(re,"rbmarkup\.");
+ var oRBMarkup = this.getField(rbmuname);
+ var bRBMU = ( oRBMarkup != null );
+ if ( RightWrong[probno] == 1 ) {
+ a[i].strokeColor = rightColor;
+ if (bRBMU) {
+ oRBMarkup.textColor=rightColor;
+ oRBMarkup.style=rightAnsSymb;
+ }
+ } else {
+ a[i].strokeColor = wrongColor;
+ if (bRBMU) {
+ oRBMarkup.textColor=wrongColor;
+ oRBMarkup.style=wrongAnsSymb;
+ }
+ }
+ }
+ }
+ f = this.getField("grpobj." + qtfield);
+ var re=/^grpobj\./;
+ if ( f != null ) {
+ var a = f.getArray();
+ for ( var i = 0; i < a.length; i++) {
+ var rbmuname = a[i].name.replace(re,"rbmarkup\.");
+ var oRBMarkup = this.getField(rbmuname);
+ var bRBMU = ( oRBMarkup != null );
+ var aX = a[i].name.split(".");
+ var probno = 1*aX[aX.length-2];
+ var grpProbno = 1*aX[aX.length-1];
+ if ( ( RightWrong[probno] != undefined ) %
+&& ( RightWrong[probno][grpProbno] == 1 ) ) {
+ a[i].strokeColor = rightColor;
+ if (bRBMU) {
+ oRBMarkup.textColor=rightColor;
+ oRBMarkup.style=rightAnsSymb;
+ }
+ } else {
+ a[i].strokeColor = wrongColor;
+ if (bRBMU) {
+ oRBMarkup.textColor=wrongColor;
+ oRBMarkup.style=wrongAnsSymb;
+ }
+ }
+ }
+ }
+ f=this.getField("rbmarkup."+qtfield);
+ if ( f != null ) f.display = display.visible;
+% f = this.getField("Ans." + qtfield);
+ % if ( f != null ) f.strokeColor = defaultColor;
+ f = this.getField("promptButton." + qtfield)
+ if ( f != null ) f.display = display.hidden;
+ f = this.getField("corr." + qtfield);
+ if ( f != null ) f.display = display.noPrint;
+% \end{macrocode}
+% dps (01/01/04) If there are qMark fields, then write marks for each question
+% to them.
+% \begin{macrocode}
+ f = this.getField("qMark."+qtfield);
+ if ( f != null )
+ {
+% console.println("ProbDist = " + ProbDist.toSource() );
+ for ( var i = 1; i <= nQuestions; i++)
+ {
+ if ( ProbValue[i] == undefined ) ProbValue[i]=0
+ f = this.getField("qMark."+qtfield+"."+(i-1));
+ if ( f != null )
+ {
+% \end{macrocode}
+% (3/22/04) This is code to account for grouping
+% \begin{macrocode}
+ // find the next non-null field
+ for ( var j=i; j <= nQuestions; j++)
+ {
+ var h = this.getField("qMark."+qtfield+"."+j);
+ if ( h != null ) break;
+ }
+ var g = f.getArray();
+ var qpts=(ProbDist[i]==undefined) ? 0 : ProbDist[i];
+ if ( !negPointsMarkupAllowed && (qpts < 0) ) qpts=0;
+ g[0].value = qpts + (( qpts == 1 ) ? " \eqptLabel\space"
+ : " \eqptsLabel");
+ }
+ }
+ this.getField("qMark."+qtfield).display = display.visible;
+ }
+}
+% \end{macrocode}
+% When pdftex is used, the total tally box does not work because pdftex does not support
+% the calculate key in AcroForms. We try to simulate this.
+% \begin{macrocode}
+function getTotalTally(basename) {
+ var sqtotal=0;
+ var f=this.getField("tally."+basename);
+ var g = f.getArray();
+ for (var i=0; i<g.length; i++) {
+ if ( g[i] == event.target ) sqtotal += (1*event.value);
+ else sqtotal += (1*g[i].value);
+ }
+% console.println("sqtotal="+sqtotal);
+ if ( ( f=this.getField("tallytotal."+basename) ) != null )
+ f.value = sqtotal;
+}
+function clearAllSubQuizzes() {
+ isAQuizUnfinished.check=false;
+ for ( var o in lstOfQuizzes) {
+ if (lstOfQuizzes[o].isSubmitted)
+ eval ( lstOfQuizzes[o].initializeWith );
+ }
+ isAQuizUnfinished.check=true;
+}
+\end{newsegment}
+% \end{macrocode}
+% \subsection{Support for Multiple Selection Questions}
+% This function
+% \begin{macrocode}
+\begin{newsegment}{Eq: Support for Multi-Selection}
+function ProcessMultiSelection(key,letterresp,probno,%
+quizno,qtfield,pts,ppts) {
+ var f = this.getField("mck."+qtfield+"."+probno);
+% \end{macrocode}
+% For the multiple selection problem, the formats for the \texttt{RightWrong} and \texttt{ProbValue}
+% arrays are as follows:
+%\begin{verbatim}
+% RightWrong[probno]
+% [0, 1, [undefined, undefined, 0, 1, 1, 0, 1]]
+%\end{verbatim}
+% The first entry records whether the user answered the question totally correctly,
+% the second entry is for awarding points, 1 if the user selected at least one correct
+% answer. The third entry is an array of right/wrong responses to the user's responses.
+%\begin{verbatim}
+% ProbValue[probno]
+% [3, 5, [undefined, undefined, -2, 3, 3, -2, 3]]
+%\end{verbatim}
+% First entry is the number of correct answers for this problem, the second entry is the
+% number of points the student has earned for this problem, the third entry is an array of points obtained
+% based on the user's responses.
+%\changes{v6.3h}{2008/10/17 }
+%{%
+% For the manswers environment, we were not determining if the user had answered the question
+% correctly.
+%}
+% \begin{macrocode}
+ if ( typeof ProbValue[probno] == "undefined" ) {
+ var g = f.getArray();
+% \end{macrocode}
+% We calculate the total number of correct alternatives in this MS field
+% \begin{macrocode}
+ var nTotalCorrect = 0;
+ for ( var i=0; i<g.length; i++ )
+ nTotalCorrect += (1*g[i].exportValues[0].charAt(0));
+ ProbValue[probno] = new Array();
+ RightWrong[probno] = new Array();
+ ProbValue[probno] = [nTotalCorrect,pts,[]];
+ RightWrong[probno][2] = new Array();
+ } else var nTotalCorrect = ProbValue[probno][0];
+ var fck = this.getField("mck."+qtfield+"."+probno+"."+quizno);
+ if ( fck.isBoxChecked(0) ) {
+ ProbValue[probno][2][quizno] = ppts;
+ RightWrong[probno][2][quizno] = key;
+ } else {
+ ProbValue[probno][2][quizno] = undefined;
+ }
+ var pointsThisProblem=0;
+ var scoreThisProblem = 0;
+ var letterResponses = new Array();
+ var areAllCorrect=1;
+ var numCorrect=0;
+ for ( var i=1; i< ProbValue[probno][2].length; i++ ) {
+ if ( typeof ProbValue[probno][2][i] != "undefined" )
+ letterResponses[i] = (String.fromCharCode(96+i));
+ pointsThisProblem += ( ( typeof ProbValue[probno][2][i]==%
+"undefined" )?0:ProbValue[probno][2][i]);
+ if ( typeof ProbValue[probno][2][i]!="undefined" ) {
+% \end{macrocode}
+% As we go through the \texttt{ProbValue[probno][2]} array, we use the index
+% to make some tallies in the \texttt{RightWrong[probno][2]} array. We multiply
+% and add all entries together. The value of \texttt{areAllCorrect} will be 1 if the
+% student only chooses correct answers, while \texttt{numCorrect} totals the number of
+% correct responses.
+% \begin{macrocode}
+ areAllCorrect *= (1*RightWrong[probno][2][i]);
+ numCorrect +=(1*RightWrong[probno][2][i]);
+ }
+ }
+% \end{macrocode}
+% The value of \texttt{scoreThisProblem} will be 0 if the user selects any false
+% answers, and will be the number of correct answers selected otherwise.
+% \begin{macrocode}
+ scoreThisProblem = areAllCorrect*numCorrect;
+% \end{macrocode}
+% Now the value of \texttt{scoreThisProblem} is 0 if the user selects any false
+% answers, and~1 if the number of correct answer equals the total number of
+% correct answers for this problem.
+% \begin{macrocode}
+ var scoreThisProblem = Number( scoreThisProblem == nTotalCorrect );
+% \end{macrocode}
+% \texttt{(02/02/09)}: If we determine this problem is right, but \texttt{pointsThisProblem==0},
+% then there must be no partial credit specification of the points, so we'll award all points.
+% \begin{macrocode}
+ if (scoreThisProblem==1 && pointsThisProblem==0 )
+ pointsThisProblem=pts;
+ ProbValue[probno][1] =
+ ( (ProbValue[probno][1] == 0) && (scoreThisProblem == 1) )
+ ? pts : pointsThisProblem;
+% \end{macrocode}
+% \texttt{passKey} represents whether positive credit is assigned; \texttt{passKey} is only 1
+% when points are awarded. \texttt{scoreThisProblem} is 0 or 1 dependent
+% on whether the problem is wrong or right.
+% \begin{macrocode}
+ var passKey = ( pointsThisProblem > 0 ) ? 1 : 0;
+ var retn = [ [ scoreThisProblem, passKey ], letterResponses ] ;
+ return retn;
+}
+function LimitSelection(n,fname,k) {
+ var f = this.getField(fname);
+ var g = f.getArray();
+ var total=0;
+ for (var i=0; i<g.length; i++) {
+ total+=( g[i].isBoxChecked(0) );
+ }
+ if (total > n) {
+ eqAppAlert(\limSelWarningMsg,3);
+ f=this.getField(fname+"."+k);
+ f.checkThisBox(0,false);
+ return false
+ } else return true;
+}
+\end{newsegment}
+% \end{macrocode}
+% \subsection{Miscellaneous JS}
+% \begin{macrocode}
+\begin{newsegment}{Eq: Miscellaneous JS}
+% \end{macrocode}
+% This function notifies the calling field of the results. If flag=0,
+% it changes the color of the field and updates the tally field.
+% \begin{macrocode}
+function chooseJSColor( b, c1, c2 ) {
+ return ( b ) ? c1 : c2;
+}
+function notifyField(success, flag, fieldname) {
+ if ( flag != 0 )
+ return (success)?true:false;
+% \end{macrocode}
+% if \texttt{flag == 0}, then we are working with a \texttt{shortquiz}, and immediate response
+% is needed.
+% \begin{macrocode}
+ var f = this.getField(fieldname);
+ var re=/^(obj|grpobj)\./;
+ var gname=fieldname.replace(re,"rbmarkup\.");
+ var g =this.getField(gname);
+ var isthereRBUP = ( g !=null );
+% \end{macrocode}
+% Extract the quiz name from the field name: \texttt{obj.QName.num} or \texttt{grpobj.QName.num}
+% \begin{macrocode}
+ var h = fieldname.replace(re,"");
+ var index=h.indexOf(".");
+ var oQName = eval(h.substring(0,index));
+ var rightColor=(typeof oQName.RightColorJSLoc=="undefined")%
+?\rghtColorJS:oQName.RightColorJSLoc;
+ var rightSymb=(typeof oQName.RightColorJSLoc=="undefined")%
+?\rghtAnsSymbJS:oQName.RightAnsSymbJSLoc;
+ var wrongColor=(typeof oQName.WrongColorJSLoc=="undefined")%
+?\wrngColorJS:oQName.WrongColorJSLoc;
+ var wrongSymb=(typeof oQName.WrongAnsSymbJSLoc=="undefined")%
+?\wrngAnsSymbJS:oQName.WrongAnsSymbJSLoc;
+ if (success) {
+ f.strokeColor = rightColor;
+ if (isthereRBUP) {
+ g.style = rightSymb;
+ g.textColor=rightColor;
+ g.display=display.visible;
+ }
+ return true;
+ } else {
+ updateTally.downState=false;
+ updateTally(fieldname);
+ f.strokeColor = wrongColor;
+ if (isthereRBUP) {
+ b2 = ( typeof oQName.WrongAnsSymbJSLoc == "undefined" );
+ g.style = wrongSymb;
+ g.textColor=wrongColor;
+ g.display=display.visible;
+ }
+ return false;
+ }
+// return null; // remove ?
+}
+% \end{macrocode}
+% \begin{macrocode}
+function updateTally(fieldname)
+{
+ var objre = /^obj\./;
+ var grpre = /^grpobj\./;
+% \end{macrocode}
+% If the question is part of a group of questions, then it has a root name of \texttt{grpobj}.
+% This root needs to be removed, as well as the sub-group number.
+% \begin{macrocode}
+ if ( grpre.test(fieldname) ) {
+ fieldname = fieldname.replace(grpre,"");
+ var pos = fieldname.lastIndexOf(".");
+ fieldname = fieldname.substring(0,pos);
+ } else if ( objre.test(fieldname) )
+ fieldname = fieldname.replace(objre,"");
+ var f = this.getField("tally."+fieldname);
+ if ( f != null ) {
+ if (!updateTally.downState) f.value += 1;
+ return true;
+ } else return false;
+
+}
+% \end{macrocode}
+% Below is the \texttt{noPeek} JS function that has been part of \textsf{exerquiz} from the
+% beginning.
+%\begin{verbatim}
+%function noPeek(qtfield,rtnPage)
+%{
+% if ( (typeof (aQuizControl[qtfield]) == "undefined") %
+%|| (aQuizControl[qtfield] != -1) ) {
+% this.pageNum = rtnPage-1;
+% eqAppAlert(\noPeekMsg,3);
+% }
+%}
+%\end{verbatim}
+% (2010/08/09 v6.3s) One user recently reported that Acrobat/Reader can crash when \texttt{noPeek} is in effect.
+% This occurs when the down arrow on the scroll bar is pressed and kept pressed by the mouse.
+% The pages can jump between the quiz and a solution page, and build up alert boxes each time.
+% Eventually, there is a crash (though I haven't experienced the crash, I have seen the effects
+% of using the down arrow on the scroll bar). Below is a proposed ``fix'' for using this
+% hellish button. We turn off the alert for 5 milliseconds but always return to the
+% starting page (\texttt{rtnPage}), it is not the best solution, but it fixes the crashing
+% problem.
+% \begin{macrocode}
+var bNoPeekWait=false;
+var oNoPeekTimer;
+function noPeek(qtfield,rtnPage)
+{
+ if (!bNoPeekWait) {
+ if ( (typeof (aQuizControl[qtfield]) == "undefined") %
+|| (aQuizControl[qtfield] != -1) ) {
+ bNoPeekWait=true;
+ oNoPeekTimer=app.setTimeOut("bNoPeekWait=false;%
+app.clearTimeOut(oNoPeekTimer);",5);
+ this.pageNum = rtnPage-1;
+ \NoPeekAlert;
+ }
+ } else this.pageNum = rtnPage-1;
+}
+% \end{macrocode}
+% When the user exits a fill-in shortquiz field, this function is called.
+% It immediately notifies user of whether their answer is right
+% or wrong, and changes the color of the boundary field.
+% \begin{macrocode}
+var oCB=\bcheckboxused
+function OnBlurRespBox (retn)
+{
+ var qname = arguments[1];
+ var oQName = eval(qname);
+ var respMsg;
+ var cTitle = "AcroTeX eDucation Bundle";
+ if (retn != null) {
+ if ( typeof appAlerts[qname] == "undefined")
+ appAlerts[qname] = {bAfterValue: false, %
+cMsg: "\doNotShowAgainMsg"};
+ var respMsg = (retn) ? \eqsqrtmsg\space : \eqsqwgmsg;
+ if ( (event.target == this) || !oCB)
+ eqAppAlert({ cMsg: respMsg, nIcon: 3, cTitle: cTitle });
+ else {
+ if ( ! appAlerts[arguments[1]].bAfterValue )
+ eqAppAlert({ cMsg: respMsg, nIcon: 3, cTitle: cTitle, %
+oCheckbox: appAlerts[qname]});
+ }
+ }
+ else {
+ var re=/^(obj|grpobj)\./;
+ var gname=event.target.name.replace(re,"rbmarkup\.");
+ var g =this.getField(gname);
+ var isthereRBUP = ( g !=null );
+ var str = event.target.value.toString();
+ if (str.replace(/\s/g,"") == "") {
+ var defaultColor=%
+(typeof oQName.DefaultColorJSLoc=="undefined")%
+?color.black:oQName.DefaultColorJSLoc;
+ if (isthereRBUP) g.display=display.hidden;
+ event.target.strokeColor = defaultColor;
+ }
+ }
+}
+function jmpToNamedDest(fName,cDest,bAlert) {
+ if ( (typeof appAlerts[fName]!="undefined" %
+&& appAlerts[fName].bAfterValue) || bAlert==0)
+ app.setTimeOut("this.gotoNamedDest(\""+cDest+"\")",500);
+ else
+ this.gotoNamedDest(cDest);
+}
+% \end{macrocode}
+% Description: This is the default function for determining whether
+% the minimal requirements for finishing a quiz have been met. The
+% default is that there is no minimal requirement.
+% Arguments: qtfield = name of the field.
+% Returns: true if minimum threshold is met, false otherwise.
+% \begin{macrocode}
+function lowThreshold(nQuestions)
+{
+ return true;
+}
+% \end{macrocode}
+% Description: This is the default function for determining whether
+% the minimal requirements for finishing a quiz have been met. Here
+% the requirements are to answer all the questions.
+% Arguments: nQuestions = number of questions.
+% Returns: true if minimum threshold is met, false otherwise.
+%
+% \noindent You can define this function as the default threshold function by
+% typing\par
+%\begin{verbatim}
+%\renewcommand\minQuizResp{highThreshold}
+%\end{verbatim}
+% \begin{macrocode}
+function highThreshold(nQuestions)
+{
+ var cnt=0;
+ for ( var i=0; i< Responses.length; i++ ) {
+ if ( typeof Responses[i]!="undefined") cnt++
+ }
+ if ( cnt<nQuestions )
+ eqAppAlert(\highThresholdMsg,3);
+ return (cnt >= nQuestions);
+}
+\end{newsegment}
+% \end{macrocode}
+% \subsection{Support for Grouped Questions}
+% These function can be called by the \texttt{mathGrp} environment to score the user's
+% responses to the grouped questions.
+% \begin{macrocode}
+\begin{newsegment}{Eq: Support for Grouped Questions}
+function groupEval(doc,qtfield,probno,aKey,aWeights)
+{
+ var totalGrpPts = aWeights[0];
+ var totalWeight = aWeights[1];
+ for ( var i=1,total=0; i< aKey.length; i++ )
+ if (aKey[i] != undefined) total += aKey[i]*aWeights[i+1];
+ return total;
+}
+function WeightedEval(doc,qtfield,probno,aKey,aWeights)
+{
+ var f = doc.getField("grpobj." + qtfield + "." + probno);
+ var nGrpQno = f.getArray().length;
+ var totalGrpPts = aWeights[0];
+ var totalWeight = aWeights[1];
+ for ( var i=1,total=0; i < aKey.length; i++ )
+ if (aKey[i] != undefined) total += aKey[i]*aWeights[i+1];
+ total /= totalWeight;
+ total = Math.floor( total * totalGrpPts );
+ return total;
+}
+% \end{macrocode}
+% This function gives full credit if all parts are answer correctly,
+% otherwise, it gives no credit. This defeats the purpose of partial
+% credit. But someone asked for it.
+% \begin{macrocode}
+function groupBernoulliEval(doc,qtfield,probno,aKey,aWeights)
+{
+ var f = doc.getField("grpobj." + qtfield + "." + probno);
+ var nGrpQno = f.getArray().length;
+ var totalGrpPts = aWeights[0];
+ for ( var i=1,isCorrect=1; i<= nGrpQno; i++ )
+ isCorrect *= (aKey[i] != undefined) ? (Number(aKey[i])) : 0;
+ return (isCorrect*totalGrpPts);
+}
+\end{newsegment}
+\end{insDLJS*}
+%</aebjs>
+%<*sumrytbls>
+% \end{macrocode}
+% This function is called by the \cs{CorrButton}, it does nothing if the ``SanityCheck''
+% fields are not present; otherwise, it colors the boundaries red, green or blue
+% depending on whether the problem is wrong, right, or wrong with partial credit given.
+% \begin{macrocode}
+\begin{insDLJS}[correctSumryTbl]{sumtbljs}{Eq: Populate Summary Table}
+function correctSumryTbl(qtfield,nQuestions) {
+% \end{macrocode}
+% \paragraph*{Checkboxes.} We begin by correcting the second column of the summary table.
+% \begin{macrocode}
+ var oQName=eval(qtfield);
+ var rightColor=(typeof oQName.RightColorJSLoc=="undefined")%
+?\rghtColorJS:oQName.RightColorJSLoc;
+ var wrongColor=(typeof oQName.WrongColorJSLoc=="undefined")%
+?\wrngColorJS:oQName.WrongColorJSLoc;
+ var partialColor=(typeof oQName.PartialColorJSLoc=="undefined")%
+?\partialColorJS:oQName.PartialColorJSLoc;
+ var sc=this.getField(qtfield+"SanityCheck");
+ var nc=this.getField(qtfield+"NoCorrections");
+ if (sc != null && nc == null ) {
+ for (var i=0; i<nQuestions; i++) {
+ var cb=this.getField(qtfield+"SanityCheck."+(i+1));
+ if (typeof RightWrong[i+1] == "undefined" ) {
+ cb.strokeColor=wrongColor;
+ continue;
+ }
+ if ( RightWrong[i+1] == 1 ) {
+ cb.strokeColor=rightColor;
+ continue;
+ }
+ if ( RightWrong[i+1] == 0 ) {
+ // this is either an obj or multiple choice q
+ if ( typeof ProbValue[i+1] == "object" )
+ cb.strokeColor=( ProbValue[i+1][2] > 0 )?%
+partialColor:wrongColor;
+ else cb.strokeColor=wrongColor; // obj q
+ continue;
+ }
+ // either multiple selection or grouped math
+ if ( RightWrong[i+1][0] == "grp" ) {
+ // grouped question
+ var f = this.getField("grpobj."+qtfield+"."+(i+1));
+ var l = f.getArray().length;
+ // is this right?
+ for (var sum=0, j=1; j<=l; j++)
+ sum+=(!!RightWrong[i+1][j]);
+ if ( sum == l ) cb.strokeColor=["RGB", 0, .6, 0];
+ else cb.strokeColor=( sum > 0 )?%
+partialColor:wrongColor;
+ continue;
+ }
+ // multiple selection
+ if ( RightWrong[i+1][0] == 1 ) cb.strokeColor=rightColor;
+ else cb.strokeColor=(RightWrong[i+1][1]== 1)?%
+partialColor:wrongColor;
+ }
+ }
+% \end{macrocode}
+% \paragraph*{Markup text fields.} Now, we insert the points into the
+% markup text fields for the summary table. We look for two types of
+% fields, in the next two lines. Each type is formatted differently.
+% \begin{macrocode}
+ var f1=this.getField(qtfield+"SanityCheckPts");
+ var f2=this.getField(qtfield+"SanityCheckOOPts");
+ var h=this.getField(qtfield+"activateSC");
+% \end{macrocode}
+% If nonnull here, we format these text fields in the usual way, `2 pts', for example.
+% \begin{macrocode}
+ if ( f1 != null ) {
+ for ( var i = 1; i <= nQuestions; i++) {
+ if ( ProbValue[i] == undefined ) ProbValue[i]=0
+ // find the next non-null field
+ var g=this.getField(qtfield+"SanityCheckPts."+i);
+ var qpts=(ProbDist[i]==undefined) ? 0 : ProbDist[i];
+ var thesePts= qpts + (( qpts == 1 )?%
+" \eqptLabel":" \eqptsLabel");
+ g.value = thesePts;
+ }
+ }
+% \end{macrocode}
+% \texttt{f2} is nonnull when \texttt{showOutOf=true} for any of the tables supporting \texttt{qtfield},
+% we repeat basically the same loop, but formatting the value differently.
+% \begin{macrocode}
+ if ( f2 != null ) {
+ for ( var i = 1; i <= nQuestions; i++) {
+ if ( ProbValue[i] == undefined ) ProbValue[i]=0
+ // find the next non-null field
+ var g=this.getField(qtfield+"SanityCheckOOPts."+i);
+ var qpts=(ProbDist[i]==undefined) ? 0 : ProbDist[i];
+ var ptValue = oQName.PtValues[i];
+ var probPts = ptValue + (( ptValue == 1 )?%
+" \eqptLabel":" \eqptsLabel");
+ g.value = qpts +" \stOutOf\space"+probPts;
+ }
+ }
+}
+function popVisitsTbl(qtfield,nQuestions) {
+ if ( aQuizControl[qtfield] == 1) {
+ this.resetForm([qtfield+"SanityCheck"]);
+ for ( var i=0; i < nQuestions; i++ ) {
+ var f=this.getField(qtfield+"SanityCheck."+(i+1));
+ f.checkThisBox(0,(typeof Responses[i+1]!="undefined"));
+ }
+ }
+}
+% \end{macrocode}
+% \DescribeMacro{fieldPopTbl} is called when there is a change in a response.
+% it gets info contained in a button embedded in the summary table (\texttt{nQuestions})
+% and then calls \texttt{popVisitsTbl()}.
+% \begin{macrocode}
+function fieldPopTbl(qtfield) {
+ var f=this.getField(qtfield+"activateSC");
+ if ( f != null) {
+ var n=Number(f.userName);
+ var a = [ qtfield, n ];
+ popVisitsTbl.apply(null,a);
+ }
+}
+\end{insDLJS}
+%</sumrytbls>
+%<*mcfi>
+\newcommand{\clickChkBxMCFI}{"Click the check box preceding this
+ math input field to enter text."}
+\begin{insDLJS}{mcf}{Eq: Supports MCFI-type questions}
+function mcfiKeyStroke(qname,n) {
+ if (event.change=="") return;
+ var qNumMC=--n;
+ var mcName="mc."+qname+"."+qNumMC;
+ var mc= this.getField(mcName);
+ var aExpVs=mc.exportValues;
+ var l=aExpVs.length-1;
+ if (!mc.isBoxChecked(l)) {
+ eqAppAlert(\clickChkBxMCFI,3);
+ event.rc=false;
+ }
+}
+function qRadioButtonMCFI(key,qname,n) {
+ var fname = "obj."+qname+"."+(n+1);
+ if ( key == 0) this.resetForm(fname);
+}
+\end{insDLJS}
+%</mcfi>
+% \end{macrocode}
+% \section{Language Definitions}
+% \StopEventually{Comment out \cs{OnlyDescription}
+% at the beginning of this file to see the language code.}
+% \subsection{French}
+% \begin{macrocode}
+%<*eqfr>
+% \end{macrocode}
+% \begin{macrocode}
+%%%%%%%%%%%%%%%%%%%%%%% eqfr.def %%%%%%%%%%%%%%%%%%%%%%%
+%% Foreign language support for the exerquiz package. %%
+%% Name of translator: Jean-Michel SARLAT %%
+%% Language: French %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Exercise label
+\renewcommand\exlabel{Exercice}
+% The value of this macro is written to \jobname.sol,
+% accented characters must be protected with a \protect
+\renewcommand\exlabelsol{\exlabel}
+
+% Solution label for solutionafter option for exercise
+\renewcommand{\eq@exsolafterDefault}{\textit{Solution} :}
+
+% Title of exercise solution section
+\renewcommand\exsectitle{Solutions des \exlabelsol s}
+\renewcommand\exsecrunhead{\exsectitle}
+
+% Title of quiz solution section
+\renewcommand\eq@sqslsectitle{Les r\'{e}ponses aux questionnaires}
+\renewcommand\sqslsectitle{\eq@sqslsectitle}
+
+% Running header/section title for solutions to quizzes
+\renewcommand\eq@sqslsecrunhead{Les r\'{e}ponses aux questionnaires}
+% User access
+\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}
+
+% Label for solutions to quizzes, appears in solutions sections
+\renewcommand\eq@sqsllabel{%
+ \protect\textbf{R\protect\'{e}ponse :}}
+\renewcommand\sqsllabel{\eq@sqsllabel}% User access
+
+% Solution label for solutionafter option for shortquiz
+\renewcommand\sqsolafter{\textit{Solution} :}
+
+% Here is the default short quiz label.
+\renewcommand\eq@sqlabel{\textcolor{red}{Question.}}
+% User access to shortquiz label
+\renewcommand\sqlabel{\eq@sqlabel}
+
+% Here is the default short quiz return label
+% No formatting allowed
+\renewcommand\eq@sqslrtnlabel{Retour au questionnaire.}
+% User access to shortquiz label
+\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}
+
+% Short quiz feedback messages
+\renewcommand\eqsqrtmsg{"Exact !"}
+\renewcommand\eqsqwgmsg{"Faux !"}
+
+% Here is the default quiz label. No formatting allowed!
+\renewcommand\eq@bqlabel{D\'ebut}
+% User access to shortquiz label
+\renewcommand\bqlabel{\eq@bqlabel}
+%==> modif JMS <==%
+% Les modifications du contenu de \eqlabel ne seront pas prises en
+% compte dans les messages de javascript (pb pour faire passer les
+% accents dans le code !). Ceci justifie pour moi l'introduction de
+% la variable \bqlabelISO ou le label de debut de questionnaire est
+% cod\'{e} ISO (octal). Cela parce que je veux utiliser le mot D\'ebut.
+% Use \protect\351, this helps out TeX4ht by Eitan Gurari
+\renewcommand\eq@bqlabelISO{D\string\351but}
+\renewcommand\bqlabelISO{\eq@bqlabelISO}
+
+% Here is the default quiz label.
+\renewcommand\eq@eqlabel{Fin}
+% User access to shortquiz label
+\renewcommand\eqlabel{\eq@eqlabel}
+%
+% JavaScript Messages for Quiz Environments
+\renewcommand\eq@Score{Score :}\renewcommand\eq@OutOf{sur}
+\renewcommand\eqInitQuizMsg{%
+ "Vous devez initialiser le questionnaire ! Clicker sur "+msg+"."}
+\renewcommand\eqMadeChoice{
+ "Vous avez d\string\\351j\string\\340 fait un choix,"
+ + " ce choix est ("+Responses[probno]+")."
+ + " Souhaitez vous le modifier ?"}
+%
+% Valeur "Yes" d'Acrobat
+%
+% Default button labels for \eqButton
+%\renewcommand\eq@local@CA{R\string\351ponses}
+\renewcommand\eq@local@CA{%
+ R\texorpdfstring{\'}{\string\351}ponses}
+\renewcommand\eq@local@RC{Correctes}
+\renewcommand\eq@local@AC{SVP !}
+%</eqfr>
+% \end{macrocode}
+% \subsection{German}
+% \begin{macrocode}
+%<*eqde>
+% \end{macrocode}
+% \begin{macrocode}
+%%%%%%%%%%%%%%%%%%%% eqde.def %%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Foreign language support for the exerquiz package. %%
+%% Name of translator: Michael Wiedmann %%
+%% e-mail address: michael.wiedmann@detewe.de %%
+%% Language: German %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% The exercise label
+\renewcommand\exlabel{\"Ubung}
+% The value of this macro is written to \jobname.sol,
+% accented characters must be protected with a \protect
+\renewcommand\exlabelsol{\protect\"Ubung}
+
+% Title of exercise solution section
+\renewcommand\exsectitle{L\"osungen der \exlabel en}
+\renewcommand\exsecrunhead{L\protect\"osungen der \exlabelsol en}
+
+% Solution label for solutionafter option
+\renewcommand{\eq@exsolafterDefault}{\textit{L\"osung}:}
+
+% Title of quiz solution section
+\renewcommand\eq@sqslsectitle{L\"osungen der Aufgaben}
+\renewcommand\sqslsectitle{\eq@sqslsectitle}
+
+% Running header/section title for solutions to quizzes
+%\renewcommand\eq@sqslsecrunhead{L\"osungen der \"Ubungen}
+\renewcommand\eq@sqslsecrunhead{L\"osungen der Aufgaben}
+% User access
+\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}
+
+% Label for solutions to quizzes, appears in solutions sections
+\renewcommand\eq@sqsllabel{%
+ \protect\textbf{L\protect\"osung zu Aufgabe:}}
+% User access
+\renewcommand\sqsllabel{\eq@sqsllabel}
+
+% Solution label for solutionafter option for shortquiz
+\renewcommand\sqsolafter{\textit{L\"osung}:}
+
+% Here is the default short quiz label.
+\renewcommand\eq@sqlabel{\textcolor{red}{Aufgabe}}
+% User access to shortquiz label
+\renewcommand\sqlabel{\eq@sqlabel}
+
+% Here is the default short quiz return label
+%\renewcommand\eq@sqslrtnlabel{Ende Aufgabe}
+%\renewcommand\eq@sqslrtnlabel{Test beenden}
+\renewcommand\eq@sqslrtnlabel{zur\"{u}ck zur Aufgabe}
+% User access to shortquiz label
+\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}
+
+% Short quiz feedback messages
+\renewcommand\eqsqrtmsg{"Richtig!"}
+\renewcommand\eqsqwgmsg{"Falsch!"}
+
+% Here is the default quiz label.
+%\renewcommand\eq@bqlabel{Beginn Aufgabe}
+\renewcommand\eq@bqlabel{Test starten}
+% User access to quiz label
+\renewcommand\bqlabel{\eq@bqlabel}
+% Used for writing JavaScript Messages on screen. Use PDFDocEncoding
+\renewcommand\eq@bqlabelISO{\eq@bqlabel}
+\renewcommand\bqlabelISO{\eq@bqlabelISO}
+
+% Here is the default quiz label.
+%\renewcommand\eq@eqlabel{Ende Aufgabe}
+\renewcommand\eq@eqlabel{Test beenden}
+% User access to quiz label
+\renewcommand\eqlabel{\eq@eqlabel}
+%
+% JavaScript Messages for Quiz Environments. Use PDFDocEncoding
+%
+\renewcommand\eq@Score{Punkte:}\renewcommand\eq@OutOf{von}
+\renewcommand\eq@ptScore{Punkte:}
+\renewcommand\eqInitQuizMsg{%
+ "Sie m\374ssen die Aufgaben zuerst initialisieren!"
+ + " Bitte klicken Sie hierf\374r auf "+msg+" am Anfang des Tests."}
+\renewcommand\eqMadeChoice{%
+ "Sie haben bereits geantwortet. Ihre Antwort war
+ ("+Responses[probno]+")." + " Wollen Sie dies \string\344ndern?"}
+\renewcommand\eq@local@CA{Korrigiere}
+\renewcommand\eq@local@RC{Meine Antworten!}
+\renewcommand\eq@local@AC{Bitte!}
+\renewcommand{\AnsPromptBtnStr}{Antwort:\space}
+\renewcommand\eqerrABS{"Betr\string\344ge sind nicht ausgeglichen.
+ Bitte korrigieren Sie das."}
+\renewcommand\eqerrBadMathFunc{"Der Ausdruck '"+aF[i]+"' ist weder
+ eine definierte Funktion noch ein g\string\374ltiger mathematischer
+ Ausdruck."}
+\renewcommand\eqParens{"runde Klammern"} % ( )
+\renewcommand\eqBrackets{"eckige Klammern"} % [ ]
+\renewcommand\eqBraces{"geschweifte Klammern"} % { }
+\renewcommand\eqerrDelimNotBal{aGroup[i][2] + " sind nicht ausgeglichen.
+ Bitte korrigieren Sie das."}
+\renewcommand\eqerrBadExp{"Ung\string\374ltiger mathematischer Ausdruck.
+ Es gibt ein Problem mit einem der Exponenten.
+ Bitte korrigieren Sie das!"}
+\renewcommand\eqerrUnfinishQuiz{"Sie haben einen Test nicht beendet.
+ Bitte beenden Sie diesen, bevor Sie einen neuen Test beginnen."}
+\dlJSStr*[noquotes]{\noPeekMsg}{"Bevor Sie den Test nicht beendet
+ haben, ist es nicht erlaubt, die L\"{o}sungen anzuschauen!"}
+\renewcommand\highThresholdMsg{"Sie m\string\374ssen alle Fragen
+ beantworten, bevor der Test ausgewertet wird."}
+\dlJSStr*[noquotes]{\eqSyntaxErrorUndefVar}{"Syntax Error: Es existiert
+ m\"{o}glicherweise eine undefinierte Variable oder ein Ausdruck
+ ist nicht im erwarteten Format geschrieben."}
+\dlJSStr[noquotes]{\eqSyntaxErrorComma}{"Syntax Error: Ein Komma wurde"
+ + " in Ihrer Antwort \""
+ + UserAns + "\" gefunden. Bitte entfernen Sie das Komma,"
+ + " sonst wird diese Antwort als falsch gewertet."}
+\dlJSStr*[noquotes]{\limSelWarningMsg}{"F\"{u}r diese Aufgabe k\"{o}nnen
+ sie h\"{o}chstens " + n + " ausw\string\344hlen."}
+\fieldJSStr*[noquotes]{\promptButtonMsg}{%
+ "M\"{o}chten Sie die richtige Antwort jetzt sehen?"
+ + " Ihre derzeitige Antwort ist diejenige, die gewertet wird."
+ + " Wenn Sie auf \\"Yes\\" klicken, k\"{o}nnen Sie ihre Antwort
+ nicht mehr \string\344ndern."
+}
+\renewcommand{\defaultReqFormMsg}{%
+ "Der Ausdruck ist nicht in der erwarteten Form."}
+%</eqde>
+% \end{macrocode}
+% \subsection{Norwegian}
+% \begin{macrocode}
+%<*eqno>
+%%%%%%%%%%%%%%%%%%%% eqno.def %%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Foreign language support for the exerquiz package. %%
+%% Name of translator: Hans Fredrik Nordhaug %%
+%% e-mail address: hansfn@mi.uib.no %%
+%% Language: Norwegian %%
+%% %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\renewcommand\exlabel{{\O}velse}
+\renewcommand\exlabelsol{{\protect\O}velse}
+
+\renewcommand\exsectitle{L{\o}sning p{\aa} {\o}velsene}
+\renewcommand\exsecrunhead{L{\protect\o}sning p{\protect\aa}
+ {\protect\o}velsene}
+
+\renewcommand{\eq@exsolafterDefault}{\textit{L{\o}sning}:}
+
+\renewcommand\eq@sqslsectitle{L{\o}sning p{\aa} oppgavene}
+\renewcommand\sqslsectitle{\eq@sqslsectitle}
+
+\renewcommand\eq@sqslsecrunhead{L{\o}sning p{\aa} oppgavene}
+\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}
+
+\renewcommand\eq@sqsllabel{%
+ \protect\textbf{L{\protect\o}sning p{\protect\aa} oppgave:}}
+\renewcommand\sqsllabel{\eq@sqsllabel}
+
+\renewcommand\sqsolafter{\textit{L{\o}sning}:}
+
+\renewcommand\eq@sqlabel{\textcolor{red}{Oppgave}}
+\renewcommand\sqlabel{\eq@sqlabel}
+
+\renewcommand\eq@sqslrtnlabel{Slutt}
+\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}
+
+\renewcommand\eqsqrtmsg{"Rett!"}
+\renewcommand\eqsqwgmsg{"Feil!"}
+
+\renewcommand\eq@bqlabel{Start oppgaver}
+\renewcommand\bqlabel{\eq@bqlabel}
+\renewcommand\eq@bqlabelISO{\eq@bqlabel}
+\renewcommand\bqlabelISO{\eq@bqlabel}
+
+\renewcommand\eq@eqlabel{Slutt}
+\renewcommand\eqlabel{\eq@eqlabel}
+
+\renewcommand\eqScore{Poeng:}\renewcommand\eqOutOf{av}
+\renewcommand\eqInitQuizMsg{"Du m\string\\345 initialisere testen!"
++" Klikk p\string\\345 "+msg+"."}
+\renewcommand\eqMadeChoice{%
+ "Du har allerede gjort et valg.
+ Valget var ("+Responses[probno]+").
+ Vil du endre det?"}
+\renewcommand\eq@local@CA{Rett}
+\renewcommand\eq@local@RC{mine svar!}
+%\renewcommand\eq@local@AC{V\string\346r s\string\345 snill!}}
+\renewcommand\eq@local@AC{%
+ V\texorpdfstring{\ae}{\string\346}r
+ s\texorpdfstring{\r}{\string\345}snill!}
+%</eqno>
+% \end{macrocode}
+% \subsection{Dutch}
+% \begin{macrocode}
+%<*eqnl>
+%%%%%%%%%%%%%%%%%%% eqnl.def %%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Foreign language support for the exerquiz package. %%
+%% Name of translator: Henny Wilbrink %%
+%% e-mail address: wsdwhw@win.tue.nl %%
+%% Language: Dutch %%
+%% %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% The exercise label
+\renewcommand\exlabel{Opgave}
+\renewcommand\exlabelsol{\exlabel}
+
+% Title of exercise solution section
+\renewcommand\exsectitle{Oplossingen van de Opgaven}
+\renewcommand\exsecrunhead{\exsectitle}
+
+% Solution label for solutionafter option for exercise
+\renewcommand{\eq@exsolafterDefault}{\textit{Oplossing}:}
+
+% Title of short quiz solution section
+\renewcommand\eq@sqslsectitle{Oplossingen van de Toetsen}
+\renewcommand\sqslsectitle{\eq@sqslsectitle}
+
+% Running header/section title for solutions to short quizzes
+\renewcommand\eq@sqslsecrunhead{Oplossingen van de Toetsen}
+% User access
+\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}
+
+% Solution label for solutionafter option
+\renewcommand{\eq@exsolafterDefault}{\textit{Oplossing}:}
+
+% Label for solutions to short quizzes, appears in solutions sections
+\renewcommand\eq@sqsllabel{\string\textbf{Oplossing van Toets:}}
+% User access
+\renewcommand\sqsllabel{\eq@sqsllabel}
+
+% Solution label for solutionafter option for shortquiz
+\renewcommand\sqsolafter{\textit{Oplossing}:}
+
+% Here is the default short quiz label.
+\renewcommand\eq@sqlabel{\textcolor{red}{Toets.}}
+% User access to shortquiz label
+\renewcommand\sqlabel{\eq@sqlabel}
+
+% Here is the default short quiz return label
+\renewcommand\eq@sqslrtnlabel{Terug naar Toets}
+% User access to shortquiz label
+\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}
+
+% Short quiz feedback messages
+\renewcommand\eqsqrtmsg{"Goed!"}
+\renewcommand\eqsqwgmsg{"Fout!"}
+
+% Here is the default quiz label.
+\renewcommand\eq@bqlabel{Begin Toets}
+% User access to shortquiz label
+\renewcommand\bqlabel{\eq@bqlabel}
+% Used for writing JavaScript Messages on screen. Use PDFDocEncoding
+\renewcommand\eq@bqlabelISO{\eq@bqlabel}
+\renewcommand\bqlabelISO{\eq@bqlabel}
+
+% Here is the default quiz label.
+% No formatting allowed
+\renewcommand\eq@eqlabel{Einde Toets}
+% User access to shortquiz label
+\renewcommand\eqlabel{\eq@eqlabel}
+
+%
+% JavaScript Messages for Quiz Environments. Use PDFDocEncoding
+%
+\renewcommand\eq@Score{Score:}\renewcommand\eq@OutOf{van de}
+
+\renewcommand\eqInitQuizMsg{%
+ "U moet de Toets initialiseren! Klik op "+msg+"."}
+\renewcommand\eqMadeChoice{%
+ "U hebt al een keuze gemaakt.
+ Uw keuze was ("+Responses[probno]+").
+ Wil u dit veranderen?"}
+%
+% Default button labels for \eqButton
+\renewcommand\eq@local@CA{Corrigeer}
+\renewcommand\eq@local@RC{Mijn Antwoorden!}
+\renewcommand\eq@local@AC{AUB!}
+%</eqnl>
+% \end{macrocode}
+% \subsection{Spanish}
+% \begin{macrocode}
+%<*eqes>
+%%%%%%%%%%%%%%%%%%% eqes.def %%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Foreign language support for the exerquiz package. %%
+%% Name of translator: Pedro Luis Luque %%
+%% e-mail address: calvo@cica.es %%
+%% Language: (spanish) %%
+%% %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% The exercise label
+\renewcommand\exlabel{Ejercicio}
+% The value of this macro is written to \jobname.sol,
+\renewcommand\exlabelsol{\exlabel}
+
+% Title of exercise solution section
+\renewcommand\exsectitle{Soluciones a los \exlabel s}
+\renewcommand\exsecrunhead{\exsectitle} %% change to @ form
+
+% Solution label for solutionafter option for exercise
+\renewcommand{\eq@exsolafterDefault}{\textit{Soluci\'{o}n}:}
+
+% Title of short quiz solution section
+\renewcommand\eq@sqslsectitle{Soluciones a los Tests}
+\renewcommand\sqslsectitle{\eq@sqslsectitle}
+
+% Running header/section title for solutions to short quizzes
+\renewcommand\eq@sqslsecrunhead{Soluciones a los Tests}
+% User access
+\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}
+
+% Label for solutions to short quizzes, appears in solutions sections
+\renewcommand\eq@sqsllabel{%
+ \string\textbf{Soluci\protect\'{o}n al Test:}}
+% User access
+\renewcommand\sqsllabel{\eq@sqsllabel}
+
+% Solution label for solutionafter option for shortquiz
+\renewcommand\sqsolafter{\textit{Soluci\'{o}n}:}
+
+% Here is the default short quiz label.
+\renewcommand\eq@sqlabel{\textcolor{red}{Test.}}
+% User access to shortquiz label
+\renewcommand\sqlabel{\eq@sqlabel}
+
+% Here is the default short quiz return label
+\renewcommand\eq@sqslrtnlabel{Final del Test}
+% User access to shortquiz label
+\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}
+
+% Short quiz feedback messages
+\renewcommand\eqsqrtmsg{"Correcto!"}
+\renewcommand\eqsqwgmsg{"Incorrecto!"}
+
+% Here is the default quiz label.
+\renewcommand\eq@bqlabel{Inicio del Test}
+% User access to shortquiz label
+\renewcommand\bqlabel{\eq@bqlabel}
+% Used for writing JavaScript Messages on screen. Use PDFDocEncoding
+\renewcommand\eq@bqlabelISO{\eq@bqlabel}
+\renewcommand\bqlabelISO{\eq@bqlabel}
+
+% Here is the default quiz label.
+% No formatting allowed
+\renewcommand\eq@eqlabel{Final del Test}
+% User access to shortquiz label
+\renewcommand\eqlabel{\eq@eqlabel}
+%
+% JavaScript Messages for Quiz Environments. Use PDFDocEncoding
+%
+\renewcommand\eq@Score{Puntos:}\renewcommand\eq@OutOf{de}
+\renewcommand\eqInitQuizMsg{"Debes inicializar el Test!
+ Click sobre "+msg+"."}
+\renewcommand\eqMadeChoice{%
+ "Ya has elegido una respuesta.
+ Tu respuesta fue ("+Responses[probno]+").
+ Quieres cambiarla?"}
+%
+% Default button labels for \eqButton
+\renewcommand\eq@local@CA{Correctas}
+\renewcommand\eq@local@RC{Mis Respuestas!}
+\renewcommand\eq@local@AC{Por Favor!}
+%</eqes>
+% \end{macrocode}
+% \subsection{Italian}
+% \begin{macrocode}
+%<*eqit>
+%%%%%%%%%%%%%%%%%%% eqit.def %%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Foreign language support for the exerquiz package. %%
+%% Name of translator: PierLuigi Zezza %%
+%% e-mail address: pzezza@cce.unifi.it %%
+%% Language: Italian %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% The exercise label
+\renewcommand\exlabel{Esercizio}
+%
+% The value of this macro is written to \jobname.sol,
+\renewcommand\exlabelsol{\exlabel}
+%
+% Title of exercise solution section
+\renewcommand\exsectitle{Soluzioni degli Esercizi }
+\renewcommand\exsecrunhead{\exsectitle}
+%
+% Solution label for solutionafter option for exercise
+\renewcommand{\eq@exsolafterDefault}{\textit{Soluzione}:}
+%
+% Title of short quiz solution section
+\renewcommand\eq@sqslsectitle{Soluzioni dei Quiz}
+\renewcommand\sqslsectitle{\eq@sqslsectitle}
+%
+% Running header/section title for solutions to short quizzes
+\renewcommand\eq@sqslsecrunhead{Soluzioni dei Quiz}
+%
+% User access
+\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}
+%
+% Label for solutions to short quizzes, appears in solutions sections
+\renewcommand\eq@sqsllabel{\string\textbf{Soluzione del Quiz:}}
+%
+% User access
+\renewcommand\sqsllabel{\eq@sqsllabel}
+%
+% Solution label for solutionafter option for shortquiz
+\renewcommand\sqsolafter{\textit{Soluzione}:}
+%
+% Here is the default short quiz label.
+\renewcommand\eq@sqlabel{\textcolor{red}{Quiz.}}
+%
+% User access to shortquiz label
+\renewcommand\sqlabel{\eq@sqlabel}
+%
+% Here is the default short quiz return label
+\renewcommand\eq@sqslrtnlabel{Fine Quiz}
+%
+% User access to shortquiz label
+\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}
+%
+% Short quiz feedback messages
+\renewcommand\eqsqrtmsg{"Giusto!"}
+\renewcommand\eqsqwgmsg{"Sbagliato!"}
+%
+% Here is the default quiz label.
+% No formatting allowed
+\renewcommand\eq@bqlabel{Inizio Test}
+%
+% User access to shortquiz label
+\renewcommand\bqlabel{\eq@bqlabel}
+\renewcommand\eq@bqlabelISO{\eq@bqlabel}
+\renewcommand\bqlabelISO{\eq@bqlabel}
+%
+% Here is the default quiz label.
+% No formatting allowed
+\renewcommand\eq@eqlabel{Fine Test}
+%
+% User access to shortquiz label
+\renewcommand\eqlabel{\eq@eqlabel}
+%
+% JavaScript Messages for Quiz Environments. Use PDFDocEncoding
+%
+\renewcommand\eq@Score{Punteggio:}\renewcommand\eq@OutOf{su}
+\renewcommand\eqInitQuizMsg{"Dovete inizializzare il Quiz!
+ Click su "+msg+"."}
+\renewcommand\eqMadeChoice{%
+ "Avete gi\string\\340 fatto una scelta.
+ La vostra scelta era ("+Responses[probno]+").
+ Volete cambiarla ?"}
+%
+% Default button labels for \eqButton
+\renewcommand\eq@local@CA{Correggere}
+\renewcommand\eq@local@RC{Le mie risposte!}
+\renewcommand\eq@local@AC{Per favore!}
+%</eqit>
+% \end{macrocode}
+% \subsection{Russian}
+% \begin{macrocode}
+%<*eqru>
+%%%%%%%%%%%%%%%%%%% eqru.def %%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Foreign language support for the exerquiz package. %%
+%% Name of translator: Sergei V. Znamenskii %%
+%% e-mail address: znamensk@rustex.botik.ru %%
+%% Language: Russian %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%\PassOptionsToPackage{unicode}{hyperref}
+\expandafter\ifx\csname inputencoding\endcsname\relax
+ \RequirePackage{inputenc}\fi
+\inputencoding{cp1251}\makeatletter
+\expandafter\ifx\csname Russian\endcsname\relax
+ \RequirePackage[russian]{babel}\fi
+% Language dependent definitions for Web.sty
+ \def\web@versionlabel{\^{A}{\aa}ð\~{n}\`{e}\"{y}}%
+ \def\web@toc{\~{N}\^{\i}\"{a}{\aa}ð{\ae}\`{a}\'{\i}\`{e}{\aa}}%
+ \def\web@continued{\"{\i}ð\^{\i}\"{a}\^{\i}\"{e}{\ae}.}%
+ \def\web@article{\'{I}\`{a}{\div}\`{a}\"{e}\^{\i}
+ \hyperlink{section.1}{}}%
+ \def\web@directory{\"{I}\`{a}\"{\i}\^{e}\`{a}}%
+ \def\web@revision{\"{A}\`{a}\`{o}\`{a} \"{\i}\^{\i}\~{n}\"{e}%
+ {\aa}\"{a}\'{\i}{\aa}\~{a}\^{\i} \`{e}\c{c}\`{\i}{\aa}%
+ \'{\i}{\aa}\'{\i}\`{e}\"{y}:}%
+ \def\web@copyright{\^{E}\^{\i}\"{\i}\`{e}ð\`{a}\'{e}\`{o}}%
+ \def\web@section{\textsection\ }%
+ % Label Navibar
+ \def\web@back{\'{I}\`{a}\c{c}\`{a}\"{a}}%
+ \def\web@doc{\"{A}\^{\i}\^{e}.}% restricted to three characters
+
+% The exercise label
+% Accents: \renewcommand\exlabel{\"Ubung} (German)
+\renewcommand\exlabel{\'{O}\"{\i}ð\`{a}{\ae}\'{\i}{\aa}\'{\i}\`{e}{\aa}}
+% The value of this macro is written to \jobname.sol,
+% accented characters must be protected with a \protect
+% E.g., \renewcommand\exlabelsol{\protect\"Ubung} (German)
+\renewcommand\exlabelsol{\^{E} \'{o}\"{\i}ð\`{a}{\ae}%
+ \'{\i}{\aa}\'{\i}\`{e}þ}
+
+% Title of exercise solution section
+% E.g.: \renewcommand\exsectitle
+% {L\"osungen der \exlabel en} (German)
+\renewcommand\exsectitle{Ð{\aa}{\o}{\aa}\'{\i}\`{e}\"{y}
+ \'{o}\"{\i}ð\`{a}{\ae}\'{\i}{\aa}\'{\i}\`{e}\'{e}}
+\renewcommand\exsecrunhead{\exsectitle} %% change to @ form
+
+% Solution label for solutionafter option for exercise
+\renewcommand\exsolafter{\textit{Ð{\aa}{\o}{\aa}\'{\i}\`{e}{\aa}}:}
+
+% Title of short quiz solution section
+% Example: \renewcommand\eq@sqslsectitle
+% {L\"osungen der Aufgaben} (German)
+\renewcommand\eq@sqslsectitle{\^{I}\`{o}\^{a}{\aa}\`{o}\^{u}
+ \^{e} \`{o}{\aa}\~{n}\`{o}\`{a}\`{\i}}
+\renewcommand\sqslsectitle{\eq@sqslsectitle}
+
+% Running header/section title for solutions to short quizzes
+\renewcommand\eq@sqslsecrunhead{\^{I}\`{o}\^{a}{\aa}\`{o}\^{u}
+ \^{e} \^{e}\^{\i}ð\^{\i}\`{o}\^{e}\`{e}\`{\i}
+ \`{o}{\aa}\~{n}\`{o}\`{a}\`{\i}}
+% User access
+\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}
+
+% Label for solutions to short quizzes, appears
+% in solutions sections
+% Protect accents with \protect
+% E.g.: \renewcommand\eq@sqsllabel
+% {\string\textbf{L\protect\"osung zu Aufgabe:}} (German)
+\renewcommand\eq@sqsllabel{%
+ \string\textbf{\^{I}\`{o}\^{a}{\aa}\`{o}\^{u}:}}
+% User access
+\renewcommand\sqsllabel{\eq@sqsllabel}
+
+% Solution label for solutionafter option for shortquiz
+\renewcommand\sqsolafter{\textit{Ð{\aa}{\o}{\aa}\'{\i}\`{e}{\aa}}:}
+
+% Here is the default short quiz label.
+\renewcommand\eq@sqlabel{%
+ \textcolor{red}{\c{C}\`{a}\"{a}\`{a}\'{\i}\`{e}{\aa}.}}
+% User access to shortquiz label
+\renewcommand\sqlabel{\eq@sqlabel}
+
+% Here is the default short quiz return label
+% No formatting allowed
+\renewcommand\eq@sqslrtnlabel{\^{a}{\aa}ð\'{\i}\'{o}\`{o}\"{u}\~{n}\"{y}}
+% User access to shortquiz label
+\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}
+
+\cyrCommand\eqsqslrtnlabel{\^{E} \^{o}\^{\i}ð\`{\i}\'{o}\"{e}%
+ \`{e}ð\^{\i}\^{a}\^{e}{\aa} \c{c}\`{a}\"{a}\`{a}\'{\i}\`{e}\"{y}}
+\renewcommand\eq@sqslrtnlabel{\eqsqslrtnlabel}
+
+
+% Here is the default quiz label.
+% No formatting allowed
+% For Example: \renewcommand\eq@bqlabel{D\'ebut} (French)
+\renewcommand\eq@bqlabel{CTAPT}
+% User access to shortquiz label
+\renewcommand\bqlabel{\eq@bqlabel}
+% Used for writing JavaScript Messages on screen.
+% Use PDFDocEncoding
+% For Example:
+% \renewcommand\eq@bqlabelISO{D\string\351but} (French)
+% Use \string not \protect, this helps out
+% TeX4ht by Eitan Gurari.
+\renewcommand\eq@bqlabelISO{\eq@bqlabel}
+\renewcommand\bqlabelISO{\eq@bqlabel}
+
+% Here is the default quiz label.
+% No formatting allowed
+\renewcommand\eq@eqlabel{\^{O}\`{E}\'{I}\`{E}{\O}}
+% User access to shortquiz label
+\renewcommand\eqlabel{\eq@eqlabel}
+\def\ScoreFieldDefaults
+{%
+ \Ff{\FfReadOnly}\BC{1 0 0}\BG{}\S{S}
+ \DV{\^{A}{\aa}ð\'{\i}\^{\i}:}\W{1}
+}
+% Default button labels for \eqButton
+\renewcommand\eq@local@CA{\`{E}\~{n}\"{\i}ð\`{a}\^{a}\`{e}\`{o}\"{u}}
+\renewcommand\eq@local@RC{\`{\i}\^{\i}\`{e} \^{\i}\`{o}\^{a}{\aa}%
+ \`{o}\^{u}!}
+\renewcommand\eq@local@AC{\"{I}\^{\i}{\ae}\`{a}\"{e}\'{o}\'{e}\~{n}%
+ \`{o}\`{a}!}
+%
+% JavaScript Messages for Quiz Environments. Use PDFDocEncoding
+% In the Text Field showing the score, there is the default phrase in
+% English Score: 2 out of 3, the word "Score" and "out of" needs
+% translation.
+%% In Cyrillic, at least with pdflatex v.1.40.3 , the same \eq@Score
+%% unfortunately can not serve both \ScoreFieldDefaults and
+%% \eqQuizTotalMsg.
+
+\renewcommand\eq@Score{\u0412\u0435\u0440\u043D\u043E:}
+\renewcommand\eq@OutOf{\u0438\u0437}
+
+% Short quiz feedback messages
+%\def\eq@sqrtmsg{"\u0412\u0435\u0440\u043D\u043E!"}
+%\def\eq@sqwgmsg{"\u041E\u0448\u0438\u0431\u043A\u0430!"}
+\def\eqsqrtmsg{"\u0412\u0435\u0440\u043D\u043E!"}
+\def\eqsqwgmsg{"\u041E\u0448\u0438\u0431\u043A\u0430!"}
+
+% If you are taking a quiz and click on an alternative without
+% initializing the quiz first, this message appears.
+% Example: \renewcommand\eqInitQuizMsg{"Sie m\string\\374ssen die
+% Aufgaben initialisieren! Bitte klicken Sie auf "+msg+"."}%(German)
+\def\eqInitQuizMsg{"\u041A\u043B\u0438\u043A\u043D\u0438\u0442\u0435
+ \u043D\u0430 \u00AB"+msg+"\u00BB, \u0447\u0442\u043E\u0431\u044B
+ \u043D\u0430\u0447\u0430\u0442\u044C
+ \u043E\u0442\u0432\u0435\u0442."}
+
+% This macro doesn't usually need translation, it uses
+% \eqScore and \eqOutOf. However, if the sentence "Score: 2 out of 3"
+% does not translate conveniently into a particular language,
+% this macro may have to be modified. It's the one that puts the
+% message in the message box.
+% \renewcommand\eqQuizTotalMsg {"\eqScore\space"+Score+"
+% \eqOutOf\space"+nQuestions}
+% \renewcommand\eqQuizPointsMsg{"\eqptScore\space"+ptScore+"
+% \eqOutOf\space"+nPointTotal}
+% \renewcommand\eqQuizPercentMsg{pcScore+"\%"}
+% \renewcommand\eqQuizGradeMsg{quizGrade}
+% In the link form of a quiz, of you change your choice, this message
+% appears.
+% For Example: \renewcommand\eqMadeChoice{"Vous avez
+% d\string\\351j\string\\340 fait un choix, ce choix est
+% ("+Responses[probno]+"). Souhaitez vous le modifier ?"}%(French)
+\renewcommand\eqMadeChoice{"\u0412\u044B \u0443\u0436\u0435
+ \u0432\u044B\u0431\u0440\u0430\u043B\u0438
+ \u043E\u0442\u0432\u0435\u0442
+ ("+Responses[probno]+"). \u0418\u043B\u0438 \u0412\u044B
+ \u043F\u0435\u0440\u0435\u0434\u0443\u043C\u0430\u043B\u0438?"}
+% Default button label of \CorrAnsButton.
+\renewcommand\eq@local@CorrAnsButton{Ans}
+% These (error) messages are generated when the user enters an invalid
+% math expression into a math fill-in response box. The messages come in
+% the form of an eqAppAlert() so PDFDocEncoding needs to be used.
+\renewcommand\eqerrABS{"\u0417\u043D\u0430\u043A\u0438
+ \u0430\u0431\u0441\u043E\u043B\u044E\u0442\u043D\u043E\u0439
+ \u0432\u0435\u043B\u0438\u0447\u0438\u043D\u044B \u043D\u0435
+ \u0441\u0431\u0430\u043B\u0430\u043D\u0441\u0438\u0440\u043E\u0432%
+ \u0430\u043D\u044B.
+ \u0418\u0441\u043F\u0440\u0430\u0432\u044C\u0442\u0435,
+ \u043F\u043E\u0436\u0430\u043B\u0443\u0439\u0441\u0442\u0430."}
+\renewcommand\eqerrBadMathFunc{"\u0412\u044B\u0440\u0430\u0436\u0435%
+ \u043D\u0438\u0435 `"+aF[i]+"' \u043D\u0435 \u044F\u0432\u043B%
+ \u044F\u0435\u0442\u0441\u044F \u043D\u0438
+ \u0432\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u043E\u0439 "
+ +"\u0444\u0443\u043D\u043A\u0446\u0438\u0435\u0439,
+ \u043D\u0438 \u043A\u043E\u0440\u0440\u0435\u043A\u0442\u043D%
+ \u044B\u043C\u043C\u0430\u0442\u0435\u043C\u0430\u0442\u0438\u0447%
+ \u0435\u0441\u043A\u0438\u043C \u0432\u044B\u0440\u0430\u0436\u0435%
+ \u043D\u0438\u0435\u043C."}
+\renewcommand\eqParens{"\u041A\u0440\u0443\u0433\u043B\u044B\u0435
+ \u0441\u043A\u043E\u0431\u043A\u0438"}
+\renewcommand\eqBrackets{"\u041A\u0432\u0430\u0434\u0440\u0430\u0442%
+ \u043D\u044B\u0435 \u0441\u043A\u043E\u0431\u043A\u0438"}
+\renewcommand\eqBraces{"\u0424\u0438\u0433\u0443\u0440\u043D\u044B\u0435
+ \u0441\u043A\u043E\u0431\u043A\u0438"}
+\renewcommand\eqerrDelimNotBal{aGroup[i][2] + " \u043D\u0435
+ \u0441\u0431\u0430\u043B\u0430\u043D\u0441\u0438\u0440%
+ \u043E\u0432\u0430\u043D\u043E.
+ \u041F\u043E\u0436\u0430\u043B\u0443\u0439\u0441\u0442\u0430,
+ \u0438\u0441\u043F\u0440\u0430\u0432\u044C\u0442\u0435."}
+\renewcommand\eqerrBadExp{"\u0418\u0441\u043F\u0440\u0430\u0432%
+ \u044C\u0442\u0435, \u043F\u043E\u0436\u0430\u043B\u0443\u0439%
+ \u0441\u0442\u0430, \u0432\u044B\u0440\u0430\u0436\u0435\u043D%
+ \u0438\u0435 \u0441\u043E \u0441\u0442\u0435\u043F\u0435\u043D%
+ \u044C\u044E."}
+\renewcommand\eqerrUnfinishQuiz{"\u041F\u043E\u0436\u0430\u043B\u0443%
+ \u0439\u0441\u0442\u0430, \u0437\u0430\u043A\u043E\u043D\u0447%
+ \u0438\u0442\u0435 \u043D\u0430\u0447\u0430\u0442\u043E\u0435
+ \u0440\u0430\u043D\u0435\u0435 \u0437\u0430\u0434\u0430\u043D%
+ \u0438\u0435."}
+\renewcommand\noPeekMsg{"\u0420\u0435\u0448\u0435\u043D\u0438\u044F
+ \u043D\u0435 \u043F\u043E\u043A\u0430\u0436\u0443\u0442\u0441\u044F,
+ \u043F\u043E\u043A\u0430 \u0437\u0430\u0434\u0430\u043D\u0438\u0435
+ \u043D\u0435 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043A
+ \u043E\u043D\u0447\u0435\u043D\u043E!"}
+\renewcommand\highThresholdMsg{"\u0412\u044B \u043D\u0435
+ \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u0435
+ \u043E\u0446\u0435\u043D\u043A\u0438, \u043F\u043E\u043A\u0430
+ \u043D\u0435 \u043E\u0442\u0432\u0435\u0442\u0438\u0442\u0435
+ \u043D\u0430 \u0412\u0421\u0415 \u0432\u043E\u043F\u0440\u043E%
+ \u0441\u044B."}
+\renewcommand\eqSyntaxErrorUndefVar{"\u0421\u0438\u043D\u0442\u0430%
+ \u043A\u0441\u0438\u0447\u0435\u0441\u043A\u0430\u044F
+ \u043E\u0448\u0438\u0431\u043A\u0430:
+ \u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E,
+ \u043F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u0430\u044F
+ \u043D\u0435 \u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435%
+ \u043D\u0430."}
+%</eqru>
+% \end{macrocode}
+% \subsection{Danish}
+% \begin{macrocode}
+%<*eqda>
+%%%%%%%%%%%%%%%%%%%% eqda.def %%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Foreign language support for the exerquiz package. %%
+%% Name of translator: Erik Leimand %%
+%% e-mail address: buhlleimand@worldonline.dk %%
+%% Language: Danish %%
+%% %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\renewcommand\exlabel{{\O}velse}
+\renewcommand\exlabelsol{{\protect\O}velse}
+
+\renewcommand\exsectitle{L{\o}sning p{\aa} {\o}velserne}
+\renewcommand\exsecrunhead{L{\protect\o}sning p{\protect\aa}
+ {\protect\o}velserne}
+
+\renewcommand{\eq@exsolafterDefault}{\textit{L{\o}sning}:}
+
+\renewcommand\eq@sqslsectitle{L{\o}sning p{\aa} opgaverne}
+\renewcommand\sqslsectitle{\eq@sqslsectitle}
+
+\renewcommand\eq@sqslsecrunhead{L{\o}sning p{\aa} opgaverne}
+\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}
+
+\renewcommand\eq@sqsllabel{%
+ \string\textbf{L{\protect\o}sning p{\protect\aa} opgave:}}
+\renewcommand\sqsllabel{\eq@sqsllabel}
+
+\renewcommand\sqsolafter{\textit{L{\o}sning}:}
+
+\renewcommand\eq@sqlabel{\textcolor{red}{Opgave.}}
+\renewcommand\sqlabel{\eq@sqlabel}
+
+\renewcommand\eq@sqslrtnlabel{Slut}
+\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}
+
+\renewcommand\eqsqrtmsg{"Rigtigt!"}
+\renewcommand\eqsqwgmsg{"Forkert!"}
+
+\renewcommand\eq@bqlabel{Start opgaver}
+\renewcommand\bqlabel{\eq@bqlabel}
+\renewcommand\eq@bqlabelISO{\eq@bqlabel}
+\renewcommand\bqlabelISO{\eq@bqlabel}
+
+\renewcommand\eq@eqlabel{Slut}
+\renewcommand\eqlabel{\eq@eqlabel}
+
+\renewcommand\eq@Score{Score:}\renewcommand\eq@OutOf{ud af}
+\renewcommand\eqQuizTotalMsg{"\eqScore\space"+Score+"
+ \eqOutOf\space"+nQuestions}
+\renewcommand\eqInitQuizMsg{"Du skal starte testen! Klik
+ p\string\\345 "+msg+"."}
+\renewcommand\eqMadeChoice{%
+ "Du har allerede valgt.
+ Du valgte ("+Responses[probno]+").
+ Vil du \string\\346ndre det?"}
+\renewcommand\eq@local@CA{Ret}
+\renewcommand\eq@local@RC{Mine svar!}
+%\renewcommand\eq@local@AC{V\string\346r s\string\345 god!}}
+\renewcommand\eq@local@AC{%
+ V\texorpdfstring{\ae}{\string\346}r
+ s\texorpdfstring{\r}{\string\345}god!}
+%</eqda>
+% \end{macrocode}
+% \subsection{Polish}
+% \begin{macrocode}
+%<*eqpo>
+%%%%%%%%%%%%%%%%%%%% eqpo.def %%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Foreign language support for the exerquiz package. %%
+%% Name of translator: Jerzy Mycielski %%
+%% e-mail address: jmyc@poczta.onet.pl %%
+%% Language: Polish %%
+%% %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% The polish accented characters included in pdfendconding is
+%% lslash and oacute, not included are zacute, zdot, cacute,
+%% nacute, sacute, aogonek, eogonek and corresponding capital
+%% characters.
+% Z \'{Z} \u0179
+% a \k{a} \u0105
+% c \'{c} \u0107
+% l \l \u0142
+% s \'{s} \u015B
+% z \.{z} \u017C
+% \'{o} \'{o} \u00F3
+\renewcommand\exlabel{Zadanie}
+\renewcommand\exlabelsol{\exlabel}
+
+\renewcommand\exsectitle{Rozwi\k{a}zania Zada\'{n}}
+\renewcommand\exsecrunhead{\protect\exsectitle}
+
+\renewcommand{\eq@exsolafterDefault}{\textit{Rozwi\k{a}znie}:}
+
+\renewcommand\eq@sqslsectitle{Rozwi\k{a}zania Test\'{o}w}
+\renewcommand\sqslsectitle{\eq@sqslsectitle}
+
+\renewcommand\eq@sqslsecrunhead{Rozwi\protect\k{a}zania
+ Test\protect\'{o}w}
+\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}
+
+\renewcommand\eq@sqsllabel{\string\textbf{Rozwi\protect\k{a}zanie
+ Testu:}}
+\renewcommand\sqsllabel{\eq@sqsllabel}
+
+\renewcommand\sqsolafter{\textit{Rozwi\k{a}zanie}:}
+
+\renewcommand\eq@sqlabel{\textcolor{red}{Test.}}
+\renewcommand\sqlabel{\eq@sqlabel}
+
+%\renewcommand\eq@sqslrtnlabel{Zako\protect\'{n}cz Test}
+\renewcommand\eq@sqslrtnlabel{Zako\ifeq@solutionsafter\else
+ \expandafter\protect\fi\'{n}cz Test}
+\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}
+
+\renewcommand\eqsqrtmsg{"Dobrze!"}
+\renewcommand\eqsqwgmsg{"\string\\u0179le!"}
+%\renewcommand\eqsqwgmsg{"\'{Z}le!"}
+
+\renewcommand\eq@bqlabel{Rozpocznij Test}
+\renewcommand\bqlabel{\eq@bqlabel}
+\renewcommand\eq@bqlabelISO{\eq@bqlabel}
+\renewcommand\bqlabelISO{\eq@bqlabel}
+
+\renewcommand\eq@eqlabel{Zakoncz Test}
+% \renewcommand\eq@eqlabel{Zako\'{n}cz Test}
+\renewcommand\eqlabel{\eq@eqlabel}
+
+\renewcommand\eq@Score{Punkt\'{o}w:}
+\renewcommand\eq@OutOf{z mozliwych}
+\renewcommand\eqQuizTotalMsg{"\eqScore\space"+Score +
+ " \eqOutOf\space"+nQuestions}
+
+\renewcommand\eqInitQuizMsg{"Musisz rozpoczac Test! Kliknij
+ na "+msg+"."}
+
+\renewcommand\eqMadeChoice{%
+ "Juz dokonal\string\\233e\string\\u015B wyboru.
+ Twoim wyborem by\string\\233o ("+Responses[probno]+").
+ Czy chcesz go zmieni\string\\u0107?"}
+%\renewcommand\eqMadeChoice{%
+%"Ju\.{z} dokona\string\233e\'{s} wyboru. Twoim wyborem"
+%+" by\string\233o ("+Responses[probno]+")."+" Czy chcesz go
+%zmieni\'{c}?"}
+
+\renewcommand\eq@local@CA{Popraw}
+\renewcommand\eq@local@RC{Moje odpowiedzi!}
+\renewcommand\eq@local@AC{Prosze!}
+%\renewcommand\eq@local@AC{Prosz\k{e}!}
+%</eqpo>
+% \end{macrocode}
+% \subsection{Finnish}
+% \begin{macrocode}
+%<*eqfin>
+%%%%%%%%%%%%%%%%%%%% eqfin.def %%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Foreign language support for the exerquiz package. %%
+%% Name of translator: Paivi Porras %%
+%% e-mail address: paivi.porras@lut.fi %%
+%% Language: Finnish %%
+%% %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\renewcommand\exlabel{Harjoitus}
+\renewcommand\exlabelsol{Harjoitus}
+
+\renewcommand\exsectitle{Ratkaisut}
+\renewcommand\exsecrunhead{Ratkaisu \exlabelsol }
+
+\renewcommand{\eq@exsolafterDefault}{\textit{Ratkaisu}:}
+
+\renewcommand\eq@sqslsectitle{Vastaukset testikysymyksiin}
+\renewcommand\sqslsectitle{\eq@sqslsectitle}
+
+\renewcommand\eq@sqslsecrunhead{Vastaukset testikysymyksiin}
+\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}
+
+\renewcommand\eq@sqsllabel{%
+ \string\textbf{Vastaus testikysymykseen:}}
+\renewcommand\sqsllabel{\eq@sqsllabel}
+
+\renewcommand\sqsolafter{\textit{Ratkaisu}:}
+
+\renewcommand\eq@sqlabel{\textcolor{red}{Testikysymys}}
+\renewcommand\sqlabel{\eq@sqlabel}
+
+\renewcommand\eq@sqslrtnlabel{Lopeta testi}
+\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}
+
+\renewcommand\eqsqrtmsg{"Oikein!"} %muokattu
+\renewcommand\eqsqwgmsg{"V\string\344\string\344rin!"} %m
+%\renewcommand\eqsqwgmsg{"V\"a\"arin!"} %m
+
+\renewcommand\eq@bqlabel{Aloita testi}
+\renewcommand\bqlabel{\eq@bqlabel}
+\renewcommand\eq@bqlabelISO{\eq@bqlabel}
+\renewcommand\bqlabelISO{\eq@bqlabelISO}
+
+\renewcommand\eq@eqlabel{Lopeta testi}
+\renewcommand\eqlabel{\eq@eqlabel}
+
+\renewcommand\eq@Score{Pisteet:}\renewcommand\eq@OutOf{/}
+\renewcommand\eqInitQuizMsg{%m
+ "Testi on aloitettava painamalla "+msg+"."}
+\renewcommand\eqMadeChoice{%m
+ "Olet jo kerran valinnut.
+ Valintasi oli ("+Responses[probno]+")."
++" Haluatko vaihtaa?"}
+\AtEndOfPackage{%
+\renewcommand\eq@local@CA{Oikein}
+\renewcommand\eq@local@RC{Omat vastaukset!}
+\renewcommand\eq@local@AC{Ole hyv\string\344!}}
+%</eqfin>
+% \end{macrocode}
+% \subsection{catalan}
+% \begin{macrocode}
+%<*eqcat>
+%%%%%%%%%%%%%%%%%%% eqcat.def %%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Foreign language support for the exerquiz package. %%
+%% Name of translator: Ramon Ballester %%
+%% e-mail address: ramon.ballester@udg.es %%
+%% Language: (catalan) %%
+%% %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% The exercise label
+\renewcommand\exlabel{Exercici}
+% The value of this macro is written to \jobname.sol,
+\renewcommand\exlabelsol{\exlabel}
+
+% Title of exercise solution section
+\renewcommand\exsectitle{Solucions als \exlabel s}
+\renewcommand\exsecrunhead{\exsectitle} %% change to @ form
+
+% Solution label for solutionafter option for exercise
+\renewcommand{\eq@exsolafterDefault}{\textit{Soluci\'o}:}
+
+% Title of short quiz solution section
+\renewcommand\eq@sqslsectitle{Solucions als Tests}
+\renewcommand\sqslsectitle{\eq@sqslsectitle}
+
+% Running header/section title for solutions to short quizzes
+\renewcommand\eq@sqslsecrunhead{Solucions als Tests}
+% User access
+\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}
+
+% Label for solutions to short quizzes, appears in solutions sections
+\renewcommand\eq@sqsllabel{%
+ \string\textbf{Soluci\protect\'{o} al Test:}}
+% User access
+\renewcommand\sqsllabel{\eq@sqsllabel}
+
+% Solution label for solutionafter option for shortquiz
+\renewcommand\sqsolafter{\textit{Soluci\'o}:}
+
+% Here is the default short quiz label.
+\renewcommand\eq@sqlabel{\textcolor{red}{Test.}}
+% User access to shortquiz label
+\renewcommand\sqlabel{\eq@sqlabel}
+
+% Here is the default short quiz return label
+\renewcommand\eq@sqslrtnlabel{Final del Test}
+% User access to shortquiz label
+\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}
+
+% Short quiz feedback messages
+\renewcommand\eqsqrtmsg{"Correcte!"}
+\renewcommand\eqsqwgmsg{"Incorrecte!"}
+
+% Here is the default quiz label.
+\renewcommand\eq@bqlabel{Inici del Test}
+% User access to shortquiz label
+\renewcommand\bqlabel{\eq@bqlabel}
+% Used for writing JavaScript Messages on screen. Use PDFDocEncoding
+\renewcommand\eq@bqlabelISO{\eq@bqlabel}
+\renewcommand\bqlabelISO{\eq@bqlabel}
+
+% Here is the default quiz label.
+% No formatting allowed
+\renewcommand\eq@eqlabel{Final del Test}
+% User access to shortquiz label
+\renewcommand\eqlabel{\eq@eqlabel}
+%
+% JavaScript Messages for Quiz Environments. Use PDFDocEncoding
+%
+\renewcommand\eq@Score{Punts:}\renewcommand\eq@OutOf{de}
+\renewcommand\eqInitQuizMsg{"Has d'iniciar el Test!
+ Prem sobre "+msg+"."}
+\renewcommand\eqMadeChoice{%
+ "Ja has elegit una resposta.
+ La teva resposta ha estat ("+Responses[probno]+").
+ Vols canviar--la?"}
+%
+% Default button labels for \eqButton
+\renewcommand\eq@local@CA{Correctes}
+\renewcommand\eq@local@RC{Les meves Respostes!}
+\renewcommand\eq@local@AC{Si us plau!}
+%</eqcat>
+% \end{macrocode}
+%
+% \subsection{Czech}
+% \begin{macrocode}
+%<*eqcz>
+%%%%%%%%%%%%%%%%%%% eqcat.def %%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Foreign language support for the exerquiz package. %%
+%% Name of translator: Robert Marik %%
+%% e-mail address: marik@mendelu.cz %%
+%% Language: (czech) %%
+%% %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\def\SFW{1.75in}
+
+% The exercise label
+\renewcommand\exlabel{Cvi\v{c}en\'{\i}}
+% The value of this macro is written to \jobname.sol,
+\renewcommand\exlabelsol{Cvi\protect\v{c}en\protect\'{\protect\i}}
+
+% Title of exercise solution section
+\renewcommand\exsectitle{\texorpdfstring{\v{R}e\v{s}en\'{\i}
+ ke cvi\v{c}en\'{\i}m}
+ {Resen\355{} ke cvicen\355m}} %% change to @ form
+\renewcommand\exsecrunhead{%
+ \string\v{R}e\string\v{s}en\string\'{\string\i}
+ ke cvi\string\v{c}en\string\'{\string\i}m}
+
+% Solution label for solutionafter option for exercise
+\renewcommand{\eq@exsolafterDefault}{\textit{\v{R}e\v{s}en\'\i}:}
+
+% Title of short quiz solution section
+\renewcommand\eq@sqslsectitle{\texorpdfstring{\v{R}e\v{s}en\'{\i}
+ kv\'{\i}z\r{u}}{Resen\355{} kv\355zu}}
+\renewcommand\sqslsectitle{\eq@sqslsectitle}
+
+% Running header/section title for solutions to short quizzes
+\renewcommand\eq@sqslsecrunhead{\v{R}e\v{s}en\'{\i} kv\'{\i}z\r{u}}
+% User access
+\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}
+
+% Label for solutions to short quizzes, appears in solutions sections
+\renewcommand\eq@sqsllabel{\string\textbf{%
+ \string\v{R}e\string\v{s}en\string\'{\string\i}
+ kv\string\'{\string\i}zu:}}
+% User access
+\renewcommand\sqsllabel{\eq@sqsllabel}
+
+% Solution label for solutionafter option for shortquiz
+\renewcommand\sqsolafter{\textit{\v{R}e\v{s}en\'{\i}}:}
+
+% Here is the default short quiz label.
+\renewcommand\eq@sqlabel{\textcolor{red}{Kv\'{\i}z.}}
+% User access to shortquiz label
+\renewcommand\sqlabel{\eq@sqlabel}
+
+% Here is the default short quiz return label
+%\renewcommand\eq@sqslrtnlabel{Konec kv\string\'{\string\i}zu}
+\renewcommand\eq@sqslrtnlabel{Zp\string\v{e}t na ot\string\'{a}zky}
+% User access to shortquiz label
+\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}
+
+% Short quiz feedback messages
+\renewcommand\eqsqrtmsg{"Spravne !"}
+\renewcommand\eqsqwgmsg{"Spatne !"}
+
+% Here is the default quiz label.
+\renewcommand\eq@bqlabel{Zacatek kvizu}
+% User access to shortquiz label
+\renewcommand\bqlabel{\eq@bqlabel}
+% Used for writing JavaScript Messages on screen. Use PDFDocEncoding
+\renewcommand\eq@bqlabelISO{Zacatek kvizu}
+\renewcommand\bqlabelISO{Zacatek kvizu}
+
+% Here is the default quiz label.
+% No formatting allowed
+\renewcommand\eq@eqlabel{Konec kvizu}
+% User access to shortquiz label
+\renewcommand\eqlabel{\eq@eqlabel}
+%
+% JavaScript Messages for Quiz Environments. Use PDFDocEncoding
+%
+%\renewcommand\eq@Score{Hodnoceni:}
+\renewcommand\eq@Score{}
+\renewcommand\eq@OutOf{z celkovych}
+\renewcommand\eqInitQuizMsg{%
+ "Chcete-li pracovat s kvizem, musite jej nejprve spustit!
+ Kliknete na "+msg+"."}
+\renewcommand\eqMadeChoice{%
+ "Uz jste si jednou odpoved vybral(a). Vase odpoved byla (" +
+ Responses[probno]+"). Chcete ji opravdu zmenit?"}
+%
+% Default button labels for \eqButton
+\renewcommand\eq@local@CA{Opravit}
+\renewcommand\eq@local@RC{odpovedi!}
+\renewcommand\eq@local@AC{Prosim!}
+% Messages for math fill-in questions
+\renewcommand\eqerrABS{"Spatne uzavrena absolutni hodnota.
+ Opravte prosim."}
+\renewcommand\eqerrBadMathFunc{"Vyraz `"+aF[i]+"' neni ani
+ definovanou funkci ani " +", ani platnym matematickym vyrazem."}
+\renewcommand\eqParens{"Zavorky (kulate)"}
+\renewcommand\eqBrackets{"Hranate zavorky"}
+\renewcommand\eqBraces{"Slozene zavorky"}
+\renewcommand\eqerrDelimNotBal{aGroup[i][2] + " nejsou parove.
+ Opravte je prosim."}
+\renewcommand\eqerrBadExp{"Spatny matematicky vyraz - problem v nekterem
+ exponentu. Opravte jej prosim."}
+\renewcommand\eqerrUnfinishQuiz{"Chyba: Nektery kviz mate nedokonceny.
+ Musite jej dokoncit, nez budete pokracovat u dalsiho kvizu. Pokud si
+ nepamatuje, ktery kviz jste nechali rozpracovany, zavrete cely
+ soubor, znovu jej otevrete a k testu, ktery chcete vyplnovat,
+ se vratte."}
+\renewcommand\noPeekMsg{"Prohlizeni reseni neni povoleno pred dokoncenim
+ kvizu!"}
+\renewcommand\highThresholdMsg{"Musite odpovedet na vsechny otazky, nez
+ ukoncite kviz."}
+\renewcommand\eqSyntaxErrorUndefVar{"Chyba: Pravdepodobne pouzivate
+ nespravnou promennou nebo mate preklep ve jmenu nektere funkce."}
+\renewcommand{\promptButtonMsg}{%
+ "Chcete ted videt spravnou odpoved? "\r\t\t
+ + "Hodnocena bude Vase soucasna odpoved. "\r\t\t
+ + "Kliknete-li na \\"Yes\\", uvidite spravnou odpoved, ale svou
+ stavajici odpoved na tuto otazku uz nebudete moct zmenit."
+}
+%</eqcz>
+% \end{macrocode}
+% \subsection{brazil}
+% \begin{macrocode}
+%<*eqbr>
+%%%%%%%%%%%%%%%%%%% eqbr.def %%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Foreign language support for the exerquiz package. %%
+%% Name of translator: Koichi Sameshima %%
+%% e-mail address: ksameshi@usp.br %%
+%% Language: (brazil) %%
+%% %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% The exercise label
+\renewcommand\exlabel{Exerc\texorpdfstring{\'{\i}}{\string\355}cio}
+% The value of this macro is written to \jobname.sol,
+\renewcommand\exlabelsol{Exerc\string\'{\string\i}cio}
+
+% Title of exercise solution section
+\renewcommand\exsectitle{Solu\texorpdfstring{\c{c}}{\string\347}%
+ \texorpdfstring{\~{o}}{%
+ \string\365}es dos Exerc\texorpdfstring{\'{\i}}{\string\355}cios}
+ %{Solu\string\\347\string\\363es dos Exerc\string\\355cios}}
+\renewcommand\exsecrunhead{%
+ Solu\protect\c{c}\protect\~{o}es dos Exerc\protect\'{i}cios}
+
+% Solution label for solutionafter option for exercise
+\renewcommand{\eq@exsolafterDefault}{\textit{Solu\c{c}\~{a}o}:}
+
+% Title of short quiz solution section
+\renewcommand\eq@sqslsectitle{Solu\c{c}\~{o}es
+ dos Testes}
+\renewcommand\sqslsectitle{\eq@sqslsectitle}
+
+% Running header/section title for solutions to short quizzes
+\renewcommand\eq@sqslsecrunhead{Solu\protect\c{c}\protect\~{o}es
+ dos Testes}
+% User access
+\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}
+
+% Label for solutions to short quizzes, appears in solutions sections
+\renewcommand\eq@sqsllabel{%
+ \string\textbf{Solu\protect\c{c}\protect\~{a}o do Teste:}}
+% User access
+\renewcommand\sqsllabel{\eq@sqsllabel}
+
+% Solution label for solutionafter option for shortquiz
+\renewcommand\sqsolafter{\textit{Solu\protect\c{c}\protect\~{a}o}:}
+
+% Here is the default short quiz label.
+\renewcommand\eq@sqlabel{\textcolor{red}{Teste.}}
+% User access to shortquiz label
+\renewcommand\sqlabel{\eq@sqlabel}
+
+% Here is the default short quiz return label
+\renewcommand\eq@sqslrtnlabel{Finaliza Teste}
+% User access to shortquiz label
+\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}
+
+% Short quiz feedback messages
+\renewcommand\eqsqrtmsg{"Correto!"}
+\renewcommand\eqsqwgmsg{"Incorreto!"}
+
+% Here is the default quiz label.
+\renewcommand\eq@bqlabel{Inicia Teste}
+% User access to shortquiz label
+\renewcommand\bqlabel{\eq@bqlabel}
+% Used for writing JavaScript Messages on screen. Use PDFDocEncoding
+\renewcommand\eq@bqlabelISO{\eq@bqlabel}
+\renewcommand\bqlabelISO{\eq@bqlabel}
+
+% Here is the default quiz label.
+% No formatting allowed
+\renewcommand\eq@eqlabel{Finaliza Teste}
+% User access to shortquiz label
+\renewcommand\eqlabel{\eq@eqlabel}
+%
+% JavaScript Messages for Quiz Environments. Use PDFDocEncoding
+%
+\renewcommand\eq@Score{Pontos:}\renewcommand\eq@OutOf{de}
+\renewcommand\eqInitQuizMsg{% ******
+ "Voc\string\352 precisa iniciar o Teste! Clique sobre "+msg+"."}
+\renewcommand\eqMadeChoice{%
+ "Voc\string\352 j\string\341 respondeu.
+ Sua resposta foi ("+Responses[probno]+").
+ Quer alter\string\341-la?"}
+%
+% Default button labels for \eqButton
+\renewcommand\eq@local@CA{Corretas}
+\renewcommand\eq@local@RC{Minhas Respostas!}
+\renewcommand\eq@local@AC{Por Favor!}
+%</eqbr>
+% \end{macrocode}
+% \subsection{turkish}
+% \begin{macrocode}
+%<*eqtr>
+%%%%%%%%%%%%%%%%%%%% eqtr.def %%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Foreign language support for the exerquiz package. %%
+%% Name of translator: Mahmut Ko\c{c}ak %%
+%% e-mail address: mkocak@ogu.edu.tr %%
+%% Language: Turkish %%
+%% %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\renewcommand\exlabel{Al\i \c st\i rma}
+\renewcommand\exlabelsol{\noexpand\c C\noexpand\"oz\noexpand\"um}
+\renewcommand\exsectitle{\exlabel lar{\i}n \c C\"oz\"umleri }
+\renewcommand\exsecrunhead{Al\noexpand\i \noexpand\c st\noexpand\i rma
+ \exlabelsol leri }
+\renewcommand\exsolafter{\textbf{\c C\"oz\"um}:}
+\renewcommand\eq@sqslsectitle{Kuizlerin \c C\"oz\"umleri }
+\renewcommand\sqslsectitle{\eq@sqslsectitle}
+\renewcommand\eq@sqslsecrunhead{Kuizlerin \c C\"oz\"umleri}
+\renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}
+\renewcommand\eq@sqsllabel{%
+ \protect\textbf{Kuiz \noexpand\c C\noexpand\"oz\noexpand\"um%
+ \noexpand\"u:}}
+\renewcommand\sqsllabel{\eq@sqsllabel}
+\renewcommand\sqsolafter{\textit{\c C\"oz\"um}:}
+\renewcommand\eq@sqlabel{\textcolor{red}{Soru}}
+\renewcommand\sqlabel{\eq@sqlabel}
+\renewcommand\eq@sqslrtnlabel{Kuizi Bitir}
+\renewcommand\sqslrtnlabel{\eq@sqslrtnlabel}
+% JavaScript alert box text
+\renewcommand\eqsqrtmsg{"Do\protect\u011Fru!"}
+\renewcommand\eqsqwgmsg{"Yanl\protect\u0131\protect\u015F!"}
+%
+\renewcommand\eq@bqlabel{Kuize Ba\c sla}
+\renewcommand\bqlabel{\eq@bqlabel}
+\renewcommand\eq@bqlabelISO{\eq@bqlabel}
+\renewcommand\bqlabelISO{\eq@bqlabelISO}
+\renewcommand\eq@eqlabel{Kuizi Bitir}
+\renewcommand\eqlabel{\eq@eqlabel}
+%
+% JavaScript messages
+%
+\renewcommand\eq@Score{Skor:}
+\renewcommand\eq@OutOf{\protect\374zerinden}
+\renewcommand\eqQuizTotalMsg{%
+ "\eqScore\space"+nQuestions+" \eqOutOf\space"+Score}
+ \renewcommand\eqQuizPointsMsg{%
+ "\eqptScore\space"+nPointTotal+" \eqOutOf\space"+ptScore}
+\renewcommand\eq@local@CorrAnsButton{Cevap}
+\renewcommand\eqInitQuizMsg{%
+ "Kuizi Bitirdiniz. Do\protect\u011Fru cevaplar\protect\u0131
+ g\protect\u00F6rmek i\protect\u00E7in 'cevap'
+ tu\protect\u015Flar\protect\u0131na
+ bas\protect\u0131n\protect\u0131z."}
+\renewcommand\eqMadeChoice{%
+ "Bir se\protect\u00E7im yapt\protect\u0131n\protect\u0131z.
+ Se\protect\u00E7iminiz ("+Responses[probno]+") idi."
+ +" Se\protect\u00E7iminizi de\protect\u011Fi\protect\u015Ftirmek
+ istermisiniz?"}
+\renewcommand\eqerrABS{"Mutlak de\protect\u011Fer do\protect\u011Fru
+ degil. L\protect\u00FCtfen d\protect\u00FCzeltiniz."}
+\renewcommand\eqerrBadMathFunc{" `"+aF[i]+"' ifadesi
+ tan\protect\u0131ml\protect\u0131 bir fonksiyon veya
+ ge\protect\u00E7erli bir matematiksel ifade de\protect\u011Fil."}
+\renewcommand\eqParens{"Parentezler"}
+\renewcommand\eqBrackets{"S\protect\u00FCsl\protect\u00FC Parentazle"}
+\renewcommand\eqBraces{"K\protect\u00F6\protect\u015Feli Parentezler"}
+\renewcommand\eqerrDelimNotBal{aGroup[i][2] + " do\protect\u011Fru
+ de\protect\u011Fil. L\protect\u00FCtfen d\protect\u00FCzeltiniz."}
+\renewcommand\eqerrBadExp{"Ge\protect\u00E7ersiz matematiksel ifade.
+ \protect\u00FCstel ifadeli bir hata.
+ L\protect\u00FCtfen d\protect\u00FCzeltiniz."}
+\renewcommand\eqerrUnfinishQuiz{"Bitirilmemi\protect\u015F bir kuiz var,
+ di\protect\u011Fer kuize ge\protect\u00E7meden \protect\u00F6nce
+ bu kuizi tamamlay\protect\u0131n."}
+\renewcommand\noPeekMsg{"Kuizi bitirmeden yada kuizden
+ ba\protect\u015Far\protect\u0131l\protect\u0131 olana kadar
+ \protect\u00E7\protect\u00F6z\protect\u00FCmleri
+ g\protect\u00F6remezsiniz.!"}
+\renewcommand\highThresholdMsg{"Kuiz sonucu hesaplanmadan
+ \protect\u00F6nce b\protect\u00FCt\protect\u00FCn
+ sorular\protect\u0131 cevapland\protect\u0131rmal\protect
+ \u0131s\protect\u0131n\protect\u0131z."}
+\renewcommand\eqSyntaxErrorUndefVar{"Syntax Error: Tan\protect
+ \u0131mlanmam\protect\u0131\protect\u015F de\protect\u011Fi\protect
+ \u015Fken veya ifadeler istenilen formatta yaz\protect
+ \u0131lmam\protect\u0131\protect\u015Ft\protect\u0131r."}
+\renewcommand\eq@local@CA{Dogru}
+\renewcommand\eq@local@RC{Benim Cevaplar\protect\u0131m!}
+\renewcommand\eq@local@AC{L\protect\374tfen!}
+%</eqtr>
+% \end{macrocode}
+% \Finale
+\endinput