% \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-2021 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> [2021/10/03 v8.8.5 % %<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} \usepackage{fancyvrb} \gdef\darg#1{\texttt{\char123\relax#1\char125\relax}} \let\env\texttt \let\opt\texttt \let\app\textsf \let\uif\textsf \def\nmpsep#1{\hskip-\marginparsep\texttt{#1}} \def\visispace{\symbol{32}} \def\ameta#1{\ensuremath{\langle\textit{\texttt{#1}}\rangle}} \def\meta#1{\textit{\texttt{#1}}} \def\SUB#1{\ensuremath{{}_{\mbox{\scriptsize\ttfamily#1}}}} \def\GT{\string>} \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}} \makeatletter \let\@latex@warning\@gobble \makeatother \begin{document} \let\env\texttt\let\pkg\textsf \let\app\textsf \let\tops\texorpdfstring \let\key\texttt \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} % \end{macrocode} %\changes{v8.8.5}{2021/10/03}{This version attempts to fix a problem induced to acrotex by displaying %the export values of choice field. The export values secretly contain a zero (0) or one (1) to signal %that the current choice is wrong or right.} %\changes{v8.6.3}{2021/01/31}{Updated documentation, informing users of \string\app{Acrobat DC} that % it is necessary to change their \string\uif{Security (Enhanced)} preferences.} %\changes{v8.2.8}{2018/12/13}{The SOL file is now written entirely when there is no solution option specified} % (2017/08/08) This version introduces multi-letter variables and what I'll term `alternate appearances'. % \changes{v8.0}{2017/08/08}{Introduce multi-letter variables and alternate appearances. Changes % made are marked by `\texttt{dps17}' throughout the DTX.} % \changes{v7.7k}{2016/04/18}{Minor bug fixes, improved driver recognition} % \changes{v7.7j}{2016/04/05}{Change in \string\pkg{eforms} to 2016/04/05 v2.8f} % % \section{Introduction} % % The \pkg{exerquiz} package provides support for the creation of exercises and quizzes % with or without solutions. These are PDF form and link based. The packages provides ``intelligent'' evaluation % of the students' responses. This package also provides code for the \pkg{eqexam} package so that these % two packages are consistent in their approach. % % \section{Package options and setup}\label{options} % % Introduce a number of useful options for \pkg{exerquiz}. % \subsection{Options for paper, solutions, JavaScript and preview} % \begin{macrocode} %<*package> \usepackage{keyval} % \end{macrocode} % Some early required packages. %\changes{v6.4t}{2012/06/18}{Added \string\pkg{ifpdf} as a required package} %\changes{v8.1a}{2017/09/03}{Added check for luatex} % \begin{macrocode} \RequirePackage{ifpdf}[2006/02/20] \RequirePackage{ifxetex}[2006/08/21] \RequirePackage{ifluatex} \@ifundefined{exqtable}{\def\exqtable{table}}{} \IfFileExists{xcolor.sty}{% \def\eq@ColorPackage{xcolor}% \PassOptionsToPackage{\exqtable,hyperref}{xcolor}} {\def\eq@ColorPackage{color}} % \end{macrocode} % \leavevmode\IndexOpt{noxcolor}^^A % An option to force % the use of the \textsf{color} package. % \begin{macrocode} \DeclareOption{noxcolor}{\def\eq@ColorPackage{color}} % \end{macrocode} % \leavevmode\IndexOpt{forpaper}^^A % Pass the \opt{monochrome} option to the color package %\changes{v6.06a}{2007/04/09} %{ % Added the \string\texttt{forcolorpaper} option for those using % \string\textsf{exerquiz} without \string\textsf{web}. %} % \begin{macrocode} \DeclareOption{forpaper}{% \eqforpapertrue\PassOptionsToPackage{monochrome}{\eq@ColorPackage} \AtBeginDocument{\AllowPeeking}} % \end{macrocode} % \leavevmode\IndexOpt{forcolorpaper}^^A % The \opt{forcolorpaper} is the same as \opt{forpaper}, but does not % pass the \pkg{monochrome} option to the color package. % \begin{macrocode} \DeclareOption{forcolorpaper}{\eqforpapertrue \AtBeginDocument{\AllowPeeking}} % \end{macrocode} % \leavevmode\IndexOpt{preview}^^A % 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} % \leavevmode\IndexOpt{nosolutions}^^A % 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} % \leavevmode\IndexOpt{noquizolutions}^^A % No solutions for quizzes (shortquiz and quiz environments). % \begin{macrocode} \DeclareOption{noquizsolutions}{\eq@noquizsolutionstrue\eq@nolinktrue} % \end{macrocode} % \leavevmode\IndexOpt{allowanswers}^^A % Only effective when \texttt{noquizsolutions} option is in force. Normally, the \uif{Correct} control % (\cs{CorrAnsButton}) does not appear; if \texttt{answersallowed} is also specified, % the \cs{CorrAnsButton} does appear. % \changes{v8.8.1}{2021/05/21}{Added the \string\texttt{allowanswers} key} % \begin{macrocode} \DeclareOption{allowanswers}{\eq@answersallowedtrue} \newif\ifeq@answersallowed \eq@answersallowedfalse %</package> %<*package|eqexam> % \end{macrocode} % An \IndexOpt{online}\texttt{online} options. % \begin{macrocode} \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} % \leavevmode\IndexOpt{nohiddensolutions}\IndexOpt{noHiddensolutions}^^A % 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} % \leavevmode\IndexOpt{solutionsafter}^^A % Solutions will appear after the statement of the exercise. % \begin{macrocode} \DeclareOption{solutionsafter}{\eq@solutionsaftertrue\eq@nolinktrue} % \end{macrocode} % \leavevmode\IndexOpt{solutionsonly}^^A % Here is a highly specialized option, put in at the request of a former friend. %\changes{v6.2f}{2007/12/21}{Added a \string\opt{solutionsonly} option} % \begin{macrocode} \DeclareOption{solutionsonly}{\solutionsonlytrue\answerkeytrue \therearesolutionstrue\AtEndOfPackage{\let\exerSolnsHeadnToc\relax}} % \end{macrocode} % \changes{v8.1k}{2018/02/04}{Added \string\cs{ifanswerkey} switch} % \begin{macrocode} \newif\ifsolutionsonly\solutionsonlyfalse \@ifundefined{ifanswerkey}{\newif\ifanswerkey\answerkeyfalse}{} % \end{macrocode} % \leavevmode\IndexOpt{contsolns}^^A % 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} % \leavevmode\IndexOpt{nocorrections}^^A % The code for correcting the |quiz| environment is % not written; this results in a smaller file. % \begin{macrocode} \DeclareOption{nocorrections}{\nocorrectionstrue} % \end{macrocode} % \leavevmode\IndexOpt{proofing}^^A % An option for marking the correct answers for shortquiz and quiz % \begin{macrocode} \DeclareOption{proofing}{\eq@proofingtrue} % \end{macrocode} % \leavevmode\IndexOpt{showgrayletters}^^A % 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} % \leavevmode\IndexOpt{vspacewithsolns}^^A % 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 only % define it here if \textsf{eqexam} is not loaded. % \changes{v6.3x}{2011/04/05}{Added \string\opt{vspacewithsolns}} % \begin{macrocode} \@ifundefined{ifvspacewithsolns}{% \DeclareOption{vspacewithsolns}{\vspacewithsolnstrue} \newif\ifvspacewithsolns\vspacewithsolnsfalse }{} % \end{macrocode} % \changes{v8.1m}{2018/02/09}{\string\cs{ifdisplayworkarea} conditionally defined} % \changes{v8.2.8}{2018/12/13}{defined \string\cs{displayworkareaOn} and % \string\cs{displayworkareaOff}} % \begin{macrocode} \@ifundefined{ifdisplayworkarea}{\newif\ifdisplayworkarea \displayworkareafalse}{} \providecommand\displayworkareaOn{\displayworkareatrue} \providecommand\displayworkareaOff{\displayworkareafalse} % \end{macrocode} % \leavevmode\IndexOpt{nodljs}^^A % 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 \pkg{insdljs} package. % \begin{macrocode} \DeclareOption{nodljs}{\PassOptionsToPackage{nodljs}{insdljs}% \AtEndOfPackage{\let\importdljs\eq@YES}} % \end{macrocode} % \leavevmode\IndexOpt{execJS}^^A % Execute any JS defined within the \env{execJS} environment. Works only for % authors using Acrobat 5.0 or Acrobat Approval. % \begin{macrocode} \DeclareOption{execJS}{\PassOptionsToPackage{execJS}{insdljs}} % \end{macrocode} % \leavevmode\IndexOpt{usealtadobe}^^A % Pass the \opt{usealtadobe} to \pkg{insdljs} as a convenience option. % \changes{v8.7.7}{2021/05/10}{Pass \string\opt{usealtadobe} option to \string\pkg{insdljs}} % \begin{macrocode} \DeclareOption{usealtadobe}{\PassOptionsToPackage{usealtadobe}{insdljs}} % \end{macrocode} % \leavevmode\IndexOpt{exercisesonly}^^A % 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} % \leavevmode\IndexOpt{debug}^^A % An option for debugging JavaScript. Pass on to insdljs package. % \begin{macrocode} \DeclareOption{debug}{\PassOptionsToPackage{debug}{insdljs}} % \end{macrocode} % \leavevmode\IndexOpt{allowrandomize}^^A % 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} % \leavevmode\IndexOpt{usesumrytbls}^^A % The declare the use of summary tables % \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} % The \IndexOpt{userbmintrvl}\opt{userbmintrvl} option defines \cs{rbmIntrvl} command, which % is a special \cs{RespBoxMath} command were some of the parameters are set by an % interval. Refer to Section~\ref{ss:rbmi} for details. % \changes{v8.7}{2021/04/24}{Added the option \string\opt{userbmintrvl}} % \begin{macrocode} \DeclareOption{userbmintrvl}{% \def\inputRBMICode{\InputIfFileExists{rbmintrvl.def} {\PackageInfo{exerquiz}{Inputting rbmintrvl.def}}% {cannot find rbmintrvl.def}}} \let\inputRBMICode\relax % \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} % Added a \texttt{luatex} option %\changes{v8.1a}{2017/09/03}{Added a \string\texttt{luatex} option} % \begin{macrocode} \DeclareOption{luatex}{% \def\eq@drivernum{1}\def\eq@driver{luatex} \PassOptionsToPackage{luatex}{\eq@ColorPackage} \PassOptionsToPackage{luatex}{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} % \leavevmode\IndexOpt{textures}^^A % 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} % \leavevmode\IndexOpt{dviwindo}^^A % Set \cmd{\eq@noformstrue}, this inserts an \cmd{\endinput} just after % the end of the \env{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 \pkg{exerquiz}, assume it is % dvipsone or dvips---\pkg{hyperref} defines the specials. % Default driver dvipsone/dvips % \begin{macrocode} \def\eq@drivernum{5} \def\eq@driver{dvipsone/dvips} \def\eq@driver@nodriver{no driver specified} % \end{macrocode} % \leavevmode\IndexOpt{unicode}^^A % Passes the unicode option to \textsf{hyperref}. % \changes{v6.3}{2008/03/19} % { % Added the \string\opt{unicode} option, which is passed to \string\pkg{hyperref}. % } % \begin{macrocode} \DeclareOption{unicode}{\PassOptionsToPackage{unicode}{hyperref}} % \end{macrocode} % \leavevmode\IndexOpt{useui}^^A % 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 \string\opt{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} % \leavevmode\IndexOpt{french}^^A % 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} % \leavevmode\IndexOpt{german}^^A % 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} % \leavevmode\IndexOpt{norsk}^^A % 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} % \leavevmode\IndexOpt{dutch}^^A % 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} % \leavevmode\IndexOpt{spanish}^^A % 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} % \leavevmode\IndexOpt{italian}^^A % 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} % \leavevmode\IndexOpt{russian}^^A % 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} % \leavevmode\IndexOpt{dansk}^^A % 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} % \leavevmode\IndexOpt{polish}^^A % 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} % \leavevmode\IndexOpt{finnish}^^A % 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} % \leavevmode\IndexOpt{catalan}^^A % 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} % \leavevmode\IndexOpt{czech}^^A % 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} % \leavevmode\IndexOpt{brazil}^^A % 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} % \leavevmode\IndexOpt{turkish}^^A % 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 \def\ifsolutionsafter{\csname ifeq@solutionsafter\endcsname} \let\solutionsaftertrue\eq@solutionsaftertrue \let\solutionsafterfalse\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 \newif\ifnocorrections \nocorrectionsfalse % \end{macrocode} % Added \cs{ifeqe@flextended} to support \pkg{eqexam} % \changes{v8.1h}{2018/01/03}{Added \string\cs{ifeqe@flextended} to support \string\pkg{eqexam}} % \changes{v8.1o}{2018/02/12}{Added \string\cs{ifcont@nnot} to support \string\pkg{eqexam}} % \begin{macrocode} \@ifundefined{ifeqe@flextended}{\newif\ifeqe@flextended \eqe@flextendedfalse}{} \@ifundefined{ifcont@nnot}{\newif\ifcont@nnot \cont@nnotfalse}{} \@ifundefined{if@eqalignfilllinestoleft} {\newif\if@eqalignfilllinestoleft\@eqalignfilllinestoleftfalse}{} % \end{macrocode} % \changes{v6.3z}{2011/04/28}{Created a switch \string\cs{ifkeepdeclaredvspacing}, % used primarily by \textsf{eqexam}} % (4/28/11) A switch to control whether the declared vertical space % for the \texttt{solution} environment is preserved during the \texttt{answerkey} % option. This is an \textsf{eqexam} feature. % \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}). % \changes{v8.2.8}{2018/12/13}{Set \string\cs{displayworkareafalse} in definition % of \string\cs{SolutionsAfter}; also, inserted \string\cs{eq@proofingfalse}} % \begin{macrocode} \def\SolutionsAfter{\solutionsAtEndfalse\eq@solutionsaftertrue \displayworkareafalse\eq@proofingfalse\eq@nolinktrue} % \end{macrocode} % The \DescribeMacro\ifcqSA\cs{ifcaSA} switch is used with the \env{cq*} environment % to create conditional content. It is true when the \env{solution} environment % is in a \textsf{solutions-after} state. % \begin{macrocode} \newif\ifcqSA\cqSAfalse % \end{macrocode} % Modified \cs{SolutionsAtEnd} (2018/02/02) to include \cs{eq@nosolutionsfalse} % and \cs{eq@proofingfalse}. % \changes{v8.1j}{2018/02/02}{Added \string\cs{eq@nosolutionsfalse} % and \string\cs{eq@proofingfalse} to the % definition of \string\cs{SolutionsAtEnd}} % \changes{v8.2.8}{2018/12/13}{Removed \string\cs{therearesolutionstrue} % from \string\cs{SolutionsAtEnd}} % \begin{macrocode} \def\SolutionsAtEnd{\solutionsAtEndtrue\vspacewithsolnstrue \eq@solutionsafterfalse\eq@nolinkfalse % \end{macrocode} % Now, if |\ifvspacewithsolns| is true, we set |\eq@nosolutionsfalse| so solutions appear % at the end of the file; otherwise, we set |\eq@nosolutionstrue|. % \changes{v8.1k}{2018/02/04}{Added a conditional within \string\cs{SolutionsAtEnd}} % \changes{v8.1m}{2018/02/09}{Include \string\cs{displayworkareatrue} in definition % of \string\cs{SolutionsAtEnd}} % \changes{v8.2.8}{2018/12/13}{Set \string\cs{displayworkareafalse} in definition % of \string\cs{SolutionsAtEnd}} % \begin{macrocode} \displayworkareafalse\ifvspacewithsolns\eq@nosolutionsfalse\else \eq@nosolutionstrue\fi\eq@proofingfalse\answerkeyfalse} \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 \newif\if@DoNotRandomize \@DoNotRandomizefalse % \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}{\doNotRandomizeChoices} % \begin{macro}{\allowRandomizedChoices} % These two commands allow for finer control over whether to randomize choices % or not. Expanding \cs{doNoRandomizeChoices} overrides the \opt{allowrandomize} % option; whereas \cs{allowRandomizedChoices} restores the original behavior % set by the \opt{allowrandomize} option. % \changes{v8.6.2}{2021/01/20}{Added \string\cs{doNoRandomizeChoices} and % \string\cs{allowRandomizedChoices}} % \begin{macrocode} \def\doNotRandomizeChoices{\@DoNotRandomizetrue} \def\allowRandomizedChoices{\@DoNotRandomizefalse} % \end{macrocode} % \end{macro} % \end{macro} % These\DescribeMacro{\saveRandomSeed}\DescribeMacro{\inputRandomSeed} two % commands are used when the \texttt{allowrandomize} option is in effect, Until % then, they do nothing. See the definition in \autoref{randomize}. % \begin{macrocode} \let\saveRandomSeed\relax \let\inputRandomSeed\relax %</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 \string\env{Form} environment % no longer creates a grouping. This was causing problems with % the \string\pkg{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} % \changes{v8.1a}{2017/09/03}{Testing for luatex} % \begin{macrocode} \let\bWebCustomize\endinput \let\eWebCustomize\relax \@ifpackageloaded{web}{% \ExecuteOptions{\eq@driver@name}% }{% \ifluatex\ExecuteOptions{luatex}\else \ifpdf\ExecuteOptions{pdftex}\else \ifxetex\ExecuteOptions{xetex}\else \InputIfFileExists{web.cfg}{} {\@ifundefined{l@tex@@@@driver}{\ExecuteOptions{dvips}} {\ExecuteOptions{dvipsone}}}\fi\fi\fi } % \end{macrocode} % \begin{macrocode} \ProcessOptions % \end{macrocode} % Input required packages. % \changes{v7.03}{2015/03/02}{Added the \string\pkg{array} package, mostly % for use in the tabular setup of parts in tabular mode.} % \begin{macrocode} \RequirePackage{array} \RequirePackage{\eq@ColorPackage} % \end{macrocode} % Changed order of loading, comment package first, then verbatim package; prior to the change, anomalous % errors, which were traced to these two packages. % \changes{v7.8k}{2017/07/25}{Changed order of loading, comment package first, then verbatim package} % \changes{v8.2.7}{2018/12/05}{require \string\pkg{aeb-comment} (version 3.1 of comment)} % \begin{macrocode} \RequirePackage{aeb-comment} \def\eq@commentChkMsg{\@ifpackageloaded{comment} {\PackageWarningNoLine{exerquiz} {The comment package is incompatible with the\MessageBreak aeb-comment package, do not use the comment package}}{}} \AtBeginDocument{\eq@commentChkMsg} \RequirePackage{verbatim} \RequirePackage{hyperref} \RequirePackage{amssymb}% used for return symbols % \end{macrocode} % (2021/05/10) Newer version of \pkg{eforms} required, as this package uses % \cs{dl@EForAF4}, which is defined by \pkg{insdljs} of the same date. % \changes{v8.7.7}{2021/05/10}{Now require \string\pkg{eforms} dated 2021/05/10} % \begin{macrocode} \RequirePackage{eforms}[2021/05/10] \dlSetPkgInfo % \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} % \begin{macrocode} \edef\eq@restoreCats{% \catcode`\noexpand\"=\the\catcode`\"\relax \catcode`\noexpand\'=\the\catcode`\'\relax \catcode`\noexpand\,=\the\catcode`\,\relax \catcode`\noexpand\(=\the\catcode`\(\relax \catcode`\noexpand\!=\the\catcode`\!\relax \catcode`\noexpand\_=\the\catcode`\_\relax } \@makeother\"\@makeother\'\@makeother\,% \@makeother\(\@makeother\!\@makeother\_ % \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\pkg{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 \string\pkg{eqexam}. They are % \string\cs{renameSolnAfterTo} for conveniently changing the solution % after label, and \string\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}} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \DescribeMacro{\adjDisplayBelow} is useful when expanded beneath distplays that % have no follow-up text below them. These seems to me, in certain situations, unnecessary % space is created. The \cs{adjDisplayBelow} attempts to remedy this. The % \DescribeMacro{\adjDisplayBelowPlus}\cs{adjDisplayBelowPlus} is the same as % \cs{adjDisplayBelow}, but adds \cs{recoverDisplayBelow}. The command \cs{adjDisplayBelow} % has a |vskip-\baselineskip|, if this is too much, use \cs{adjDisplayBelowPlus}. % \begin{macrocode} \newcommand{\adjDisplayBelow}{\vskip-\lastskip\vskip-\baselineskip} \newcommand{\adjDisplayBelowPlus}{\adjDisplayBelow\recoverDisplayBelow} \def\recoverDisplayBelow{\vskip\belowdisplayskip} %</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> %<*package> % \end{macrocode} % Announce driver option % \begin{macrocode} \PackageInfo{exerquiz}{* Using \eq@driver\space option *} %</package> %<*package|eqexam> % \end{macrocode} % \subsection{Handles, counters and such} % Handles to write solutions to quizzes and exercises to a file. % \begin{macrocode} \newcommand{\writeToExSolns@}[1]{% \ifsolutionsonly\else \ifOKToWriteExamData \set@display@protect \immediate\write\ex@solns{#1}\set@typeset@protect \fi\fi } \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}} \let\writeToExSolns\@gobble \else \newwrite\ex@solns \immediate\openout \ex@solns \jobname.sol \let\writeToExSolns\writeToExSolns@ % \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 \let\writeT@ExSolns\writeToExSolns \newwrite\quiz@solns \immediate\openout \quiz@solns \jobname.qsl \newcommand{\writeToQzSolns}[1]{\ifOKToWriteExamData\set@display@protect \immediate\write\quiz@solns{#1}\set@typeset@protect\fi} \let\writeT@QzSolns\writeToQzSolns \def\eq@IWAuxOut#1{\immediate\write\@auxout{#1}} \def\eq@IWDefs#1{\immediate\write\eq@xrefdefns{#1}} % \end{macrocode} % \changes{v8.2.8}{2018/12/13}{more controls for solution files} % Two sets of controls for the solution files. If \DescribeMacro\normalSolnWrites % \cs{normalSolnWrites} is expanded (the default), solutions are written to the solution files % as they normally do; if \DescribeMacro\noSolnWrites\cs{noSolnWrites} is in force, nothing is written % to the solution file, except for verbatim content from the \env{solution} % environments. When all else fails, when verbatim content is written to the solution files that % you don't want to appear, use \DescribeMacro\bHideSolnIn\cs{bHideSolnIn\darg{\ameta{wrt-cmd}}} % to write \cs{iffalse} then \DescribeMacro\eHideSolnIn\cs{eHideSolnIn\darg{\ameta{wrt-cmd}}} % to close off the conditional. Where, \ameta{wrt-cmd} is either \cs{writeToSolnFile} (or \cs{writeToExSolns}), or % \cs{writeToQzSolns}. % For example, %\begin{Verbatim}[xleftmargin=\parindent,fontsize=\small, %commandchars={!()},codes={\catcode`\%=9}] %\bHideSolns\writeToSolnFile % for eqexam %\begin{exam}{test} %... %\end{exam} %\eHideSolns\writeToSolnFile %\end{Verbatim} %Now this exam has no footprint within the solution file. % \begin{macrocode} \@ifundefined{ifOKToWriteExamData}{\newif\ifOKToWriteExamData \OKToWriteExamDatatrue}{} \def\noSolnWrites{\OKToWriteExamDatafalse} \def\normalSolnWrites{\OKToWriteExamDatatrue} \def\bHideSolnIn#1{#1{\protect\iffalse}\noSolnWrites} \def\eHideSolnIn#1{\normalSolnWrites#1{\protect\fi^^J}} % \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}} % \end{macrocode} % (2020/01/01) In certain circumstances, page numbering is incorrect; traced it to the % use of \cs{count0}/\cs{count\cs{z@}}, possibly not used within a group. As a fix, % replaced this usage with the counter \cs{eqtmpcnta}. % \changes{v8.5.7}{2020/01/01}{added public counter \string\cs{eqtmpcnta}} % \changes{v8.5.8}{2020/01/01}{Replaced \string\cs{count\string\cs{z@}} and % \string\cs{count0} with \string\cs{eqtmpcnta}, this fixed the page number % leakage problem} % \begin{macrocode} \newcount\eqtmpcnta %</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 %</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 %</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}[xleftmargin=\parindent,fontsize=\small, %commandchars={!()},codes={\catcode`\%=9}] %\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} % This\DescribeMacro{\exrtnlabelformatwp} is the formatted return label (return from the solution), % for an exercise with parts. % \begin{macrocode} \newcommand\exrtnlabelformatwp{$\square$} %</package> %<*package|eqexam> % \end{macrocode} % \begin{macro}{\aboveexskip} % \begin{macro}{\belowexskip} % Amount of skip before and after exercise environment % \begin{macrocode} \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 \string\cs{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 \string\cs{nolinkcolor} into a text fill-in. Now, the command \string\cs{nolinkcolor} % fills in \string\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}[xleftmargin=\parindent,fontsize=\small, %commandchars={!()},codes={\catcode`\%=9}] %\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}[xleftmargin=\parindent,fontsize=\small, %commandchars={!()},codes={\catcode`\%=9}] %\begin{exercise}[!ameta(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}[xleftmargin=\parindent,fontsize=\small, %commandchars={!()},codes={\catcode`\%=9}] %\begin{exercise}[!ameta(ctr)]* ...\end{exercise} %\begin{exercise*}[!ameta(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.\medskip % % \noindent With the exercises\DescribeMacro{\exerSolnInExtFile}, % 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}[xleftmargin=\parindent,fontsize=\small, %commandchars={!()},codes={\catcode`\%=9}] %\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{} %</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}[xleftmargin=\parindent,fontsize=\small, %commandchars={!()},codes={\catcode`\%=9}] %\begin{exercise} %\begin{cq} %!quad(This is the question) %\end{cq} %\begin{solution} %!quad(This is the question) %\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{\withinsoldoctrue\cqSAfalse \eqCQDeclarations} \def\eqTopOfQslPage{\withinqsldoctrue} \eq@turnMessageOff \includecomment{qPage}\excludecomment{sPage} \eq@turnMessageOn %</package|eqexam> %<*package> \def\writecqQSfalse{% \writeT@ExSolns{\protect\eqTopOfSolnPage}} \def\writeTopOfQslPage{\writeT@QzSolns{\protect\eqTopOfQslPage}} \AtBeginDocument{\writecqQSfalse\writeTopOfQslPage} %</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 formated 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}[xleftmargin=\parindent,fontsize=\small, %commandchars={!()},codes={\catcode`\%=9}] %... %\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. % \changes{v8.2.8}{2018/12/13}{write \string\cs{declareterminex} only if not solutionsafter} % \begin{macrocode} \global\terminexchangedtrue % dps cq \ifeq@solutionsafter\else \writeT@ExSolns{\protect\decleqterminex{\protect \cqFmtPasteQues{\cq@CutName}}\eq@commentchar}\fi\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\writeT@ExSolns{\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. % \changes{v8.2.8}{2018/12/13}{write \string\cs{declareterminex} only if not \string\opt{solutionsafter}} % \begin{macrocode} \newcommand\restoreNormalSolns{\ifeq@solutionsafter\else \writeT@ExSolns{\protect\decleqterminex{\protect \eqterminexDEF}\eq@commentchar}\fi} % \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\let\insE@rlyAtQues\@empty \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 \string\textsf{contsolns.dtx}} % \changes{v8.5.10}{2020/03/14}{Added \string\cs{priorexlabelheader} to support \string\pkg{eqexam}} % \begin{macrocode} \let\prior@exerSolnHeaderHook\@empty \newcommand\exerSolnHeader[3]{% \prior@exerSolnHeaderHook \ifeqforpaper\else\webnewpage\fi\markright{#1}%\par\noindent% \priorexlabelheader %</package|eqexam> %<*package> \noindent\hypertarget{#2}{#3}\global\let\priorexlabelheader\relax %</package> %<*eqexam> #3\global\let\priorexlabelheader\relax %</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} \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 \string\cs{eqEXt} so that it has two %required arguments} % \begin{macrocode} \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}[xleftmargin=\parindent,fontsize=\small, %commandchars={!()},codes={\catcode`\%=9}] %\eqEXt{\eqExtArg}{\eqFilterArg}\exerSolnHeader %!quad{\exsecrunhead}{ex.1}{\textbf{Exercise\ 1.}}\relax %!quad... %!quad!ameta(solution content) %!quad... %\ReturnTo{qex.1}{\hbox {$\square $}}\endeqEXt\par\medskip %\end{Verbatim} % \changes{v6.7a}{2013/05/03}{Change name of \string\cs{eq@writeexheader} to \string\cs{eqExerSolnHeader}} % \begin{macrocode} \let\eqExerSolnHeader\@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 \string\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 \string\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 \insE@rlyAtQues\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 \DescribeMacro{\decleqterminex}\cs{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 \string\cs{eqEXt}} % (2013/04/07) Added another argument into \cs{eqEXt}, used for filtering.\par\medskip % \noindent % (2018/02/13) When solutions are written to the SOL file, they are not normally in a group. % If you execute \DescribeMacro\makeExSolnsLocalOn\cs{makeExSolnsLocalOn}, each solution % is written in a group. Undo this with \DescribeMacro\makeExSolnsLocalOff\cs{makeExSolnsLocalOff}, % which is the historic default. % \changes{v8.1p}{2018/02/13}{Added grouping for exercise solutions to the SOL file} % \begin{macrocode} \newif\ifmakeExSlLocal \makeExSlLocalfalse \def\makeExSolnsLocalOn{\makeExSlLocaltrue} \def\makeExSolnsLocalOff{\makeExSlLocalfalse} \let\eqMrkSoln\@gobble \let\priorexlabelheader\relax \def\eqExerSolnHeaderSngl{% \ifmakeExSlLocal\protect\begingroup^^J\fi \ifx\eqMrkCpyArg\@empty\else \protect\eqMrkSoln{\eqMrkCpyArg}\fi \protect\eqEXt{\eqExtArg}{\eqFilterArg}\protect \solnItemMngt\protect\exerSolnHeader{\exsecrunhead}{ex.\the@exno}% {\exsllabelformat}\exer@solnheadhook \exersolnheadhook\protect\eqterminex} \def\eq@@writeexheader{\ifeq@hidesolution\else\ifOKToWriteExamData \set@display@protect \immediate\write\verbatim@out{\eqExerSolnHeaderSngl}% \set@typeset@protect\fi\fi} % \end{macrocode} %\changes{v6.7}{2013/04/07}{Inserted another argument into \string\cs{eqEXt}} % Added another argument into \cs{eqEXt}, used for filtering. % \begin{macrocode} \def\eqExerSolnHeaderList{% \ifmakeExSlLocal\protect\begingroup^^J\fi \ifx\eqMrkCpyArg\@empty\else \protect\eqMrkSoln{\eqMrkCpyArg}\fi \protect\eqEXt{\eqExtArg}{\eqFilterArg}\protect \solnItemMngt\protect\exerSolnHeader{\exsecrunhead}% {ex.\the@exno\thepartno}{\exsllabelformatwp}% \exer@solnheadhook\exersolnheadhook\protect\eqterminex} \def\eq@@writeexheaderlist{\ifeq@hidesolution\else\ifOKToWriteExamData \set@display@protect\immediate \write\verbatim@out{\eqExerSolnHeaderList}\set@typeset@protect\fi\fi} % \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 \string\cs{ckSolnOpt} and \string\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. % \changes{v8.1g}{2017/12/27}{added \string\cs{pushEnvir} and \string\cs{popEnvir} to remove % \string\cs{everypar} influence in \string\cs{solnexer@woparts}} % \changes{v8.1o}{2018/02/12}{Added cond. definition for \string\cs{if@eqalignfilllinestoleft}} % \begin{macrocode} \let\exsolnonceonlytophook\relax \def\solnexer@woparts{% \ifanswerkey\ifeqe@flextended\ifcont@nnot \ifx\solutionparshape\@empty\else % dpsj8 \pushEnvir \everypar{}\if@eqalignfilllinestoleft\else \parshape=1 \leadinIndent \linewidth\fi \popEnvir \fi\fi\fi\fi\def\bLeaveVspace{x}% = no vertical space added \exsolnonceonlytophook % dps27 \global\let\exsolnonceonlytophook\relax % \end{macrocode} % The following lines are needed to get a better alignment % with the bgonly key option, in \pkg{eqexam}. % \changes{v8.1f}{2017/12/04}{Added lines to support eqexam} % \begin{macrocode} \@ifundefined{KV@eqefillLines@bgonly}{} {\ifKV@eqefillLines@bgonly\ifvmode\else \par\leavevmode\strut\fi\fi \ifKV@eqefillLines@outlineonly\leavevmode\strut\fi}% \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} \let\leavevspace\relax % dpsj5 \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\eq@quessolskip \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} \if@eqlinedfiller \ifx\soln@keys@nLines\@empty \def\eq@lines@next{\vspaceFiller{#1}}\else \def\eq@lines@next{\eq@linesXPgs}\fi \else \def\eq@lines@next{\parbox[b][#1][t]{\linewidth} {\vspaceFiller{#1}}}% \fi\eq@lines@next}% \fi }\expandafter\leavevspace \fi} % \end{macrocode} % \changes{v6.8g}{2014/04/08}{Added key-val here for \string\pkg{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 \string\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 \string\pkg{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} % dpsj5 moved to solnexer@@@woparts % \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}} % \changes{v8.1h}{2018/01/03}{Added \string\cs{@solnafterSkipOnce} (package use only)} % \begin{macrocode} \def\solnsafterSkip#1{\setlength{\@tempdima}{#1}% \edef\solnsafterSkipAmt{\the\@tempdima}% \def\solutionsafterSkip{\vskip\solnsafterSkipAmt\relax}} \solnsafterSkip{\smallskipamount} \def\@solnafterSkipOnce#1{\setlength{\@tempdima}{#1}% \xdef\@solnafterSkipOnceAmt{\the\@tempdima}}% \def\@@solnafterSkipOnce{\vskip\@solnafterSkipOnceAmt\relax %dpsj3 \gdef\@solnafterSkipOnceAmt{0pt}} \def\@solnafterSkipOnceAmt{0pt} % \end{macrocode} % Add separation between the question and the \texttt{solution} environment. % \changes{v8.1d}{2017/11/13}{Added \string\cs{quessolsep} for exercises (eqexam)} % \begin{macrocode} \def\quessolSkip#1{\setlength{\@tempdima}{#1}% \edef\eq@quessolskip{\noexpand\vskip\the\@tempdima\relax}} \def\eq@quessolskip{\vskip\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 \string\cs{comment} and \string\cs{endcomment}. For some reason, % yet to be determined, there are problems when using the \string\opt{fortextbook} % option when hiding solutions. %} %\changes{v8.2.9}{2019/02/11}{\string\cs{eqSavedComment}\string\cs{dlcomment}, \string\cs{dlcomment}\space %is not defined in \string\pkg{insdljs}} % \begin{macrocode} \let\eqSavedComment\dlcomment \let\endeqSavedComment\enddlcomment % \end{macrocode} %\changes{v7.4}{2015/03/23}{added \string\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}% \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\solutionafterExCmds#1{\def\@rgi{#1}\ifx\@rgi\@empty \let\eqSolnExCmds\relax\else \def\eqSolnExCmds{#1}\fi} \let\eqSolnExCmds\relax \def\eq@b@ddCodeSpecialDef#1{#1}% \let\eq@b@ddCodeSpecial\eq@b@ddCodeSpecialDef \def\solnexer@@@woparts{\ifeq@solutionsafter\else \expandafter\begingroup\fi \global\thereissolutiontrue \global\let\procsoln\relax \global\let\endprocsoln\relax \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\endeqSavedComment \def\eq@next{\procsoln}% \else \eq@ckglobalhide \ifeq@hidesolution \let\procsoln\eqSavedComment \let\endprocsoln\endeqSavedComment \else \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 \let\procsoln\relax \let\endprocsoln\relax \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 \@@solnafterSkipOnce \eqe@setStartSolns \fi \else\par\kern0pt \solutionsafterSkip \@@solnafterSkipOnce \noindent\strut\eqe@setStartSolns \fi \parskip\eqeques@parsep \ifx\endparts\endexercise@parts@tabular \eq@setPrbSolnAftrIndnt \restorejustify \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} % \eqSolnExCmds \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 % \end{macrocode} % Write \cs{eqExerSolnHeader} after all. % \changes{v8.2.8}{2018/12/13}{write \string\cs{eqExerSolnHeader} after all} % \begin{macrocode} \global\therearesolutionstrue\expandafter\procsoln \fi }% \fi \eq@b@ddCodeSpecial{\eq@next}% }% dpsj4 % \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> % \end{macrocode} % \changes{v8.2.6}{2018/12/03}{defined \string\cs{eq@commentchar}} % \begin{macrocode} \bgroup\catcode`\%=12\relax \gdef\eq@commentchar{%}\egroup \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 % \end{macrocode} % Tack on comment character at the end of the line. % \changes{v8.2.6}{2018/12/03}{defined \string\cs{eq@commentchar}} % \begin{macrocode} \eq@commentchar^^J% %dpsd03 %</package> %<*eqexam> \protect\ReturnTo{page.\the\c@page}% {\protect\mbox{\if\exerstar*\exrtnlabelformatwp\else \exrtnlabelformat\fi}}% \protect\endeqEXt\ifeqforpaper\protect\par{\belowexsolnskip}\fi \eq@commentchar^^J% %</eqexam> %<*package|eqexam> % \end{macrocode} % \changes{v8.2.5}{2018/10/03}{\string\cs{ifmakeExSlLocal} misplaced, corrected} % \begin{macrocode} \ifmakeExSlLocal\protect\endgroup^^J\fi } % \end{macrocode} % \end{macro} % \begin{macro}{\endsolnexer@woparts} % Unless \cmd{\eq@solutionsaftertrue}, then \cmd{\endverbitim}, % and write return labels. % \begin{macrocode} \let\eq@e@ddCodeSpecialDef\relax % dpsj4 \let\eq@e@ddCodeSpecial\eq@e@ddCodeSpecialDef % dpsj6 % \end{macrocode} % Added \cs{kdvsp@Restore} to support % the \texttt{flextended} option from \textsf{eqexam}. See the placement % of this command below its default definition of \cs{relax}. % \changes{v8.1i}{2018/01/20}{Added \string\cs{kdvsp@Restore} to support % the \string\opt{flextended} option from \string\pkg{eqexam}} % \begin{macrocode} \let\kdvsp@Restore\relax \def\eq@clearMrkCpy{\if@targetforextr \global\let\eqMrkCpyArg\@empty \global\@targetforextrfalse\fi } \def\endsolnexer@woparts{\endprocsoln\eq@e@ddCodeSpecial \pkg@endsolnexerhook \eq@clearMrkCpy \ifeq@solutionsafter\else \expandafter\endgroup\fi % from \begingroup at \solnexer@@@woparts \global\let\exsolnonceonlytophook\relax \ifx\sameVspace\@empty\gdef\sameVspace{0pt}\fi \ifvspacewithsolns\vspaceFmt{\sameVspace}\else \ifeq@nosolutions\ifeq@solutionsafter\else \vspaceFmt{\sameVspace}\fi\fi\fi \if\currhideopt H% \ifkeepdeclaredvspacing\vskip\sameVspace\fi \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 \ifx\isitleadin\eq@YES\parshape=0 \fi \if\exerstar*% \eq@fititin{\mbox{\exrtnlabelformatwp}}\else \eq@fititin{\mbox{\exrtnlabelformat}}\fi \ifx\istabularexer\eq@YES\unskip\kern0pt\else\par\fi % \end{macrocode} % if \cs{ifkeepdeclaredvspacing} is true, we attempt % to preserve the vertical space declared by the \textsf{solution} environment when % \cs{ifeq@solutionsafter} is true. % \changes{v6.3z}{2011/04/28}{if \string\cs{ifkeepdeclaredvspacing} is true, we attempt % to preserve the vertical space declared by the \string\env{solution} environment when % \string\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 \string\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}, |\@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 \eq@ckglobalhide \ifeq@hidesolution\else \endsolnexerhookaux % \end{macrocode} % Here's were we write the trailer for the solution % \changes{v8.2.6}{2018/12/03}{if \string\cs{@targetforextrfalse}, set \string\cs{@targetforextrfalse}} % \begin{macrocode} \writeT@ExSolns{\eqExerSolnTrailer}% \fi \fi \fi \kdvsp@Restore \endsolnexerhook\penalty0\relax} % \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 \texttt{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 \string\texttt{exercise*} environment, this is equivalent to the \string\texttt{*} option of the % \string\env{exercise} environment. You can use either version, but now, \string\env{exercise*} is preferred. %} % \begin{macrocode} \let\eq@exerstarEnv\relax \newenvironment{exercise*}{\def\eq@exerstarEnv{*}\exercise} {\global\let\insE@rlyAtQues\@empty\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 \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}% \vskip\eqparts@itemsep\relax\fi \topofpartshook \let\itsExerParts\eq@YES \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 \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 \string\cs{setPartsWidth} to set \string\cs{part@indent}. Also % defined \string\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. % \changes{v8.5.10}{2020/03/14}{\string\cs{probInMinip@ge} set to \string\cs{relax}} % \begin{macrocode} \def\eq@item@common{\eq@insertContAnnot\eqp@rtc@lcm@rk \global\let\probInMinip@ge\relax \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]{{% \setlength{\@tempdima}{#1}% \xdef\eqparts@itemsep{\the\@tempdima}}} \let\eqpartsitemsep\partsitemsep \def\eqparts@itemsep{0pt} \newcommand\partsparsep[1]{{% \setlength{\@tempdima}{#1}% \xdef\eqparts@parsep{\the\@tempdima}}} \def\eqparts@parsep{0pt} \newcommand\partstopsep[1]{{% \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 \let\probInMinip@ge\relax % \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}% % \end{macrocode} % Write to SOL file, unless solutions-after. % \changes{v8.2.8}{2018/12/13}{Write to SOL file, unless solutions-after} % \begin{macrocode} \global\let\eqExerSolnHeader\eq@@writeexheaderlist \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 \settowidth{\eq@tmplength}{\parts@indent\eqe@prtsepPrb}% \xdef\prtsIndntSep{\the\eq@tmplength}% \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}{\eqparts@topsep}% \setlength{\parskip}{0pt}% \setlength{\partopsep}{0pt plus 1pt minus 1pt}% \ifdim\eqeques@parsep=0pt \setlength{\parsep}{\eqparts@parsep}% \else \setlength{\parsep}{\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} \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 % \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 % \end{macrocode} % If \cs{probInMinip@ge} has been redefined, continue to \cs{eq@item@common} to support \pkg{eqexam}. % \changes{v8.5.10}{2020/03/14}{Change in logic for \string\cs{item} to support \string\pkg{eqexam}} % \begin{macrocode} \def\item{\ifx\probInMinip@ge\relax \ifx\@currenvir\eqthisenv \def\eq@next{\eq@item@common}\else \def\eq@next{\eq@item}\fi \else\def\eq@next{\eq@item@common}\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 % % \noindent(2017/02/09) Added \pkg{xkeyval} to optional argument of \env{parts}. Syntax is now %\begin{verbatim} % \begin{parts}[<num>|nCols=<num>,minVspace=<length>] %\end{verbatim} % \changes{v7.8e}{2017/02/09}{Added xkeyval to optional argument of \string\env{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 \ifx\eq@tabMarkChk\@gobble \def\eq@atnext{\expandafter \tabularnewline\expandafter[#1]}\else \def\eq@atnext{\resettabMark\tabularnewline \noalign{\expandafter\kern#1}}\fi \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}{% \setcounter{partno}{0}% % \end{macrocode} % \changes{v8.2.8}{2018/12/13}{Write to SOL file, unless solutions-after} % \begin{macrocode} \global\let\eqExerSolnHeader\eq@@writeexheaderlist % \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 \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{eq@partstabcolsep} to leave % room for \cs{tabcolsep=}\cs{eq@partstabcolsep} between columns. %\begin{verbatim} % n=\exerwparts@cols % width=(\linewidth-2*(n-1)*\tabcolsep)/n %\end{verbatim} % \begin{macrocode} \eq@tmpdima=\linewidth \advance\eq@tmpdima-\prtsIndntSep\relax \@tempcnta\exerwparts@cols\relax \advance\@tempcnta-1\relax \multiply\@tempcnta2\relax \@tempdima\prtsIndntSep\relax \divide\@tempdima 2\relax \edef\halfWidth{\the\@tempdima}% \advance\@tempdima\eq@partstabcolsep\relax \tabcolsep\@tempdima \multiply\@tempdima\@tempcnta \advance\eq@tmpdima-\@tempdima \divide\eq@tmpdima by\exerwparts@cols\relax %dpsj3 \edef\widthOfPartsBox{\the\eq@tmpdima}% dpsj2 % \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 \noindent\normalbaselines\kern0pt \prior@parts@hook\abovepartshook % \end{macrocode} %\changes{v7.03}{2015/03/02}{Added \string\texttt{\string\GT{\string\cs{strut}}}, this gives % better control over vertical spacing.}% % \changes{v7.4}{2015/03/23}{inserted \string\cs{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 \string\cs{endexercise@parts@tabular}} % A vertical space adjustment\par\medskip\noindent % (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| % \changes{v8.2.8}{2018/12/13}{write \string\cs{eqExerSolnHeader} after all} % \begin{macrocode} \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}% \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} % End of the \texttt{parts} environment. % \end{environment} % 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 \string\cs{tabControlOn} and \string\cs{tabControlOff}. % Tab control is interfering with regular tabular environments, or anywhere % \string\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}}% \let\eqgrii\relax \let\eqgriii\relax %</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} % \begin{macrocode} \define@key{exEnum}{labelwidthTo}[\normalsize\normalfont\bfseries00.\ ]% {\def\exE@labelwidthTo{#1}} \define@key{exEnum}{labelwidth}[\@empty]{\def\exE@labelwidth{#1}} % \end{macrocode} % Keys continued.\IndexKey{topsep}% % \IndexKey{parsep}\IndexKey{itemsep}\IndexKey{labelsep}\IndexKey{continue}% % \begin{macrocode} \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]|. % \changes{v8.2.6}{2018/12/03}{Inserted \string\cs{eqprior} prior to \string\env{exEnumerate} env} % The \cs{eqprior} command normally does nothing unless it is redefined. % \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\writeT@ExSolns{^^J\string\eqgrii \protect\begin{exEnumerate}\eq@commentchar^^J}\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}% \settowidth{\labelsep}{\normalfont\ }% \setlength{\leftmargin}{\labelwidth}% }\item\relax}{\ifExSolutionsSet\else \writeT@ExSolns{\string\eqgrii \protect\end{exEnumerate}\eq@commentchar^^J}\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} % End of enumeration exercises section %</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{\@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} \newif\if@targetforextr \@targetforextrfalse \newcommand\filterFor[1]{\def\eqFilterArg{#1}} \newcommand{\mrkForIns}[1]{\def\eqMrkCpyArg{#1}\global \@targetforextrtrue\@ifundefined{#1@mfc} {\global\@namedef{#1@mfc}{}} {\PackageWarning{exerquiz/eqexam} {The name '#1' has already been used.\MessageBreak Please choose another, otherwise results may\MessageBreak be as unexpected}}\ignorespaces} \let\eqMrkCpyArg\@empty \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{\InputExrSolnsLevel}\nmpsep{*[\ameta{name}]\darg{\ameta{level}}} The solutions to the exercises % are in their own section, historically this has been \cs{section*}; however for some documents, it is % desirable to have a numbered section number \cs{section} or \cs{chapter}, or \cs{chapter*}. The % \cs{InputExrSolnsLevel} is designed to ease the task of changing how section-type. \ameta{level} is usually % \texttt{section} or \texttt{chapter}; use \texttt* if you want solutions to be in \cs{section*} or \cs{chapter*}; % if the \ameta{name} is used, the beginning of the solutions is marked with \cs{label\darg{name}}. % \changes{v8.5.5}{2019/12/17}{Added \string\cs{InputQzSolnsLevel}} % \begin{macrocode} \def\InputExrSolnsLevel{\@ifstar {\def\eq@ExrSolnsStar{*}\InputExrSolnsLevel@i} {\let\eq@ExrSolnsStar\@empty\InputExrSolnsLevel@i}} \newcommand{\InputExrSolnsLevel@i}[2][]{% \def\eq@ExrSolnsLabel{#1}\def\eq@ExrSolnsLevel{#2}} \InputExrSolnsLevel*{section} % \end{macrocode} %\DescribeMacro{\exerSolnsHeadnToc} sets the section title for the solutions % to the exercises. May be redefined, I suppose. % \begin{macrocode} \def\exerSolnsHeadnToc{% \edef\eq@mkCmd{\expandafter\noexpand \csname\eq@ExrSolnsLevel\endcsname\eq@ExrSolnsStar}% \eq@mkCmd{\exsectitle}\if!\eq@ExrSolnsLabel!\else \label{\eq@ExrSolnsLabel}\fi \if\eq@ExrSolnsStar*% % \addtocontents{toc}{\protect\def\protect\web@finalDot{}} \addcontentsline{toc}{\eq@ExrSolnsLevel}{% \@ifundefined{web@latextoc}{}{% \ifx\web@latextoc\eq@YES\else \protect\numberline{}\fi }\exsectitle }% \fi } % \end{macrocode} %\changes{v6.4q}{2012/03/23}{define \string\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}. \DescribeMacro\eqExSolFileName % \cs{eqExSolFileName} is defined in support of the \texttt{solutionsonly} option and the \pkg{ci-solns} package. % \changes{v8.2.8}{2018/12/13}{Defined \string\cs{eqExSolFileName}} % \begin{macrocode} \newif\ifExSolutionsSet \ExSolutionsSetfalse \def\eqExSolFileName{\jobname.sol} \newcommand{\exerSolnInput} {% \@ifundefined{eqe@IWO}{}{\ifsolutionsAtEnd \eqe@IWO\@auxout{\string\csarg\string\gdef {eqExamQuesLastPage}{\arabic{page}}}\fi}\let\webnewpage\relax \ifsolutionsonly\else % \end{macrocode} % \changes{v8.2.6}{2018/12/03}{place \string\cs{endinput} at end of sol file} % place \cs{endinput} at end of sol file % \begin{macrocode} \bgroup\OKToWriteExamDatatrue \writeT@ExSolns{\string\endinput}\egroup \immediate\closeout\ex@solns\fi \ifeq@nosolutions\else \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 \string\cs{eq@normalheader} after \string\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{\global\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{\eqExSolFileName} {\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 \string\cs{expdfbookmark} to bookmark exercises. %} % We have to increase the \texttt{tocdepth} so hyperref will create the bookmark at the % subsection level. % \begin{macrocode} {\eqtmpcnta\value{tocdepth} \advance\eqtmpcnta\tw@ \xdef\eqbmkmrkdepth{\the\eqtmpcnta}} \@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. %\medskip\par\noindent % Colors used by \pkg{exerquiz}: \texttt{webgreen} normally defined in \pkg{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 \string\cs{proofingsymbol} to a text fillin. This creates the command % \string\cs{@proofingsymbol}. Can now control the symbol and the color (through \string\cs{proofingsymbolColor} % } % \begin{macrocode} \newcommand{\proofingsymbolColor}[1]{\def\@proofingsymbolColor{#1}} \proofingsymbolColor{red} \let\@proofsymbolredefined\eq@Zero \newcommand{\proofingsymbol}[1]{\let\@proofsymbolredefined\eq@One \def\@proofingsymbol{\textcolor{\@proofingsymbolColor}{#1}}} \def\@proofingsymbol{\textcolor{\@proofingsymbolColor}{\ding{52}}} \def\setproofingsymbol{\ifx\@proofsymbolredefined\eq@One\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\insE@rlyAtQues\@empty \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} % \leavevmode\IndexKey{topsep}^^A % \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} % \leavevmode\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} % \leavevmode\IndexKey{color}^^A % A color key set the color of the numbers in a question environment. % \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][]{% % \end{macrocode} % Insert \cs{nopartquestion} to fix problem % with \cs{multipartquestion} % \changes{v8.8.4}{2021/10/02}{Insert \string\cs{nopartquestion} to fix problem % with \string\cs{multipartquestion}} % \begin{macrocode} \nopartquestion \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 \insE@rlyAtQues\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. % \changes{v8.6.7}{2021/04/12}{Remove the misplaced \string\cs{endcsname} % \string\cs{@thispr@b}, within the \string\env{questions} environment.} % \begin{macrocode} {\@tempcnta\z@\let\@thispr@b\@empty \@whilenum\@tempcnta<\@eqquestiondepth\do{\advance\@tempcnta\@ne \ifx\@thispr@b\@empty\edef\@thispr@b{\@nameuse {theeqquestionno\romannumeral\the\@tempcnta}}\else \edef\@thispr@b{\@thispr@b\@nameuse {theeqquestionno\romannumeral\the\@tempcnta}}\fi }\xdef\@currentQues{\@thispr@b}}% \makebox[\labelwidth][r]{\normalfont \@nameuse{label\@quesctr}}% format label \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}% }% }{\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} % % \subsection{Preliminaries} % Beginning with 2021/05/15 v8.7, we introduce several changes that affect % both \env{shortquiz} and \env{quiz} environments. These definitions are % placed here. % \changes{v8.7}{2021/05/15}{Enhanced control over placement of \string\cs{eq@answersEndHook}} % % These definitions support the added control over the \ameta{content} placed by the % command \cs{answersEndHook\darg{\ameta{content}}}. The \ameta{content} argument is % usally a combination of \cs{sqTallyBox} and \cs{sqSolnBtn} commands, but can be anything. % % Another aspect of the change is the \cs{setAnsEnvLinewidth}. Through this command, the % value of \cs{linewidth} can be changed within the \env{answers} and \env{manswers} environmnts. % \begin{macro}{\setAnsEnvLinewidth}\hskip-\marginparsep\,\texttt{\darg{\ameta{length}}} Sets the % \cs{linewidth} of the \env{answers} and \env{manswers} for both the \env{list} and \env{tabular} modes. % It it not shown here, but within each of these envioronments, before the change is made % the ``natural'' \cs{linewidth} is saved as \DescribeMacro\natlinewidth\cs{natlinewidth}, % this value is available only locally, within the environments. % % All changes corresponding to enhanced control over placement of \ameta{content} are marked in the source % by \texttt{dps21-5-15}, \texttt{dps21-5-16}, and \texttt{dps21-5-17}. % \begin{macrocode} \def\setAnsEnvLinewidth#1{\def\@nsLineWidth{#1}} % dps21-5-17 \let\@nsLineWidth\@empty % dps21-5-17 % \end{macrocode} % \end{macro} % \begin{macro}{\answersEndHook}\hskip-\marginparsep\,\texttt{\darg{\ameta{content}}} % Internally, defines the text macro \cs{eq@answersEndHook} to expand to \ameta{content}. % The command also defines text macro \cs{insertAnsEndHookHere} to expand to \ameta{content}. % \cs{eq@answsersEndHook} is used when placing \ameta{content} in the default location; % while \cs{insertAnsEndHookHere} is used to place \ameta{content} at the location specified % by the value of the \texttt{insertAt} key of the \cs{bChoices} command. % \begin{macrocode} \newcommand\answersEndHook[1]{\def\eq@answersEndHook{#1}% \ifx\eq@answersEndHook\@empty\else \def\insertAnsEndHookHere{#1}% \fi } % dps21-5-15 \let\eq@answersEndHook\@empty \let\insertAnsEndHookHere\@empty % dps21-5-15 % \end{macrocode} % \end{macro} % \begin{macrocode} % \end{macrocode} % At the end of each of the targeted envionments, we insert \ameta{content}, % provided a value for \texttt{insertAt} has not been specified; otherwise, we % do nothing as \ameta{content} has been inserted according to the value % of \texttt{insertAt}. % \begin{macrocode} \def\@insertAndHookAtEndEnv{% dps21-5-16 \ifx\insertAnsHookAt\@empty \eq@answersEndHook \else % dps21-5-16 \ifnum\insertAnsHookAt>\aeb@RowCnt \eq@answersEndHook \PackageWarning{exerquiz}{insertAt=\insertAnsHookAt: The value (\insertAnsHookAt) of insertAt is greater\MessageBreak than the number of rows (\aeb@RowCnt). Using the default\MessageBreak positioning instead} \else % \end{macrocode} % Reset the value of \cs{insertAnsHookAt} to its default value. The document % author must specify \texttt{insertAt} for each \cs{eChoices} where a nondefault % placement is wanted. % \begin{macrocode} \global\let\insertAnsHookAt\@empty \fi \fi } % \end{macrocode} % \cs{@insertAnsHookAt} is inserted at the end of \cs{Ans}/\cs{eAns} pair; % the \ameta{content} is placed just after the text of this item. % \begin{macrocode} \def\@insertAnsHookAt{% dps21-5-16 \let\eqe@next\relax \ifx\insertAnsHookAt\@empty\else \ifnum\insertAnsHookAt=\aeb@RowCnt \def\eqe@next{\insertAnsEndHookHere}\fi \fi\eqe@next } % \end{macrocode} % Repetitive code to increment the \cs{aeb@RowCnt} macro. % \begin{macrocode} \def\@incRowCnt{{\@tempcnta\aeb@RowCnt\advance\@tempcnta\@ne \xdef\aeb@RowCnt{\the\@tempcnta}}% dps21-5-16 } % \end{macrocode} % % \subsection{The \texttt{shortquiz} environment} % % 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}[xleftmargin=\parindent,fontsize=\small, %commandchars={!()},codes={\catcode`\%=9}] %\begin{shortquiz}*[!ameta(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 \string\cs{sq@afterhook} for use by \string\pkg{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 \let\ListOfSQuizNames\@empty \newenvironment{shortquiz}{\def\eqPTs{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{oQuestion} and \texttt{quiz} environments. % \begin{macrocode} \xdef\eq@pageThisQ{\the\c@page}% \let\@currentQues\@empty {\eqtmpcnta\@shortquizCnt\relax\advance\eqtmpcnta\@ne \xdef\@shortquizCnt{\the\eqtmpcnta}}% \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}[xleftmargin=\parindent,fontsize=\small, %commandchars={!()},codes={\catcode`\%=9}] %\begin{shortquiz}[!ameta(basename)] %\end{Verbatim} % The \texttt{[\ameta{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}% {\eqtmpcnta\@shortquizCnt\relax\advance\eqtmpcnta\@ne \xdef\@shortquizCnt{\the\eqtmpcnta}}% \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> % \end{macrocode} % The hidden ID field for a short-quiz % \begin{macrocode} \def\sq@IDTxtField{\makebox[0pt][l]{% \textField[\autoCenter{n}\BC{}\BG{} \S{S}\textSize{0}\Ff{\FfReadOnly} \AA{\AAFormat{% if\eqSP(typeof\eqSP\oField=="undefined")\eqSP var\eqSP\oField=new\eqSP Object;\r \oField.sqTlyTotCnt=0;\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}{2bp}{2bp}}% } % \end{macrocode} % The \uif{Format} code for the hidden quiz ID text field. %\changes{v8.6}{2020/11/29}{\string\cs{qz@IDTxtField}: Format code now in \string\env{defineJS}} % \begin{macrocode} \begin{defineJS}[\makeesc\!\makecmt\%]{\qzIDFmt} if(typeof aQuizzesInDoc=="undefined") var aQuizzesInDoc=new Array(); if (aQuizzesInDoc.indexOf("!oField")) aQuizzesInDoc.push("!oField"); % \end{macrocode} % (2019/06/22) Added in declaration of quiz object. %\changes{v8.2.12}{2019/06/22}{Added declaration of quiz object} % \begin{macrocode} if (typeof !oField=="undefined") var !oField=new Object; \end{defineJS} % \end{macrocode} % The hidden text field for quizzes. The role of this field is to initialize things % for the associated quiz. This field has \uif{Format} code (\cs{qzIDFmt}), and the \app{Reader} will % execute this code when the page is opened. The code creates a new array \texttt{aQuizzesInDoc}, if needed, % and adds this quiz to the list of quizzes in the doc. Refer to \cs{qzIDFmt} above. % \changes{v8.8.2}{2021/05/29}{Check for dupl short-quiz names} % \begin{macrocode} \def\qz@IDTxtField{\makebox[0pt][l]{\textField[\autoCenter{n}\BC{}\BG{} \S{S}\textSize{0}\Ff{\FfReadOnly} \AA{\AAFormat{\qzIDFmt}}]{qzID\oField}{2bp}{2bp}}} %</package> %<*package|eqexam> \let\eqQuizType\relax \def\@@shortquiz[#1]{\csarg % dps5-29 \ifx{SQName-#1}\relax \csarg\gdef{SQName-#1}{1}\else \PackageWarning{exerquiz}{% The short-quiz name '#1' is already used,\MessageBreak please choose a quiz name unique throughout\MessageBreak this document}\csarg\gdef{SQName-#1}{0}% \fi \gdef\oField{#1}\gdef\curr@quiz{#1}\gdef\currQuiz{#1}% \edef\tmp@Exp{\noexpand\g@addto@macro\noexpand \ListOfSQuizNames{,#1}}\tmp@Exp % \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 \env{shortquiz} can be % used with the \env{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 \string\cs{sqPostHeaderHook} and % \string\cs{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} % \end{macrocode} % When solutions are written to the QSL file, they are not normally in a group. % If you execute \DescribeMacro\makeQzSolnsLocalOn\cs{makeQzSolnsLocalOn}, each solution % is written in a group. Undo this with \DescribeMacro\makeQzSolnsLocalOff\cs{makeQzSolnsLocalOff}, % which is the historic default. % \changes{v8.1p}{2018/02/13}{Added grouping for quiz solutions to the QSL file} % \begin{macrocode} \newif\ifmakeQzSlLocal \makeQzSlLocalfalse \def\makeQzSolnsLocalOn{\makeQzSlLocaltrue} \def\makeQzSolnsLocalOff{\makeQzSlLocalfalse} \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{% \ifmakeQzSlLocal\protect\begingroup^^J\fi % \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 \ifx\eqMrkCpyArg\@empty\else \protect\eqMrkSoln{\eqMrkCpyArg}\fi \protect\eqQt{\eqFilterArg}\else \ifx\prior@eqSQt\@empty\else\prior@eqSQt\fi \ifx\eqMrkCpyArg\@empty\else \protect\eqMrkSoln{\eqMrkCpyArg}\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 \eq@clearMrkCpy \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 \string\cs{promoteNewPageHere}} % \changes{v6.8a}{2014/01/01}{Made an optional argument, but test for required argument as swell.} % \changes{v8.5.6}{2020/01/01}{\string\cs{promoteNewPageHere}: added condition, first arg must be greater % then 0pt; otherwise, do nothing} % \begin{macrocode} \newcommand\pnphDflt{.1\textheight} \newcommand{\promoteNewPageHere}[1][\pnphDflt]{% \@ifnextchar\bgroup{\eq@promoteNewPageHere} {\eq@promoteNewPageHere{#1}}% } \def\eq@promoteNewPageHere#1{\setlength{\@tempdimb}{#1}% \ifdim\@tempdima>\z@\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\fi } % \end{macrocode} % The two macros\DescribeMacro{\saveDest}\cs{saveDest} and \DescribeMacro{\useDest}\cs{useDest} 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 %</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% \ifmakeQzSlLocal\protect\endgroup^^J\fi } %</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} % End package and begin package|eqexam %</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. % \texttt{\#1} is the \cmd{\noPeek} parameters; \texttt{\#2} is the named destination to this % solution; \texttt{\#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 \string\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} % The\DescribeMacro{\noPeekAction} default definition of \cs{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))>> >> } %</package> %<*package|eqexam> % \end{macrocode} % \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} \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{\InputQzSolnsLevel}\nmpsep{*[\ameta{name}]\darg{\ameta{level}}} The solutions to the quizzes % are in their own section, historically this has been \cs{section*}; however for some documents, it is % desirable to have a numbered section number \cs{section} or \cs{chapter}, or \cs{chapter*}. The % \cs{InputQzSolnsLevel} is designed to ease the task of changing how section-type. \ameta{level} is usually % \texttt{section} or \texttt{chapter}; use \texttt* if you want solutions to be in \cs{section*} or \cs{chapter*}; % if the \ameta{name} is used, the beginning of the solutions is marked with \cs{label\darg{name}}. % \changes{v8.5.5}{2019/12/17}{Added \string\cs{InputQzSolnsLevel}} % \begin{macrocode} \def\InputQzSolnsLevel{\@ifstar {\def\eq@QzSolnsStar{*}\InputQzSolnsLevel@i} {\let\eq@QzSolnsStar\@empty\InputQzSolnsLevel@i}} \newcommand{\InputQzSolnsLevel@i}[2][]{% \def\eq@QzSolnsLabel{#1}\def\eq@QzSolnsLevel{#2}} \InputQzSolnsLevel*{section} % \end{macrocode} % \DescribeMacro{\quizSolnsHeadnToc} sets up the quiz solution title. % \begin{macrocode} \def\quizSolnsHeadnToc{% \edef\eq@mkCmd{\expandafter\noexpand \csname\eq@QzSolnsLevel\endcsname\eq@QzSolnsStar}% \eq@mkCmd{\sqslsectitle}\if!\eq@QzSolnsLabel!\else \label{\eq@QzSolnsLabel}\fi \if\eq@QzSolnsStar*% \addcontentsline{toc}{\eq@QzSolnsLevel}{% \@ifundefined{web@latextoc}{}{% \ifx\web@latextoc\eq@YES\else \protect\numberline{}\fi }\sqslsectitle }% \fi } % \end{macrocode} % \DescribeMacro{\quizSolnInput} is the command that actually inputs % the solutions file \cmd{\jobname.qsl}. % \changes{v8.2.6}{2018/12/03}{Placed \string\cs{endinput} at the end of % the quiz solutions file} % \begin{macrocode} \newcommand{\quizSolnInput}{% \global\let\webnewpage\relax \bgroup\OKToWriteExamDatatrue \writeT@QzSolns{\string\endinput}\egroup \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{\global\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} % Begin joint package and eqexam %</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 \env{quiz*} environment instead. %\begin{Verbatim}[xleftmargin=\parindent,fontsize=\small, %commandchars={!()},codes={\catcode`\%=9}] %\begin{quiz}[*]{!ameta(base-name)} % ... %\end{quiz} %\end{Verbatim} %Brief description of parameters: % \begin{itemize} % \item optional \texttt{*} means to use checkboxes, otherwise use links; % \item \texttt{\ameta{base-name}}: required argument is the base name of quiz. % \end{itemize} % Note that I set \cs{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, |\setlength{\tabcolsep}{6pt}|. % \begin{macrocode} \newenvironment{quiz}{\goodbreak \@ifstar {\gdef\qstar{*}\@quiz*f} {\gdef\qstar{x}\@quiz*l}% }{\aeb@endquiz} \def\@quizCnt{0} % \end{macrocode} % \cs{ListOfQuizNames} and \cs{ListOfSQuizNames} are master lists of all % quizzes in the document. % \changes{v7.8l}{2017/07/29}{Added \string\cs{ListOfQuizNames} and % \string\cs{ListOfSQuizNames}} % \changes{v8.8.2}{2021/05/29}{Check for dupl quiz names} % \begin{macrocode} \let\ListOfQuizNames\@empty \def\@quiz*#1#2{\csarg % dps5-29 \ifx{QzName-#2}\relax \csarg\gdef{QzName-#2}{1}\else \PackageWarning{exerquiz}{% The quiz name '#2' is already used,\MessageBreak please choose a quiz name unique throughout\MessageBreak this document}\csarg\gdef{QzName-#2}{0}% \fi % \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} {\eqtmpcnta\@quizCnt\advance\eqtmpcnta\@ne \xdef\@quizCnt{\the\eqtmpcnta}}% % \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 \string\cs{xdef}\string\cs{oField}\string\darg{\#2}, this is % needed for \string\textsf{apb.dtx}} % Add \string\cs{listOfQuizNames} to track quizzes % \changes{v7.8k}{2017/07/25}{Added \string\cs{listOfQuizNames} to track quizzes} % \begin{macrocode} \g@addto@macro\ListOfQuizNames{,#2}% \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{\flJSStr*[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{macro}{\@initQuiz} % \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 object % listing all quizzes in the document, the value is the quiz object. We add properties % isSubmitted and initializeWith to the quiz object.} %\changes{v8.6.1}{2020/12/30}{Changed the comparison method for \string\cs{priorInitQuiz} and % \string\cs{postInitQuiz} to reflect their \string\cs{newcommand} definition.} %\changes{v8.8.1}{2021/05/21}{Added a gateway into \string\cs{@initQuiz}} % \begin{macrocode} \begingroup \catcode`<=1 \catcode`\>=2 \@makeother\{ \@makeother\} \gdef\jsLB<{>\gdef\jsRB<}> \endgroup % \end{macrocode} % (2021/05/21) Added a gate keeper into \uif{Begin Quiz}. Normally, all code % passes through, but this can be modified by redefining \DescribeMacro\BeginQuizG@te % \cs{BeginQuizG@te}; restore any changes with \DescribeMacro\restoreBeginQuiz % \cs{restoreBeginQuiz}. % \begin{macrocode} \newcommand{\BeginQuizG@te}{if (true)} \def\Norm@lBeginQuiz{if (true)} \def\restoreBeginQuiz{\let\BeginQuizG@te\Norm@lBeginQuiz} \newcommand\@initQuiz{% \BeginQuizG@te\space\jsLB\jsR\jsT var\eqSP\curr@quiz=new Object();\jsR\jsT lstOfQuizzes["\curr@quiz"]=\curr@quiz;\jsR\jsT \curr@quiz.oAlertCheck={bAfterValue:false};\jsR\jsT \curr@quiz.Grp={};% \ifx\defaultColorJSLoc\@empty\else\jsR\jsT \oField.DefaultColorJSLoc=\defaultColorJSLoc;\fi \ifx\rghtColorJSLoc\@empty\else\jsR\jsT \oField.RightColorJSLoc=\rghtColorJSLoc;\fi \ifx\wrngColorJSLoc\@empty\else\jsR\jsT \oField.WrongColorJSLoc=\wrngColorJSLoc;\fi \ifx\partialColorJSLoc\@empty\else\jsR\jsT \oField.PartialColorJSLoc=\partialColorJSLoc;\fi \ifx\rghtAnsSymbJSLoc\@empty\else\jsR\jsT \oField.RightAnsSymbJSLoc=\rghtAnsSymbJSLoc;\fi \ifx\wrngAnsSymbJSLoc\@empty\else\jsR\jsT \oField.WrongAnsSymbJSLoc=\wrngAnsSymbJSLoc;\fi \ifx\corrAnsSymbJSLoc\@empty\else\jsR\jsT \oField.CorrAnsSymbJSLoc=\corrAnsSymbJSLoc;\fi \ifx\eqGradeScaleLoc\@empty\else\jsR\jsT \oField.GradeScaleLoc=new Array(\eqGradeScaleLoc);\fi \ifx\eqCorrLocalChoiceFully\@empty\else\jsR\jsT \oField.fullyCorrectLoc=\eqCorrLocalChoiceFully;\fi \if$\priorInitQuiz$\else\jsR\jsT\priorInitQuiz\fi\jsR\jsT InitializeQuiz("\curr@quiz",\ifnocorrections0\else1\fi);% \ifx\eq@CGI\@empty\jsR\jsT\curr@quiz.isSubmitted=false;\else \jsR\jsT\curr@quiz.isSubmitted=true;\fi \jsR\jsT\curr@quiz.initializeWith=% 'InitializeQuiz("\curr@quiz",\ifnocorrections0\else1\fi);';% \if$\postInitQuiz$\else\jsR\jsT\postInitQuiz\fi\jsR \jsRB } % \end{macrocode} % The following is the \env{defineJS} version of \cs{@initQuiz}. This is experiemental % for now, not yet implemented. %\begin{verbatim} %\begin{defineJS}[\makeesc\!\makecmt\%]{\@initQuiz} %var !curr@quiz=new Object(); %lstOfQuizzes["!curr@quiz"]=!curr@quiz; %!curr@quiz.oAlertCheck={bAfterValue:false}; %!curr@quiz.Grp={};% %!ifx!defaultColorJSLoc!@empty!else %!oField.DefaultColorJSLoc=!defaultColorJSLoc;!fi% %!ifx!rghtColorJSLoc!@empty!else %!oField.RightColorJSLoc=!rghtColorJSLoc;!fi% %!ifx!wrngColorJSLoc!@empty!else %!oField.WrongColorJSLoc=!wrngColorJSLoc;!fi% %!ifx!partialColorJSLoc!@empty!else %!oField.PartialColorJSLoc=!partialColorJSLoc;!fi% %!ifx!rghtAnsSymbJSLoc!@empty!else %!oField.RightAnsSymbJSLoc=!rghtAnsSymbJSLoc;!fi% %!ifx!wrngAnsSymbJSLoc!@empty!else %!oField.WrongAnsSymbJSLoc=!wrngAnsSymbJSLoc;!fi% %!ifx!corrAnsSymbJSLoc!@empty!else %!oField.CorrAnsSymbJSLoc=!corrAnsSymbJSLoc;!fi% %!ifx!eqGradeScaleLoc!@empty!else %!oField.GradeScaleLoc=new Array(!eqGradeScaleLoc);!fi% %!ifx!eqCorrLocalChoiceFully!@empty!else %!oField.fullyCorrectLoc=!eqCorrLocalChoiceFully;!fi% %!if$!priorInitQuiz$!else %!priorInitQuiz!fi% %InitializeQuiz("!curr@quiz",!ifnocorrections0!else1!fi);% %!ifx!eq@CGI!@empty %!curr@quiz.isSubmitted=false;!else %!curr@quiz.isSubmitted=true;!fi %!curr@quiz.initializeWith=% %'InitializeQuiz("!curr@quiz",!ifnocorrections0!else1!fi);';% %!if$!postInitQuiz$!else %!postInitQuiz!fi %\end{defineJS} %\end{verbatim} % \end{macro} % \begin{macro}{\priorInitQuiz} % \begin{macro}{\postInitQuiz} % These two commands 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} % Here are a couple\DescribeMacro{\eq@submitURL}\DescribeMacro{\eq@insertHiddenFields}{} % of macros that appear in `\uif{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} % \begin{macro}{\priorSubmitQuiz} % \begin{macro}{\postSubmitQuiz} % These two commands are defined in this package, but are use in \pkg{eq2db}. % \begin{macrocode} \newcommand\priorSubmitQuiz{} \newcommand\postSubmitQuiz{} % \end{macrocode} % \end{macro} % \end{macro} % % \subsubsection{With Links} % % \begin{macro}{\eq@BeginQuizLink} % `\uif{Begin Quiz}' with links % \begin{macrocode} \def\eq@@BeginQuizLinkActions{\A{\JS{\@initQuiz}}} \def\eq@BeginQuizLinkDefaults{\Border{0 0 0}} \let\bqlabelFmt\@empty \def\eq@BeginQuizLink{\qz@IDTxtField \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'. % \changes{v8.6}{2020/11/29}{Action for End Quiz Lnk now a \string\env{defineJS} env} % \begin{macrocode} \def\eq@@EndQuizLinkActions{\A{\JS{\eQzBtnActns}}} \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}{2bp}{2bp}}% \makebox[0pt][r]{\eq@hiddenScoreData\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. % \changes{v8.6}{2020/11/29}{Action for End Quiz Btn now a \string\env{defineJS} env} % \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{\@initQuiz}}} \newcommand\eq@BeginQuizButton[1][]{% \mbox{\qz@IDTxtField\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} % \DescribeMacro\EndQuizG@te is an entry point in the \uif{End Quiz} action % that, if redefined, allows the document author to intercept the end of the quiz % code and insert alternate code lines; perhaps giving the student one last chance % to change his/her quiz before submittal. A document author may redefine \cs{EndQuizLastChance} % for one quiz, then change the \cs{eQzBtnActns} code by back to its default by expanding % \DescribeMacro\restoreEndQuiz\cs{restoreEndQuiz} after the quiz. See the DTX of the % package \pkg{eq-pin2corr} for an example of redefining \cs{EndQuizLastChance}. % The default definition is to ``pass-thru'' with no action. % \changes{v8.8.1}{2021/05/21}{\string\cs{EndQuizG@te} defined as part % of \string\cs{eQzBtnActns}} % \begin{macrocode} \newcommand{\EndQuizG@te}{if (true)} \def\Norm@lEndQuiz{if (true)} \def\restoreEndQuiz{\let\EndQuizG@te\Norm@lEndQuiz} % \end{macrocode} % \begin{macro}{\eQzBtnActns} % The `End Quiz' JavaScript action code % \changes{v8.8.1}{2021/05/21}{Modified \string\cs{eQzBtnActns} to allow more % customizations by inserting \string\cs{EndQuizLastChance} into the code} % \begin{macrocode} \begin{defineJS}[\makeesc\*\makecmt\%]{\eQzBtnActns} if (!isQuizInitialized("*curr@quiz")) eqAppAlert(InitMsg("*bqlabelISO"),3); else { if (*minQuizResp(*thequestionno)&&_ModalNotOn){ % \end{macrocode} % Insert one last chance. % \begin{macrocode} *EndQuizG@te { *curr@quiz.PtValues=new Array(*pointValuesArray); ProbType=[*ptypeArray];% *if@inclkey *curr@quiz.CorrAns=new Array(*corrAnsArray);*fi % \end{macrocode} % (2021/02/17) Pass a fourth argument to \texttt{DisplayQuizResults()}, its default % value is \texttt{bDisplaySilent=false}, but can be changed locally % to \texttt{true}. When \texttt{bDisplaySilent=true}, \texttt{DisplayQuizResults()} % does not write its results to any field (\uif{Score Field}, \uif{Points Field}, etc.). % \changes{v8.6.4}{2021/02/17}{We pass % a new \texttt{bDisplaySilent} argument to \texttt{DisplayQuizResults} for ``silent reporting''} % \begin{macrocode} DisplayQuizResults("*curr@quiz",*theeqpointvalue,% *thequestionno,bDisplaySilent); bDisplaySilent=false; var h=this.getField("ScoreData.*curr@quiz"); h.value=Score+";"+NQuestions+";"% +ptScore+";"+NPointTotal;% *ifx*eq@submitURL*empty*else *eq@submitURL*fi% *if$*postSubmitQuiz$*else *postSubmitQuiz*fi resetQuiz("*curr@quiz"); } } } \end{defineJS} % \end{macrocode} % \end{macro} % \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{\eQzBtnActns}}} % \end{macrocode} % Save end quiz button action. The \DescribeMacro\restoreNormalEndQuiz\cs{restoreNormalEndQuiz} % restores the action to its original definition. % \changes{v8.8.3}{2021/06/24}{Added \string\cs{restoreNormalEndQuiz}} % \begin{macrocode} \let\eq@@EndQuizButtonActionsDefSave\eq@@EndQuizButtonActions % dps0624 \def\restoreNormalEndQuiz % dps0624 {\let\eq@@EndQuizButtonActions\eq@@EndQuizButtonActionsDefSave} \newcommand{\eq@hiddenScoreData}{\makebox[0pt][r]{% \textField[\BC{}\F{\FHidden}]{ScoreData.\curr@quiz}{2bp}{2bp}}} % \end{macrocode} % \begin{macro}{\eq@EndQuizButton} % \begin{macrocode} \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@hiddenScoreData\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 the \pkg{eq2db} package. % (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}} % \end{macrocode} % \leavevmode\DescribeMacro\CorrBtnActionsJS is the JavaScript action % to support the \cs{eqButton}/\cs{CorrButton}. The macro may be redefined % using the \env{defineJS*} environment. Copy and pasted the contents into % a new \env{defineJS*} environment and modify the code. % \changes{v8.5}{2019/10/11}{Incorporated \string\env{defineJS} into % the action of \string\cs{eqButton}} % \begin{macrocode} \begin{defineJS}[\makeesc\@]{\CorrBtnActionsJS} if (isEndQuizPushed("@eqBaseName")){ correctQuiz("@eqBaseName",@thequestionno); % \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") correctSumryTbl("@eqBaseName",@thequestionno); } \end{defineJS} \def\@@eqButtonActions{\A{\JS{\CorrBtnActionsJS}}} \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}{\string\cs{CorrButton} is now an alias for \string\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}% {\RadioFieldSize}{\RadioFieldSize}{Yes}{}% {\eq@setWidgetProps\eq@Check@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 \string\cs{currQuiz} which contains the quiz name. Can be used in conjunction % with \string\cs{floatQuiz} and \string\cs{startQuizHere}. % } % \changes{v8.1k}{2018/02/04}{Added \string\cs{oField} to list in \string\cs{DeclareQuiz}} % \begin{macrocode} \def\DeclareQuiz#1{\edef\oField{#1}% \edef\thisQuiz{#1}\edef\curr@quiz{#1}% \edef\currQuiz{#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 \string\cs{floatQuiz}, \string\cs{dockQuiz} and \string\cs{startQuizHere} to start a quiz in an % arbitrary place prior to the beginning of the quiz. % } %\par\medskip\noindent Usage: %\begin{verbatim} %\DeclareQuiz{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 \string\cs{aeb@@titleQuzi} to \string\cs{aebTitleQuiz}} % \changes{v6.7p}{2013/12/11}{Added optional parameter to \string\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}{\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 \string\cs{showCreditMarkup} and \string\cs{hideCreditMarkup} to show partial credit markup %} %\changes{v6.3k}{2008/01/09} %{ % Added \string\cs{ptsLabel} and \string\cs{ptLabel} to localize the markup in the margin of a quiz %} % \begin{macrocode} \newcounter{qMarkCnt} % \end{macrocode} % When a question has multi-parts, use \DescribeMacro{\multipartquestion}\cs{multipartquestion} to suppress % the partial credit markup. % \begin{macrocode} \def\multipartquestion{\global \let\aeb@multipart\eq@One } % \end{macrocode} % The default is that a question does not have multiple parts, use \DescribeMacro{\nopartquestion}\cs{nopartquestion} % to return to this detault after a \cs{multipartquestion} has been expanded. % \changes{v8.8.4}{2021/10/02}{Define \string\cs{nopartquestion} to recover from % \string\cs{multipartquestion}} % \begin{macrocode} \def\nopartquestion{\global \let\aeb@multipart\eq@Zero } \let\aeb@multipart\eq@Zero % \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} % \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\nopartquestion\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} %\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 \string\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} % Begin joint package and eqexam %</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 \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 \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: % \string\cs{setMClabelsep} and \string\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, 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{ifwithinsoldoc}{\newif\ifwithinsoldoc\withinsoldocfalse}{} \@ifundefined{ifwithinqsldoc}{\newif\ifwithinqsldoc\withinqsldocfalse}{} \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{ifwithinsoldoc} {\refstepcounter{quizno}}{\ifwithinsoldoc\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}{% % \end{macrocode} % Save the natural width of the line, then readjust the % width if \cs{@nsLineWidth} is not empty. % \begin{macrocode} \edef\natlinewidth{\the\linewidth}% dps21-5-17 \ifx\@nsLineWidth\@empty\else % dps21-5-17 \setlength{\linewidth}{\@nsLineWidth}\fi \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 \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} % End joint package and eqexam %</package|eqexam> %<package> \setlength{\labelsep}{0pt}% %<eqexam> \setlength{\labelsep}{0pt}% %<*package|eqexam> \def\Ans{\Ans@list}% }% list }{\@insertAndHookAtEndEnv\endlist\setcounter{quizno}{0}} % dps21-5-16 % \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 \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} % \end{macrocode} % Save the natural width of the line, then readjust the % width if \cs{@nsLineWidth} is not empty. % \begin{macrocode} \edef\natlinewidth{\the\linewidth}% dps21-5-17 \ifx\@nsLineWidth\@empty\else % dps21-5-17 \setlength{\linewidth}{\@nsLineWidth}\fi \eq@tmpdima\linewidth \@tempcnta#1\relax % n-1 \advance\@tempcnta\m@ne\relax % 2(n-1) \multiply\@tempcnta\tw@ \@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 \string\cs{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 re-initialize the % \texttt{quizno} counter. Added \cs{answersEndHook}. % \begin{macrocode} \def\endanswers@sq{\endtabular\setcounter{quizno}{0}% \@insertAndHookAtEndEnv % dps21-5-16 \global\let\@nsLineWidth\@empty % dps21-5-17 \reset@doendpe{\the\everypar}% \ifinner\else%\par \removelastskip % \removelastparskip \vspace{\aboveanswersSkip}\@endpetrue \fi } \def\endmanswers@sq{\endtabular\setcounter{quizno}{0}% \@insertAndHookAtEndEnv % dps21-5-16 \global\let\@nsLineWidth\@empty % dps21-5-17 \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. % \changes{v8.8.5}{2021/10/03}{Allow MC in short-quizzes to have check box to dismiss % alert box.} % \begin{macrocode} \def\sqWrongRespJS{% dpsx \ifx\@sqTurnOffAlerts\eq@One% OnBlurRespBox(false,"\oField");\r\fi this.getField("mc.\curr@quiz.\thequestionno").value="\alph{quizno}"; } \def\sqRightRespJS{% dpsx \ifx\@sqTurnOffAlerts\eq@One% OnBlurRespBox(true,"\oField");\r\fi this.getField("mc.\curr@quiz.\thequestionno").value="\alph{quizno}"; } \def\Ans@sq@l@Actions{\A{% \if\Ans@choice\eq@One\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{ifwithinsoldoc}{\refstepcounter{quizno}} {\ifwithinsoldoc\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> % \end{macrocode} % (2021/10/03) Move 0 and 1 to tooltip of underlying radio button that flags % choice as incorrect and incorrect. % \begin{macrocode} \if\Ans@choice\eq@One % dpsx \def\Ans@c@l@Choice{\TU{1}% \BC{}\Ff{\FfReadOnly}}% \def\rbf@Opts{\symbolchoice{\sq@corrsymch}% \textColor{\sq@corrsymcol}}% \else \def\Ans@c@l@Choice{\TU{0}\DV{Yes}% \Ff{\FfReadOnly}\BC{}}% \def\rbf@Opts{\symbolchoice{\sq@wrgsymch}% \textColor{\sq@wrgsymcol}}% \fi \makebox[0pt][l]{\expandafter\radio@@Button\expandafter{\rbf@Opts}% {mc.\curr@quiz.\thequestionno}% % \end{macrocode} % (2021/10/03) Remove 0 and 1 from export value radio button % \begin{macrocode} {\eq@tmpdima}{\RadioFieldSize}{\alph{quizno}}% dpsx % {\eq@tmpdima}{\RadioFieldSize}{\Ans@choice\alph{quizno}}% {\eq@protect\A}{\eq@setWidgetProps\eq@l@check@driver}% {\Ans@r@l@Defaults\every@RadioButton \every@qRadioButton}}% \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} % \subsubsection{Answers for the \texttt{answers} and \texttt{manswers} Environment} % \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.\string\cs{oFields} so it is printable} % \begin{macrocode} % \end{macrocode} %\DescribeMacro{\TUChoice}\hskip-\marginparsep\texttt{\darg{\ameta{text}}} A generic %tooltip for radio buttons and check boxes for MS and MS questions. The default %is |\TUChoice{Choice}|. %\changes{v8.8.5}{2021/10/03}{Added \string\cs{TUChoice}} % \begin{macrocode} \def\TUChoice#1{\def\TU@Choice{#1}} \TUChoice{Choice} % \end{macrocode} % \begin{macrocode} \def\@@Ans@sq@f@Defaults{% \BC{0 0 0}\Ff{\FfNoToggleToOff}\W{1}%\F{\FPrint} \textSize{12}\textColor{0 g}\TU{\TU@Choice} % dpsx } % \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} % JavaScript code for the mouse up action for the \emph{correct} choice of the radio button field % (\texttt{mc.\ameta{fld-name}.\ameta{q-num}}) for the form version of a multiple choice question of a \texttt{shortquiz}. % \begin{macrocode} \begin{defineJS}[\makeesc\*\makecmt\%]{\Ans@sq@f@ActionsTrue} *ifx*@sqTurnOffAlerts*eq@One% OnBlurRespBox(true,"*oField"); *fi% var qzSolnDest="*@qzsolndest"; var solnAfter=*ifeq@solutionsafter% true*else% false*fi; % \end{macrocode} % Introduce changes in this code in response to \cs{sqSolnBtn} command. % \changes{v8.7.5}{2021/05/05}{\string\cs{sqSolnBtn} changes: execute block % if \string\cs{sqSolnBtn} not detected} % \begin{macrocode} var f=this.getField("corr.*oField.*thequestionno"); if (f==null) { if ((qzSolnDest!="") && !solnAfter) % jmpToNamedDest("*oField","*@qzsolndest",% *ifx*@sqTurnOffAlerts*eq@Zero0*else1*fi);% *ifx*eqAddAAMouseUpMC*empty*else *eqAddAAMouseUpMC*fi } \end{defineJS} % \end{macrocode} % JavaScript code for the mouse up action for the \emph{incorrect} choice of the radio button field % (\texttt{mc.\ameta{fld-name}.q-num}) for the form version of a multiple choice question of a \texttt{shortquiz}. % \begin{macrocode} \begin{defineJS}[\makeesc\*\makecmt\%]{\Ans@sq@f@ActionsFalse} *ifx*@sqTurnOffAlerts*eq@One% OnBlurRespBox(false,"*oField"); *fi% var qzSolnDest="*@qzsolndest"; updateTally("*oField.*thequestionno");% *ifx*eqAddAAMouseUpMC*empty*else *eqAddAAMouseUpMC*fi \end{defineJS} % \end{macrocode} % The actions for the form version of a multiple choice question of a \texttt{shortquiz}. % \begin{macrocode} \def\Ans@sq@f@Actions{\AAmouseup{\if\Ans@choice\eq@One \Ans@sq@f@ActionsTrue\else\Ans@sq@f@ActionsFalse\fi} \AAmousedown{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 % \end{macrocode} % The \cs{Ans} for a short-quiz, using forms. % \begin{macrocode} \def\Ans@sq@f{\if\eq@listType\eq@One \stepcounter{quizno}\else \@ifundefined{ifwithinsoldoc}{\refstepcounter{quizno}} {\ifwithinsoldoc\stepcounter{quizno}\else \refstepcounter{quizno}\fi}\fi \PBS\raggedright %</package|eqexam> % \end{macrocode} %\changes{v6.7d}{2013/05/27}{added \string\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 %</package|eqexam> %<*eqexam> \Ans@sq@f@driver %</eqexam> %<*package> \mbox{\expandafter\radio@@Button\expandafter{\rbf@Opts}% {mc.\oField.\thequestionno}% {\RadioFieldSize}{\RadioFieldSize}% {\alph{quizno}}{\eq@protect\A}% % {\Ans@choice\alph{quizno}}{\eq@protect\A}% {\eq@setWidgetProps\eq@Radio@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> \let\Ans@ck@sq@f\Ans@sq@f %</eqexam> %<*package> \def\@@Ans@ck@sq@f@Defaults{% \BC{0 0 0}\Ff{\FfNoToggleToOff}\TU{\TU@Choice} % dpsx \F{\FPrint}\textSize{12}\textColor{0 g}\W{1} } \begingroup \catcode`\&=12 \gdef\eq@AND{&&} \endgroup % \end{macrocode} % Mouse up action for a \emph{correct answer box} (a checkbox) to MS question of short-quiz % (field name: \texttt{mc.\ameta{fld-name}.\ameta{ques-num}}.\ameta{choice-num}) % \begin{macrocode} \begin{defineJS}[\makeesc\*\makecmt\%]{\Ans@ck@sq@f@ActionsTrue} var fName=event.target.name; var g=this.getField("mck.*oField.*thequestionno"); var a=g.getArray(); % dpsx var h=this.getField("mcq.*oField.*thequestionno"); var b=h.getArray(); % \end{macrocode} % (2021/10/03) Work with the tooltop of \texttt{mcq} rather than the export value % of \texttt{mck}. % \begin{macrocode} for (var i=0; i<a.length; i++) if ( (a[i].isBoxChecked(0)) && (b[i].userName=="0" ) ) %(a[i].value.charAt(0)==0) ) a[i].checkThisBox(0,false);% *ifx*@sqTurnOffAlerts*eq@One OnBlurRespBox(true,"*oField");*else *fi% var qzSolnDest="*@qzsolndest"; var solnAfter=*ifeq@solutionsafter% true*else% false*fi; % \end{macrocode} % Introduce changes in this code in response to \cs{sqSolnBtn} command. % \changes{v8.7.5}{2021/05/05}{\string\cs{sqSolnBtn} changes: execute block % if \string\cs{sqSolnBtn} not detected} % \begin{macrocode} var f=this.getField("corr.*oField.*thequestionno"); if (f==null) { if ( (qzSolnDest != "") && !solnAfter ) { for (var i=0; i<a.length; i++){ % if ((a[i].exportValues[0].charAt(0)==1) && % dpsx % % \end{macrocode} % (2021/10/03) Work with the tooltop of \texttt{mcq} rather than the export value % of \texttt{mck}. % \begin{macrocode} if ((b[i].userName=="1") && (!a[i].isBoxChecked(0))) break; } } if (i>=a.length) jmpToNamedDest("*oField","*@qzsolndest",% *ifx*@sqTurnOffAlerts*eq@Zero0*else1*fi);% *ifx*eqAddAAMouseUpMS*empty*else *eqAddAAMouseUpMS*fi } \end{defineJS} % \end{macrocode} % Mouse up action for a \emph{incorrect answer box} (a checkbox) to MS question of short-quiz % (field name: \texttt{mc.\ameta{fld-name}.\ameta{ques-num}}.\ameta{choice-num}) % \begin{macrocode} \begin{defineJS}[\makeesc\*\makecmt\%]{\Ans@ck@sq@f@ActionsFalse} var fName=event.target.name; var g=this.getField("mck.*oField.*thequestionno"); var a=g.getArray(); % dpsx var h=this.getField("mcq.*oField.*thequestionno"); var b=h.getArray(); for (var i=0; i<a.length; i++) { % if (a[i].value.charAt(0)==0) { % \end{macrocode} % (2021/10/03) Work with the tooltop of \texttt{mcq} rather than the export value % of \texttt{mck}. % \begin{macrocode} if (b[i].userName=="0") { if ( fName != a[i].name ) a[i].checkThisBox(0,false); } }% *ifx*@sqTurnOffAlerts*eq@One OnBlurRespBox(false,"*oField");*fi% *ifx*oField*@empty*else updateTally("*oField.*thequestionno");*fi% *ifx*eqAddAAMouseUpMS*empty*else *eqAddAAMouseUpMS*fi \end{defineJS} % \end{macrocode} % Set all actions for check box for a MS question of a short-quiz % (field name: \texttt{mc.\ameta{fld-name}.\ameta{ques-num}}.\ameta{choice-num}) % \begin{macrocode} \def\Ans@ck@sq@f@Actions{% \AAmouseup{\if\Ans@choice\eq@One \Ans@ck@sq@f@ActionsTrue\else \Ans@ck@sq@f@ActionsFalse\fi} \AAmousedown{updateTally.downState=!!event.target.isBoxChecked(0);}} % \end{macrocode} % The check boxes to a MS question in an \env{manswers} environment of a short-quiz; the name of this field % |mc.\oField.\thequestionno.\arabic{quizno}|. % \begin{macrocode} \def\Ans@ck@sq@f{\if\eq@listType\eq@One \stepcounter{quizno}\else \@ifundefined{ifwithinsoldoc}{\refstepcounter{quizno}} {\ifwithinsoldoc\stepcounter{quizno}\else \refstepcounter{quizno}\fi}\fi\PBS\raggedright \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 \settowidth{\eq@tmplength}{\eq@lw@f}\eq@tmpdima\wd\eq@tmpbox \hangindent\eq@tmplength\hangafter\@ne % dps \insertGrayLetters % 6.3d \mbox{\expandafter\check@@Box\expandafter{\rbf@Opts}% {mck.\oField.\thequestionno.\arabic{quizno}}% {\RadioFieldSize}{\RadioFieldSize} {\alph{quizno}}{\eq@protect\A}% % {\Ans@choice\alph{quizno}}{\eq@protect\A}% dpsx {\eq@setWidgetProps\eq@Check@driver}% {\@@Ans@ck@sq@f@Defaults\Ans@ck@sq@f@Actions\every@CheckBox \every@sqCheckBox}}% \def\late@options{\BC{}}% \if\Ans@choice\eq@One % dpsx \eq@addExpandTo\late@options{\TU{1}}\else \eq@addExpandTo\late@options{\TU{0}}\fi \makebox[0pt][r]{\check@@Box{}% dpsx {mcq.\oField.\thequestionno.\arabic{quizno}}% {0pt}{0pt}{Yes}{}% \@tempdimb {\eq@setWidgetProps\eq@Check@driver}% {\Ans@c@f@Defaults\every@RadioButton \every@qRadioButton\late@options}}% dpsx \Ans@proofing{\RadioFieldSize}\eq@hspanner \ignorespaces } % \end{macrocode} % \end{macro} % \subsection{For the \texttt{quiz} environment} % \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 \string\texttt{manswers} environment, and supporting elements, both {\string\LaTeX} % and JavaScript. This \string\texttt{manswers} environment is for the \string\texttt{quiz} environment % only. There is a \string\texttt{manswers} environment for the \string\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}{% % \end{macrocode} % Save the natural width of the line, then readjust the % width if \cs{@nsLineWidth} is not empty. % \begin{macrocode} \edef\natlinewidth{\the\linewidth}% dps21-5-17 \ifx\@nsLineWidth\@empty\else % dps21-5-17 \setlength{\linewidth}{\@nsLineWidth}\fi \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}% \@insertAndHookAtEndEnv % dps21-5-17 \global\let\@nsLineWidth\@empty % dps21-5-17 \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 % \end{macrocode} % Save the natural width of the line, then readjust the % width if \cs{@nsLineWidth} is not empty. % \begin{macrocode} \edef\natlinewidth{\the\linewidth}% dps21-5-17 \ifx\@nsLineWidth\@empty\else % dps21-5-17 \setlength{\linewidth}{\@nsLineWidth}\fi \eq@tmpdima\linewidth \@tempcnta#1\relax % n-1 \advance\@tempcnta\m@ne % 2(n-1) \multiply\@tempcnta\tw@ \@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 \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}% \@insertAndHookAtEndEnv % dps21-5-17 \global\let\@nsLineWidth\@empty % dps21-5-17 \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\eqSP =\eqSP"\alph{quizno}";\jsR % =\eqSP"\Ans@choice\alph{quizno}";\jsR // dpsx 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}\TU{\TU@Choice} % dpsx \textSize{12}\textColor{0 g}\Ff{\FfReadOnly} } % \end{macrocode} % (2021/10/03) Changes are needed to radio buttons and checkboxes (Commands: \cs{Ans@l},\cs{Ans@ck@l}, \cs{Ans@@f}, and \cs{Ans@@ck@f}) % of the \env{answers} and \env{manswers} environments. AA/AR has changed the way they display the tooltip: changed % from `\ameta{tooltip}' to `\ameta{tooltip}\texttt:\,\ameta{export-value}'. Unfortunately, the \ameta{export-value} % contains code that signals whether this field is a correct choice or not: an export value that begins with a % one (1) indicates a correct choice, which one that begins with a zero (0) marks an incorrect choice. When the student passes % his mouse cursor over a choice, he sees `1a' or `0b'; seeing enough of these patterns, their meaning will become known. % % The workaround is to move the binary flag to the tooltip of the underlying checkbox, which is readonly, hence, % there is not over display of this field. In the fields listed above, we insert \cs{TU{1}} or \cs{TU{0}} % into each of the checkboxes whose names begin with \texttt{mcq}. % % The final step is to change the JavaScript to look at the \texttt{mcq} fields rather than % the \texttt{mc} or \texttt{mck} fields. % \changes{v8.8.5}{2021/10/03}{Changes required by changes in the display of % tooltip for choice fields} % \begin{macrocode} \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)}% % \end{macrocode} % (2013/10/24) Imperative that radio button have no boundary line. % \begin{macrocode} \def\late@options{\BC{}}% \if\Ans@choice\eq@One\relax\eq@recordAnsChoice\fi \makebox[0pt][l]{\radio@@Button{}{mc.\curr@quiz.\thequestionno}% {\eq@tmpdima}{\RadioFieldSize}{\alph{quizno}}% dpsx % {\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}}% \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@choice\eq@One \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@choice\eq@One \eq@addExpandTo\late@options{\TU{1}}% \ifx\@qzsolndest\@empty\else \ifeq@noquizsolutions\else \eq@addExpandTo\late@options{% \BC{\solution@Color}}% \fi \fi \else \eq@addExpandTo\late@options{\TU{0}}% \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\eqSP ckfName="mck.\curr@quiz.\thequestionno.\arabic{quizno}";\jsR var\eqSP ckf = this.getField(ckfName);\jsR ckf.checkThisBox(0,!ckf.isBoxChecked(0));\jsR var\eqSP _bOK=true;\jsR \ifx\eqlimselTo\@empty\else _bOK=LimitSelection(\eqlimselTo,% "mck.\curr@quiz.\thequestionno","\arabic{quizno}");\jsR \fi if(_bOK)\eqSP{\jsR\jsT var\eqSP 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 }}}% } % \end{macrocode} % \begin{macrocode} \def\Ans@ck@l@Defaults{% \BC{}\S{S}\W{1}\H{N}\Ff{\FfNoToggleToOff}\TU{\TU@Choice} % dpsx \textSize{12}\textColor{0 g}\Ff{\FfReadOnly} } % \end{macrocode} % \begin{macrocode} \def\Ans@ck@l{\leavevmode \if\eq@listType1\stepcounter{quizno}% \else\refstepcounter{quizno}\fi \if\Ans@choice\eq@One\eq@recordAnsChoice\fi \PBS\raggedright \settowidth{\eq@tmplength}{\eq@lw@l}\sbox{\eq@tmpbox}{\eq@l@l}% \hangindent\eq@tmplength\hangafter\@ne \eq@tmpdima\wd\eq@tmpbox \def\link@@Content{(\hfil\linkContentFormat\hfil)}% \makebox[0pt][l]{% \check@@Box{}{mck.\curr@quiz.\thequestionno.\arabic{quizno}}% {\eq@tmpdima}{\RadioFieldSize}{\alph{quizno}}% dpsx % {\eq@tmpdima}{\RadioFieldSize}{\Ans@choice\alph{quizno}}% {\eq@protect\A}{\eq@setWidgetProps\eq@l@check@driver}% {\Ans@ck@l@Defaults\every@RadioButton \every@qckCheckbox}}% \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@choice\eq@One \edef\Ans@c@l@Choice{\noexpand\TU{1}\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{\TU{0}\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}\TU{\TU@Choice} % dpsx \F{\FPrint}\textSize{12}\textColor{0 g} } % \end{macrocode} % Action of the radio button field % \begin{macrocode} \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}} } % \end{macrocode} % Action of the check box underlying the radio button field % \begin{macrocode} \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 \string\cs{insertGrayLetters}. This can be defined to place symbols under % the multiple choice form boxes. The command \string\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 \string\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> % \end{macrocode} % The \cs{Ans} command for a quiz using forms. % \begin{macrocode} \def\Ans@@f{% \settowidth{\eq@tmplength}{\eq@lw@f}% \hangindent=\eq@tmplength\hangafter=\@ne \bottomOfAnsfStack\insertGrayLetters \edef\rbf@Opts{\ifaeb@usecircles\else \noexpand\symbolchoice{\qz@chksymb}\fi \noexpand\textColor{\qz@chksymbcol}}% \if\Ans@choice\eq@One\eq@recordAnsChoice\fi \mbox{\expandafter\radio@@Button\expandafter{\rbf@Opts}% {mc.\curr@quiz.\thequestionno}% {\RadioFieldSize}{\RadioFieldSize}{\alph{quizno}}% dpsx % {\RadioFieldSize}{\RadioFieldSize}{\Ans@choice\alph{quizno}}% {\eq@protect\A}{\eq@setWidgetProps\eq@Radio@driver}% {\Ans@r@f@Defaults\Ans@r@f@Actions\every@RadioButton \every@qRadioButton\insert@circlesymbol}}% \let\late@options\@empty \ifnocorrections\else \if\Ans@choice\eq@One \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 \string\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 \string\cs{late@options} commands.} % \begin{macrocode} \ifaeb@usecircles\def\late@options{\BC{}}\fi \if\Ans@choice\eq@One \eq@addExpandTo\late@options{\TU{1}}% \ifx\@qzsolndest\@empty\else \ifeq@noquizsolutions\else \eq@addExpandTo\late@options{% \BC{\solution@Color}}% \fi \fi \else \eq@addExpandTo\late@options{\TU{0}}% \fi \makebox[0pt][r]{\check@@Box{}% {mcq.\curr@quiz.\thequestionno.\arabic{quizno}}% {\RadioFieldSize}{\RadioFieldSize}{Yes}{}% {\eq@setWidgetProps\eq@Check@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@choice\eq@One\eq@recordAnsChoice\fi \PBS\raggedright\Ans@@ck@f} % \end{macrocode} % \begin{macrocode} \def\Ans@ck@f@Defaults{% \BC{0 0 0}\S{S}\W{1}\Ff{\FfNoToggleToOff} \TU{\TU@Choice} % dpsx \textSize{12}\textColor{0 g} } % \end{macrocode} % Action of the radio button field % \begin{macrocode} \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\eqSP_bOK=true;\jsR \ifx\eqlimselTo\@empty\else _bOK\eqSP=\eqSP 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)\eqSP{\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 }}}% } % \end{macrocode} % Action of the check box underlying the radio button field % \begin{macrocode} \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\@ne \bottomOfAnsfStack\insertGrayLetters % \end{macrocode} % The bottom most checkbox % \begin{macrocode} \bottomOfAnsfStack\insertGrayLetters \def\cbf@Opts{\symbolchoice{\qz@chksymb}% \textColor{\qz@chksymbcol}}% \mbox{\expandafter\check@@Box\expandafter{\cbf@Opts}% {mck.\curr@quiz.\thequestionno.\arabic{quizno}}% {\RadioFieldSize}{\RadioFieldSize}{\alph{quizno}}% dpsx % {\RadioFieldSize}{\RadioFieldSize}{\Ans@choice\alph{quizno}}% {\eq@protect\A}{\eq@setWidgetProps\eq@Check@driver}% {\Ans@ck@f@Defaults\Ans@ck@f@Actions\every@RadioButton \every@qckCheckbox}}% \ifnocorrections\else \if\Ans@choice\eq@One \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@choice\eq@One \eq@addExpandTo\late@options{\TU{1}}% \ifx\@qzsolndest\@empty\else \ifeq@noquizsolutions\else \eq@addExpandTo\late@options{% \BC{\solution@Color}}\fi \fi \else \eq@addExpandTo\late@options{\TU{0}}% \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@Check@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} % Begin joint package and eqexam %</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 \string\texttt{label} parameter to \string\cs{bChoices}. %} % A new key, \IndexKey{label}\texttt{label=\ameta{name}}, 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} % New key, \IndexKey{insertAt}\texttt{insertAt=\ameta{n}} inserts the content of % the \cs{answersEndHook\darg{\ameta{content}}} at line \ameta{n}. % \begin{macrocode} \def\rmFracPrt#1.#2\@nil{\gdef\intPrt{#1}} \define@key{bchoice}{insertAt}[]{% \let\insertAtMsg\relax \def\rmFr@cPrt##1.##2\@nil{\def\intP@rt{##1}} \def\@rgi{#1}\ifx\@rgi\@empty \def\insertAtMsg{\PackageWarning{exerquiz} {An empty value for insertAt, will use\MessageBreak the default positioning}}% \else \rmFr@cPrt#1.\@nil \expandafter\@tempcnta\intP@rt\relax \ifnum\@tempcnta<\@ne \def\insertAtMsg{\PackageWarning{exerquiz} {insertAt=#1: The value (#1) of insertAt must be\MessageBreak greater than zero. Using the default\MessageBreak positioning instead}} \else \xdef\insertAnsHookAt{\the\@tempcnta} \fi \fi \insertAtMsg } % dps21-5-15 \let\insertAnsHookAt\@empty % \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 \global\let\@tempholdSaveChoice\@empty \global\let\bChoiceLabel\@empty \setkeys{bchoice}{#1}% dps21-5-15 \def\aeb@RowCnt{0}\global\eq@tabColCnt\z@ \ifnum\aeb@numCols=\@ne % 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 \string\texttt{label} parameter % of \string\cs{bChoices}: \string\cs{eq@saveAns}, \string\cs{eq@displayAns}, % \string\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}>\tw@ \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}<\tw@\else \ifnum\@nameuse{NumAns\eq@namearg}>\tw@\relax \else\leavevmode\space\fi\eqAnd\space\fi } \long\def\eq@displayAns#1{\advance\@tempcnta\@ne \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 \string\cs{useSavedAns}, \string\cs{useSavedAlts}, and \string\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{} % \end{macrocode} % This command gets, and sets the list of alternatives % \begin{macrocode} \long\def\@getListAns\Ans#1\eAns{%\@@par \@incRowCnt % dps21-5-16 % \end{macrocode} % We record the list as we process each item. % \begin{macrocode} \eq@saveAns#1\eAns \Ans#1% dps21-5-15 \@insertAnsHookAt % dps21-5-16 \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{% \@incRowCnt % dps21-5-16 \let\eq@tabSep\@empty \xdef\numShortCols{#1}% %\typeout{!! compare #1 with \aeb@numCols}% \@tempcnta\aeb@numCols % dps21-5-16 \advance\@tempcnta-#1 %\typeout{!! need \the\@tempcnta\space more tabs}% \global\let\nAddT@bs\@empty \@whilenum\@tempcnta>\z@\do {\g@addto@macro\nAddT@bs{&}\advance\@tempcnta\m@ne}% %\toks@=\expandafter{\nAddT@bs}\typeout{!! \the\toks@}% \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@tabColCnt\@ne % dps21-5-16 \let\@save@tabSep\eq@tabSep % dps21-5-16 \ifnum\eq@tabColCnt=\numShortCols \global\eq@tabColCnt\z@ % dps21-5-16 \xdef\eq@tabSep{% \noexpand\nAddT@bs \noexpand\@insertAnsHookAt \noexpand\\ \noalign{\kern\@rowskip\relax}\noexpand\@incRowCnt }% \else \gdef\eq@tabSep{&}% \fi \@ifnextchar\eChoices{\@save@tabSep\Ans#1\rowsep{\rowsep@default}% \nAddT@bs\@insertAnsHookAt\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{% % \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 \string\texttt{\string\#1} to \string\cs{the}\string\cs{@temptokena} Fixing % a nasty bug. Reported by Christopher C.} % \begin{macrocode} \def\defineEachAns#1{\advance\eqtmpcnta\@ne \@temptokena={#1}\csarg\xdef {SavedAns\bChoiceLabel-Idx\the\eqtmpcnta}{\the\@temptokena}% \ifsolutionsonly\else {\let\\\relax\eq@IWDefs{\string \csarg\string\gdef{SavedAns\bChoiceLabel-Idx\the\eqtmpcnta}% {\the\@temptokena}}}% \fi } \def\defineEachChoice#1{\advance\eqtmpcnta\@ne \@temptokena={#1}\csarg\xdef {SavedAlts\bChoiceLabel-Idx\the\eqtmpcnta}% {\the\@temptokena}\ifsolutionsonly\else {\let\\\relax\eq@IWDefs{\string \csarg\string \gdef{SavedAlts\bChoiceLabel-Idx\the\eqtmpcnta}% {\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 \eqtmpcnta\z@\let\\\defineEachAns\the\toks@ \xdef\@currNCntAns{\the\eqtmpcnta}\csarg \xdef{NumAns\bChoiceLabel}{\@currNCntAns}% \ifsolutionsonly\else{\eq@IWDefs{\string \csarg\string\gdef{NumAns\bChoiceLabel}{\the\eqtmpcnta}}}\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 \eqtmpcnta\z@\relax\let\\\defineEachChoice\the\toks@ \eqtmpcnta\@ne\toks@={}%{\ignorespaces\@gobble}% \loop \edef\temp@exp{\the\toks@\noexpand\\{% \noexpand\useSavedAlts[\the\eqtmpcnta]{\bChoiceLabel} \noexpand\useSavedAns[\the\eqtmpcnta]{\bChoiceLabel}}}% \toks@=\expandafter{\temp@exp}% \ifnum\eqtmpcnta<\@currNCntAns\relax \advance\eqtmpcnta\@ne \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} % end joint package and eqexam %</package|eqexam> % \end{macrocode} % \begin{macrocode} % Begin randomize segment %<*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 \string\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} % \DescribeMacro{\writeSeedToSolnFile} writes the current % value of \cs{randomi} to the solution file. May be useful in randomizing choices % in the solution file in the same order they were randomized in the main document. % \changes{v7.8h}{2017/04/14}{Added \string\cs{writeSeedToSolnFile}} % \begin{macrocode} \def\writeSeedToSolnFile{\writeT@ExSolns{\string\randomi=\the\randomi}} % \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 \key{random} key. If \key{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 \string\cs{bChoices} % and \string\cs{eChoices}. % } % \changes{v8.6.2}{2021/01/20}{Incorporated \string\cs{if@DoNotRandomize} % into the \string\cs{@ansChoices} macro for MC and MS questions} % \changes{v8.7}{2021/05/15}{Support for the \texttt{insertAt} key % of \cs{bChoices}; initialize macro \string\cs{aeb@numRows}} % \begin{macrocode} \def\@ansChoices[#1]{% \global\let\@tempholdSaveAns\@empty \global\let\@tempholdSaveChoice\@empty \global\let\bChoiceLabel\@empty \ifeq@randomizeallChoices \setkeys{bchoice}{#1,random=true}\else \setkeys{bchoice}{#1}\fi \global\eq@tabColCnt\z@ \def\aeb@RowCnt{0}% dps21-5-15 \if@DoNotRandomize\eq@randomizeChoicesfalse\fi \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=\@ne % 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} \eqtmpcnta\z@\aeb@hold=\expandafter{\@temphold}\def\@temphold{}% \expandafter\@tfor\expandafter \@temp\expandafter:\expandafter=\the\aeb@hold \do {% \advance\eqtmpcnta\@ne \ifnum\eqtmpcnta=\aeb@ranChoice\relax \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\m@ne \ifnum\aeb@numChoices=\z@ \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{\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 \string\cs{REF} in support of the \string\texttt{showgrayletters} option. %} %\changes{v6.4d}{2011/07/14}{% % Correct \string\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 \string\cs{useMCCircles} and \string\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{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. % \changes{v8.8.2}{2021/05/29}{Check for dupl oQuestion names} % \begin{macrocode} \let\oqpriorhook\@empty \newenvironment{oQuestion}[1]{\csarg % dps5-29 \ifx{oQName-#1}\relax \csarg\gdef{oQName-#1}{1}\else \PackageWarning{exerquiz}{% The quiz name '#1' is already used,\MessageBreak please choose a quiz name unique throughout\MessageBreak this document}\csarg\gdef{oQName-#1}{0}% \fi % \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}% \g@addto@macro\ListOfSQuizNames{,#1}\let\@qzsolndest\@empty \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 % \end{macrocode} % (2021/05/07) Reset \cs{eqpriorhook} at end of \env{oQuestions} environment. % \changes{v8.7.6}{2021/05/07}{Reset \string\cs{eqpriorhook} at end of \string\env{oQuestions} environment} % \begin{macrocode} \global\let\oqpriorhook\@empty \aftergroup\ignorespaces } \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 \string\cs{negPointsAllowed} to allow negative scores on quizzes. This is only relevant % when the quiz has a \string\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 \string\cs{requireAlertBox} to turn off the ``Do not show this message again'' checkbox for objective questions. %} %The alert box displays the message \DescribeMacro{\doNotShowAgainMsg}\cs{doNotShowAgainMsg}, which by default is %``Do not show this message again''. This message appear when \DescribeMacro{\allowNoAlertBox}\cs{allowNoAlertBox} (the default) % is in effect. % \begin{macrocode} \def\requireAlertBox{\def\bcheckboxused{false}} \def\allowNoAlertBox{\def\bcheckboxused{true}} \allowNoAlertBox % \end{macrocode} % \end{macro} % When \DescribeMacro{\useCkBxAlertsOn}\cs{useCkBxAlertsOn} is expanded in the preamble, alerts % generated by links (usually a short-quiz) uses a check box that allows its dismissal % subsequently. \DescribeMacro{\useCkBxAlertsOff}\cs{useCkBxAlertsOff} reverts the behavior % to alert boxes with no check box, the old default. % \changes{v8.8.5}{2021/10/03}{Added \string\cs{useCkBxAlertsOn}} % \begin{macrocode} \def\useCkBxAlertsOn{\def\buseckbx{true}} % dpsx \def\useCkBxAlertsOff{\def\buseckbx{false}} \useCkBxAlertsOn % \end{macrocode} % \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. % % \changes{v8.0}{2017/08/08}{Support for multi-letter variables and alternate appearances} % \textbf{Multi-letter variables.} Beginning with v8.0 (2017/08/08) support for multi-letter variables and appearance replacement % is added. Within the \texttt{\#3}, use the following notation: %\begin{verbatim} % (x\rpl{alpha}{y}z) %\end{verbatim} %This declares three variables, \texttt{x}, \texttt{alpha}, and \texttt{z}. What in fact is %taking place is that \texttt{alpha} is replaced by \texttt{y} and processing continues from there. % % \textbf{Alternate appearances.} Additionally, there is now a scheme for replacing the variables % with alternate appearances. %\begin{verbatim} % (x\rpl{alpha->\\u03B1}{y}z) %\end{verbatim} %The arrow notation (\texttt{->}) tells \pkg{exerquiz} to replace \texttt{alpha} with the unicode character %\verb~\u03B1~ (note the double backslash above), which is the Greek letter alpha ($\alpha$). % % \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} % \changes{v8.1}{2017/09/02}{Sanitize superscript before reading parameters in \string\cs{RespBoxMath}} % \begin{macrocode} \newcommand\RespBoxNT{\RespBoxMath} \newcommand\RespBox{\RespBoxMath} % \end{macrocode} % (2018/03/21) Exclude unicode from \cs{RespBoxMath} % \changes{v8.2.2}{2018/03/21}{Exclude unicode from \string\cs{RespBoxMath}} % \changes{v8.2.3}{2018/09/12}{Made subscript catode 12 in \string\cs{RespBoxMath}} % \changes{v8.2.4}{2018/09/24}{Defined \string\cs{eqsanitize} for \string\cs{RespBoxMath}} % \begin{macrocode} \def\eqsanitize{\@makeother\_\@makeother\^\@makeother\&} \newcommand\RespBoxMath{\def\rbFlag{0}\begingroup\Hy@unicodefalse \eqsanitize\@RespBox} % \end{macrocode} % Within \cs{RespBoxMath}, \cs{rpl} (\cs{rpl=\texttt{\underbar{r}e\underbar{pl}ace}}) is \cs{let} to \cs{eq@rpl}. The command \cs{rpl}, used % within the variable argument of \cs{RespBoxMath}, declares a multi-letter variable. There are % two styles, one an extension of the other: (1) |\rpl{alpha}{x}|, declares that the multi-letter % variable `\texttt{alpha}' is the same as the usual single variable `\texttt{x}'; (2) |\rpl{alpha->\\u03B1}{x}| declare % the variable `\texttt{alpha}' to be the same as `\texttt{x}', it also says to use |\\u0381| as the % format appearance of `\texttt{alpha}'. % \changes{v7.9a}{2017/08/05}{Added \string\cs{eq@rpl} to support multi-letter variables} % \begin{macrocode} \def\eq@rpl#1#2{_rplVarsBy('#1','#2')@} % dps17 % \end{macrocode} % \textbf{Correcting an incorrect entry.} A variation on the objective style math problem is to initially populate the response box with an % incorrect answer and ask the student to correct it. (Good for future teachers.) The problem type set % straightforward when multi-variables are not used, just specify the \cs{V} and \cs{DV} keys in the % optional argument of \cs{RespBoxMath}. When multi-variables are used, we enclose the question % with \DescribeMacro{\bInitAltAppr}\cs{bInitAltAppr}/\allowbreak\DescribeMacro{\eInitAltAppr}\cs{eInitAltAppr}. There are two variations, the first is for % a non-\app{dvips/Distiller} workflow (document JavaScript are embedded at the creation of the PDF; % the second variation is with Distiller, where the document JavaScript is embedded with \app{Acrobat} % after the creation of the PDF. In the latter case, the JavaScript functions used below (\texttt{processMathVars}, % \texttt{getSubstValue}, and \texttt{RespBoxAppr} are not available yet when the document is initially % opened in \app{Acrobat}. As a result, an exception is thrown. When the exception is thrown, % \texttt{app.setTimeOut} gives a delay and the field is reset after 25 milliseconds, this causes % the \emph{initial} alternate appearance to appear, if that is desired. % \changes{v8.1a}{2017/09/03}{Added \string\cs{bInitAltAppr}/\string\allowbreak\string\cs{eInitAltAppr} % command pair for setting the initial alternate appearance} % \begin{macrocode} \ifnum\eq@drivernum=\z@ \def\RorRT{\r\t}\else\def\RorRT{\r}\fi % \end{macrocode} % The following commands are in support of the \cs{bInitAltAppr}/\allowbreak\cs{eInitAltAppr} command pair. % \begin{macrocode} \def\toAltApprCnt{0}\def\toAltApprVar{_toAltAppr\toAltApprCnt} \def\toAltApprCntInc{{\@tempcnta=\toAltApprCnt\relax \advance\@tempcnta\@ne\xdef\toAltApprCnt{\the\@tempcnta}}} \def\setCoreInitAltAppr{% var\eqSP_substVars=\indepVars;\RorRT var\eqSP_mathVars=processMathVars(_substVars);\RorRT var\eqSP_substValue=getSubstValue(_substVars,event.value);\RorRT event.value=RespBoxAppr(event);\RorRT getSubstValue.aSubsts=[];% } % \end{macrocode} % \leavevmode\DescribeMacro{\bInitAltAppr}\DescribeMacro{\eInitAltAppr} This command pair % are used to set the initial value of a \cs{RespBoxMath} field. % See the {Acro\negthinspace\TeX} article \url{http://www.acrotex.net/blog/?p=1335} % for a discussion of the use of \cs{bInitAltAppr}/\allowbreak % \cs{bInitAltAppr}. % An alternate method is to use \cs{formatInitAltApprs} directly % \begin{macrocode} \def\bInitAltAppr{\ifShowAppr \def\ShowApprSAVE{true}\toAltApprCntInc\ShowApprfalse \def\eqAddAAFormat{\ifnum\eq@drivernum=\z@ try\eqLBr\RorRT\fi \setCoreInitAltAppr\ifnum\eq@drivernum=\z@\r\eqRBr catch(e){\RorRT var\eqSP\toAltApprVar=% app.setTimeOut('this.resetForm("'+event.target.name+'");% app.clearTimeOut(\toAltApprVar);',250);\r}\fi}\else \def\ShowApprSAVE{false}\fi } \def\eInitAltAppr{\@nameuse{ShowAppr\ShowApprSAVE}% \ifShowAppr\altApprOn\let\eqAddAAFormat\@empty\fi} % \end{macrocode} % Get any changes in the appearance of the text box % \changes{v6.4c}{2011/07/01}{\string\cs{RespBoxMath} now records its lists of % independent variables under the global variable \string\texttt{\_mathVars}.} % \begin{macrocode} \begin{defineJS}[\makeesc\*\makecmt\%]{\AAKqRespBoxMath} % \end{macrocode} % \cs{AAKqRespBoxMath} is the default keystroke action script for \cs{RespBoxMath} % \begin{macrocode} if(event.willCommit){ RecordPointValue(*eqPTs,*thequestionno*ifx*grpquestions*eq@One,% *thegrpquestionno,*grpPointValue,*grpTotalWeight,% "*grpEvalFunction"*fi); RecordProblemType("*eqQT",*thequestionno); % \end{macrocode} % If there are substitute variables, \cs{ifSubstVars} is true, and the script below % are the lines developed in support of multi-letter variables. % \begin{macrocode} *ifSubstVars% var _substVars=*indepVars; var _mathVars=processMathVars(_substVars); var _substValue=getSubstValue(_substVars,event.value); var _substAns=getSubstValue(_substVars,"*eqCorrectAns"); var retn=*processJSfunc(*rbArgs,% *compareJSfunc,_substValue);*else% var _mathVars=*indepVars; var retn=*processJSfunc(*rbArgs,*compareJSfunc);*fi ProcUserResp(retn,event.value,*thequestionno,0% *ifx*grpquestions*eq@One,*thegrpquestionno*fi); } if (!isQuizInitialized("*currQuiz")) { *eqObjAlert*eqAppAlert(InitMsg("*bqlabelISO"),3); event.rc = false;% *ifx*eqAddAAKeystroke*@empty*else *eqAddAAKeystroke*fi } \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\eqAddAAFormat\@empty % \end{macrocode} % \DescribeMacro{\eqSP}\cs{eqSP} is a space character to keep \textsf{dvips} from breaking lines at space. % \begin{macrocode} \def\eqSP{\string\040} \def\eqLBr{\string\173} \def\eqRBr{\string\175} % \end{macrocode} % Keystroke action for \cs{RespBoxMath}. % \begin{macrocode} \begin{defineJS}[\makeesc\!\makecmt\%]{\rbmAAKey} if(event.willCommit) { !ifSubstVars% % \end{macrocode} % If there are multi-letter variables (\cs{SubstVarstrue}), we insert the code developed. % \begin{macrocode} var _substVars=!indepVars; var _mathVars=processMathVars(_substVars); var _substValue=getSubstValue(_substVars,event.value); var _substAns=getSubstValue(_substVars,"!eqCorrectAns"); var retn=!processJSfunc(!rbArgs,% !compareJSfunc,_substValue);!else% var _mathVars=!indepVars; var retn=!processJSfunc(!rbArgs,!compareJSfunc);!fi% !ifx!@sqTurnOffAlerts!eq@One OnBlurRespBox(retn,"!curr@quiz");!fi% !ifx!eqAddAAKeystroke!@empty!else !eqAddAAKeystroke!fi } \end{defineJS} % \end{macrocode} % The actions of \cs{RespBoxMath} % \begin{macrocode} \def\@@RespBoxMathActions{% \AA{\if\eqQuizType\isQZ \AAKeystroke{\AAKqRespBoxMath} \AAFormat{\ifShowAppr\ifSubstVars\ifarrowDelim % \end{macrocode} % The \texttt{RespBoxApp()} JavaScript function replaces the multi-letter variable (\texttt{alpha}, for example) % with its appearance (|\\u03B1|, eg). % \begin{macrocode} try{event.value=RespBoxAppr(event);}catch(e){}\r \fi\fi\fi\eqAddAAFormat} \else \AAKeystroke{\rbmAAKey} \AAFormat{\ifShowAppr\ifSubstVars\ifarrowDelim try{event.value=RespBoxAppr(event);}catch(e){}\r\fi\fi\fi \eqAddAAFormat}% \AAOnFocus{\JS{var retn = null;}}% \AAOnBlur{\JS{OnBlurRespBox(null,"\curr@quiz");}}% \fi } } \def\annot@subtype@rbm{rbm} \newcommand\@RespBox[1][] {% \edef\annot@subtype{\annot@subtype@rbm}% \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\let\rpl\eq@rpl \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. % \changes{v8.1}{2017/09/02}{Sanitize superscript before \string\cs{pdfstringdef} is applied} % \changes{v8.1c}{2017/09/30}{Define \string\cs{eqCorrectAnsTeX} to display the answer % in preview mode.} % \begin{macrocode} \def\eq@RespBox#1{\pdfstringdef\eqCorrectAns{#1}% \gdef\eqCorrectAnsTeX{#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"}\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 suggestion 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} \newif\ifarrowDelim\arrowDelimfalse % \end{macrocode} % The problem is to detect when \cs{indepVars} contains the arrow notation (\verb~->~), this signals % that the appearance of the user's response is to be replaced by another appearance. The command % \cs{GiiRpli} attempts to do just that, it sets \cs{arrowDelim} to true if an arrow is detectect, % otherwise, to false. % \begin{macrocode} \def\rpl@#1#2{\rpl@i#1->\@nil} \def\rpl@i#1->#2\@nil{\def\argii{#2}\ifx\argii\@empty\else \global\arrowDelimtrue\fi} \def\GiiRpli#1{\global\arrowDelimfalse\GiiRplii#1\rpl{}{}\@nil} \def\GiiRplii#1\rpl#2#3#4\@nil{\def\argiv{#4}% \ifx\argiv\@empty\let\eq@next\relax\else \rpl@{#2}{#3}\ifarrowDelim\let\eq@next\relax\else \def\eq@next{\GiiRplii#4\@nil}\fi\fi \eq@next} % \end{macrocode} % \textbf{Is arrow specified?} \cs{isAltApprSpec} determines whether the delimiter `\texttt{->}' is present, if it is % we set |\global\arrowDelimtrue|, otherwise it is globally set to false. Its supporting % code is listed above: \cs{rpl@} and \cs{GiiRpli} % \begin{macrocode} \def\isAltApprSpec#1{\bgroup\if\frstIsrpl\eq@YES\GiiRpli{#1}\else \expandafter\GiiRpli\expandafter{#1}\fi\egroup} % dps17 % \end{macrocode} % If the independent variables are passed as a command, we need % to expand first; on the other hand, if the argument is literal and begins with \cs{rpl} % we do not expand first. This is to get a correct determination of \cs{ifSubstVars} % and \cs{ifarrowDelim}. % \begin{macrocode} \def\isFrstrpl#1#2\@nil{\ifx#1\rpl\let\frstIsrpl\eq@YES\else \let\frstIsrpl\eq@NO\fi} % \end{macrocode} % Macros to count the number of independent variables % \begin{macrocode} \def\cntComm@s#1{\@tempcnta\z@\expandafter\cntComm@si#1,,\@nil} \def\cntComm@si#1,#2,\@nil{\def\argii{#2}\ifx\argii\@empty \def\eq@next{\edef\nC{\the\@tempcnta}}\else \advance\@tempcnta\@ne\def\eq@next{\cntComm@si#2,\@nil}\fi \eq@next}\def\eq@SC{;}\def\rplSofT#1#2{#2} \def\cntVars#1{\let\rpl\rplSofT\edef\eV@rs{#1}\let\rpl\eq@rpl \cntComm@s{\eV@rs}\ifnum\nC>\z@ \@tempcnta\nC\relax\advance\@tempcnta\@ne \xdef\nV{\the\@tempcnta}\else\@tempcnta\z@ \expandafter\cntVarsi\eV@rs;\@nil\fi} \def\cntVarsi#1#2\@nil{\def\argii{#2}% \ifx\argii\eq@SC\def\eq@next{\advance\@tempcnta\@ne \edef\nV{\the\@tempcnta}}\else\advance\@tempcnta\@ne \def\eq@next{\cntVarsi#2\@nil}\fi \eq@next} \def\eq@X{x} % \end{macrocode} % It there repetition? (\texttt{[0,1]*3}, eg) % \begin{macrocode} \def\eq@isThereRept#1{\let\eq@isRept\eq@Zero\expandafter \eq@isThereRepti#1*\@nil} \def\eq@isThereRepti#1*#2\@nil{\def\argii{#2}\ifx\argii\@empty \let\eq@isRept\eq@Zero\else\let\eq@isRept\eq@One\fi} % \end{macrocode} % Expand repetition if present (\texttt{[0,1]*3=[0,1]x[0,1]x[0,1]}, eg) % \begin{macrocode} \def\eq@obeyReptOfIntrvls#1{% \expandafter\eq@isThereRept\expandafter{#1}% sets \eq@isRept \if\eq@isRept\eq@Zero\relax\let\eq@interv@ls\@empty\expandafter \g@addto@macro\expandafter\eq@interv@ls \expandafter{#1}\let\eq@next\relax\else\let\eq@interv@ls\@gobble \def\eq@next{\expandafter \eq@obeyReptOfIntrvlsi#1x[]x\@nil}\fi\eq@next} \def\eq@obeyReptOfIntrvlsi#1[#2]#3#4x#5\@nil{% \def\argi{#2}\def\argii{#3}\def\argiv{#5}% \ifx\argi\@empty\let\eq@next\relax\else \ifx\argii\eq@X\g@addto@macro\eq@interv@ls{x[#2]}% \def\eq@next{\eq@obeyReptOfIntrvlsi#4x#5x\@nil}\else % repetition of an interval \eq@ddtorepIntrvl{[#2]}{#4}% \def\eq@next{\eq@obeyReptOfIntrvlsi#5x\@nil}\fi \fi \eq@next } \def\eq@ddtorepIntrvl#1#2{\@tempcnta=#2 \eq@ddtorepIntrvli{#1}{#2}} \def\eq@ddtorepIntrvli#1#2{\@whilenum\@tempcnta>\z@\do {\g@addto@macro\eq@interv@ls{x#1}\advance\@tempcnta\m@ne}} % \end{macrocode} % Macros to count the number of intervals. First determine if there % are repetitions if so, expand them \cs{eq@obeyReptOfIntrvls} returns % the expanded intervals in \cs{eq@interv@ls} % \begin{macrocode} \def\cntIv@ls#1{\@tempcnta\z@\expandafter\cntIv@lsi#1xxx\@nil}% % \end{macrocode} % Before counting the intervals, determine if there is repetition, if so % expand those intervals appropriately. % \begin{macrocode} \def\cntIv@lsi#1x#2x\@nil{\def\argii{#2}\ifx\argii\eq@X \advance\@tempcnta\@ne \edef\nI{\the\@tempcnta}\let\eq@next\relax\else \advance\@tempcnta\@ne\def\eq@next{\cntIv@lsi#2x\@nil}\fi \eq@next} % \end{macrocode} % A interval specification might have an intersection in it (\texttt{\&}, so for the purpose % of counting, we count the intervals up to the first ampersand. % \changes{v8.1b}{2017/09/06}{Fixed a problem with the use of \string\cs{RespBoxMath} % when it is within a tabular environment.} % \begin{macrocode} \begingroup\@makeother\& \gdef\eq@ProcIntrvls#1{\expandafter \eq@ProcIntrvlsi#1&&\@nil} \gdef\eq@ProcIntrvlsi#1\@nil{\def\argii{#2}% \ifx\argii\@empty % \end{macrocode} % The intervals do not contain an ampersand. % Expand intervals, if necessary result returns in \cs{eq@interv@ls} % \begin{macrocode} \eq@obeyReptOfIntrvls{#1}% % \end{macrocode} % Count the intervals % \begin{macrocode} \cntIv@ls{\eq@interv@ls}% \else % \end{macrocode} % The intervals contain an ampersand (union of two intervals of equal dimension assumed, % \meta{interval${}_1$}\texttt{\&}\meta{interval${}_1$}). % Expand the first set of union. % \begin{macrocode} \eq@obeyReptOfIntrvls{#1}% % \end{macrocode} % Save this result in \cs{interv@ls} % \begin{macrocode} \edef\interv@ls{\eq@interv@ls}% \cntIv@ls{\eq@interv@ls}% % \end{macrocode} % Expand the second set of union % \begin{macrocode} \eq@obeyReptOfIntrvls{#2}% \edef\eq@interv@ls{\interv@ls&\eq@interv@ls}% \fi } \endgroup % \end{macrocode} % \cs{RespBoxMath} continues here % \begin{macrocode} \def\@eq@RespB@x#1(#2)[#3]#4#5#6{\xdef\@qzsolndest{#3}% dps17 \gdef\indepVars{"#2"}\isFrstrpl#2\@nil \if\frstIsrpl\eq@YES \def\@IVi{#2}\else\expandafter\def\expandafter \@IVi\expandafter{#2}\fi \edef\@IVii{#2}% \ifx\@IVi\@IVii % \end{macrocode} % If \cs{indepVars} (\texttt{\#2}) does not contain \cs{rpl}, the two versions % of \cs{@IVi} and \cs{@IVii} should compare favorably. If they differ, the difference % is due to the presence of \cs{rpl}. % \begin{macrocode} \global\SubstVarsfalse \else \global\SubstVarstrue \isAltApprSpec{#2}% \fi % \end{macrocode} % \textbf{Counting number of variables.} We count the number of independent variables. % \begin{macrocode} \cntVars{#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,% \ifSubstVars_substAns\else"#1"\fi,#4,% \eq@defaultRDPrecision}% \else \def\eq@defaultCompare{diffCompare}% \def\rbArgstmp{\rbFlag,% \ifSubstVars_substAns\else"#1"\fi,#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\eq@chkivIntrvls\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{[0,1]} % \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\eq@chkivIntrvls{\@ifnextchar[{\eq@chkivIntrvlsi}% {\eq@chkivIntrvlsii}} % \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\eq@chkivIntrvlsi#1\\{\eq@ProcIntrvls{#1}% \def\rbArgs{\rbArgstmp,"\eq@interv@ls",_mathVars}% dps17 \@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. We also test for the presence of the optional % of a customized comparison function, parameter \texttt{\#9} % \begin{macrocode} \def\eq@chkivIntrvlsii#1\\#2{\def\nI{1}% \def\rbArgs{\rbArgstmp,"[#1,#2]",_mathVars}% \@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\medskip % \begin{macrocode} \def\@eq@@RespBox[#1]{\@ifstar{\jsRespBox[#1]}% {\jsRespBox[#1]{ProcResp}}} \def\eq@ProcRespIntervals{ProcRespIntervals} \def\eq@ProcRespSetNum{ProcRespSetNum} \def\eq@ProcRespSetSym{ProcRespSetSym} \def\eq@ProcRespEvalEq{ProcRespEvalEq} \def\eq@ProcRespEvalEqNonZero{ProcRespEvalEqNonZero} \def\eq@ProcRespEvalEqList{ProcRespEvalEqList} \def\eq@ProcRespEvalEqListNonZero{ProcRespEvalEqListNonZero} \def\jsRespBox[#1]#2{\def\compareJSfunc{#1}% \def\processJSfunc{#2}\gdef\g@processJSfunc{#2}% 01/11 \ifnum\nV=\nI\relax\else \ifx\processJSfunc\eq@ProcRespSetNum\else \ifx\processJSfunc\eq@ProcRespSetSym\else \ifx\processJSfunc\eq@ProcRespEvalEq\else \ifx\processJSfunc\eq@ProcRespEvalEqNonZero\else \ifx\processJSfunc\eq@ProcRespEvalEqList\else \ifx\processJSfunc\eq@ProcRespEvalEqListNonZero\else \PackageWarning{exerquiz}{The number of variables does not match\MessageBreak the number of intervals. The problem\MessageBreak may not evaluate properly}\fi\fi\fi\fi\fi\fi\fi % \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 % \end{macrocode} % Remove parentheses from the argument of \cs{eq@recordCorrAns}. % \changes{v8.2}{2018/03/18}{Corrected \string\cs{eq@recordCorrAns}} % \changes{v8.2.1}{2018/03/19}{If not a math group, record this data} % \begin{macrocode} \ifx\grpquestions\eq@Zero \eq@recordCorrAns{"\eqCorrectAns"}\fi \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 % hbox \endgroup % \RespBoxMath } % \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\eqCorrectAnsTeX } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \begin{macrocode} %</package> %<*rbmIntrvl> % \end{macrocode} % \subsubsection{The \texorpdfstring{\protect\cs}{\textbackslash}{rbmIntrvl} command}\label{ss:rbmi} % This code segment is input into \pkg{exerquiz} when the \opt{userbmintrvl} is specified. % The commands of this section are motivated by an {Acro\negthinspace\TeX} user (Thor G). He % wants to ask his students to make a series of calculations, the result of % which is to be entered into a \cs{RespBoxMath} input box. He is willing to % accept the response as correct if the response falls into a designated % interval $[a,b]$. % % Two commands are defined, one internal (\cs{c@lcEPInfo}) and the other public {\cs{rbmIntrvl}}. % % The first command \cs{c@lcEPInfo} takes as its parameters an (closed) interval of numbers. % It calculates the midpoint \DescribeMacro\intrCAns\cs{intrCAns} and % \DescribeMacro\intrPrec\cs{intrPrec}. The first number can be used as a (representative) point % value of the answer; the second is used as the precision parameter of \cs{RespBoxMath}. % \changes{v8.7}{2021/04/24}{Added \string\cs{rbmIntrvl}} % \begin{macrocode} \def\c@lcEPInfo[#1,#2]{% \setlength{\eflength}{(#1pt+#2pt)/2}% \edef\intrCAns{\strip@pt\eflength}% \setlength{\eflength}{(#2pt-#1pt)/2}% \edef\intrPrec{\strip@pt\eflength}% } % \end{macrocode} % \DescribeMacro\rbmIntrvl\hskip-\marginparsep\texttt{\darg{[\meta{a{\upshape,}b}]}} % This macro takes as its first argument the interval you want the student response % to fall into. The command expands \cs{c@lcEPInfo} then \cs{RespBoxMath}. Use \cs{intrCAns} and \cs{intrPrec} % in the arguments of \cs{RespBoxMath}. % \begin{macrocode} \newcommand{\rbmIntrvl}[1]{\c@lcEPInfo#1\RespBoxMath} % \end{macrocode} % \cs{rbmIntrvl} has implied arguments, those of \cs{RespBoxMath}. Below is a simple example. %\begin{Verbatim}[xleftmargin=\parindent,fontsize=\small,codes={\catcode`\%=9}] %\rbmIntrvl{[6.40,6.90]}{\intrCAns}{1}{\intrPrec}{[0,1]} %\end{Verbatim} %Following the interval declaration are the parameters of \cs{RespBoxMath}. The first %one following the interval is the correct answer (\cs{intrCAns}), the midpoint of the interval; %the third argument following the interval is the precision parameter of \cs{RespBoxMath}, %which is taken to be \cs{intrPrec}, the half-width of the interval. % \begin{macrocode} %</rbmIntrvl> %<*package> % \end{macrocode} % We input the definition of \cs{rbmIntrvl} here, if the \opt{userbmintrvl} % option is taken. % \begin{macrocode} \inputRBMICode % \end{macrocode} %\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(% \ifx\@sqTurnOffAlerts\eq@One retn\else null\fi,"\curr@quiz");} \def\eqObjAlertIfFalse{if (false) } \def\eqObjAlert{% \ifx\eqQuizType\isQZ\ifx\eq@online\eq@YES\ifeq@noquizsolutions \else\eqObjAlertIfFalse\fi\fi\fi} \def\eqAppAlert{eqAppAlert} % \end{macrocode} % Keystroke action for \cs{RespBoxTxt} for a quiz % \changes{v8.6.4}{2021/02/15}{Corrected coding of \string\cs{AAKqRespBoxTxt}, wrong % escape char} % \begin{macrocode} \begin{defineJS}[\makeesc\*\makecmt\%]{\AAKqRespBoxTxt} if(event.willCommit){ RecordPointValue(*eqPTs,*thequestionno*ifx*grpquestions*eq@One,% *thegrpquestionno,*grpPointValue,*grpTotalWeight,% "*grpEvalFunction"*fi); RecordProblemType("*eqQT",*thequestionno); var retn = ProcRespTxt(*rbTxtAlt); ProcUserResp(retn,event.value,*thequestionno,0% *ifx*grpquestions*eq@One,*thegrpquestionno*fi); } if (!isQuizInitialized("*currQuiz")) { *eqObjAlert*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 }% } % \end{macrocode} % The keystroke action for \cs{RespBoxTxt} for a short-quiz % \changes{v8.6.5}{2021/02/21}{Removed comment character from last line % of \string\cs{rbtAAKey}} % \begin{macrocode} \begin{defineJS}[\makeesc\!\makecmt\%]{\rbtAAKey} if(event.willCommit) { var retn = ProcRespTxt(!rbTxtAlt);% !ifx!@sqTurnOffAlerts!eq@One !RespBoxTxtOnBlur!fi }% !ifx!eqAddAAKeystroke!@empty!else% !eqAddAAKeystroke!fi \end{defineJS} \def\@@RespBoxTxtActions{% \AA{\if\eqQuizType\isQZ % \end{macrocode} % Added \cs{eqAddAAKeystroke} to \cs{@@RespBoxTxtActions} % \changes{v7.8i}{2017/07/21}{Added \string\cs{eqAddAAKeystroke} to \string\cs{@@RespBoxTxtActions}} % \begin{macrocode} \AAKeystroke{\AAKqRespBoxTxt\eqAddAAKeystroke} \AAFormat{\eqAddAAFormat} \else \AAKeystroke{\rbtAAKey} \AAFormat{\eqAddAAFormat} \AAOnFocus{\JS{var\eqSP retn=null;}} % \end{macrocode} % (2005/12/02) 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} \ifx\@sqTurnOffAlerts\eq@Zero \AAOnBlur{\JS{\RespBoxTxtOnBlur}}\fi \fi } } \def\annot@subtype@rbt{rbt} \newcommand\@RespBoxTxt[1][]{% \edef\annot@subtype{\annot@subtype@rbt}% \eq@AddProbToQzQuesList \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=\@ne % \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 \eqtmpcnta=#4\relax\ifnum\eqtmpcnta>\z@\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\eqtmpcnta\m@ne \ifnum\eqtmpcnta=\z@ \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} % \DescribeMacro{\txtRef}\hskip-\marginparsep\texttt{\darg{\ameta{label}}} % The \cs{RespBoxTxt} can be used for a matching-type question. We define a special % \cs{ref}-type command that produces plain text. Refer to demo file % \texttt{qz-matching.tex} for details. % \changes{v8.6.4}{2021/02/15}{Support for matching-type question based in % \string\cs{RespBoxTxt}} % \begin{macrocode} \def\txtRef#1{\@ifundefined{r@#1} {??}{\aeb@exiii\@firstoffive\csname r@#1\endcsname}} % \end{macrocode} % \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} % \RespBoxTxtPC[#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}[\makeesc\*\makecmt\%]{\AAKqRespBoxTxtPC} if(event.willCommit){ RecordPointValue(*eqPTs,*thequestionno*ifx*grpquestions*eq@One,% *thegrpquestionno,*grpPointValue,*grpTotalWeight,% "*grpEvalFunction"*fi); RecordProblemType("*eqQT",*thequestionno); var retn = ProcRespTxtPC(*rbTxtAlt); *ifx*grpquestions*eq@One% ProbValue[*thequestionno][3+*thegrpquestionno]% =ProcRespTxtPC.txtPCpCr;*else% ProbValue[*thequestionno]=ProcRespTxtPC.txtPCpCr;*fi ProcUserResp(retn,event.value,*thequestionno,0% *ifx*grpquestions*eq@One,*thegrpquestionno*fi); } if (!isQuizInitialized("*currQuiz")) { *eqObjAlert*eqAppAlert(InitMsg("*bqlabelISO"),3); event.rc = false; } \end{defineJS} \begin{defineJS}[\makeesc\!\makecmt\%]{\rbtPCAAKey} if(event.willCommit) { retn = ProcRespTxtPC(!rbTxtAlt);% !ifx!@sqTurnOffAlerts!eq@One !RespBoxTxtOnBlur!fi% } \end{defineJS} \def\@@RespBoxTxtPCActions{% \AA{% \if\eqQuizType\isQZ \AAKeystroke{\AAKqRespBoxTxtPC} \else \AAKeystroke{\rbtPCAAKey} \AAOnFocus{\JS{var\eqSP retn=null;}} \ifx\@sqTurnOffAlerts\eq@Zero \AAOnBlur{\JS{\RespBoxTxtOnBlur}}\fi \fi } } % \end{macrocode} % Here is the beginning of \cs{RespBoxTxtPC}. % \begin{macrocode} \newcommand{\RespBoxTxtPC}{\def\rbFlag{0}\@RespBoxTxtPC} \def\annot@subtype@rbtpc{rbtpc} \newcommand\@RespBoxTxtPC[1][]{% \edef\annot@subtype{\annot@subtype@rbtpc}% \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 \eqtmpcnta=#3\relax\ifnum\eqtmpcnta>\z@\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\eqtmpcnta\m@ne \ifnum\eqtmpcnta=\z@ \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} % \begin{macro}{\SpellCheck}\hskip-\marginparsep\texttt{[\ameta{options}]} % This command is designed to be used with text fill-in questions; the action of this button % allows the user to correct spelling, but it does record the number of initially misspelled words. % The placement of this field is after the text field (\cs{RespBoxTxt} or \cs{RespBoxTxtPC}) so % it can pick up on the field name. The root name of this field is \texttt{spl}. Two helper commands % are defined: \DescribeMacro{\splChkCA}\cmd{\splChkCA} and \DescribeMacro{\splChkTU}\cmd{\splChkTU}. % \changes{v8.5.11}{2020/11/11}{Added \string\cs{SpellCheck}} % \begin{macrocode} \def\afterSplChkActn#1{\def\@fterSplChkActn{\r #1}} \let\@fterSplChkActn\@empty \newcommand{\splChkCA}{Check} \newcommand{\splChkTU}{Check spelling} \newcommand\SpellCheck[1][]{% \pushButton[\CA{\splChkCA}\TU{\splChkTU}\S{S} #1\A{\JS{% \ifx\grpquestions\eq@One var targetFldName=% "grpobj.\curr@quiz.\thequestionno.\thegrpquestionno"; \else \ifx\annot@subtype\annot@subtype@rbe var targetFldName="essay.\curr@quiz.\thequestionno"; \else var targetFldName="obj.\curr@quiz.\thequestionno"; \fi \fi\r var splErrors=checkTheSpelling(targetFldName);\@fterSplChkActn }}]{spl.\curr@quiz.\thequestionno}{}{11bp}} % \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 server-side script for storage % in a database. The instructor can later bring up the student's response % and assign a grade. Syntax: %\begin{quote}\ttfamily % \string\RespBoxEssay[\ameta{opts}][\ameta{dest}]\darg{\ameta{wd}}\darg{\ameta{ht}}\\[3pt] % \string\RespBoxEssay[\ameta{opts}]*\darg{\ameta{wd}}\darg{\ameta{ht}} % \end{quote} % The second argument declares the problem has a \env{solution} file; we define the target % of the solution two ways: an explicit \ameta{dest} string or a star (\texttt*), where % the destination is automatically named. If you use \ameta{dest}, you must have % a first optional argument \ameta{opts}, even if its only empty (\texttt{[]}), to correctly % parse this construction. % \changes{v8.3}{2019/08/13}{\string\env{solution} environment now defined for % \string\cs{RespBoxEssay}} % \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}% } % \end{macrocode} % Begin the \cs{RespBoxEassay} command. % \begin{macrocode} \def\annot@subtype@rbe{rbe} \newcommand\RespBoxEssay[1][]{\edef\annot@subtype{\annot@subtype@rbe}% \def\rbe@rgi{#1}\RespBoxEssay@i} \def\RespBoxEssay@i{\@ifnextchar[%] {\RespBoxEssay@ii} {\@ifstar{\RespBoxEssay@ii[\curr@quiz.\thequestionno]}}% {\RespBoxEssay@ii[]}% } \newcommand\RespBoxEssay@ii[3][]{% \smallskip\addtocounter{eqpointvalue}{\eqPTs}% % \end{macrocode} % (2019/06/26) Added \cs{eq@AddProbToQzQuesList} for \cs{RespBoxEssay} % \changes{v8.2.13}{2019/06/26}{Added \string\cs{eq@AddProbToQzQuesList} % for \string\cs{RespBoxEssay}} % \begin{macrocode} \eq@AddProbToQzQuesList \stepcounter{questionno}% \xdef\@qzsolndest{#1}% \edef\eqtmp{\aPointType}\xdef\aPointType{\eqtmp,[\eqPTs,"essay"]}% \expandafter\mbox\expandafter{\expandafter\text@@Field \expandafter{\rbe@rgi}{essay.\curr@quiz.\thequestionno}{#2}{#3}% {\eq@protect\AA}{\eq@setWidgetProps \eq@TextField}{\RespBoxEssayDefaults\@@RespBoxEssayActions \every@eqTextField}}% } % \end{macrocode} % \end{macro} % \section{Fields that play a supportive role} % % \subsection{Support for the short-quiz} % % \subsubsection{The \tops{\protect\cs}{\textbackslash}{sqTallyBox} command} % % \begin{macro}{\sqTallyBox}\hskip-\marginparsep\texttt{[\ameta{options}]} % The \cmd{\sqTallyBox} holds the number of incorrect responses to the % question. This box is not required to appear. % \begin{macrocode} \let\@@sqTallyBoxActions\@empty \def\sqTallyBoxDefaults{% \BC{0 0 0}\W{1}\textColor{1 0 0 rg}\S{I}\Q{2}\Ff{\FfReadOnly}} \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} % \subsubsection{The \tops{\protect\cs}{\textbackslash}{sqTallyTotal} command} % \begin{macro}{\sqTallyTotal}\hskip-\marginparsep\texttt{[\ameta{options}]} % This text field stores the tally total. Only used within the % \env{shortquiz} environment. Takes on optional parameter; this % parameter can be used to modify the appearance of the fields. Two special % key-values are also recognized: \cs{weakpass\darg{\ameta{n}}} and \cs{strongpass\darg{\ameta{n}}} % \begin{macrocode} \def\sqTallyTotalDefaults{% \rawPDF{}\W{1}\BC{0 0 0}\S{I}\textColor{1 0 0 rg} \Q{2}\Ff{\FfReadOnly} } % \end{macrocode} % \DescribeMacro{\sqWeakMsg} The message that appears in an alert box % when the use has exceeded the weak-pass limit. % \begin{macrocode} \flJSStr{\sqWeakMsg}{You have missed too many questions. After you finish, it is recommended you retake this quiz with fewer errors and greater understanding.} % \end{macrocode} % \DescribeMacro{\sqStrongMsg} The message that appears in an alert box % when the use has exceeded the strong-pass limit. % \begin{macrocode} \flJSStr{\sqStrongMsg}{You have missed too many questions. We are resetting the quiz. Start over, this time with fewer errors and greater understanding.} % \end{macrocode} % The code that formats the field and if needed, responds to the weak-pass % or strong-pass parameter. % \changes{v8.7.8}{2021/05/13}{Use try/catch (\string\cs{dlTC}) in number format.} % \begin{macrocode} \def\@@sqTallyTotalActions{\AA{% \AAKeystroke{\dl@EForAF4Number_Keystroke(0,0,0,0,"",true);} \AAFormat{\dlTC{\dl@EForAF4Number_Format(0,0,0,0,"",true);}} \AACalculate{% \dl@EForAF4Simple_Calculate("SUM",new Array("tally.\oField"));\r var sqTlyTotl=event.value; \ifx\eq@strongpass\@empty \ifx\eq@weakpass\@empty\else\r % \end{macrocode} % \textbf{Weak pass:} When \uif{sqTlyTotl} exceeds \cs{eq@weakpass}, % an alert message with a message of \cs{sqWeakMsg}. % \begin{macrocode} if(sqTlyTotl > \eq@weakpass) {\r\t if (\oField.sqTlyTotCnt==0)\r\t\t app.alert(\sqWeakMsg);\r\t \oField.sqTlyTotCnt++;\r } \fi \else\r % \end{macrocode} % \textbf{Strong pass:} When \uif{sqTlyTotl} exceeds \cs{eq@strongpass}, % an alert message with a message of \cs{sqStrongMsg}, and the whole % short-quiz is reset. % \begin{macrocode} if(sqTlyTotl > \eq@strongpass) {\r\t app.alert(\sqStrongMsg);\r \@@sqClearButtonJSCode\r event.value=0;\r } \fi }}} % \end{macrocode} % \begin{macrocode} \def\@eqweakpass#1{\def\eq@weakpass{#1}} \def\@eqstrongpass#1{\def\eq@strongpass{#1}} \let\eq@weakpass\@empty \let\eq@strongpass\@empty % \end{macrocode} % On 2021/05/07, the action of \cs{sqTallyTotal} is enhanced; two special keys-values % are defined: \cs{weakpass\darg{\ameta{n}}} and \cs{strongpass\darg{\ameta{n}}}. % For the weak pass, as soon as the student misses more than \ameta{n} questions, % an alert box message; for the strong pass, an alert message appears and the quiz % is reset. % \changes{v8.7.6}{2021/05/07}{Enhanced capabilities of \string\cs{sqTallyTotal}} % \begin{macrocode} \newcommand\sqTallyTotal[1][]{% \processAppArgs#1\end\@nil \mbox{\text@@Field{#1}{tallytotal.\oField}{\TBW}% {\DefaultHeightOfWidget}{\eq@protect\AA}% {\eq@setWidgetProps\eq@TextField}% {\sqTallyTotalDefaults\@@sqTallyTotalActions\every@eqTextField \every@sqTallyTotal}}% } % \end{macrocode} % \end{macro} % % \subsubsection{The \tops{\protect\cs}{\textbackslash}{sqClearButton} command} % % \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 \string\texttt{this.getField("obj.\string\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 color % \changes{v8.6}{2020/11/29}{Rewrote SQ clear button using \string\env{defineJS} env} % \begin{macrocode} \begin{defineJS}[\makeesc\*\makecmt\%]{\@@sqClearButtonJSCode} ProcessIt = false; if ( typeof *oField == "undefined" ) *oField = new Object; if (typeof appAlerts["*oField"] == "undefined") appAlerts["*oField"] = new Object; % dpsx this.resetForm(new Array("mc.*oField","mck.*oField","obj.*oField",% "tally.*oField","grpobj.*oField")); var f = this.getField("obj.*oField"); if ( f != null ) f.strokeColor=*ifx*defaultColorJSLoc*@empty% *defaultColorJS*else*defaultColorJSLoc*fi; f = this.getField("grpobj.*oField"); % \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; f = this.getField("rbmarkup.*oField"); if ( f != null ) f.display=display.hidden; *oField.Grp = {}; appAlerts["*oField"].bAfterValue=false; % \end{macrocode} % \begin{macrocode} *oField.sqTlyTotCnt=0; ProcessIt=true; \end{defineJS} \def\@@sqClearButtonActions{\A{\JS{\@@sqClearButtonJSCode}}} \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} % % \subsubsection{The \tops{\protect\cs}{\textbackslash}{sqSolnBtn} command} % The default scheme for pointing the student to the soltuion to a MC or MS question % is through the buttons themselves. For MC, when the student chooses the correct % answer from the choice field, the page jumps to the soltution page automatically % (assuming there is a solution); for MS, the same jump does not occur until all % correct choices are made. % % In this section, we introduce an alternate scheme for handling jumps to MC and % MS questions. % \changes{v8.7.5}{2021/05/05}{Defined \string\cs{sqSolnBtn}} % \par\medskip\noindent % \DescribeMacro{\sqSolnMCMsg} Alert message for MC question % \begin{macrocode} \flJSStr{\sqSolnMCMsg}{You must first select the correct answer to see the solution.} % \end{macrocode} % \DescribeMacro{\sqSolnMSMsg} Alert message for MS question % \begin{macrocode} \flJSStr{\sqSolnMSMsg}{You must first select all the correct answers to see the solution.} % \end{macrocode} % \DescribeMacro{\sqCorrSolCodeMC} The code for \cs{sqSolnBtn} when the choice % field is MC % \begin{macrocode} \begin{defineJS}[\makeesc\*\makecmt\%]{\sqCorrSolCodeMC} var qzSolnDest="*@qzsolndest"; var solnAfter=*ifeq@solutionsafter% true*else% false*fi; var qzSolnDest="*@qzsolndest"; var f=this.getField("mc.*oField.*thequestionno"); if(f.value.charAt(0)=="1") { if ((qzSolnDest!="") && !solnAfter) % jmpToNamedDest("answer",qzSolnDest,1); } else app.alert(*sqSolnMCMsg); \end{defineJS} % \end{macrocode} % \DescribeMacro{\sqCorrSolCodeMS} The code for \cs{sqSolnBtn} when the choice % field is MS % \begin{macrocode} \begin{defineJS}[\makeesc\*\makecmt\%]{\sqCorrSolCodeMS} // multiple selection var g=this.getField("mc.*oField.*thequestionno"); var a=g.getArray(); var qzSolnDest="*@qzsolndest"; var solnAfter=*ifeq@solutionsafter% true*else% false*fi; var qzSolnDest="*@qzsolndest"; var f=this.getField("corr.*oField.*thequestionno"); if ( (qzSolnDest != "") && !solnAfter ) { for (var i=0; i<a.length; i++){ if ((a[i].exportValues[0].charAt(0)==1) && % (!a[i].isBoxChecked(0))) break; } } if (i>=a.length) jmpToNamedDest("*oField","*@qzsolndest",% *ifx*@sqTurnOffAlerts*eq@Zero0*else1*fi); else app.alert(*sqSolnMSMsg); \end{defineJS} % \end{macrocode} % The action for \cs{sqSolnBtn} as a function of whether % this is a MC or MS button. % \begin{macrocode} \def\sqCorrSolButtonActionHook{\ifx\aeb@answerType \aeb@answerType@r\JS{\sqCorrSolCodeMC}\else \JS{\sqCorrSolCodeMS}\fi } % \end{macrocode} % \DescribeMacro{\sqSolnBtn}\hskip-\marginparsep\texttt{[\ameta{options}]} The % code for \cs{sqSolnBtn}. This command is usually inserted into the workflow % through the \cs{answersEndHook} command. % \begin{macrocode} \newcommand{\sqSolnBtn}[1][]{% \def\Fld@name{corr.\oField.\thequestionno}% \edef\@@CorrSolButtonActions{\noexpand \A{\noexpand\sqCorrSolButtonActionHook}}% % \end{macrocode} % The \cs{sqSolnBtn} button only appears when \cs{@qasolndest} is nonempty. % \begin{macrocode} \ifx\@qzsolndest\@empty\else \mbox{\push@@Button{#1}{\Fld@name}{}{\DefaultHeightOfWidget}% {\eq@protect\A}{\eq@setButtonProps\eq@Button@driver}% {\CorrAnsButtonDefaults\@@CorrSolButtonActions \every@ButtonField\every@CorrAnsButton}}\fi } % \end{macrocode} % % \subsection{The \tops{\protect\cs}{\textbackslash}{CorrAnsButton} buttons} % % \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 % \end{macrocode} % The script for the \cs{CorrAnsButton} accommodates multi-letter variables % \begin{macrocode} \ifShowAppr \ifarrowDelim if(typeof event.target.appr=="undefined")\r\JST\t event.target.appr=false;\r\JST event.target.appr=!event.target.appr;\r\JST if(event.target.appr) {\r\t\JST var\eqSP_substVars=\indepVars;\r\t\JST var\eqSP_substAns=getSubstValue(_substVars,"\CorrectAns");\r\t\JST var\eqSP value=RespBoxAppr("\CorrectAns");\r\JST } else\eqSP var\eqSP value="\CorrectAns";\r\JST \else var\eqSP value="\CorrectAns";\r\JST \fi \else var\eqSP value="\CorrectAns";\r\JST \fi \processJSfunc("Ans.\curr@quiz",value,\currQuiz);\r \ifx\@qzsolndest\@empty\else }\fi }} % \end{macrocode} % \leavevmode\DescribeMacro{\sqCorrAnsCode} % The JavaScript code for \cs{CorrAnsButton} now in a \env{defineJS} env. % \changes{v8.6}{2020/11/29}{code for \string\cs{CorrAnsButton} now in a % \string\env{defineJS} env} % \begin{macrocode} \begin{defineJS}[\makeesc\!\makecmt\%]{\sqCorrAnsCode} !ifx!@qzsolndest!@empty% !processJSfunc("obj.!oField.!thequestionno","!CorrectAns",% !currQuiz);!else% if (event.shift) this.gotoNamedDest("!@qzsolndest"); else !processJSfunc("obj.!oField.!thequestionno","!CorrectAns",% !currQuiz);!fi \end{defineJS} \def\sqCorrAnsButtonActionHook{\JS{\sqCorrAnsCode}} % \end{macrocode} % \leavevmode\DescribeMacro{\CorrAnsButton} % The definition of \cs{CorrAnsButton} % \begin{macrocode} \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\@qzsolndest\@empty\let\JST\@empty\else \let\JST\jsT\fi % dps17 \ifx\eq@ProcRespIntervals\g@processJSfunc \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}}% % \end{macrocode} % (2021/05/21) Code to support the \texttt{allowanswers} option. When the options \texttt{noquizsolutions} % and \texttt{allowanswers} are both specified, the \cs{CorrAnsButton} is typeset. % Normally, when \texttt{noquizsolutions} is specified, \cs{CorrAnsButton} not typeset. % \begin{macrocode} \let\eq@insertFld\eq@YES \ifeq@noquizsolutions\let\eq@insertFld\eq@NO \ifeq@answersallowed\let\eq@insertFld\eq@YES\fi\fi \ifx\eq@insertFld\eq@YES \mbox{\let\rpl\eq@rpl \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} % % \subsection{The \tops{\protect\cs}{\textbackslash}{@PromptButton} command} % % \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} \begin{defineJS}[\makeesc\*\makecmt\%]{\PromptButtonActionCode} if (!isQuizInitialized("*currQuiz")) { eqAppAlert(InitMsg("*bqlabelISO"),3); event.rc=false; } else { if ( !*currQuiz.oAlertCheck.bAfterValue ) { var resp=eqAppAlert({ cMsg:*promptButtonMsg, nIcon: 2, nType: 2, cTitle: ("AcroTeX Prompt Message"), oCheckbox: *currQuiz.oAlertCheck }); } % \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 ) { var field=this.getField("obj.*currQuiz.*thequestionno"); field.readonly=true; field=this.getField("Ans.*currQuiz"); if (field!=null) field.value = ("*AnsPromptBtnStr*PromptAns"); } } \end{defineJS} \def\PromptButtonActionHook{\JS{\PromptButtonActionCode}} % \end{macrocode} % \DescribeMacro{\@PromptButton}\hskip-\marginparsep\texttt{[\ameta{options}]\darg{\ameta{answer}}} % 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} % % \subsection{The \tops{\protect\env}{}{mathGrp} environment} % % \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. % \changes{v8.6}{2020/11/29}{Action for group answer btn now a \string\env{defineJS} env} % \begin{macrocode} \def\CorrAnsButtonGrpDefaults{% \CA{\eq@local@CorrAnsButton}\W{1}\S{S}\BC{0 0 0} \BG{.7529 .7529 .7529}\H{P} } \begin{defineJS}[\makeesc\!\makecmt\%]{\cabGrpActn} !ifx!@qzsolndest!@empty!else% if (event.shift) this.gotoNamedDest("!@qzsolndest"); else !fi% { var aCorrectAns=!CorrectAns; var beginGrp=1; var grpOffset=beginGrp; if(!currQuiz.Grp==null)!currQuiz.Grp={}; if(typeof !currQuiz.Grp["!thequestionno"]=="undefined") { !currQuiz.Grp["!thequestionno"]={offset:0}; } else { !currQuiz.Grp["!thequestionno"].offset=% ++(!currQuiz.Grp["!thequestionno"].offset)!%aCorrectAns.length; grpOffset=beginGrp% +!currQuiz.Grp["!thequestionno"].offset; } var f=this.getField("grpobj.!curr@quiz.!thequestionno." % + grpOffset); % \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){ f.readonly=false; f.setFocus(); eqDelay=app.setTimeOut(% "f.readonly=true;app.clearTimeOut(eqDelay);",10); } else f.setFocus(); !if!eqQuizType!isQZ% DisplayAnswer("Ans.!curr@quiz",% aCorrectAns[!currQuiz.Grp["!thequestionno"].offset],!currQuiz);!else% DisplayAnswer("grpobj.!oField.!thequestionno."+ grpOffset,% aCorrectAns[!currQuiz.Grp["!thequestionno"].offset],!oField);!fi } \end{defineJS} \def\CorrAnsButtonGrpActionHook{\JS{\cabGrpActn}} \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 \else\noexpand\BC{\solution@Color}\fi \noexpand\A{\noexpand\CorrAnsButtonGrpActionHook}}% \ifeq@noquizsolutions\let\x\relax\else \def\x{\mbox{\push@@Button{#1}{\Fld@name}{}% {\DefaultHeightOfWidget}{\eq@protect\A}% {\eq@setButtonProps\eq@Button@driver}% {\CorrAnsButtonGrpDefaults\@@CorrAnsButtonGrpActions \every@ButtonField\every@CorrAnsButton}}}\fi\x \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% % \end{macrocode} % Cosmetic change replaced \cs{noexpand} with \cs{string}. % \changes{v8.2.15}{2019/08/06}{replace \string\cs{noexpand} with \string\cs{string}} % \changes{v8.5.4}{2019/11/03}{Reverted to \string\cs{noexpand}} % \begin{macrocode} \noexpand\eqQzQuesList{\noexpand \@eqListExp{\@currentQues}{\the\c@page}}}% % \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 } %</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<\@ne\@tempcntb=\@ne\fi \ifnum\@tempcntb>\thr@@\@tempcntb=\thr@@\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}% \eqtmpcnta\smrytbl@ntables\relax % \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} \eq@rowcnt\z@\@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\eqtmpcnta=\tw@ \divide\@tempcntb\tw@ \advance\@tempcntb\ifodd\value{questionno}\tw@\else\@ne\fi \xdef\@beginSecCol{\the\@tempcntb}\advance \@tempcntb\m@ne \fi % \end{macrocode} % Three table support % \begin{macrocode} \ifnum\eqtmpcnta=\thr@@ \edef\eq@n{\the\@tempcntb}% \divide\@tempcntb\eqtmpcnta \edef\eq@q{\the\@tempcntb}% \@tempcnta=\@tempcntb\multiply\@tempcnta3 \edef\eq@p{\the\@tempcnta}% \@tempcnta=\eq@n \advance\@tempcnta-\eq@p\relax \ifnum\@tempcnta=\z@ \@tempcntb=\eq@q \advance\@tempcntb\@ne \xdef\@beginSecCol{\the\@tempcntb}% \advance\@tempcntb\eq@q\relax \xdef\@beginThrdCol{\the\@tempcntb}% \else\ifnum\@tempcnta=\@ne \@tempcntb=\eq@q \advance\@tempcntb\@ne \edef\nB@lCols{\the\@tempcntb}% \advance\@tempcntb\@ne \xdef\@beginSecCol{\the\@tempcntb}% \advance\@tempcntb\eq@q\relax \xdef\@beginThrdCol{\the\@tempcntb}% \else\ifnum\@tempcnta=\tw@ \@tempcntb=\eq@q \advance\@tempcntb\@ne \edef\nB@lCols{\the\@tempcntb}% \advance\@tempcntb\@ne \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{quote}\ttfamily %\string\@eqListExp\darg{\ameta{question\_label}}\darg{\string\thepage} %\end{quote} % 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@rowcnt\@ne % \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=\@ne \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\eqtmpcnta>\@ne\ifnum\eq@rowcnt=\@beginSecCol\relax \eq@endtab\expandafter\sumrytablesep\expandafter\eq@begintab \fi\fi \ifnum\eqtmpcnta=\thr@@\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\eq@rowcnt=\value{questionno}\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 \csarg\string\gdef{\currQuiz QzQuesList}{\eqQzQuesList}}% \eq@IWAuxOut{\string \csarg\string\gdef{\currQuiz nQuestions}{\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} % End sumrytbls segment %</sumrytbls> %<*mcfi> % \end{macrocode} % \subsection{Posing MC/math fill-in questions} % \begin{macrocode} \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} % \section{eForms Support} % \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} % End of package segment %</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} \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}{\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 \let\eqGenButton\pushButton \newcommand\everyeqIcon[1]{\def\every@eqIcon{#1}} \def\every@eqIcon{} % \end{macrocode} % % \subsection{Utility macro to dynamically modify appearances} % % This internal command is used to dynamically modify the appearance of form fields. % \begin{macro}{\eq@addExpandTo}\hskip-\marginparsep\texttt{\darg{\ameta{\cs{CMD}}}\darg{\ameta{KVPs}}} % The \cs{eq@addExpandTo} is a utility command that adds eforms key-value pairs to the % end of the macro \texttt{\ameta{\cs{CMD}}}. The second argument of the KVP is expanded first. % Used to dynamically modify appearances of a form field. % \changes{v8.8.5}{2021/10/03}{Added \string\cs{eq@addExpandTo}} % \begin{macrocode} \def\eq@addExpandTo#1#2{\bgroup\let\protect\noexpand \toks@=\expandafter{#1}\protectedKeys*{p@Keys}{#2}% \edef\x{\@nameuse{p@Keys}}\toks2=\expandafter{\x}% \xdef#1{\the\toks@\the\toks2}\egroup } % \end{macrocode} % \end{macro} % \subsection{Additional Format and Action keys} % % \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} % Define a special value (\cs{formatInitAltApprs}) for \cs{AddAAFormat} used in initializing \cs{RespBoxMath} problems, % where there are alternate appearances. % See the {Acro\negthinspace\TeX} Blog article \url{http://www.acrotex.net/blog/?p=1335} for a discussion of the use of \cs{formatInitAltApprs}. % \changes{v8.1a}{2017/09/03}{Define a special value (\string\cs{formatInitAltApprs}) for \string\cs{AddAAFormat}} % \begin{macrocode} \def\formatInitAltApprs{\formatInitAltApprs} \def\@eqAddAAFormat#1{\def\@rgi{#1}\ifx\@rgi\formatInitAltApprs \bInitAltAppr\else\def\eqAddAAFormat{#1}\fi} \def\eqAddAAFormat{} \def\formatAsSet{try{formatAsSet()}catch(e){}} \def\formatAsVector{try{formatAsVector()}catch(e){}} % \end{macrocode} % \end{macro} % What follows are a series of three ``action'' keys, that is, their arguments are % JavaScript code. They are meant to be used in highly specialized settings. % \begin{macro}{\setActionKeys} % The action keys can be set through the optional argument, if available, or they can be set % globally using the command \cs{setActionKeys}. The only keys supported for use % as the argument of \cs{setActionKeys} are \cs{AddAAKeystroke\{\meta{code}\}}, % \cs{AddAAMouseUpMC\{\meta{code}\}}, and \cs{AddAAMouseUpMS\{\meta{code}\}}, though % this is not enforced due to the obscure nature their use. The action settings remain % in force until you cancel them out with \cs{AddAAKeystroke\{\}}, for example. % \changes{v7.8k}{2017/07/22}{Added \string\cs{setActionKeys}} % \changes{v7.8j}{2017/07/23}{Restricted the use of \string\cs{setActionKeys} to a % selected number of keys} % \begin{macrocode} \def\eq@SupActnLst{{\AddAAKeystroke}{\AddAAMouseUpMC}% {\AddAAMouseUpMS}{\AddAAFormat}} \newcommand\setActionKeys{\edef\catOfAt{\the\catcode`@}% \ifnum\catOfAt=11 \let\eq@CatTail\relax\else \makeatletter\let\eq@CatTail\makeatother\fi\setActionKeysi} \def\setActionKeysi#1{\let\eq@itsGood\eq@One \def\setActionKeys@cont{\processAppArgs#1\end\@nil}% \begingroup\eq@checkivValidKeys#1\end\ef@nil\endgroup\eq@CatTail} \def\eq@checkivValidKeys#1#2{\def\eq@GOOD{good}\expandafter \@tfor\expandafter \@ction\expandafter:\expandafter=\eq@SupActnLst\do{% \expandafter\def\@ction{good}}% \ifx\end#1% if #1=\end, #2=\ef@nil. \def\eq@next{\aftergroup\setActionKeys@cont}% \else \if\eq@itsGood\eq@One \let\itp@ss0\let\@@next\relax \expandafter\@tfor\expandafter \@ction\expandafter:\expandafter=\eq@SupActnLst\do{% \expandafter\ifx\expandafter#1\@ction \let\itp@ss\eq@One\@break@tfor \fi}% do \if\itp@ss\eq@Zero\let\eq@itsGood\eq@Zero \def\eq@next{\def\eq@lastArg{#1}\expandafter \eq@sqkErrorMsg\ef@gobbletonil}\else \let\eq@next\eq@checkivValidKeys\fi \else\let\eq@next\ef@gobbletonil\fi \fi %\ifx\end \eq@next } \def\eq@sqkErrorMsg#1{\PackageError{exerquiz}{The key \expandafter \string\eq@lastArg\space is not supported by \string\setActionKeys.\MessageBreak Remove the key or correct the spelling of the key}{}} % \end{macrocode} % The \DescribeMacro{\addToAction}\cs{addToAction} is a companion to \cs{setActionKeys}. When % \cs{setActionKeys} sets a key, later in the document, you might want to add to that action % earlier defined. Thus, \verb~\addToAction{\AddAAFormat}{var x=2;}~ appends % \texttt{var x=2;} to the code already defined earlier by % \cs{setActionKeys}, I hope. The first argument is one of the keys in \cs{eq@SupActnLst} % (the only ones accepted), the second argument is the script to add to the previously added script. % The optional \texttt{*}-argument reverses the order the code is arranged. % \begin{macrocode} \def\addToAction{\makeatletter\@ifstar{\let\isSt@r\eq@YES\@ddToAction} {\let\isSt@r\eq@NO\@ddToAction}} \def\@ddToAction#1#2{\let\eq@itsGood\eq@One \def\setActionKeys@cont{\@@ddToAction{#1}{#2}}\begingroup \eq@checkivValidKeys{#1}{#2}\end\ef@nil\endgroup\makeatother} \def\@@ddToAction#1#2{\@getCmdName{#1}% \if\isSt@r\eq@YES\toks2={#2}% \toks@=\aeb@exiii{\csname eq\@CmdName\endcsname}% \edef\tmp@tokshold{\the\toks2 \the\toks@}% \toks@=\expandafter{\tmp@tokshold}\else \toks@=\aeb@exiii{\csname eq\@CmdName\endcsname#2}\fi \expandafter\edef\csname eq\@CmdName\endcsname{\the\toks@}% } % \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 \string\cs{AddAAKeystroke} to the recognizable set of keys. This will be obeyed % within the optional arguments of \string\cs{RespBoxMath} and \string\cs{RespBoxTxt}. %} % \begin{macrocode} \def\@eqAddAAKeystroke#1{\def\argi{#1}\ifx\argi\@empty \def\eqAddAAKeystroke{}\else\def\eqAddAAKeystroke{\r #1}\fi} %\r \def\eqAddAAKeystroke{} % \end{macrocode} % \end{macro} % \begin{macro}{\AddAAMouseUpMC} % \begin{macro}{\AddAAMouseUpMS} % Added form keys (for MC and MS questions), can be use to add additional % action with a mouse up event. % \changes{v7.8j}{2017/07/21}{Added form keys \string\cs{@eqAddAAMouseUpMC} % and \string\cs{@eqAddAAMouseUpMS}} % \begin{macrocode} \def\@eqAddAAMouseUpMC#1{\def\argi{#1}\ifx\argi\@empty \def\eqAddAAMouseUpMC{}\else\def\eqAddAAMouseUpMC{#1}\fi} \def\eqAddAAMouseUpMC{} \def\@eqAddAAMouseUpMS#1{\def\argi{#1}\ifx\argi\@empty \def\eqAddAAMouseUpMS{}\else\def\eqAddAAMouseUpMS{#1}\fi} \def\eqAddAAMouseUpMS{} % \end{macrocode} % \end{macro} % \end{macro} % \subsection{An pushbutton to hold an icon appearance} % I don't remember much about the \cs{eqIcon} command, don't remember % how this is used. % \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} \eq@restoreCats %</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} % (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\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\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"} \newif\ifSubstVars\SubstVarsfalse % dps17 \newif\ifShowAppr\ShowApprtrue % dps17 \def\altApprOn{\ShowApprtrue} % dps17 \def\altApprOff{\ShowApprfalse} % dps17 \def\corrChoiceFullyOn{\def\eqCorrChoiceFully{true}} \def\corrChoiceFullyOff{\def\eqCorrChoiceFully{false}} \corrChoiceFullyOn % \end{macrocode} % Implement a local version of full corrections of MC and MS % \changes{v8.1l}{2018/02/07}{Add local version of \string\cs{corrChoiceFullOn}} % \begin{macrocode} \def\corrLocalChoiceFullyOn{\def\eqCorrLocalChoiceFully{true}} \def\corrLocalChoiceFullyOff{\def\eqCorrLocalChoiceFully{false}} \def\resetLocalChoiceFully{\let\eqCorrLocalChoiceFully\@empty} \resetLocalChoiceFully % no local implementation \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 \dlPkgInfoPkg Dated \dlPkgInfoDate */ var exerquizLoaded = true; this.disclosed = true; app.runtimeHighlight=false; var bDisplaySilent=false; // dps \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 \texttt{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}[xleftmargin=\parindent,fontsize=\small, %commandchars={!()},codes={\catcode`\%=9}] %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 NQuestions=0; var NPointTotal=0; var e = Math.E; var pi = Math.PI; var replaceExclaim = \replaceexclaim; var negPointsAllowed = \negpointsallowed; var negPointsMarkupAllowed = \negpointsmarkupallowed; var aQuizControl = new Object; 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 \string\texttt{JSf} array into \string\texttt{JSfBuiltIn} and \string\texttt{JSfCustom}. This % allows us to identify the built-in JavaScript functions. I concatenate these two % into \string\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 \textsf{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 \string\texttt{\_mathVars} which % holds the variables of the current \string\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); } 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; % \end{macrocode} % When `a' is a variable, and the user types in `a cos(x)', exerquiz eventually removes spaces and this % becomes `acos(x)', which is not is wanted. Early on, we replace `a' with `(a)' so it is interpreted as % a factor: `a cos(x) becomes `(a) cos(x)', which when spaces are stripped out, becomes `(a)cos(x)'. % \changes{v8.1b}{2017/09/06}{Enclosed literal `a' in parentheses to disambiguate `a cos' from `acos'.} % \begin{macrocode} re = /\b(a)\b/g; UserInput = UserInput.replace(re, "(a)"); UserInput = stripWhiteSpace (UserInput); if (!ok2Continue) return null; % \end{macrocode} % See if there are matching `\texttt{[]}', `\verb~{}~' 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 `\verb~{}~' with `\texttt{()}'; only parentheses % are used in JavaScript for grouping. % \begin{macrocode} UserInput = ChngAllGrpsToParens(UserInput); % \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. % \begin{macrocode} 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; } } if (!ok2Continue) { eqAppAlert(\eqerrBadExp,3); return false; } else { % \end{macrocode} %(2007/02/23) 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. %\changes{v6.06}{2007/02/23}{% % Now, just before we return the parsed expression, we append all built-in % JavaScript functions and constants with \string\texttt{Math.}, this is to avoid % having to use the \string\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,indepVars,oComp) { if (!ProcessIt) return null; var fieldname = event.target.name; var bSubstVars=(arguments.length>7); // dps17 % \end{macrocode} % The introduction of multi-letter variables, necessitates a slight revision of the JavaScript function % \texttt{ProcResp()}. This fundamental function, changes to this function must be propagated % to \pkg{dljslib} to all `proc resp' function. % \begin{macrocode} var UserAns=(arguments.length>7)?arguments[7]:event.value; var success = _ProcResp(flag,CorrAns,UserAns,% n,epsilon,domain,indepVars,oComp); % \end{macrocode} % 09/07/09 Added next line to avoid double alert boxes % \begin{macrocode} if ( success == -1 || !ok2Continue ) { resetHeadsUp(flag,fieldname); return null; } // dps17 if ( success == null ) { resetHeadsUp(flag,fieldname); return syntaxError(), null; } // dps17 return notifyField(success, flag, fieldname); } // changed name of var comp -> oComp function _ProcResp(flag,CorrAns,UserAns,n,epsilon,domain,% indepVars,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 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{indepVars} 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{indepVars} must be either % of the old style, or the new style, not a mixture of both, e.g. \texttt{"xyi:n"}. % \begin{macrocode} indepVars = TypeParameters(indepVars); if (!ok2Continue) return null; var success=randomPointCompare(n,domain,indepVars,% 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}[xleftmargin=\parindent,fontsize=\small, %commandchars={!()},codes={\catcode`\%=9}] %priorParse: nodec, %priorParse: [nodec,noBinFac], %priorParse: [nodec,noBinFac,[myFunc,arg1, arg2,..]], %\end{Verbatim} % \begin{macrocode} retn=_o(UserAns); 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} } 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} 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,indepVars,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,indepVars,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} var ckDZRe=/\b([^0-9]*)(\d*)\./g; function ckDZReRepl(match,a,b,offset,string){ if (b[0]!="0") return match; else return util.printf(a+"\%d.",b); } 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()}. % \changes{v8.7.4}{2021/05/03}{Changed logic in \string\texttt{diffCompare()} function} % \begin{macrocode} var rtnCode = 0; % \end{macrocode} % JavaScript has problems with numbers that are not properly written. % If a number has a decimal point, the integer part of the decimal must be blank, a zero (0), % or must begin with a non-zero number. In the \texttt{String.replace()} method below, % the regular expression \texttt{ckDZRe} identifies leading digits, and the function % \texttt{ckDZReRepl} is a replacement function that implements the requirements described above. % The same changes is made in \texttt{reldiffCompare()} below. % \begin{macrocode} _G=_G.replace(ckDZRe,ckDZReRepl); eval("try {if(isNaN(_G = eval(_G))) rtnCode=-1; }" +"catch (e) { rtnCode=1; }"); % \end{macrocode} %Below is the code removed on 2021/05/01 for the above two lines. When |_G="00.00"|, for example. %and |ifNaN(_G = eval(_G))| is executed, a exception is thrown and \texttt{null} is returned; %even though the string does evaluate to a number, but JavaScript does not recognize it as such. %As a result, we try an alternate strategy. The same change is made in the function %\texttt{reldiffCompare()}, below. %\begin{Verbatim}[xleftmargin=\parindent,codes={\catcode`\%=9}] %eval("try {if(isNaN(_G = eval(_G))) rtnCode=-1; }" % +"catch (e) { rtnCode=1; }"); %\end{Verbatim} % \begin{macrocode} 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. % \changes{v8.7.1}{2021/05/01}{Changed logic in \string\texttt{reldiffCompare()} function} % \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; _G=_G.replace(ckDZRe,ckDZReRepl); 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 \textsf{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 = 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} \begin{newsegment}{Eq: Support for multi-letter variables} if (!String.prototype.trim) { String.prototype.trim = function () { return this.replace(/^[\s\string\\uFEFF\string\\xA0]+|% [\s\string\\uFEFF\string\\xA0]+$/g, ''); }; } % \end{macrocode} % \makebox[0pt][r]{\texttt{\_rplVarsBy\hskip\marginparsep}}\hskip-\marginparsep\texttt{(str1,str2)} % replaces \texttt{str1} by \texttt{str2}; i.e., % |_rplVarsBy('theta','x')|. The first argument is a multi-letter variable, % the second is a single letter variable that \pkg{exerquiz} works with directly. % \begin{macrocode} function _rplVarsBy(str1,str2) { var re=new RegExp(str1,"g"); var result=str1.replace(re,str2); return result; } % \end{macrocode} % \makebox[0pt][r]{\texttt{processMathVars\hskip\marginparsep}}\hskip-\marginparsep\texttt{(str)} % searches through \texttt{str} for the string \texttt{\_rplVarsBy}; if found, it gets all string % content up to the next \texttt{@} marker. It replaces the multi-letter with single letter and returns % the \pkg{exerquiz} single-leter variable list. %\begin{verbatim} % var _substVars="a,_rplVarsBy('omega->\u03C9','y')@"; % var _mathVars=processMathVars(_substVars); % var _substValue=getSubstValue(_substVars,event.value); % var _substAns=getSubstValue(_substVars,"a+omega"); %\end{verbatim} % \begin{macrocode} function processMathVars(str) { var pos1,pos2,lead,tmp; while ((pos1=str.indexOf("_rplVarsBy"))!=-1) { pos2=str.indexOf("@"); lead=str.substring(0,pos1); tmp=str.substring(pos1,pos2); str=str.substring(pos2+1); % \end{macrocode} % For example, for |tmp="_rplVarsBy('omega->\u03C9','y')"|, after \texttt{eval(tmp)}, \texttt{tmp} is then % \texttt{y}. % \begin{macrocode} tmp=eval(tmp); % \end{macrocode} % Combine this new result with the old, for example \texttt{str="a,y"}, for the example above. % \begin{macrocode} str=lead+tmp+str; } str=str.replace(/\s/g,""); return str; } % \end{macrocode} % \makebox[0pt][r]{\texttt{getSubstValue}\hskip\marginparsep}\hskip-\marginparsep\texttt{(v,s)} % Below is a two multi-letter variable example: %\begin{verbatim} % var _substVars= % "c_rplVarsBy('theta->\u03B8','x')@_rplVarsBy('alpha->\u03B1','y')@"; % var _mathVars=processMathVars(_substVars); % var _substValue=getSubstValue(_substVars,event.value); % var _substAns=getSubstValue(_substVars,"-c alpha sin(theta)"); % var retn=ProcResp(0,_substAns,3,.0001,"[0,1]x[0,1]x[0,1]",% % _mathVars,diffCompare,_substValue); %\end{verbatim} %The first argument is \texttt{v}, the variable list; it might be \texttt{"xyz"}, or %if there are substitutions, it might be as above (see \texttt{\_substVars}). The second %argument is \texttt{s}, the user's answer or the author's answer. % \begin{macrocode} getSubstValue.aSubsts=new Array(); function getSubstValue(v,s){ var pos1,pos2,tmp,args,re,arg1,arg2; % \end{macrocode} % Change new style to old.\\ % \textbf{New style} (commas):\\\null\quad|v="c,_rplVarsBy('theta->\u03B8','r:x')@,%|\\\null\qquad %|_rplVarsBy('alpha->\u03B1','r:y')@";|\\ % \textbf{Old style} (no commas):\\\null\quad|v="c_rplVarsBy('theta->\u03B8','x')@%|\\\null\qquad %|_rplVarsBy('alpha->\u03B1','y')@";|\\ %We want to remove the commas that are \emph{not preceded} by a single quote (\texttt'), as this type %are inside the argument of \texttt{\_rplVarsBy}. We also remove things like \texttt{r:x}. % \begin{macrocode} re=/([^'])(,)/g; v=v.replace(re,'$1'); re=/([ri]\string\:)+(\string\w)/g; v=v.replace(re,'$2'); % \end{macrocode} % Now, develop an array of all variables and their substitutes. % ie,\\|getSubstValue.aSubsts=[ ["theta","\u03B8"],["alpha","\u03B1"],...];| % \begin{macrocode} getSubstValue.aSubsts=[]; // dps17 var start=0; while (true) { v=v.substring(start); pos1=v.indexOf("_rplVarsBy"); if (pos1==-1) break; pos2=v.indexOf("@"); args=v.substring(pos1+10+1,pos2-1); tmp=args.split(","); arg1=eval(tmp[0].toString()); tmp1=arg1.split("->"); for (var i=0; i<tmp1.length; i++) tmp1[i]=tmp1[i].trim(); if (tmp1.length==1) getSubstValue.aSubsts.push(tmp1[0]); else getSubstValue.aSubsts.push(tmp1); arg2=eval(tmp[1].toString()); re=new RegExp(tmp1[0],"g"); s=s.replace(re,arg2); start=pos2+1; } return s; } % \end{macrocode} % \makebox[0pt][r]{\texttt{RespBoxAppr}\hskip\marginparsep}\hskip-\marginparsep\texttt{(e)} % The variable is either an event object (when called from a format event) or is a string % (when called from an Ans button). Assume \texttt{e="-c*alpha*sin(theta)"}. % We go through the \texttt{etSubstValue.aSubsts}, and replace each variable % developed by \texttt{getSubstValue()} by its substitute variable. Here a lines from % an Ans button %\begin{verbatim} % var _substVars="c_rplVarsBy('theta->\u03B8','x')@ % _rplVarsBy('alpha->\u03B1','y')@"; % var _substAns=getSubstValue(_substVars,"-c*alpha*sin(theta)"); % var value=RespBoxAppr("-c*alpha*sin(theta)"); %\end{verbatim} %We must call \texttt{getSubstValue()} prior to calling this function. % \begin{macrocode} function RespBoxAppr(e){ var value=(typeof e=="object")?e.value:e; var re; for (var i=0; i<getSubstValue.aSubsts.length; i++) { if (typeof getSubstValue.aSubsts[i]=="object") { re=new RegExp(getSubstValue.aSubsts[i][0],"g"); value=(value.replace(re,getSubstValue.aSubsts[i][1],"g")); } } return value; } \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 \string\texttt{this} to % \string\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{macrocode} % JavaScript support of spell checking command |\SpellCheck| % \changes{v8.5.11}{2020/11/11}{JavaScript support of spell checking command \string\cs{SpellCheck}}. % Returns the number of misspelled words, but allows user to to correct. % \begin{macrocode} function checkTheSpelling(targetFieldName) { var spellChkCnt=0; % var thisName=event.target.name; % \end{macrocode} % The root name of the \cs{SpellCheck} field is \texttt{spl}. Here we replace % the root name with \texttt{obj} to get the field name of the previous \cs{RespBoxTxt(PC)} % field. For the \texttt{spell.checkWord()} method, \app{PDF-XChange Editor} returns \texttt{undefined}. % This (spell checking) is a AR/AA feature only. % \begin{macrocode} var f=this.getField(targetFieldName); var value=f.value; var valueStrip = value.replace(/\s+/g,""); if ( valueStrip != "" ) { aBrk=value.split(/\s+/); for (var i=0; i<aBrk.length; i++){ var word=aBrk[i]; var aRetnSC=spell.checkWord(word); if (aRetnSC!=null) spellChkCnt++; } var corrdStr=spell.checkText(value); f.value=corrdStr; } return spellChkCnt; } \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 Object(); % \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]); } } % \end{macrocode} % (2021/04/04) Added try/catch to catch exceptions. % \changes{v8.6.6}{2021/04/04}{Added some try/catch pairs to avoid tossing cookies} % \begin{macrocode} function ProcUserNoResp(key,userresp,probno,notify) { if ( arguments.length > 4 ) { try{ RightWrong[probno][arguments[4]] = undefined; Responses[probno][arguments[4]] = undefined; } catch(e){}; var bVoidArray=true; try { for (var i=0; i<Responses[probno].length; i++) { if ( typeof Responses[probno][i] != "undefined") { bVoidArray=false; break; } } } catch(e){}; 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; % \end{macrocode} % (2021/05/29) Pressing \uif{Shift-Begin Quiz} will clear the quiz, % but not initialize for another quiz. % \changes{v8.8.1}{2021/05/25}{Shift-Begin Quiz clears the quiz, but does % not initialize the quiz.} % \begin{macrocode} if (arguments.length>2) aQuizControl[qtfield] = arguments[2]; // 0 or 1 designed for 0 else aQuizControl[qtfield] = (event.shift)?0:1; // dps5-25 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<4) { 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 resetHeadsUp(flag,fieldname) { if (flag==1) return; var pos1=fieldname.indexOf("."); var pos2=fieldname.indexOf(".",pos1+1); var baseName=fieldname.substring(pos1+1,pos2); var oQName=eval(baseName); var defaultColor=(typeof oQName.DefaultColorJSLoc=="undefined")% ?\defaultColorJS:oQName.DefaultColorJSLoc; var f=this.getField(fieldname); if (f!=null) f.strokeColor=defaultColor; } 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} % \leavevmode\IndexJS{RecordPointValue}\hskip-\marginparsep\texttt{(\ameta{ptValue},\ameta{probno}}\\ % \texttt{[,grpquestionno,grpPointValue,\ameta{total-weight},\ameta{grpEvalFunction}])}\\ % The function \texttt{RecordPointValue} has two required parameters. For a grouped question, % there are four \emph{more} parameters, they are, in order (2) \texttt{grpquestionno} (3) \texttt{grpPointValue} % (4) total weight (5) \texttt{grpEvalFunction}, a JS function that evaluates the group.\par\medskip\noindent % The elements of the \texttt{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, \ameta{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; NPointTotal=nPointTotal; NQuestions=nQuestions; % \end{macrocode} % If \texttt{RightWrong} is undefined, set length = 0 (dps5-24) % \begin{macrocode} var l=(typeof RightWrong=="undefined")?0:RightWrong.length; for (var i=1; i < l; 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; % \end{macrocode} % If the user receives negative points, we change it to zero points. % \changes{v8.5.9}{2020/02/21}{If the user receives negative points, we change it to zero points.} % \begin{macrocode} if (!negPointsAllowed && % !negPointsMarkupAllowed && (ProbDist[i]<0) ) ProbDist[i]=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); % \end{macrocode} % (2021/02/17) If there is a fourth argument for this function, it should % be either \texttt{true} or \texttt{false}; if \texttt{true}, \texttt{DisplayQuizResults()} % does not display quiz results; the default is \texttt{false}. This feature is used in the % demo file \texttt{qz-pin-to-correct.tex} found on the {Acro\negthinspace\TeX} Blog. % \changes{v8.6.4}{2021/02/17}{Added conditional (\string\texttt{\_bSilent})} % \begin{macrocode} var _bSilent=(arguments.length > 3 ) ? arguments[3] : false; if (!_bSilent) { 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} % \leavevmode % \IndexJS{correctQuiz}\hskip-\marginparsep\texttt{(\ameta{fld-name},\ameta{num-ques})} % This function is called when the \uif{Correct} control is pressed on a quiz. % Dependencies: \texttt{RightWrong}, \texttt{ProbDist} (if \texttt{qMark} is present). Other dependencies % needed to save the state of the quiz after the \uif{End Quiz} control is pressed and before the % \uif{Correct} control is pressed: % \begin{macrocode} function correctQuiz(qtfield,nQuestions) { % \end{macrocode} % (2019/10/14) If \texttt{oRecordOfQuizData} is present (from \pkg{eq-save}), we use that data from the quiz. % \changes{v8.5.1}{2019/10/14}{Incorporated oRecordOfQuizData into correctQuiz()} % \begin{macrocode} var bROQD=(typeof oRecordOfQuizData=="object"); if(bROQD && % (typeof oRecordOfQuizData["RightWrong."+qtfield]!="undefined")) { RightWrong=oRecordOfQuizData["RightWrong."+qtfield]; ProbDist=oRecordOfQuizData["ProbDist."+qtfield]; } % \end{macrocode} % Determine the color scheme to be used. % \begin{macrocode} 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} % Implement a local version of fully correcting MC and MS questions. % \changes{v8.1l}{2018/02/07}{Add local version of \string\cs{corrChoiceFullOn}} % \begin{macrocode} var bFullyCorrect=(typeof oQName.fullyCorrectLoc=="undefined")% ?\eqCorrChoiceFully:oQName.fullyCorrectLoc; % \end{macrocode} % MC or MS questions % \begin{macrocode} var f = this.getField("mcq." + qtfield); % \end{macrocode} % For MC question, show only the incorrect ones, depending on the % switch \texttt{bFullyCorrect}. % \changes{v8.1f}{2017/12/04}{Added an option for MC question not to % show the correct answer, but only the incorrect ones.} % \begin{macrocode} if ( f != null) { if (bFullyCorrect) { f.display = display.visible; } else { for (var n=1; n<=nQuestions; n++) { var h=this.getField("mc."+qtfield+"."+n); var bOk=(h!=null); if(bOk) var choiceType="mc"; else { h=this.getField("mck."+qtfield+"."+n); bOk=(h!=null); var choiceType="mck"; } if (bOk) { var mcq=this.getField("mcq."+qtfield+"."+n); var g=mcq.getArray(); if (choiceType=="mc") { for (var j=0; j< g.length; j++) { g[j].display=(h.isBoxChecked(j))?% display.visible:display.hidden; } } else { var ck=h.getArray(); for (var j=0; j< g.length; j++) { g[j].display=(ck[j].isBoxChecked(0))?% display.visible:display.hidden; } } } } } } 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 ( (typeof RightWrong!="undefined") && % // dps5-24 (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("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 ) { 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(); if (typeof ProbDist == "undefined" ) var qpts=0; // dps5-24 else 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); // dpsx var f = this.getField("mcq."+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++ ) % \end{macrocode} % (2021/10/03) Work with the tool tip of \texttt{mcq} rather than the export value % of \texttt{mck}. % \begin{macrocode} nTotalCorrect += (1*g[i].userName); % nTotalCorrect += (1*g[i].exportValues[0].charAt(0)); // dpsx 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; } % \end{macrocode} % \leavevmode\IndexJS{LimitSelection}\hskip-\marginparsep\texttt{(\ameta{n},\ameta{fname},\ameta{index}} % This function supports the \cs{limitSelectionTo\darg{\ameta{n}}} command. The function determines % whether the user has chosen more than \ameta{n} in a MS choice field. The widget that activated this % function is \texttt{\ameta{fname}.\ameta{index}}. % \begin{macrocode} 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; } } % \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 short-quiz 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 bCB=\bcheckboxused % \end{macrocode} % (2021/10/03) Boolean to use extended alert boxes for MC and MS, short-quiz. % \begin{macrocode} var bUseCkBx=\buseckbx; // dpsx 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; % \end{macrocode} % If \texttt{event.target} is the Doc object, the function has been called from % a link; if called from a field action \texttt{event.target} is a Field object. % \begin{macrocode} if ( !bUseCkBx && ( (event.target == this) || !bCB ) ) // dpsx 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")% ?\defaultColorJS:oQName.DefaultColorJSLoc; if (isthereRBUP) g.display=display.hidden; event.target.strokeColor = defaultColor; } } } function jmpToNamedDest(fName,cDest,bAlert) { if (cDest == "") return; 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]; % \end{macrocode} % (2019/06/30) if negative points are not allowed, make qpts zero if necessary % \changes{v8.2.14}{2019/06/30}{Added a condition if negPointsAllowed} % \begin{macrocode} if ( !negPointsAllowed && (qpts < 0) ) qpts=0; 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]; if ( !negPointsAllowed && (qpts < 0) ) qpts=0; 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 !} \dlJSStr*[noquotes]{\limSelWarningMsg}{"Pour cette question, vous \u00EAtes autoris\'{e} \`{a} faire au plus " + n + " s\'{e}lections."} %</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."} \flJSStr*[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!} \dlJSStr*[noquotes]{\limSelWarningMsg}{"For dette sp\string\370rsm\string\345let har du lov til \string\345 gj\string\370re p\string\345 det meste " + n + " valg."} %</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!} \dlJSStr*[noquotes]{\limSelWarningMsg}{"Voor deze vraag mag je maximaal " + n + " selecties maken."} %</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!} \dlJSStr*[noquotes]{\limSelWarningMsg}{"Para esta pregunta, se le permite hacer como m\'{a}ximo " + n + " selecciones."} %</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!} \dlJSStr*[noquotes]{\limSelWarningMsg}{"Per questa domanda, \`{e} possibile effettuare al massimo " + n + " selezioni."} %</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!} \dlJSStr*[noquotes]{\limSelWarningMsg}{"Til dette sp\string\370rgsm\string\345l, er du lov til at g\string\370re h\string\370jst " + n + " valg."} %</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}!} \dlJSStr*[noquotes]{\limSelWarningMsg}{"Na to pytanie, mo\u017Cesz dokona\u0107 co najwy\u017Cej " + n + " wybor\string\363w."} %</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!}} \dlJSStr*[noquotes]{\limSelWarningMsg}{"T\string\344h\string\344n kysymykseen, voit tehd\string\344 enint\string\344\string\344n " + n + " valintoja."} %</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!} \dlJSStr*[noquotes]{\limSelWarningMsg}{"Per a aquesta pregunta, se li permet fer com a m\`{a}xim " + n + " seleccions."} %</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." } \dlJSStr*[noquotes]{\limSelWarningMsg}{"Pro tuto ot\string\341zku m\u016F\u017Eete prov\'{e}st maxim\'{a}ln\u011B " + n + " v\u00FDb\u0115ry."} %</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!} \dlJSStr*[noquotes]{\limSelWarningMsg}{"Pro tuto ot\string\341zku m\u016F\u017Eete prov\'{e}st maxim\'{a}ln\u011B " + n + " v\u00FDb\u0115ry."} %</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"+Score+" \eqOutOf\space"+nQuestions} \renewcommand\eqQuizPointsMsg{% "\eqptScore\space"+ptScore+" \eqOutOf\space"+nPointTotal} \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!} \dlJSStr*[noquotes]{\limSelWarningMsg}{"Bu soru i\u00E7in, en fazla " + n + " se\u00E7im yapmak i\u00E7in izin verilir."} %</eqtr> % \end{macrocode} % \Finale