The exam class^{∗}

Jason Alexander^{†}

1997/11/24

Abstract A new class file, exam, for L^{A}TEX 2ε is defined. It automates several features used in designing tests: (1) it provides for the binding of questions and answers in an intuitive and natural way; (2) if (1) is done, exam will, at the user’s request, automatically generate answer keys; (3) multiple versions of the same test are automatically generated, with the ordering of questions within each section randomly permuted so as to minimize cheating; and (4) environments are provided to assist in constructing the most common types of test question: true/false, multiple-choice, fill-in-the-blank, short answer and essay question.

1 Description

Teaching at the university level is a rewarding and enjoyable profession, but it seems almost universally agreed upon that the examination process is a distasteful one. Not merely for the students, mind you, but also for the faculty as well (although it is difficult to convince the student body of this fact). Personally, I find the writing of exams enjoyable, but the administering and grading of same falls rather far behind. The exam class cannot help with the latter options, but it can make your life considerably easier with the former in certain settings.

In a large university settings, professors commonly use multiple versions of the same test. The argument being that different versions of the same test reduce cheating insofar as copying off of one’s neighbor becomes more difficult. This is one way the process of writing exams becomes tedious and distasteful: once faced with a completed test, randomly rearranging the questions to make cheating harder. Human beings evolved to recognize patterns readily and thus do not easily generate random numbers (or pseudo-random numbers, for that matter). Consequently, most “randomly rearranged” tests consist of patterns: every other question, questions listed in reverse order, etc. But this problem is minor. The real problem is that rearranging the order of questions is boring. Why can’t a computer do it for me? Well, with the exam class, that can now happen.

∗This file has version number v1.02, last revised 1997/11/24.

†If you use this package and find it helpful, please email me at jalex@ea.oac.uci.edu so that I have some idea of the number of people who use this. :-) Of course, send all bug reports to me as well.

2 Usage

To begin, simply create a new L^{A}TEX 2ε document starting with

 \documentclass{exam}
 \begin{document}

If you want to create an exam in 12pt type, use \documentclass[12pt]{exam} instead. If you need to load additional packages, they may be loaded via the command \usepackage as always.

Most exams are split into sections corresponding to the type of question asked, and exam encourages (actually, requires) this practice. There are five environments defined, one environment for each type of question: fillin, shortanswer, truefalse, multiplechoice, and fixed. Starred forms of these environments are also provided, so the environment names fillin*, shortanswer*, truefalse*, multiplechoice*, and fixed* are permitted.

All the environments are carefully designed to facilitate binding answers to questions. This not only makes the job of writing the exam easier, but it allows answer keys to be easily generated.

2.1 Options and Switches

There are three ways that one can customize the output of the exam class: options, switches, and special formatting environments. The first two are the easiest to use and are documented here. Descriptions of the special formatting environments (such as frontmatter, endmatter, etc.) can be found in section 3.1.

By an ‘option’ I simply mean what L^{A}TEX 2ε considers an option: anything that can be included (in brackets) after the \documentclass command. Since the exam class is built upon the ordinary L^{A}TEX 2ε article class, most of the standard L^{A}TEX options work as described in Lamport’s The L^{A}TEX Companion. Most, but not all—in order to get twocolumn output, the multicol package must be installed. In addition, there are five options not found in the article class: nokey, onekey, noform, mcbold, and mcunderline. The option nokey suppressing generation of answer keys, onekey only creates an answer key for the first exam, and the option noform suppresses the form label that is ordinarily added to each exam. The option mcbold identifies the correct answer in multiple choice questions by boldface rather than a box around the correct letter. The option mcunderline identifies the correct answer in multiple choice questions by underlining. Note that the mcbold and mcunderline options are cumulative: requesting both options will give you boldface underlined answers. If neither one is specified, exam will default to boxing the letter of the correct answer. This is shown in the examples below.

One technical note: In the case the mcunderline option is given, the correct answer may span several lines. The ordinary L^{A}TEX 2ε command \underline does not provide for this possibility. Consequently, I incorporated the ulem package, written by Donald Arseneau, for underlining. Since this package is a central part of this class, all the code from ulem has been incorporated into this class—you do not need to, and should not try to, load it again.

By a ‘switch’, I mean a single command that changes an internal parameter that affects the overall formatting of the exam. Switches should be included in the preamble, simply because that is the natural place to put them. Although, if one knows what one is doing, they may be placed elsewhere. The following describe all currently available switches:

\NumberOfVersions The \NumberOfVersions macro takes a single numerical argument—the number of different versions of the test to generate. It may be placed anywhere in the file, but I prefer to put it right after the \begin{document} so that in case it needs to be changed, one does not need to hunt through the entire exam. Note that, under the default settings, if you set the number of versions to more than 26, you will get an error. This is because the forms are labelled according to letters of the alphabet, and L^{A}TEX 2ε doesn’t like it when you try to ask for the 27th letter of the alphabet. If you really need more than 27 copies of an exam, you will need to use one of the special formatting environments, described in 3.1 to redefine certain fields.

\class The \class macro takes one argument: the name of the class to appear on the exam. For example, \class{Math 205A: Set Theory} will cause the name of the class to appear in the appropriate place (if you are using the default setting).

\examname \examname takes one argument, just like \class. The argument is used to iden-

tify the type of test. For example, \examname{Final Exam}, \examname{Midterm Exam},
\examname{Pop Quiz},. . .

\ConstantBlanks \ConstantBlanks has one mandatory argument (a length). It tells TEX to typeset the underline in fill-in-the-blank environments using lines of a constant length, regardless of the length of the correct word.

\ProportionalBlanks \ProportionalBlanks has one mandatory argument (a real number r). It tells TEX to typeset the underline in fill-in-the-blank environments using lines that are exactly r times the length of the correct answer when the correct answer is typeset by TEX. The default setting is \ProportionalBlanks{1}.

   If you include both \ConstantBlanks and \ProportionalBlanks in the

preamble, you will not get an error. Instead the exam will be typeset using whichever switch was last set.

\StudentInfoLineSpacing      \StudentInfoLineSpacing requires a length as its argument. This value is

used to determine the amount of additional spacing between lines in the student data box appearing in the upper right-hand corner of the exam. The default value is 6pt.

2.1.1 Summary of Options

Option Name  Required Package Function

Ordinary L^{A}TEX article options (except for

twocolumn)

none Ordinary function

twocolumn

multicol generate a two column exam

nokey

none suppress all answer keys

onekey

none generate only the first answer key, suppressing all others

noform

none suppress the labels identifying the form of the exam (only works for the default settings, see the description of examtop)

mcbold

none identify the correct answer in multiple-choice environments by using boldface

mcunderline

none identify the correct answer in multiple-choice environments by underlining it

2.1.2 Summary of Switches

Switch Name  Function

\NumberOfVersions specify number of exams to make

\class  Class data (E.g., “Philosophy 29”)
\examname  Exam name (E.g., “Midterm Exam”)

\ConstantBlanks  See above
\ProportionalBlanks  See above
\StudentInfoLineSpacing  Set spacing in data box

2.2 The fillin environment

fillin This environment is primarily intended for fill-in-the-blank questions (sad to say, such questions are asked in a college environment). The general syntax is

\begin{fillin}
  \begin{question}
    How much \blank{wood} could a \blank{woodchuck} chuck if a woodchuck could
    \blank{chuck} wood?
  \end{question}
  \begin{question}
     She sells \blank{seashells} by the \blank{seashore}.
  \end{question}
\end{fillin}

When typeset, the questions will be printed in the exam as:

1. How much  could a  chuck if a woodchuck could  wood?
2. She sells  by the  .

but in the answer key as:

1. How much \underline{wood} could a \underline{woodchuck} chuck if a woodchuck could \underline{chuck} wood?

2. She sells \underline{seashells} by the \underline{seashore}.

2.3 The shortanswer environment

shortanswer The most likely type of question asked on university exams is the short-answer question. Whether it be mathematics, physics, or philosophy (my three areas of interest, in no particular order), such questions allow the instructor to assess the student’s breadth of knowledge. The shortanswer environment does not format its questions in any particular way other than enumerating them, but it does allow the binding of answers to questions. Although including an answer is not mandatory, I find it helpful just to note exactly what it was that I had in mind at the time I asked the question. And your TA’s will probably like it, too. The general syntax is:

 \begin{shortanswer}
   \begin{question}
     State Hobbes' definition of the state of nature and the role it plays in
     his social philosophy.
     \begin{answer}
       The state of nature is\ldots
     \end{answer}
   \end{question}
   \begin{question}
     State several examples that seem to illustrate that Mill's theory of
     Utilitarianism cannot be followed in practice, and explain why.
     Afterwards, state Mill's response to the problems you raised.
     \begin{answer}
       Often times it appears we need to act on our moral instincts without
       taking time to deliberate (as in the case of saving a drowning child).
       According to Mill, though, it seems that before each moral action we
       ought to deliberate in order to be sure that the action we take is such
       as to maximize the overall general utility\ldots
     \end{answer}
   \end{question}
 \end{shortanswer}

Note that the answer environment appears inside the question environment. This is important and bad things will happen if you don’t do it.

In the exam, this will be typeset as:

1. State Hobbes’ definition of the state of nature and the role it plays in his social philosophy.

2. State several examples that seem to illustrate that Mill’s theory of Utilitarianism cannot be followed in practice, and explain why. Afterwards, state Mill’s response to the problems you raised.

In the answer key, this will be typeset as:

1. State Hobbes’ definition of the state of nature and the role it plays in his social philosophy.

Answer: The state of nature is…

2. State several examples that seem to illustrate that Mill’s theory of Utilitarianism cannot be followed in practice, and explain why. Afterwards, state Mill’s response to the problems you raised.

Answer: Often times it appears we need to act on our moral instincts without taking time to deliberate (as in the case of saving a drowning child). According to Mill, though, it seems that before each moral action we ought to deliberate in order to be sure that the action we take is such as to maximize the overall general utility…

2.4 The truefalse environment

truefalse I have a running debate with a friend over whether true/false questions have any merit as a tool for measuring comprehension. Regardless of that, I decided to include them anyway. The general syntax is:

\begin{truefalse}
\begin{question}
\answer{False} Laden swallows fly faster than unladen swallows,
especially if they carry coconuts.
\end{question}
\begin{question}
\answer{True} Quantum mechanics was first stated using the
mathematical tools of Hilbert spaces by John von~Neumann.
\end{question}
\end{truefalse}

Again, notice that the answer environment appears within the question environment. The above will be typeset in the exam as:

Laden swallows fly faster than unladen swallows, especially if they carry coconuts.

Quantum mechanics was first stated using the mathematical tools of Hilbert spaces by John von Neumann.

It will be typeset in the answer key as:

\underline{False} Laden swallows fly faster than unladen swallows, especially if they carry coconuts.

\underline{True} Quantum mechanics was first stated using the mathematical tools of Hilbert spaces by John von Neumann.

2.5 The multiplechoice Environment

multiplechoice It isn’t difficult to format multiple choice questions in ordinary L^{A}TEX 2ε (just use multiply nested enumerate’s), but this environment has two nicer features: it provides for a simpler entry scheme, and in the answer key it boxes the correct answer. The syntax is:

 \begin{multiplechoice}
   \begin{question}
     How much wood could a woodchuck chuck if a woodchuck could chuck wood?
      \choice{A lot.}
      \choice{More than most.}
      \choice{Exactly $\pi$ cords.}
      \choice[!]{It depends on the nature of the woodchuck.}
   \end{question}
 \end{multiplechoice}

In the exam, this is typeset as:

1. How much wood could a woodchuck chuck if a woodchuck could chuck wood?

(a) A lot.

(b) More than most.

(c) Exactly π cords.

(d) It depends on the nature of the woodchuck.

In the answer key, if neither of the options mcbold nor mcunderline were given, the answer will be typeset as:

1. How much wood could a woodchuck chuck if a woodchuck could chuck wood?

(a) A lot.

(b) More than most.

(c) Exactly π cords.

(d) It depends on the nature of the woodchuck.

A couple of notes: you may have any number of choices—although I used four in the example, anything from 1–26 will work. Also, notice that the correct answer was specified by giving the optional argument of ! to \choice.

2.6 The fixed environment

fixed To put it very simply, fixed acts exactly the same as shortanswer, with the exception that the order of the questions is not rearranged for different copies of the exam. I intended it for, say, a block of essay questions at the end of the test. For such questions, usually there is a small number (like 2–3) and you don’t care about rearranging the order.

2.7 Starred forms of the above environments

Each of the above environments has a *-ed form that differs from the previous description only in that the default identifier is suppressed. That is, every unstarred environment begins with the identifier:

Section N. ⟨argument⟩

where N is the current section number and ⟨argument⟩ is an optional argument given to the environment. For example, if the first environment in an exam is a multiplechoice environment, including

 \begin{multiplechoice}[The Easy Questions]

in the input file will result in

Section 1. The Easy Questions

to be typeset in the exam.

However, one might not always desire the section identifier. If so, then using a *-ed environment suppresses the section identifer. If an optional arguments is given, it will be typeset flush left. E.g.,

 \begin{multiplechoice*}[The Hard Questions]

will produce

The Hard Questions

In the exam.

All the environments described above (with the exception of question and answer) can take an optional argument. This is meant to be a title for that particular section of the test, stating the number of points per question, etc.

2.8 The block environment

block Soon after version 1.01 of exam was released, several people pointed out to me that a highly desirable feature should be provided. The problem people faced was the following: Sometimes, when writing an exam, one wants to include a graph, table, etc. and then have several questions pertaining to that graph, table, etc. In the first release of exam it was impossible (well, impossible without using an undocumented “trick”) to do this, since every question would be randomly repositioned upon typesetting.

The block environment enables one to identify a group of questions, as well as some preceeding text, as a “block” that should be kept together even though the rest of the section gets rearranged. So, if one has three questions in a block, those questions will always be kept together, in the same order, but that block will be randomly shuffled with the rest of the questions in the section. (If this is unclear, take a look at the sample files.)

The syntax is straightforward. For example:

 \begin{block}
 Here is a spot where you can put some instructions, a graph, or whatever
 you want to preceed the questions in this block.
  \begin{question}
    This is the first question.
    \begin{answer}
      This is the answer to the first question.
    \end{answer}
  \end{question}
  \begin{question}
    This is the second question.
    \begin{answer}
      This is the answer to the second question.
    \end{answer}
  \end{question}
  \begin{question}
    This is the third question.
    \begin{answer}
      This is the answer to the third question.
    \end{answer}
  \end{question}
 \end{block}

Will keep those three questions together when the rearranging happens.

The block environment may be used in any of the previously described question environments.

3 Special Formatting Tools

The following environments, macros, and length parameters allow the user to customize virtually every aspect of the exam. As I describe below, the default settings of the exam are defined using these environments. None of these environments allow for setting the headers and footers of the exam (that will be one thing I’d like to add in the next release).

3.1 Special Formatting Environments

frontmatter Any material enclosed in the frontmatter environment will be typeset on a page (or pages) by itself before the exam (and the key, too). For example, if one wanted to make a cover sheet for the exam with the class name and a place for the student to write their name, i.d. number, and so forth.

endmatter Any material enclosed in the endmatter environment will be typeset on a page (or pages) by itself after the exam (and the key, too). For example, if one wanted to place a page with several important equations, constants, and tables at the end of the exam for students to reference, if needed.

examtop Any material enclosed in the examtop environment will be typeset on the next page following the frontmatter text, if an exam is being created, and will be omitted if an answer key is being created. The default settings of the exam class use this environment to create the area for the class name, student name, etc. as follows:

 \begin{examtop}
   \@@line{\parbox{3in}{\classdata \\
           \examtype\ifincludeform, Form: \fbox{\textsf{\Alph{version}}}\fi}
           \hfill
           \parbox{3in}{\normalsize \namedata}}
           \bigskip
 \end{examtop}

Where \classdata and \examtype are macros that use the current values assigned by the switches \class and \examname. \ifincludeform is defined to be true unless the noform option was given, in which case it is defined to be false.

The definition of \namedata is:

 \def\namedata{Name: \hrulefill \\[\namedata@vspace]
              Student Number: \hrulefill \\[\namedata@vspace]
              TA: \hrulefill \\[\namedata@vspace]
              Date: \hrulefill}
Where \namedata@vspace is the length set by the switch \StudentInfoLineSpacing.

For those who don’t know, \@@line is the L^{A}TEX 2ε equivalent of Plain TEX’s \line command. If you wish to use \@@line in defining your own examtop or keytop, please be sure to use \makeatletter and \makeatother in the appropriate places, otherwise you could get errors.

keytop Any material enclosed in the keytop environment will be typeset on the next page following the frontmatter text, if a key is being created, and will be omitted if an exam is being created. The default settings of the exam class use this environment to create the top of an answer key as follows:

  \begin{keytop}
  \@@line{\hfill \Huge Answer Key
          \ifincludeform for Exam \fbox{\textsf{\Alph{version}}}
          \fi \hfill}
          \bigskip
  \end{keytop}

exampreface Any material enclosed in the exampreface environment will be typeset on the same page as the examtop text, right beneath it but before any sections of the exam are included. In case you are wondering what this environment does that cannot be done with examtop, your question is very good. The difference is this: The material enclosed in the exampreface environment is sensitive to whether the twocolumn option was given. If the twocolumn option was given, then the material in exampreface will be typeset at the start of the first column. By contrast, the material given in examtop is always typeset in a single column spanning the entire textwidth of the page, at the top of the exam.

keypreface Any material enclosed in the keypreface environment will be typeset on the same page as the keytop text, right beneath it but before any sections are included. As described above, if the twocolumn option was given, then the material in keypreface will be typeset at the start of the first column. By contrast, the material given in keytop is always typeset in a single column spanning the entire textwidth of the page, at the top of the key.

examclosing Essentially the same as the exampreface environment, with the obvious change that the enclosed material is typeset at the end of the exam, on the same page as the rest of the exam (if possible), but before the endmatter. (Any material enclosed in an endmatter environment is typeset on a page by itself after the exam or key.)

keyclosing Essentially the same as the keypreface environment, with the obvious change that the enclosed material is typeset at the end of the key, on the same page as the rest of the key (if possible), but before the endmatter.

3.2 Special Formatting Macros

Due to the special way the exam class constructs a document (see the technical notes in section 4), several special macros are provided which enable the user to easily take advantage of the way exams are constructed. In addition, there are several lengths which the user can modify to further customize the appearance of the exam.

\exam The \exam macro takes one argument, which can be any command or sequence of commands subject to the constraints described in the technical notes. The argument will be included wherever it is if and only if an exam is being made, otherwise the argument will be ignored.

\key The \key macro takes one argument, which can be any command or sequence of commands subject to the constraints described in the technical notes. The argument will be included wherever it is if and only if a key is being made, otherwise the argument will be ignored.

\examvspace Just like the ordinary L^{A}TEX command \vspace, with the exception that the

vertical space is included if and only if an exam is being typeset.

\examvspace* Just like the ordinary L^{A}TEX command \vspace*, with the exception that the

vertical space is included if and only if an exam is being typeset.

\examhspace Just like the ordinary L^{A}TEX command \hspace, with the exception that the

horizontal space is included if and only if an exam is being typeset.

\examhspace* Just like the ordinary L^{A}TEX command \hspace*, with the exception that the

horizontal space is included if and only if an exam is being typeset.

\keyvspace Just like the ordinary L^{A}TEX command \hspace*, with the exception that the

horizontal space is included if and only if a key is being typeset.

\keyvspace* Just like the ordinary L^{A}TEX command \hspace*, with the exception that the

horizontal space is included if and only if a key is being typeset.

\keyhspace Just like the ordinary L^{A}TEX command \hspace*, with the exception that the

horizontal space is included if and only if a key is being typeset.

\keyhspace* Just like the ordinary L^{A}TEX command \hspace*, with the exception that the

horizontal space is included if and only if a key is being typeset. \word The last new command (in version 1.02) is \word. This command allows the

user to insert inessential changes in the wording of a question between various versions of the exam. Thus, not only will the order of the questions be different, but the actual wording of the questions will be slightly different as well. For example, if one includes:

 \begin{question}
 Is the most well-known \word{{astronomer} {wrestler} {physicist}} in
 the world \word{{Carl Sagan} {Rowdy Roddy Piper} {Albert Einstein}}?
 \end{question}

in an exam, the first version of the exam will include the question

1. Is the most well-known astronomer in the world Carl Sagan?

but the second version of the exam will include

1. Is the most well-known wrestler in the world Rowdy Roddy Piper?

and the third version of the exam will include

1. Is the most well-known physicist in the world Albert Einstein?

Let’s call the argument of \word an option-list. If one requests more versions of an exam than options in an option-list, \word will behave as if the option list you gave “wrapped.” That is, if one requests five copies of an exam but includes \word{{A} {B}} in the input file, A will be printed on the fifth version of the exam, because \word will act as if the option list was

\word{{A} {B} {A} {B} {A} {B}}, where A is the fifth option.

If it turns out that your exams are becoming absolutely unreadable through excessive use of \word, chances are you are not introducing inessential changes in the wording of a question, but are actually trying to write two different exams simultaneously.

3.3 Length Parameters

The following table describes lengths that the user may set to whatever value they wish, and the effect that it has upon the appearance of the exam (or key).

Length  Initial Value  Effect

 \beforesectsep  \medskipamount  Space inserted before the cur-

rent section heading.

 \aftersectsep   \medskipamount  Space inserted after the cur-

rent section heading.

 \beforeinstsep  \medskipamount  Space inserted before any in-

structions for the current section are typeset.

 \afterinstsep   \medskipamount-\topsep Space inserted after the in-

structions for the current section but before the questions.

Given the above parameters, there are two rules that determine whether space is inserted. (1) If the section heading is empty (as might happen if someone used a starred environment form and then did not include any optional argument), then neither \beforesectsep nor \aftersecsep are used to insert vertical space, and (2) if there are no instructions for a section, then neither \beforeinstsep nor \afterinstsep are used to insert vertical space.

4 Technical Notes

Most L^{A}TEX commands will work without a problem in the exam class, but there is one noteworthy class of exceptions: no command, environment, or macro that involves a catcode change will work with the exam class. For example, neither \verb nor the enumerate environment will work within the exam class since catcode changes are essential to the operation of these environments. The reason for this restriction has to do with how the exam class creates an exam.

Very briefly (and this is all one needs to know, unless one wants to hack some the code), the idea is this: every section header, block header, instructions, and question is saved to a uniquely named macro which allows the exam class to retrieve it when it is needed. Since all of these things are saved in macros, TEX “peeks” at each character (without typesetting it) when it reads the file. Consequently, every character in the exam gets a catcode assigned to it before any typesetting takes place.

Future versions of the exam class might lift this restriction (and just use token lists for everything, instead of macros), but there are two possible problems with this approach: first, TEX limits the number of distinct token lists to only 256— which shouldn’t really a problem, in practice, but could. Second, it has been my experience that a single token list cannot store nearly the amount of information that a single macro can. For example, on my machine (a Dell 166 w/ 32MB RAM running MikTeX), I can only store approximately 15 pages of material in a single token list, whereas I can store approximately 45–50 pages of material in a single macro. So, even if I were to assign distinct token lists to each section of the exam, no single section of the exam could contain more than 15 pages of material without exceeding the memory on some systems.

I’ll have to think about it.

4.1 Bugs

This isn’t really a “bug”, so to speak, because it doesn’t cause any crashes, but it is an instance of unexplained L^{A}TEX behavior that I cannot figure out. Use of the block environment sometimes causes underfull hbox warnings. I cannot, at this point, diagnose the source of the problem. Fortunately, though, this bug does not seem to cause any visible typesetting errors. Anyone who figures this out and tells me how to fix it shall be awarded $10.00 and my permanent gratitude.

4.2 Changes

Previous releases of the exam class required that instructions for a given section be specified as such by using the \instructions command. The need for using \instructions has been lifted as of release 1.02. The rule is this: all material between the start of a section and the first \begin{question} or \begin{block} will be taken to be the instructions for that section. Old exams created with \instructions should still work with the new release (the \instructions macro has simply been redefined as \relax).

Thus, if you are using fixed to format a series of essay questions, you might want to tell students that they only need to write answers to two of the following three questions. The instruction text is always typeset at the beginning of a section, before any questions are typeset.

5 The Code

First just some declarations and stuff that says we are building an extension to the ordinary L^{A}TEX class article.

1 ⟨∗header⟩

 2 \ProvidesFile{exam.dtx}
 3 \NeedsTeXFormat{LaTeX2e}
 4 \ProvidesClass{exam}
 5 \newcounter{passes}
 6 \setcounter{passes}{2}
 7 \newif\ifincludeform
 8 \includeformtrue
 9 \newif\ifmcbold \mcboldfalse
10 \newif\ifmcunder \mcunderfalse
11 \newif\ifulem \ulemfalse
12 \newif\ifbox \boxtrue
13 \newif\iftwocolumn \twocolumnfalse
14 \gdef\@OneKeyHook{\relax}
15 \DeclareOption{mcbold}{\mcboldtrue\boxfalse}
16 \DeclareOption{mcunderline}{\mcundertrue \boxfalse}

17 \DeclareOption{nokey}{\setcounter{passes}{1}}
18 \DeclareOption{onekey}{\setcounter{passes}{2}
19 \gdef\@OneKeyHook{\setcounter{passes}{1}
20  \gdef\@OneKeyHook{\relax}}}
21 \DeclareOption{noform}{\includeformfalse}
22 \DeclareOption{twocolumn}{\twocolumntrue}
23 \DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
24 \ProcessOptions
25 \LoadClass{article}
26 \iftwocolumn \RequirePackage{multicol} \fi
27 \ifmcbold
28 \ifmcunder
29  \def\MCfont#1{\textbf{\uline{#1}}}
30 \else
31  \def\MCfont#1{\textbf{#1}}
32 \fi
33 \else
34 \ifmcunder
35  \def\MCfont#1{\uline{#1}}
36 \else
37  \def\MCfont#1{\relax{#1}}
38 \fi
39 \fi

40 ⟨/header⟩

5.1 The random number generator

RANDOM.TEX v.1 (Donald Arseneau) Generating random numbers in TeX.

\nextrandom Random integers are generated in the range 1 to 2147483646 by the macro \nextrandom. The result is returned in the counter \randomi. Do not change \randomi except, perhaps, to initialize it at some random value. If you do not initialize it, it will be initialized using the time and date. (This is a sparse initialization, giving fewer than a million different starting values, but you should use other sources of numbers if they are available–just remember that most of the numbers available to TEXare not at all random.)

\setrannum The \nextrandom command is not very useful by itself, unless you have exactly 2147483646 things to choose from. Much more useful is the \setrannum command which sets a given counter to a random value within a specified range. There are three parameters: \setrannum{⟨counter⟩}{⟨minimum⟩}{⟨maximum⟩}. For

example, to simulate a die-roll: \setrannum{\die}{1}{6} \ifcase\die. . .

\setrandimen If you need random numbers that are not integers, you will have to use

\pointless dimen registers and \setrandimen. For example, to set a random page

width: \setrandimen \hsize{3in}{6.5in}. The “\pointless” macro will

remove the “pt” that TeX gives so you can use the dimensions as pure ‘real’ numbers. In that case, specify the range in pt units. For example,

\setrandimen\answer{2.71828pt}{3.14159pt} The answer is \pointless\answer.

The random number generator is the one by Lewis, Goodman, and Miller (1969) and used as ran0 in Numerical Recipies using Schrage’s method for avoiding overflows. The multiplier is 16807(7^{5}) the added constant is 0, and the modulus is 147483647(2^{31} − 1) The range of integers generated is 1 − 2147483646. A smaller range would reduce the complexity of the macros a bit, but not much– most of the code deals with initialization and type-conversion. On the other hand, the large range may be wasted due to the sparse seed initialization.

I do not include the code in the documentation.

5.2 Incorporating the package ulem

This code is not listed in the documentation.

5.3 The code for the exam class

We now define an environment question that saves the surrounded text to a macro \sec@⟨section-number⟩@qst⟨question-number⟩, where ⟨section-number⟩ and ⟨question-number⟩ are expressed as lower case roman numerals (this way they can be part of the macro name). Note that we must use lower case roman numerals since, I believe, L^{A}TEX 2ε the \Roman command uses the \uppercase command, which is not expanded fully until further along in TEX’s gullet than we want.

First, define some new counters and token lists.

41 ⟨∗othercode⟩

42 \setcounter{section}{0}
43 \newcounter{extract}
44 \newcounter{question} \setcounter{question}{1}
45 \newcounter{length} \setcounter{length}{0}
46 \newcounter{temp} \setcounter{temp}{1}
47 \newcounter{wordtemp} \setcounter{wordtemp}{1}
48 \newcounter{form}
49 \newcounter{version}
50 \newcounter{current@section}
51 \newcounter{current@question}
52 \newcounter{innerloop}
53 \newcounter{sect}
54 \newcounter{sectionindex}
55 \newcounter{answer}
56 \newcounter{choice}
57 \setcounter{choice}{1}
58 \newcounter{mcquestion} \setcounter{mcquestion}{1}
59 \newcounter{mcchoice} \setcounter{mcchoice}{1}
60 \newcounter{savelistcnt}
61 \newlength{\blank@length}
62 \newlength{\temp@length}
63 \newlength{\temp@@length}
64 \newlength{\namedata@vspace}
65 \newlength{\beforesectsep}
66 \setlength{\beforesectsep}{\medskipamount}
67 \newlength{\aftersectsep}
68 \setlength{\aftersectsep}{\medskipamount}

69 \newlength{\beforeinstsep}
70 \setlength{\beforeinstsep}{\medskipamount}
71 \newlength{\afterinstsep}
72 \setlength{\afterinstsep}{\medskipamount}
73 \addtolength{\afterinstsep}{-\topsep}
74 \newif\ifchoice \choicefalse
75 \newif\ifanswer
76 \newif\ifnotfixed
77 \newif\ifcblanks \cblanksfalse
78 \newif\ifpblanks \pblankstrue
79 \newif\ifidentifier \identifierfalse
80 \newif\ifFirstQuestionInBlock \FirstQuestionInBlocktrue
81 \global\newtoks\temptoks
82 \global\newtoks\temp@toks

\setrannum requires a “traditional” counter (i.e., a non-L^{A}TEXcounter (i.e., a counter whose name doesn’t begin with c@.

83 \newcount\exam@c
84 \newcount\exam@n
85 \newcount\exam@m
86 \setrannum{\exam@m}{1}{10}
87 \newtoks\@toklist

section Questions naturally occur in blocks which have, more-or-less, the same general format. For example, one will naturally have a block of true/false questions together, followed by a block of short answer, and then a block of essay questions. We don’t want to mix questions between blocks (so that the true/false questions are interspersed between the short answer questions). Thus we need to index the questions by section type as well as question number.

88 \def\section{\stepcounter{section}
89 \setcounter{question}{1}}

\get@instructions This macro collects everything between it and the next \begin token. It then calls the \find@instructions@end macro to check whether the \begin token belongs to the question environment or some other environment.

90 \long\def\get@instructions#1\begin{\@toklist=\expandafter{\the\@toklist#1}%
91 \find@instructions@end}
\find@instructions@end If we are at \begin{question} or \begin{block} save everything to the appro-

priately named macro. Otherwise, continue collecting tokens

92 \def\find@instructions@end#1{%
93 \def\@tempa{#1}%
94 \ifx\@tempa\@Q
95  \let\@next=\Qwrap@up@instructions
96 \else
97  \ifx\@tempa\@Block
98  \let\@next=\Bwrap@up@instructions
99  \else
100  \@toklist=\expandafter{\the\@toklist\begin{#1}}%

101  \let\@next=\get@instructions
102 \fi\fi\@next}

\Qwrap@up@instructions Use the counters section and question to save the collected token list in a macro named as described earlier.

103 \def\Qwrap@up@instructions{%
104 \edef\@@temp{\roman{section}}
105 \expandafter\xdef\csname inst@sec\@@temp\endcsname{\the\@toklist}
106 \begin{question}}
107 % \end{macro}

108 %

109 % \begin{macro}{\Bwrap@up@instructions}
110 % Use the counters |section| and |question| to save the collected token list
111 % in a macro named as described earlier.
112 %    \begin{macrocode}
113 \def\Bwrap@up@instructions{%
114 \edef\@@temp{\roman{section}}
115 \expandafter\xdef\csname inst@sec\@@temp\endcsname{\the\@toklist}
116 \begin{block}}
117 % \end{macro}

118 %

119 % \begin{macro}{\endsection}
120 % At the end of a section, make a list of question indexes.
121 %    \begin{macrocode}
122 \def\endsection{\make@qlist}

\make@qlist As described below, we need to create a token list containing the index numbers of each question. This is done by a while-loop as follows:

123 \def\make@qlist{%
124 \setcounter{temp}{1}
125 \edef\@tempa{\roman{section}}%

We need to create a new token list to hold the question indexes. While we are at it, might as well create the token list to hold the rearranged question indexes. This saves us having to include a while-loop later.

126 \global\expandafter\newtoks\csname qlist@sec\@tempa\endcsname
127 \global\expandafter\newtoks\csname qlist@scr@sec\@tempa\endcsname
128 \global\csname qlist@scr@sec\@tempa\endcsname={}

Now being a while-loop where each pass through the loop appends an index number to the question list.

129 \@whilenum \value{question}>1 \do{%
130  \edef\@questionnumber{\arabic{temp}}%
131  \expandafter\append\expandafter{\@questionnumber}%
132  {\csname qlist@sec\@tempa\endcsname}
133  \addtocounter{question}{-1}
134  \addtocounter{temp}{1}}}

5.4 The question environment

\question We define \question so that it reads in and saves the surround text to a macro like in the tabularx environment.

135 \def\question{\@toklist={}
136 \get@question@body}

\endquestion Increment the question counter so that the next question will be assigned the right name

137 \def\endquestion{\stepcounter{question}}

\get@question@body This macro collects everything between it and the next \end token. It then calls the \find@question@end macro to check whether the \end token belongs to the question environment or some other environment.

138 \long\def\get@question@body#1\end{\@toklist=\expandafter{\the\@toklist#1}%
139 \find@question@end}

\find@question@end If we are at \end{question}, save everything to the appropriately named macro. Otherwise, continue collecting tokens

140 \def\find@question@end#1{%
141 \def\@tempa{#1}%
142 \ifx\@tempa\@Q\expandafter\wrap@up
143  \else\@toklist=\expandafter{\the\@toklist\end{#1}}%
144  \expandafter\get@question@body\fi}

\wrap@up Use the counters section and question to save the collected token list in a macro named as described earlier.

145 \def\wrap@up{%
146 \edef\@tempa{\roman{section}}%
147 \edef\@tempb{\roman{question}}%
148 \ifx\@currentsectionname\@truefalse
149 \expandafter\xdef\csname sec\@tempa @qst\@tempb\endcsname{%
150  \noexpand\@tfitem
151  \noexpand\@beforequestionhook
152  \the\@toklist
153  \noexpand\@endquestionhook}
154 \else
155 \ifx\@currentsectionname\@truefalsestar
156  \expandafter\xdef\csname sec\@tempa @qst\@tempb\endcsname{%
157  \noexpand\@tfitem
158  \noexpand\@beforequestionhook
159  \the\@toklist
160  \noexpand\@endquestionhook}
161  \else
162  \ifx\@currentsectionname\@MC
163  \expandafter\xdef\csname sec\@tempa @qst\@tempb\endcsname{%
164  \noexpand\@mcitem
165  \noexpand\begin{minipage}[t]{\noexpand\linewidth}
166  \noexpand\@beforequestionhook

167  \the\@toklist
168  \noexpand\@mcenditem
169  \noexpand\end{minipage}
170  \noexpand\@endquestionhook}
171  \else
172  \ifx\@currentsectionname\@MCstar
173  \expandafter\xdef\csname sec\@tempa @qst\@tempb\endcsname{%
174  \noexpand\@mcitem
175  \noexpand\begin{minipage}[t]{\noexpand\linewidth}
176  \noexpand\@beforequestionhook
177  \the\@toklist
178  \noexpand\@mcenditem
179  \noexpand\end{minipage}
180  \noexpand\@endquestionhook}
181  \else
182  \expandafter\xdef\csname sec\@tempa @qst\@tempb\endcsname{%
183  \noexpand\item
184  \noexpand\@beforequestionhook
185  \the\@toklist
186  \noexpand\@endquestionhook}
187 \fi\fi\fi\fi
188 \end{question}}

\@Q Store the name of the environment for comparison in \find@question@end

189 \def\@Q{question}

5.5 The block environment

\block This macro provides a “block” environment that prevents the questions it surrounds from being rearranged.

190 \def\block{\@toklist={}
191 \get@block@body}
\get@block@body
192 \long\def\get@block@body#1\end{\@toklist=\expandafter{\the\@toklist #1}%
193 \find@block@end}
\find@block@end
194 \def\find@block@end#1{%
195 \def\@tempa{#1}%
196 \ifx\@tempa\@Block\expandafter\block@wrap@up
197  \else\@toklist=\expandafter{\the\@toklist\end{#1}}%
198  \expandafter\get@block@body\fi}
\block@wrap@up
199 \def\block@wrap@up{%
200 \edef\@tempa{\roman{section}}%
201 \edef\@tempb{\roman{question}}%
202 \expandafter\xdef\csname sec\@tempa @qst\@tempb\endcsname{%

203 \noexpand\@startofblockhook
204 \noexpand\@blockbreaklist
205 \the\@toklist
206 \noexpand\@endofblockhook}%
207 \end{block}}
\@startofblockhook
208 \def\@startofblockhook{\relax}

\@blockbreaklist This macro keeps any text from the start of a block from being too closely connected with the previous question. The \item[] is necessary in case the randomizing routine moves the block so that it is the first question (without an \item we get an error as L^{A}TEX 2ε will complain about a “missing \item”.

209 \def\@blockbreaklist{\@testforquestion}

\@testforquestion Checks to see if the tokens immediately following \begin{block}are the tokens \begin{question}. We have to use 3 arguments because when we called \get@block@body to get the material for \@toklist, we followed it with a \relax command (I’m not sure why I did this, but apparently I had a reason at the time). Thus what we are interested in testing are not the first two tokens of \@toklist but rather the second and third tokens.

210 \def\@testforquestion#1#2{%
211 \def\@@@temp{#2}
212 \ifx#1\begin
213  \ifx\@@@temp\@Q
214  \relax
215  \else
216  \item[]
217  \fi
218 \else
219  \item[]
220 \fi #1{#2}}
\@endofblockhook
221 \def\@endofblockhook{\relax}
\@Block
222 \def\@Block{block}
\endblock
223 \def\endblock{\stepcounter{question}}

5.6 The frontmatter environment

\frontmatter We define \frontmatter so that it reads in and saves the surround text to a macro like in the tabularx environment.

224 \def\frontmatter{\@toklist={}
225 \get@frontmatter@body}

\endfrontmatter This doesn’t need to do anything.

226 \def\endfrontmatter{\relax}

\get@frontmatter@body This macro collects everything between it and the next \end token. It then calls the \find@frontmatter@end macro to check whether the \end token belongs to the frontmatter environment or some other environment.

227 \long\def\get@frontmatter@body#1\end{%
228 \@toklist=\expandafter{\the\@toklist#1}%
229 \find@frontmatter@end}

\find@frontmatter@end If we are at \end{frontmatter}, save everything to the appropriately named macro. Otherwise, continue collecting tokens

230 \def\find@frontmatter@end#1{%
231 \def\@tempa{#1}%
232 \ifx\@tempa\@Frontmatter
233  \expandafter\frontmatter@wrap@up
234 \else
235  \@toklist=\expandafter{\the\@toklist\end{#1}}%
236  \expandafter\get@frontmatter@body
237 \fi}

\frontmatter@wrap@up Save all the scanned text into an appropriately named macro for later recall.

238 \def\frontmatter@wrap@up{%
239 \xdef\@frontmattertext{\the\@toklist}
240 \end{frontmatter}}

\@Frontmatter Store the name of the environment for comparison in \find@frontmatter@end

241 \def\@Frontmatter{frontmatter}

5.7 The endmatter environment

The endmatter environment behaves just like the frontmatter environment, except the enclosed text is saved in a differently-named macro.

\endmatter We define \endmatter so that it reads in and saves the surround text to a macro like in the tabularx environment.

242 \def\endmatter{\@toklist={}
243 \get@endmatter@body}

\endendmatter This doesn’t need to do anything.

244 \def\endendmatter{\relax}

\get@endmatter@body This macro collects everything between it and the next \end token. It then calls the \find@endmatter@end macro to check whether the \end token belongs to the endmatter environment or some other environment.

245 \long\def\get@endmatter@body#1\end{%
246 \@toklist=\expandafter{\the\@toklist#1}%
247 \find@endmatter@end}

\find@endmatter@end If we are at \end{endmatter}, save everything to the appropriately named macro. Otherwise, continue collecting tokens

248 \def\find@endmatter@end#1{%
249 \def\@tempa{#1}%
250 \ifx\@tempa\@Endmatter
251  \expandafter\endmatter@wrap@up
252 \else
253  \@toklist=\expandafter{\the\@toklist\end{#1}}%
254  \expandafter\get@endmatter@body
255 \fi}

\endmatter@wrap@up Save the scanned text to an appropriately named macro for later recall.

256 \def\endmatter@wrap@up{%
257 \xdef\@endmattertext{\the\@toklist}
258 \end{endmatter}}

\@Endmatter Store the name of the environment for comparison in \find@endmatter@end

259 \def\@Endmatter{endmatter}
   We now initialize \@frontmattertext and \@endmattertext to a randomly

chosen garbage value that no user will ever use. This enables us to test in the main loop whether the user has used frontmatter or endmatter in her document.

260 \begin{frontmatter}
261 \relax
262 \end{frontmatter}
263 \begin{endmatter}
264 \relax
265 \end{endmatter}

5.8 The exampreface environment

The exampreface environment behaves just like the frontmatter environment, except the enclosed text is saved in a differently-named macro—one that will be printed just beneath any text specified in the examtop environment.

\exampreface We define \exampreface so that it reads in and saves the surround text to a macro like in the tabularx environment.

266 \def\exampreface{\@toklist={}
267 \get@exampreface@body}

\endexampreface This doesn’t need to do anything.

268 \def\endexampreface{\relax}

\get@exampreface@body This macro collects everything between it and the next \end token. It then calls the \find@exampreface@end macro to check whether the \end token belongs to the exampreface environment or some other environment.

269 \long\def\get@exampreface@body#1\end{%
270 \@toklist=\expandafter{\the\@toklist#1}%
271 \find@exampreface@end}

\find@exampreface@end If we are at \end{exampreface}, save everything to the appropriately named macro. Otherwise, continue collecting tokens

272 \def\find@exampreface@end#1{%
273 \def\@tempa{#1}%
274 \ifx\@tempa\@Exampreface
275  \expandafter\exampreface@wrap@up
276 \else
277  \@toklist=\expandafter{\the\@toklist\end{#1}}%
278  \expandafter\get@exampreface@body
279 \fi}

\exampreface@wrap@up Save the scanned text to an appropriately named macro for later recall.

280 \def\exampreface@wrap@up{%
281 \xdef\@examprefacetext{\the\@toklist}
282 \end{exampreface}}

\@Exampreface Store the name of the environment for comparison in \find@exampreface@end

283 \def\@Exampreface{exampreface}

5.9 The examclosing environment

The examclosing environment behaves just like the frontmatter environment, except the enclosed text is saved in a differently-named macro.

\examclosing We define \examclosing so that it reads in and saves the surround text to a macro like in the tabularx environment.

284 \def\examclosing{\@toklist={}
285 \get@examclosing@body}

\endexamclosing This doesn’t need to do anything.

286 \def\endexamclosing{\relax}

\get@examclosing@body This macro collects everything between it and the next \end token. It then calls the \find@examclosing@end macro to check whether the \end token belongs to the examclosing environment or some other environment.

287 \long\def\get@examclosing@body#1\end{%
288 \@toklist=\expandafter{\the\@toklist#1}%
289 \find@examclosing@end}

\find@examclosing@end If we are at \end{examclosing}, save everything to the appropriately named macro. Otherwise, continue collecting tokens

290 \def\find@examclosing@end#1{%
291 \def\@tempa{#1}%
292 \ifx\@tempa\@Examclosing
293  \expandafter\examclosing@wrap@up
294 \else
295  \@toklist=\expandafter{\the\@toklist\end{#1}}%
296  \expandafter\get@examclosing@body
297 \fi}

\examclosing@wrap@up Save the scanned text to an appropriately named macro for later recall.

298 \def\examclosing@wrap@up{%
299 \xdef\@examclosingtext{\the\@toklist}
300 \end{examclosing}}

\@Examclosing Store the name of the environment for comparison in \find@examclosing@end

301 \def\@Examclosing{examclosing}
   We now initialize \@\examprefacetext and \@examclosingtext to \relax so

that in case the user doesn’t specify any special text, nothing will be typeset in the actual exam.

302 \begin{exampreface}
303 \relax
304 \end{exampreface}
305 \begin{examclosing}
306 \relax
307 \end{examclosing}

5.10 The keypreface environment

The keypreface environment behaves just like the frontmatter environment, except the enclosed text is saved in a differently-named macro—one that will be printed just beneath any text specified in the keytop environment.

\keypreface We define \keypreface so that it reads in and saves the surround text to a macro like in the tabularx environment.

308 \def\keypreface{\@toklist={}
309 \get@keypreface@body}

\endkeypreface This doesn’t need to do anything.

310 \def\endkeypreface{\relax}

\get@keypreface@body This macro collects everything between it and the next \end token. It then calls the \find@keypreface@end macro to check whether the \end token belongs to the keypreface environment or some other environment.

311 \long\def\get@keypreface@body#1\end{%
312 \@toklist=\expandafter{\the\@toklist#1}%
313 \find@keypreface@end}

\find@keypreface@end If we are at \end{keypreface}, save everything to the appropriately named macro. Otherwise, continue collecting tokens

314 \def\find@keypreface@end#1{%
315 \def\@tempa{#1}%
316 \ifx\@tempa\@Keypreface
317  \expandafter\keypreface@wrap@up
318 \else
319  \@toklist=\expandafter{\the\@toklist\end{#1}}%
320  \expandafter\get@keypreface@body
321 \fi}

\keypreface@wrap@up Save the scanned text to an appropriately named macro for later recall.

322 \def\keypreface@wrap@up{%
323 \xdef\@keyprefacetext{\the\@toklist}
324 \end{keypreface}}

\@Keypreface Store the name of the environment for comparison in \find@keypreface@end

325 \def\@Keypreface{keypreface}

5.11 The keyclosing environment

The keyclosing environment behaves just like the frontmatter environment, except the enclosed text is saved in a differently-named macro.

\keyclosing We define \keyclosing so that it reads in and saves the surround text to a macro like in the tabularx environment.

326 \def\keyclosing{\@toklist={}
327 \get@keyclosing@body}

\endkeyclosing This doesn’t need to do anything.

328 \def\endkeyclosing{\relax}

\get@keyclosing@body This macro collects everything between it and the next \end token. It then calls the \find@keyclosing@end macro to check whether the \end token belongs to the keyclosing environment or some other environment.

329 \long\def\get@keyclosing@body#1\end{%
330 \@toklist=\expandafter{\the\@toklist#1}%
331 \find@keyclosing@end}

\find@keyclosing@end If we are at \end{keyclosing}, save everything to the appropriately named macro. Otherwise, continue collecting tokens

332 \def\find@keyclosing@end#1{%
333 \def\@tempa{#1}%
334 \ifx\@tempa\@Keyclosing
335  \expandafter\keyclosing@wrap@up
336 \else
337  \@toklist=\expandafter{\the\@toklist\end{#1}}%
338  \expandafter\get@keyclosing@body
339 \fi}

\keyclosing@wrap@up Save the scanned text to an appropriately named macro for later recall.

340 \def\keyclosing@wrap@up{%
341 \xdef\@keyclosingtext{\the\@toklist}
342 \end{keyclosing}}

\@Keyclosing Store the name of the environment for comparison in \find@keyclosing@end

343 \def\@Keyclosing{keyclosing}

   We now initialize \@keyprefacetext and \@keyclosingtext to \relax so

that in case the user doesn’t specify any special text, nothing will be typeset in the actual exam.

344 \begin{keypreface}
345 \relax
346 \end{keypreface}
347 \begin{keyclosing}
348 \relax
349 \end{keyclosing}

5.12 Macros for manipulating token lists

In order to make manipulation of token lists easier, (or, really, to just increase the overall readability of the syntax, we define some macros to manipulate token lists.

\append \append{⟨string⟩}{⟨token-list⟩} appends ⟨string⟩ to the rightmost end of ⟨token-list⟩.

Note that we use \@separator between entries in the list, rather than \\ as recommended in the TEXbook, since we will later want to redefine the list separator and execute the list. If we used \\, we run into potential conflicts in executing the list, since L^{A}TEX 2ε, at any given point during the execution of the list entry, might redefine \\ in such a way as to screw things up.

350 \def\append#1#2{%
351 \global\temp@toks=\expandafter{\the #2\@separator {#1}}%
352 \global#2=\expandafter{\the\temp@toks}}

\length The usage is \length{⟨token-list⟩}. So \length{\foo} computes the length of the token list \foo, where it is assumed that the separator between list elements

is \@separator.
353 \def\length#1{%
354 \setcounter{length}{0}
355 \def\@separator##1{\stepcounter{length}}\the#1}

\remove \remove{⟨number⟩}{⟨token-list⟩} removes the ⟨number⟩th element from the token list ⟨token-list⟩, redefining ⟨token-list⟩ to be that list. As always, we assume that the list elements are separated by the token \@separator.

356 \def\remove#1#2{%
357 \exam@c=0
358 \temptoks={}
359 \def\@separator##1{\advance\exam@c by 1\relax
360  \ifnum\exam@c=#1\relax%
361  \setcounter{extract}{##1}%
362  \else\append{##1}{\temptoks}
363  \fi}
364 \the#2
365 \global#2=\expandafter{\the\temptoks}}

5.13 Scrambling the order of the questions

The general idea is that, for each section, we form a token list named \qlist@sec⟨c⟩

of the form: {\@separator{1}\@separator{2}. . . \@separator{⟨n⟩} where ⟨c⟩ is

the number of the section (in roman numerals), and ⟨n⟩ is the number of questions in section ⟨c⟩. We call a while-loop to loop ⟨n⟩ times, each time removing a randomly chosen entry from the token list. This entry is appended to the list \qlist@scr⟨m⟩@sec⟨c⟩, where ⟨m⟩ is the current value (in roman numerals) of the form we are generating. Once this list is built, we can then typeset the questions by simply redefining \@separator and executing the new scrambled list.

\@enddocumenthook Redefine the \@enddocumenthook so that the questions are automatically generated without the user needing to insert a command after all the question blocks. This has the ironic effect that absolutely nothing the user sees in the input file causes the text to be created. I haven’t been real careful to prevent collisions occurring with other applications that use \@enddocumenthook, so this could be a source of problems.

First, save any previously assigned meaning to \@enddocumenthook so that we don’t clobber it.

366 \let\@oldenddocumenthook=\@enddocumenthook
367 \def\@enddocumenthook{%

First, in case someone used the block environment, redefine the question environment so that it does the right thing.

368 \gdef\question{\item \@beforequestionhook}
369 \gdef\endquestion{\@endquestionhook}

We need to create the number of forms specified, so we loop over the total number of forms. Initialize the counter version to 1 (this is the value we will loop over) and step the counter form (so that we actually generate all the forms that the user wants).

370 \setcounter{version}{1}
371 \stepcounter{form}

Loop until the value of version exceeds form.

372 \@whilenum \value{version}<\value{form} \do{%

But two passes per exam are needed (once for the exam, once for the answers), so we create an “inner-loop” to take care of this problem. Since we will want the answer key to have a slightly different format (where the answers are included!) it pays to make this on the second pass.

373  \setcounter{innerloop}{0}
374  \@whilenum \value{innerloop}<\value{passes} \do{%

Reset the page counter so that no new exams or answer keys start on page 17 (for example).

375  \setcounter{page}{1}

If innerloop=0, we are making an exam. If not, we are making an answer key, so take the appropriate action for the top of the form. Since we won’t want absentminded professors to make 200+ copies of the answer key, print the title of the answer key using \Huge to call attention to it.

376  \ifx\@frontmattertext\relax
377  \relax
378  \else
379  \@frontmattertext \pagebreak
380  \fi
381  \ifnum \value{innerloop}=0 %
382  \@examtopmatter
383  \answerfalse
384  \iftwocolumn \begin{multicols}{2}\fi
385  \@examprefacetext
386  \else%
387  \@keytopmatter
388  \answertrue
389  \iftwocolumn \begin{multicols}{2}\fi
390  \@keyprefacetext
391  \fi
392  \setcounter{sectionindex}{0}

And finally, once we have started making the exam, we need to loop over each individual section.

393  \@whilenum \value{sectionindex}<\value{section} \do{%
394  \addtocounter{sectionindex}{1}

Store the roman numeral for the value of sectionindex in the macro \current@section so we can use it in \csname… \endcsname pairs.

395  \edef\current@section{\roman{sectionindex}}

Compute the length of \qlist@sec⟨current@section⟩

396  \length{\csname qlist@sec\current@section\endcsname}

Here’s the main meat of the code. Pick a random number between 1 and the length of \qlist@sec⟨current@section⟩. Store it in the counter \exam@m. Remove the mth element from \qlist@sec⟨current@section⟩ and store it as the first element in \qlist@scr@sec⟨current@section⟩. Continuing to do this will rearrange the order of the questions. The only thing we need to keep in mind is to change the requested range of the random number to keep in mind the fact that we removed an element from \qlist@sec⟨current@section⟩. Although there are faster ways to do this, I chose to opt for more readable code, since this part of the program is so complex anyway.

397  \csname sec\current@section @fixed\endcsname
398  \ifnotfixed
399  \ifanswer\relax\else
400  \typeout{Scrambling section \current@section, question: }\fi
401  \@whilenum \value{length}>0 \do{%
402  \setrannum{\exam@m}{1}{\value{length}}
403  \remove{\exam@m}{\csname qlist@sec\current@section\endcsname}

404  \edef\@TEMP{\theextract}
405  \ifnum \value{length}=1
406  \message{\@TEMP.}
407  \else \message{\@TEMP,}\fi

The two \expandafter’s are necessary to prevent the token list \qlist@scr@sec⟨current@section⟩

 from consisting of nothing but \@separator{\@TEMP}\@separator{\@TEMP}. . .
408  \expandafter\append\expandafter{\@TEMP}{\csname
409  qlist@scr@sec\current@section\endcsname}
410  \length{\csname qlist@sec\current@section\endcsname}}
411  \else
412  \csname qlist@scr@sec\current@section\endcsname=\expandafter{%
413  \the\csname qlist@sec\current@section\endcsname}
414  \fi

Finally, the code dealing with processing the different types of questions. Each type of question is processed in the exact same way: we perform an \ifx to test to see what type of question it is, and if it is that type of question, execute the following code, which redefines \begin{answer}… \end{answer} as necessary to achieve the desired effects.

The first type of question is shortanswer

415  \expandafter\ifx\csname type@sec\current@section\endcsname\@shortanswer

Specify an exact meaning for \@separator, which will appear when we execute the question list.

416  \def\@separator##1{\setcounter{temp}{##1}
417  \edef\current@question{\roman{temp}}
418  \csname sec\current@section @qst\current@question\endcsname}

If we are making a answer, define the answer environment to be the following:

419  \ifanswer
420  \gdef\answer{\begin{description} \item[Answer:]}
421  \gdef\endanswer{\end{description}}
422  \else

Otherwise, make answer gobble the answer

423  \def\answer{\get@noanswer@body}
424  \def\endanswer{\relax}
425  \def\@S{answer}
426  \long\def\get@noanswer@body##1\end{\find@answer@end}
427  \def\find@answer@end##1{\def\@tempa{##1}
428  \ifx\@tempa\@S\expandafter\finish@up
429  \else\expandafter\get@noanswer@body\fi}
430  \def\finish@up{\end{answer}}
431  \fi

Typeset the section heading.

432  \par\vspace{\beforesectsep}
433  \noindent {\large Section \arabic{sectionindex}. \space
434  \csname head@sec\current@section\endcsname}
435  \par\vspace{\aftersectsep}

436  \ifx\csname inst@sec\current@section\endcsname\relax
437  \relax
438  \else
439  \vspace{\beforeinstsep}
440  \csname inst@sec\current@section\endcsname
441  \par\vspace{\afterinstsep}
442  \fi
443  \begin{enumerate}
444  \the\csname qlist@scr@sec\current@section\endcsname
445  \end{enumerate}
446  \fi

The next type of question is fixed. This is just like shortanswer.

447  \expandafter\ifx\csname type@sec\current@section\endcsname\@fixed

Specify an exact meaning for \@separator, which will appear when we execute the question list.

448  \def\@separator##1{\setcounter{temp}{##1}
449  \edef\current@question{\roman{temp}}
450  \csname sec\current@section @qst\current@question\endcsname}

If we are making a answer, define the answer environment to be the following:

451  \ifanswer
452  \gdef\answer{\begin{description} \item[Answer:]}
453  \gdef\endanswer{\end{description}}
454  \else

Otherwise, make answer gobble the answer

455  \def\answer{\get@noanswer@body}
456  \def\endanswer{\relax}
457  \def\@S{answer}
458  \long\def\get@noanswer@body##1\end{\find@answer@end}
459  \def\find@answer@end##1{\def\@tempa{##1}
460  \ifx\@tempa\@S\expandafter\finish@up
461  \else\expandafter\get@noanswer@body\fi}
462  \def\finish@up{\end{answer}}
463  \fi

Typeset the section heading.

464  \par\vspace{\beforesectsep}
465  \noindent {\large Section \arabic{sectionindex}. \space
466  \csname head@sec\current@section\endcsname}
467  \par\vspace{\aftersectsep}
468  \ifx\csname inst@sec\current@section\endcsname\relax
469  \relax
470  \else
471  \vspace{\beforeinstsep}
472  \csname inst@sec\current@section\endcsname
473  \par\vspace{\afterinstsep}
474  \fi
475  \begin{enumerate}
476  \the\csname qlist@scr@sec\current@section\endcsname

477  \end{enumerate}

The next line is necessary in case the fixed environment is the last one in an exam. If other environments appear after fixed, then this switch will be reversed at the start of the loop that scrambles the order of the questions. But if no environments appear after fixed, this switch will remain set, causing the reassignment of token lists below to fail. I.e., from here on out no rearrangment of the exam questions will occur. That’s why we include the below switch.

478  \global\notfixedtrue
479  \fi

The next type of question is fill-in-the-blank

480  \expandafter\ifx\csname type@sec\current@section\endcsname\@fillin
 Define \@separator again.
481  \def\@separator##1{\setcounter{temp}{##1}
482  \edef\current@question{\roman{temp}}
483  \csname sec\current@section @qst\current@question\endcsname}

Define \blank so that it either makes just an underline or an underline with the word printed over it.

484  \ifanswer
485  \ifcblanks
486  \def\blank##1{\mbox{\rule[-1pt]{\blank@length}{.4pt}%
487  \hspace{-\blank@length}%
488  \makebox[\blank@length]{##1}}}
489  \fi
490  \ifpblanks
491  \def\blank##1{\settowidth{\temp@length}{##1}%
492  \mbox{\rule[-1pt]{\blank@multiplier\temp@length}{.4pt}%
493  \hspace{-\blank@multiplier\temp@length}%
494  \makebox[\blank@multiplier\temp@length]{##1}}}
495  \fi
496  \else
497  \ifcblanks
498  \def\blank##1{\rule[-1pt]{\blank@length}{.4pt}}
499  \fi
500  \ifpblanks
501  \def\blank##1{\settowidth{\temp@length}{##1}%
502  \rule[-1pt]{\blank@multiplier\temp@length}{.4pt}}
503  \fi
504  \fi

Typeset the section heading.

505  \par\vspace{\beforesectsep}
506  \noindent {\large Section \arabic{sectionindex}. \space
507  \csname head@sec\current@section\endcsname}
508  \par\vspace{\aftersectsep}
509  \ifx\csname inst@sec\current@section\endcsname\relax
510  \relax
511  \else

512  \vspace{\beforeinstsep}
513  \csname inst@sec\current@section\endcsname
514  \par\vspace{\afterinstsep}
515  \fi
516  \begin{enumerate}
517  \the\csname qlist@scr@sec\current@section\endcsname
518  \end{enumerate}
519  \fi

We now conduct a series of tests to see exactly what type of question the current section contains. Once a match is made, the appropriate macro (defined below) is expanded, which typesets all the questions in that section.

520  \expandafter\ifx\csname type@sec\current@section\endcsname\@fillinstar
521  \@fillinstarmain
522  \fi
523  \expandafter\ifx\csname type@sec\current@section\endcsname\@MC
524  \@multiplechoicemain
525  \fi
526  \expandafter\ifx\csname type@sec\current@section\endcsname\@MCstar
527  \@multiplechoicestarmain
528  \fi
529  \expandafter\ifx\csname type@sec\current@section\endcsname\@shortanswerstar
530  \@shortanswerstarmain
531  \fi
532  \expandafter\ifx\csname type@sec\current@section\endcsname\@truefalse
533  \@truefalsemain
534  \fi
535  \expandafter\ifx\csname type@sec\current@section\endcsname\@truefalsestar
536  \@truefalsestarmain
537  \fi
538  \expandafter\ifx\csname type@sec\current@section\endcsname\@fixedstar
539  \@fixedstarmain
540  \fi

541 }

This is the end of the code for the sections while-loop.

542  \ifnum \value{innerloop}=0 %
543  \@examclosingtext\par
544  \else
545  \@keyclosingtext\par
546  \fi
547  \iftwocolumn \end{multicols} \fi
548  \ifx\@endmattertext\relax
549  \relax
550  \else
551  \pagebreak \@endmattertext \par
552  \fi
553  \pagebreak
554  \addtocounter{innerloop}{1}}
555  \@OneKeyHook

This is the end of the code for the inner while-loop (that generates both exams and answer sheets. Toggle the value of \ifanswer so that on the second pass we generate answers to the questions. Add one to innerloop, too.

556  \stepcounter{version}
557  \setcounter{sectionindex}{0}

This is the end of the code for the form while-loop. Add -1 to form to keep track of the number of copies we’ve made, and redefine the \qlist@sec⟨section⟩ lists, since they were eaten up by \remove during the randomization. (This is what the next loop does.)

558  \@whilenum \value{sectionindex}<\value{section} \do{%
559  \addtocounter{sectionindex}{1}
560  \edef\current@section{\roman{sectionindex}}
561  \csname sec\current@section @fixed\endcsname
562  \ifnotfixed
563  \csname qlist@sec\current@section\endcsname=\expandafter{\the\csname
564  qlist@scr@sec\current@section\endcsname}
565  \csname qlist@scr@sec\current@section\endcsname={}
566  \else \notfixedtrue\fi}

567 }}

6 The layout of the exam

\NumberOfVersions A user-level command to specify the number of version to make. Originally initialized to 1.

568 \def\NumberOfVersions#1{\setcounter{form}{#1}}
569 \NumberOfVersions{1}

\instructions Often one wants to preface a block of questions with a series of instructions for the student. Previous releases had defined \instructions to do this, but that command is obsolete as of version 1.02. Thus, we define \instructions to be

\relax.
570 \def\instructions{\relax}

\classdata This command saves its argument in the macro \classdata (it is intended for data like the class name and course number. E.g., Phil 29: Critical Reasoning). Originally initialized to \relax.

571 \def\class#1{\def\classdata{#1}}
572 \def\classdata{\relax}

\examtype Allows one to specify the name of the exam (midterm, final, etc.)

573 \def\examname#1{\def\examtype{#1}}
574 \examname{Exam}

\namedata Placed in a \parbox, \namedata contains all the standard fields ordinarily required in a large university setting. If you should be so lucky as to teach at a place where student numbers are not required, simply delete the appropriate line.

575 \def\namedata{Name: \hrulefill \\[\namedata@vspace]
576  Student Number: \hrulefill \\[\namedata@vspace]
577  TA: \hrulefill \\[\namedata@vspace]
578  Date: \hrulefill}

6.1 Types of questions

In the standard exam package, five types of questions have special formats: true/false, fill-in-the-blank, short answer, multiple choice, and fixed (meaning: don’t swap the order of the questions). Since we will want to distinguish between these types of questions when creating the exam, we need a way to identify a particular section with a particular type of question. We do this in the following way: for each section, we define a macro \type@sec⟨section⟩ consisting of a single string containing the name of the type of question. That string will later be used to identify the section as such and take appropriate action.

fillin The environment for fill-in-the-blank questions.

579 \newenvironment{fillin}[1][:]
580 {\begin{section}
581 \def\@currentsectionname{fillin}
582 \edef\@@temp{\roman{section}}
583 \expandafter\gdef\csname type@sec\@@temp\endcsname{fillin}
584 \expandafter\gdef\csname sec\@@temp @fixed\endcsname{\notfixedtrue}
585 \ifx#1:
586  \expandafter\gdef\csname head@sec\@@temp\endcsname{\relax}
587 \else
588  \expandafter\gdef\csname head@sec\@@temp\endcsname{#1}
589 \fi
590 \get@instructions \relax}
591 {\end{section}}

fillin* The environment for fill-in-the-blank questions without section identifiers.

592 \newenvironment{fillin*}[1][:]
593 {\begin{section}
594 \def\@currentsectionname{fillin*}
595 \edef\@@temp{\roman{section}}
596 \expandafter\gdef\csname type@sec\@@temp\endcsname{fillin*}
597 \expandafter\gdef\csname sec\@@temp @fixed\endcsname{\notfixedtrue}
598 \ifx#1:
599  \expandafter\gdef\csname head@sec\@@temp\endcsname{\relax}
600 \else
601  \expandafter\gdef\csname head@sec\@@temp\endcsname{#1}
602 \fi
603 \get@instructions \relax}
604 {\end{section}}

truefalse The environment for true/false questions

605 \newenvironment{truefalse}[1][:]
606 {\begin{section}

607 \def\@currentsectionname{truefalse}
608 \edef\@@temp{\roman{section}}
609 \expandafter\gdef\csname type@sec\@@temp\endcsname{truefalse}
610 \expandafter\gdef\csname sec\@@temp @fixed\endcsname{\notfixedtrue}
611 \ifx#1:
612  \expandafter\gdef\csname head@sec\@@temp\endcsname{\relax}
613 \else
614  \expandafter\gdef\csname head@sec\@@temp\endcsname{#1}
615 \fi
616 \get@instructions \relax}
617 {\end{section}}

truefalse* The environment for true/false questions without the section identifier.

618 \newenvironment{truefalse*}[1][:]
619 {\begin{section}
620 \def\@currentsectionname{truefalse*}
621 \edef\@@temp{\roman{section}}
622 \expandafter\gdef\csname type@sec\@@temp\endcsname{truefalse*}
623 \expandafter\gdef\csname sec\@@temp @fixed\endcsname{\notfixedtrue}
624 \ifx#1:
625  \expandafter\gdef\csname head@sec\@@temp\endcsname{\relax}
626 \else
627  \expandafter\gdef\csname head@sec\@@temp\endcsname{#1}
628 \fi
629 \get@instructions \relax}
630 {\end{section}}

shortanswer The environment for short answer questions

631 \newenvironment{shortanswer}[1][:]
632 {\begin{section}
633 \def\@currentsectionname{shortanswer}
634 \edef\@@temp{\roman{section}}
635 \expandafter\gdef\csname type@sec\@@temp\endcsname{shortanswer}
636 \expandafter\gdef\csname sec\@@temp @fixed\endcsname{\notfixedtrue}
637 \ifx#1:
638  \expandafter\gdef\csname head@sec\@@temp\endcsname{\relax}
639 \else
640  \expandafter\gdef\csname head@sec\@@temp\endcsname{#1}
641 \fi
642 \get@instructions \relax}
643 {\end{section}}

shortanswer* The environment for short answer questions, without the section identifier

644 \newenvironment{shortanswer*}[1][:]
645 {\begin{section}
646 \def\@currentsectionname{shortanswer*}
647 \edef\@@temp{\roman{section}}
648 \expandafter\gdef\csname type@sec\@@temp\endcsname{shortanswer*}
649 \expandafter\gdef\csname sec\@@temp @fixed\endcsname{\notfixedtrue}

650 \ifx#1:
651  \expandafter\gdef\csname head@sec\@@temp\endcsname{\relax}
652 \else
653  \expandafter\gdef\csname head@sec\@@temp\endcsname{#1}
654 \fi
655 \get@instructions \relax}
656 {\end{section}}

multiplechoice The environment for multiple choice questions

657 \newenvironment{multiplechoice}[1][:]
658 {\begin{section}
659 \def\@currentsectionname{multiplechoice}
660 \edef\@@temp{\roman{section}}
661 \expandafter\gdef\csname type@sec\@@temp\endcsname{multiplechoice}
662 \expandafter\gdef\csname sec\@@temp @fixed\endcsname{\notfixedtrue}
663 \ifx#1:
664  \expandafter\gdef\csname head@sec\@@temp\endcsname{\relax}
665 \else
666  \expandafter\gdef\csname head@sec\@@temp\endcsname{#1}
667 \fi
668 \get@instructions \relax}
669 {\end{section}}

multiplechoice* The environment for multiple choice questions, minus the “Form:” that the ordinary environment includes.

670 \newenvironment{multiplechoice*}[1][:]
671 {\begin{section}
672 \def\@currentsectionname{multiplechoice*}
673 \edef\@@temp{\roman{section}}
674 \expandafter\gdef\csname type@sec\@@temp\endcsname{multiplechoice*}
675 \expandafter\gdef\csname sec\@@temp @fixed\endcsname{\notfixedtrue}
676 \ifx#1:
677  \expandafter\gdef\csname head@sec\@@temp\endcsname{\relax}
678 \else
679  \expandafter\gdef\csname head@sec\@@temp\endcsname{#1}
680 \fi
681 \get@instructions \relax}
682 {\end{section}}

fixed Prevents the questions from being rearranged.

683 \newenvironment{fixed}[1][:]
684 {\begin{section}
685 \def\@currentsectionname{fixed}
686 \edef\@@temp{\roman{section}}
687 \expandafter\gdef\csname type@sec\@@temp\endcsname{fixed}
688 \expandafter\gdef\csname sec\@@temp @fixed\endcsname{\notfixedfalse}
689 \ifx#1:
690  \expandafter\gdef\csname head@sec\@@temp\endcsname{\relax}
691 \else

692  \expandafter\gdef\csname head@sec\@@temp\endcsname{#1}
693 \fi
694 \get@instructions \relax}
695 {\end{section}}

fixed* Prevents the questions from being rearranged and doesn’t print the section identifier.

696 \newenvironment{fixed*}[1][:]
697 {\begin{section}
698 \def\@currentsectionname{fixed*}
699 \edef\@@temp{\roman{section}}
700 \expandafter\gdef\csname type@sec\@@temp\endcsname{fixed*}
701 \expandafter\gdef\csname sec\@@temp @fixed\endcsname{\notfixedfalse}
702 \ifx#1:
703  \expandafter\gdef\csname head@sec\@@temp\endcsname{\relax}
704 \else
705  \expandafter\gdef\csname head@sec\@@temp\endcsname{#1}
706 \fi
707 \get@instructions \relax}
708 {\end{section}}

6.2 Loose Ends

The following macros just contain the environment names for identification in the main loop.

709 \def\@fillin{fillin}
710 \def\@fillinstar{fillin*}
711 \def\@shortanswer{shortanswer}
712 \def\@shortanswerstar{shortanswer*}
713 \def\@truefalse{truefalse}
714 \def\@truefalsestar{truefalse*}
715 \def\@MC{multiplechoice}
716 \def\@MCstar{multiplechoice*}
717 \def\@fixed{fixed}
718 \def\@fixedstar{fixed*}

\choice This is one of the complicated macros in the package. From the user’s point of view, it indicates one answer to a multiple choice question. Internally, \choice has to recognize whether it is the first or last question, taking different action depending on which it is. Moreover, \choice has to format the label differently depending on whether or not we are creating an exam or a test. Note that, for reasons of sanity, I do not attempt to rearrange the order of the choices.

719 \newcommand{\choice}[3][]{%
720 \ifchoice \relax
721  \else \@mcstartlist \choicetrue
722 \fi
723 \ifanswer
724  \if#1!%

725  \ifbox \vspace{-\fboxsep}\item[\hfill\fbox{(\alph{choice})}\hfill] #2
726  \vspace{-\fboxsep}%
727  \else
728  \item[\hfill\MCfont{(\alph{choice})}\hfill] \MCfont{#2}
729  \fi
730  \else \item[\hfill(\alph{choice})\hfill] #2
731  \fi \stepcounter{choice}
732 \else
733  \item[\hfill(\alph{choice})\hfill] #2
734  \stepcounter{choice}
735 \fi
736 \ifx#3\choice \relax
737 \else \end{list}
738  \setcounter{choice}{1}
739  \choicefalse
740 \fi #3}

\@mcstartlist The parameters used to start the \begin{list} environment used in the \choice macro.

741 \def\@mcstartlist{\begin{list}{}{%
742 \setlength{\topsep}{6pt}
743 \setlength{\rightmargin}{0pt}
744 \setlength{\labelwidth}{.35in}
745 \setlength{\leftmargin}{.5in}
746 \setlength{\labelsep}{.15in}
747 \setlength{\itemindent}{0in}
748 \setlength{\itemsep}{0pt}}}

6.3 More User-Level Macros

\Fullpages Just a command so that people can automatically set the page margins to full-sized pages. Only defined for US letter, sorry.

749 \newcommand{\Fullpages}{\setlength{\topmargin}{0pc}
750  \setlength{\oddsidemargin}{0pc}
751  \setlength{\evensidemargin}{0pc}
752  \setlength{\headheight}{0pc}
753  \setlength{\headsep}{0pc}
754  \setlength{\textwidth}{6.5in}
755  \setlength{\textheight}{9in}}

756 ⟨/othercode⟩

\ConstantBlanks Sets the blanks in fillin to be of constant width

757 \def\ConstantBlanks#1{\setlength{\blank@length}{#1}\cblankstrue\pblanksfalse}

\ProportionalBlanks Sets the blanks in fillin to be proportional to the actual typeset width of the word.

758 \def\ProportionalBlanks#1{\edef\blank@multiplier{#1}\cblanksfalse\pblankstrue}
759 \ProportionalBlanks{1}

\StudentInfoLineSpacing Sets the amount of spacing between the lines in the \namedata macro.

760 \newcommand{\StudentInfoLineSpacing}[1]{\setlength{\namedata@vspace}{#1}}
761 \StudentInfoLineSpacing{6pt}

\examtop We define \examtop so that it reads in and saves the surround text to a macro like in the tabularx environment.

762 \def\examtop{\@toklist={}
763 \get@examtop@body}

\endexamtop This doesn’t need to do much.

764 \def\endexamtop{\relax}

\get@examtop@body This macro collects everything between it and the next \end token. It then calls the \find@examtop@end macro to check whether the \end token belongs to the question environment or some other environment.

765 \long\def\get@examtop@body#1\end{%
766 \@toklist=\expandafter{\the\@toklist#1}%
767 \find@examtop@end}

\find@examtop@end If we are at \end{examtop}, save everything to the appropriately named macro. Otherwise, continue collecting tokens

768 \def\find@examtop@end#1{%
769 \def\@tempa{#1}%
770 \ifx\@tempa\@XMtop\expandafter\XMtop@wrap@up
771  \else\@toklist=\expandafter{\the\@toklist\end{#1}}%
772  \expandafter\get@examtop@body\fi}

\XMtop@wrap@up Save the gathered information to a macro for later use.

773 \def\XMtop@wrap@up{\xdef\@examtopmatter{\the\@toklist}%
774 \end{examtop}}

\@XMtop Store the name of the environment for comparison in \find@question@end

775 \def\@XMtop{examtop}

examtop This environment is defined via the macros below. It allows the user to customize the text at the top of the exam. The example here is the default definition.

776 \begin{examtop}
777 \@@line{\parbox{3in}{\classdata \\
778  \examtype\ifincludeform, Form:
779  \fbox{\textsf{\Alph{version}}}\fi}
780  \hfill
781  \parbox{3in}{\normalsize \namedata}}
782  \bigskip
783 \end{examtop}

\keytop We define \keytop so that it reads in and saves the surround text to a macro like in the tabularx environment.

784 \def\keytop{\@toklist={}
785 \get@keytop@body}

\endkeytop This doesn’t need to do much.

786 \def\endkeytop{\relax}

\get@keytop@body This macro collects everything between it and the next \end token. It then calls the \find@keytop@end macro to check whether the \end token belongs to the question environment or some other environment.

787 \long\def\get@keytop@body#1\end{\@toklist=\expandafter{\the\@toklist#1}%
788 \find@keytop@end}

\find@keytop@end If we are at \end{keytop}, save everything to the appropriately named macro. Otherwise, continue collecting tokens

789 \def\find@keytop@end#1{%
790 \def\@tempa{#1}%
791 \ifx\@tempa\@KYtop\expandafter\KYtop@wrap@up
792  \else\@toklist=\expandafter{\the\@toklist\end{#1}}%
793  \expandafter\get@keytop@body\fi}

\KYtop@wrap@up Save the gathered information to a macro for later use.

794 \def\KYtop@wrap@up{\xdef\@keytopmatter{\the\@toklist}%
795 \end{keytop}}

\@KYtop Store the name of the environment for comparison in \find@keytop@end

796 \def\@KYtop{keytop}

keytop This environment is defined via the macros below. It allows the user to customize the text at the top of the exam. The example here is the default definition.

797 \begin{keytop}
798 \@@line{\hfill \Huge Answer Key
799  \ifincludeform for Exam \fbox{\textsf{\Alph{version}}}
800  \fi \hfill}
801  \bigskip
802 \end{keytop}

\word This macro enables one to insert minor (read: inessential) changes in wording between different versions of the test. For example, including the command \word|{Carl Sagan} {Bob Dole}| in the text will cause the phrase “Carl Sagan” to be printed in that place on every odd-numbered test and “Bob Dole” to be printed in that place on every even-numbered test. In the event that more versions of the test are requested than options given, \word acts as if the given list of options repeats itself. I.e., in the above case, if we requested four different versions of the examn, \word will behave as if the command given were

\word|{Carl Sagan} {Bob Dole} {Carl Sagan} {Bob Dole}|.

First we define a string to be equal to a space so that we can allow for any number of spaces to be given in the option list.

803 \def\@Space{ }

The \word macro just saves the option-list in a macro named \@wordlist and invokes the macro \@wordmain which most of the work.

804 \def\word#1{\def\@wordlist{#1}\expandafter\@wordmain\@wordlist \stop}

805

806 \def\@wordmain#1{%

Check to see if the current argument is a space. If so, ignore it.

807 \ifx#1\@Space
808 \let\@next=\@wordmain
809 \else

If the current argument is not a space, but is \stop, this means that fewer options were given than versions of the test were requested. Thus we need to start \@wordmain again at the beginning of the option list. This is what the

\@dumpthenstart macro does.
810 \ifx#1\stop
811  \let\@next=\@dumpthenstart
812 \else%

If the current argument is none of the above, then it is an actual option. However, we must check whether it is the option we want. If it is, then typeset it and gobble everything up to (and including) \stop. If not, just throw the current argument away and get the next one.

813  \ifnum\value{wordtemp}=\value{version}%
814  #1\let\@next=\@gobbletostop
815  \else
816  \stepcounter{wordtemp}%
817  \let\@next=\@wordmain
818  \fi
819 \fi
820 \fi
821 \@next}
\@dumpthenstart
822 \def\@dumpthenstart{\expandafter\@wordmain\@wordlist \stop}
\@gobbletostop
823 \def\@gobbletostop#1\stop{\relax\setcounter{wordtemp}{1}}

7 Macros to format types of questions

\ifsection This macro increases the readability of the code in the definition of \@enddocumenthook when we test to see just which type of questions the current section consists of.

824 \def\ifsection#1#2{\def\@temp{#1}
825 \expandafter\ifx\csname type@sec\current@section\endcsname\@temp #2 \fi}

\@fillinstarmain This contains all the commands to be invoked if the current section in the main loop is a multiple-choice environment.

826 \def\@fillinstarmain{%

Define \question and \endquestion in case someone used the block environment inside fillin*.

827 \def\question{\item \@beforequestionhook}
828 \def\endquestion{\@endquestionhook}

Define —separator— again.

829 \def\@separator##1{\setcounter{temp}{##1}
830  \edef\current@question{\roman{temp}}
831  \csname sec\current@section @qst\current@question\endcsname}

Define \blank so that it either makes just an underline or an underline with the word printed over it: just the underline is printed unless we are making an answer key, hence the \ifanswer. Exactly how \blank gets defined depends upon whether the user requested for constant-length blanks or proportional-length blanks, so we need to test for these, also.

832 \ifanswer
833  \ifcblanks
834  \def\blank##1{\mbox{\rule[-1pt]{\blank@length}{.4pt}%
835  \hspace{-\blank@length}%
836  \makebox[\blank@length]{##1}}}
837  \fi
838  \ifpblanks
839  \def\blank##1{\settowidth{\temp@length}{##1}%
840  \mbox{\rule[-1pt]{\blank@multiplier\temp@length}{.4pt}%
841  \hspace{-\blank@multiplier\temp@length}%
842  \makebox[\blank@multiplier\temp@length]{##1}}}
843  \fi
844 \else
845  \ifcblanks
846  \def\blank##1{\rule[-1pt]{\blank@length}{.4pt}}
847  \fi
848  \ifpblanks
849  \def\blank##1{\settowidth{\temp@length}{##1}%
850  \rule[-1pt]{\blank@multiplier\temp@length}{.4pt}}
851  \fi
852 \fi

Once all the above work is done, we can actually begin the typesetting process. Since this is a starred environment, there is no section identifier.

853  \par\medskip

If the heading for this section is empty, don’t print anything (including the additional \par\medskip), but if the heading is not empty, print it plus the additional

 \par\medskip.
854  \ifx\csname head@sec\current@section\endcsname\relax
855  \relax
856  \else
857  \vspace{\beforesectsep}
858  \noindent{\csname head@sec\current@section\endcsname}
859  \par\vspace{\aftersectsep}

860  \fi
861  \ifx\csname inst@sec\current@section\endcsname\relax
862  \relax
863  \else
864  \vspace{\beforeinstsep}
865  \csname inst@sec\current@section\endcsname
866  \par\vspace{\afterinstsep}
867  \fi
868  \begin{enumerate}
869  \the\csname qlist@scr@sec\current@section\endcsname
870  \end{enumerate}}

\@multiplechoicemain This contains all the commands to be invoked if the current section in the main loop is a multiple-choice environment.

871 \def\@multiplechoicemain{\setcounter{mcchoice}{1}

First, redefine the \question, \endquestion pairs in case someone used the block environment within multiplechoice.

872 \def\question{\item \begin{minipage}[t]{\linewidth} \@beforequestionhook}
873 \def\endquestion{\@endquestionhook \end{minipage}}

Now define \@separator so that it calls the appropriate macro.

874 \def\@separator##1{\setcounter{temp}{##1}
875  \edef\current@question{\roman{temp}}
876  \csname sec\current@section @qst\current@question\endcsname}

Put some vertical space on the page.

877 \par\vspace{\beforesectsep}

Print the section identifier.

878 \noindent {\large Section \arabic{sectionindex}. \space
879 \csname head@sec\current@section\endcsname}
880  \par\vspace{\aftersectsep}
881 \ifx\csname inst@sec\current@section\endcsname\relax
882  \relax
883 \else
884  \vspace{\beforeinstsep}
885  \csname inst@sec\current@section\endcsname
886  \par\vspace{\afterinstsep}
887 \fi

Start typesetting the questions

888 \begin{enumerate}
889  \the\csname qlist@scr@sec\current@section\endcsname
890 \end{enumerate}}

\@multiplechoicestarmain This contains all the commands to be invoked if the current section in the main loop is a multiple-choice environment.

891 \def\@multiplechoicestarmain{\setcounter{mcchoice}{1}

First, redefine the \question, \endquestion pairs in case someone used the block environment within multiplechoice.

892 \def\question{\item\begin{minipage}[t]{\linewidth}
893  \@beforequestionhook}
894 \def\endquestion{\@endquestionhook \end{minipage}}

Now define \@separator so that it calls the appropriate macro.

895 \def\@separator##1{\setcounter{temp}{##1}
896  \edef\current@question{\roman{temp}}
897  \csname sec\current@section @qst\current@question\endcsname}

If the heading for this section is empty, don’t print anything (including the additional \par\medskip), but if the heading is not empty, print it plus the additional

 \par\medskip.
898  \ifx\csname head@sec\current@section\endcsname\relax
899  \relax
900  \else
901  \par\vspace{\beforesectsep}
902  \noindent{\csname head@sec\current@section\endcsname}
903  \par\vspace{\aftersectsep}
904  \fi
905  \ifx\csname inst@sec\current@section\endcsname\relax
906  \relax
907  \else
908  \vspace{\beforeinstsep}
909  \csname inst@sec\current@section\endcsname
910  \par\vspace{\afterinstsep}
911  \fi
912 \begin{enumerate}
913  \the\csname qlist@scr@sec\current@section\endcsname
914 \end{enumerate}}

\@truefalsemain This contains all the commands to be invoked if the current section in the main loop is a true/false environment.

915 \def\@truefalsemain{%

First, define \@separator so that it calls the macro where the right question is saved.

916 \def\@separator##1{\setcounter{temp}{##1}
917  \edef\current@question{\roman{temp}}
918  \csname sec\current@section @qst\current@question\endcsname}

Redefine \question and \endquestion to work properly in case someone used a block environment to keep a couple of true/false questions together

919 \def\question{\@tfitem \@beforequestionhook}
920 \def\endquestion{\@endquestionhook}

Since the appearance of a true/false question depends heavily on whether we are typesetting an answer key or not, we have to make a number of definitions (or redefinitions) depending upon whether we are currently making an answer key.

921  \ifanswer

If we are typesetting an answer, we don’t want the argument given to \answer to do anything, so we define it so that it gobbles its argument.

922  \def\answer##1{\relax}

If we aren’t typesetting an answer, then we are typesetting a test. We must define \answer so that it saves the answer in a macro so that it can be recalled when the answer key is typeset.

923  \else
924  \def\answer##1{\expandafter\gdef
925  \csname tf@sol\current@question\endcsname{##1}}
926  \vspace{-\smallskipamount}
927  \fi

Since we always typeset the answer key after the exam, we know that tf@sol⟨current@question⟩ is defined to be the answer to the question (this is done by appropriately defining \answer below). Thus we may

928  \par\vspace{\beforesectsep}
929  \noindent {\large Section \arabic{sectionindex}. \space
930  \csname head@sec\current@section\endcsname}
931  \par\vspace{\aftersectsep}
932  \ifx\csname inst@sec\current@section\endcsname\relax
933  \relax
934  \else
935  \vspace{\beforeinstsep}
936  \csname inst@sec\current@section\endcsname
937  \par\vspace{\afterinstsep}
938  \fi

It turns out that we need to redefine (slightly) the dimensions of the list we are using in order to get the answer key and exam to look good. Thus the following depends upon which we are currently making.

939  \ifanswer
940  \begin{list}{}
941  {\setlength{\rightmargin}{0pt}
942  \setlength{\labelwidth}{.4in}
943  \setlength{\leftmargin}{.5in}
944  \setlength{\labelsep}{.1in}
945  \setlength{\itemindent}{0in}
946  \setlength{\itemsep}{3pt}}
947  \the\csname qlist@scr@sec\current@section\endcsname
948  \end{list}
949  \else
950  \begin{list}{$\underline{\mbox{\hphantom{false}}}$}
951  {\setlength{\rightmargin}{0pt}
952  \setlength{\labelwidth}{.35in}
953  \setlength{\leftmargin}{.5in}
954  \setlength{\labelsep}{.15in}
955  \setlength{\itemindent}{0in}
956  \setlength{\itemsep}{3pt}}
957  \the\csname qlist@scr@sec\current@section\endcsname

958  \end{list}
959  \fi}
\@truefalsestarmain Almost exactly the same as \@truefalsemain above.
960 \def\@truefalsestarmain{%
961 \def\@separator##1{\setcounter{temp}{##1}
962  \edef\current@question{\roman{temp}}
963  \csname sec\current@section @qst\current@question\endcsname}
964 \def\question{\@tfitem \@beforequestionhook}
965 \def\endquestion{\@endquestionhook}
966 \ifanswer
967  \def\answer##1{\relax}
968 \else
969  \def\answer##1{\expandafter\gdef
970  \csname tf@sol\current@question\endcsname{##1}}
971  \vspace{-\smallskipamount}
972 \fi
973 \par\medskip

If the heading for this section is empty, don’t print anything (including the additional \par\medskip), but if the heading is not empty, print it plus the additional

 \par\medskip.
974 \ifx\csname head@sec\current@section\endcsname\relax
975  \relax
976 \else
977  \par\vspace{\beforesectsep}
978  \noindent{\csname head@sec\current@section\endcsname}
979  \par\vspace{\aftersectsep}
980 \fi
981 \ifx\csname inst@sec\current@section\endcsname\relax
982  \relax
983 \else
984  \vspace{\beforeinstsep}
985  \csname inst@sec\current@section\endcsname
986  \par\vspace{\afterinstsep}
987 \fi
988 \ifanswer
989  \begin{list}{}
990  {\setlength{\rightmargin}{0pt}
991  \setlength{\labelwidth}{.4in}
992  \setlength{\leftmargin}{.5in}
993  \setlength{\labelsep}{.1in}
994  \setlength{\itemindent}{0in}
995  \setlength{\itemsep}{3pt}}
996  \the\csname qlist@scr@sec\current@section\endcsname
997  \end{list}
998 \else
999  \begin{list}{$\underline{\mbox{\hphantom{false}}}$}
1000  {\setlength{\rightmargin}{0pt}
1001  \setlength{\labelwidth}{.35in}

1002  \setlength{\leftmargin}{.5in}
1003  \setlength{\labelsep}{.15in}
1004  \setlength{\itemindent}{0in}
1005  \setlength{\itemsep}{3pt}}
1006  \the\csname qlist@scr@sec\current@section\endcsname
1007  \end{list}
1008 \fi}

\@shortanswerstarmain This contains all the commands to be invoked if the current section in the main loop is a shortanswer* environment.

1009 \def\@shortanswerstarmain{%

Redefine \question and \endquestion in case someone used the block environment inside a shortanswer* environment.

1010 \def\question{\item \@beforequestionhook}
1011 \def\endquestion{\@endquestionhook}

Specify an exact meaning for —separator—, which will appear when we execute the question list.

1012 \def\@separator##1{\setcounter{temp}{##1}
1013  \edef\current@question{\roman{temp}}
1014  \csname sec\current@section @qst\current@question\endcsname}

If we are making a answer, define the answer environment to be the following:

1015 \ifanswer
1016  \def\answer{\begin{description} \item[Answer:]}
1017  \def\endanswer{\end{description}}
1018 \else

Otherwise, make answer gobble the answer

1019  \def\answer{\get@noanswer@body}
1020  \def\endanswer{\relax}
1021  \def\@S{answer}
1022  \long\def\get@noanswer@body##1\end{\find@answer@end}
1023  \def\find@answer@end##1{\def\@tempa{##1}
1024  \ifx\@tempa\@S\expandafter\finish@up
1025  \else\expandafter\get@noanswer@body\fi}
1026  \def\finish@up{\end{answer}}

1027 \fi

Typeset the section heading.

1028 \par\medskip

If the heading for this section is empty, don’t print anything (including the additional \par\medskip), but if the heading is not empty, print it plus the additional

  \par\medskip.
1029 \ifx\csname head@sec\current@section\endcsname\relax
1030  \relax
1031 \else
1032  \par\vspace{\beforesectsep}
1033  \noindent{\csname head@sec\current@section\endcsname}

1034  \par\vspace{\aftersectsep}

1035 \fi

1036 \ifx\csname inst@sec\current@section\endcsname\relax
1037  \relax
1038 \else
1039  \vspace{\beforeinstsep}
1040  \csname inst@sec\current@section\endcsname
1041  \par\vspace{\afterinstsep}

1042 \fi

1043 \begin{enumerate}
1044  \the\csname qlist@scr@sec\current@section\endcsname
1045 \end{enumerate}}

\@fixedstarmain This contains all the commands to be invoked if the current section in the main loop is a fixed* environment.

1046 \def\@fixedstarmain{%

Again, define \question and \endquestion in case someone used a block environment within a fixed* environment. This isn’t as crazy as one might think, since a block is the easiest way to place text before a question (i.e., before a questionnumber).

1047 \def\question{\item \@beforequestionhook}
1048 \def\endquestion{\@endquestionhook}

Specify an exact meaning for —separator—, which will appear when we execute the question list.

1049 \def\@separator##1{\setcounter{temp}{##1}
1050  \edef\current@question{\roman{temp}}
1051  \csname sec\current@section @qst\current@question\endcsname}

If we are making a answer, define the answer environment to be the following:

1052 \ifanswer
1053  \gdef\answer{\begin{description} \item[Answer:]}
1054  \gdef\endanswer{\end{description}}

Otherwise, make answer gobble the answer

1055 \else
1056  \def\answer{\get@noanswer@body}
1057  \def\endanswer{\relax}
1058  \def\@S{answer}
1059  \long\def\get@noanswer@body##1\end{\find@answer@end}
1060  \def\find@answer@end##1{\def\@tempa{##1}
1061  \ifx\@tempa\@S\expandafter\finish@up
1062  \else\expandafter\get@noanswer@body\fi}
1063  \def\finish@up{\end{answer}}

1064 \fi

Typeset the section heading.

1065 \par\medskip

If the heading for this section is empty, don’t print anything (including the additional \par\medskip), but if the heading is not empty, print it plus the additional

\par\medskip.
1066 \ifx\csname head@sec\current@section\endcsname\relax
1067  \relax
1068 \else
1069  \par\vspace{\beforesectsep}
1070  \noindent{\csname head@sec\current@section\endcsname}
1071  \par\vspace{\aftersectsep}

1072 \fi

1073 \ifx\csname inst@sec\current@section\endcsname\relax
1074  \relax
1075 \else
1076  \vspace{\beforeinstsep}
1077  \csname inst@sec\current@section\endcsname
1078  \par\vspace{\afterinstsep}

1079 \fi

1080 \begin{enumerate}
1081  \the\csname qlist@scr@sec\current@section\endcsname
1082 \end{enumerate}

The next line is necessary in case the fixed environment is the last one in an exam. If other environments appear after fixed, then this switch will be reversed at the start of the loop that scrambles the order of the questions. But if no environments appear after fixed, this switch will remain set, causing the reassignment of token lists below to fail. I.e., from here on out no rearrangment of the exam questions will occur. That’s why we include the below switch.

1083 \global\notfixedtrue}

\@endquestionhook This provides a “hook” for inserting something (like a place to put points) at the end of every question. Originally initialized to just \relax

1084 \def\@endquestionhook{\relax}

\@beforequestionhook This provides a “hook” for inserting something (like a place to put points) at the end of every question. Originally initialized to just \relax.

1085 \def\@beforequestionhook{\relax}

\@tfitem This is a fancy version of \item that must be used for the true/false environment because of the way the exams and answers are printed.

1086 \def\@tfitem{%
1087 \ifanswer
1088  \item[\uline{\mbox{\csname tf@sol\current@question\endcsname}}]
1089 \else
1090  \item
1091 \fi}

\@mcitem This is a fancy version of \item that must be used for the multiple choice environment because we want to put the question text inside a minipage to keep it from being broken across pages.

1092 \def\@mcitem{\item\begin{minipage}[t]{\linewidth}}

\@mcenditem This completes the minipage environment begun above.

1093 \def\@mcenditem{\end{minipage}}

\answerspace Inserts a particular amount of space for an answer to be given only on the actual exam. The space is suppressed in the answer key.

1094 \def\answerspace#1{\ifanswer \relax \else \vspace*{#1} \fi}

\exam Whatever is given as an argument to this macro will only be included if we are typesetting an exam.

1095 \def\exam#1{\ifanswer\relax\else #1\fi}

\key Whatever is given as an argument to this macro will only be included if we are typesetting an answer key.

1096 \def\key#1{\ifanswer#1\fi}

\examvspace Insert the specified amount of vertical space only if we are making an exam. At the same time, check to see if the command was a starred command or not.

1097 \def\examvspace{\@ifnextchar*{\@examvspacestar}{\@examvspace}}
\@examvspacestar
1098 \def\@examvspacestar*#1{\exam{\vspace*{#1}}}
\@examvspace
1099 \def\@examvspace#1{\exam{\vspace{#1}}}

\examhspace Insert the specified amount of horizontal space only if we are making an exam. At the same time, check to see if the command was a starred command or not.

1100 \def\examhspace{\@ifnextchar*{\@examhspacestar}{\@examhspace}}
\@examhspacestar
1101 \def\@examhspacestar*#1{\exam{\hspace*{#1}}}
\@examhspace
1102 \def\@examhspace#1{\exam{\hspace{#1}}}

\keyvspace Insert the specified amount of vertical space only if we are making an exam. At the same time, check to see if the command was a starred command or not.

1103 \def\keyvspace{\@ifnextchar*{\@keyvspacestar}{\@keyvspace}}
\@keyvspacestar
1104 \def\@keyvspacestar*#1{\key{\vspace*{#1}}}
\@keyvspace
1105 \def\@keyvspace#1{\key{\vspace{#1}}}

\keyhspace Insert the specified amount of vertical space only if we are making an exam. At the same time, check to see if the command was a starred command or not.

1106 \def\keyhspace{\@ifnextchar*{\@keyhspacestar}{\@keyhspace}}
\@keyhspacestar
1107 \def\@keyhspacestar*#1{\key{\hspace*{#1}}}
\@keyhspace
1108 \def\@keyhspace#1{\key{\hspace{#1}}}

Index

Numbers written in italic refer to the page where the corresponding entry is described, the ones underlined to the code line of the definition, the rest to the code lines where the entry is used.

Symbols

\@@@temp . . . . . 211, 213 \@@line . . . . . . 777, 798 \@@temp . . . . . . 104,

105, 114, 115, 582–584, 586, 588, 595–597, 599, 601, 608– 610, 612, 614, 621–623, 625, 627, 634–636, 638, 640, 647– 649, 651, 653, 660–662, 664, 666, 673–675, 677, 679, 686– 688, 690, 692, 699–701, 703, 705

\@Block … 97, 196, \underline{222}

\@Endmatter . . . 250, \underline{259}
\@Examclosing . 292, \underline{301}
\@Exampreface . 274, \underline{283}
\@Frontmatter . 232, \underline{241}

\@KYtop . . . . . . 791, \underline{796}

\@Keyclosing . . 334, \underline{343}
\@Keypreface . . 316, \underline{325}

\@MC . . . . . . 162, 523, 715 \@MCstar . . 172, 526, 716

\@OneKeyHook . . . . . .

… 14, 19, 20, 555 \@Q … 94, 142, \underline{189}, 213 \@S . . . . . . 425, 428,

457, 460, 1021, 1024, 1058, 1061

\@Space . . . . . . 803, 807 \@TEMP …. 404, 406–408 \@XMtop . . . . . . 770, \underline{775}

\@beforequestionhook

…. 151, 158, 166, 176, 184, 368, 827, 872, 893, 919, 964, 1010, 1047, \underline{1085}

\@blockbreaklist . .

. . . . . . . . 204, \underline{209}

\@currentsectionname

. . . . . . . . 148, 155, 162, 172, 581, 594, 607, 620, 633, 646, 659, 672, 685, 698

\@dumpthenstart 811, \underline{822}
\@enddocumenthook . \underline{366}
\@endmattertext . . .

…. 257, 548, 551

\@endofblockhook . .

. . . . . . . . 206, \underline{221}

\@endquestionhook .

…. 153, 160, 170, 180, 186, 369, 828, 873, 894, 920, 965, 1011, 1048, \underline{1084}

\@examclosingtext .

. . . . . . . . 299, 543

\@examhspace 1100, \underline{1102}
\@examhspacestar . .

. . . . . . 1100, \underline{1101}

\@examprefacetext .

. . . . . . . . 281, 385

\@examtopmatter 382, 773
\@examvspace 1097, \underline{1099}
\@examvspacestar . .

. . . . . . 1097, \underline{1098} \@fillin . . . . . 480, 709

\@fillinstar . . 520, 710
\@fillinstarmain . .

. . . . . . . . 521, \underline{826} \@fixed . . . . . . 447, 717

\@fixedstar . . . 538, 718
\@fixedstarmain . . .

. . . . . . . 539, \underline{1046}

\@frontmattertext .

…. 239, 376, 379

\@gobbletostop 814, \underline{823}
\@ifnextchar . . 1097,

1100, 1103, 1106

\@keyclosingtext . .

. . . . . . . . 341, 545

\@keyhspace . 1106, \underline{1108}
\@keyhspacestar . . .

. . . . . . 1106, \underline{1107}

\@keyprefacetext . .

. . . . . . . . 323, 390

\@keytopmatter 387, 794

\@keyvspace . 1103, \underline{1105}
\@keyvspacestar . . .

. . . . . . 1103, \underline{1104}

\@mcenditem . . . . . . .

… 168, 178, \underline{1093} \@mcitem . 164, 174, \underline{1092}

\@mcstartlist . 721, \underline{741}
\@multiplechoicemain

. . . . . . . . 524, \underline{871}

\@multiplechoicestarmain

. . . . . . . . 527, \underline{891} \@next . . . . . . 95, 98,

101, 102, 808, 811, 814, 817, 821

\@oldenddocumenthook

. . . . . . . . . . . 366

\@questionnumber . .

. . . . . . . . 130, 131

\@separator . . . . . . .

. 351, 355, 359, 416, 448, 481, 829, 874, 895, 916, 961, 1012, 1049

\@shortanswer . 415, 711
\@shortanswerstar .

. . . . . . . . 529, 712

\@shortanswerstarmain

. . . . . . . 530, \underline{1009}

\@startofblockhook .

. . . . . . . . 203, \underline{208} \@temp . . . . . . . 824, 825 \@tempa . . 93, 94, 97,

125–128, 132, 141, 142, 146, 149, 156, 163, 173, 182, 195, 196, 200, 202, 231, 232, 249, 250, 273, 274, 291, 292, 315, 316, 333, 334, 427, 428, 459, 460, 769, 770, 790, 791, 1023, 1024, 1060, 1061

\@tempb . . . . . . 147, 149, 156, 163, 173, 182, 201, 202

\@testforquestion .

. . . . . . . . 209, \underline{210} \@tfitem . . . . . 150,

157, 919, 964, \underline{1086} \@toklist 87, 90, 100,

105, 115, 135, 138, 143, 152, 159, 167, 177, 185, 190, 192, 197, 205, 224, 228, 235, 239, 242, 246, 253, 257, 266, 270, 277, 281, 284, 288, 295, 299, 308, 312, 319, 323, 326, 330, 337, 341, 762, 766, 771, 773, 784, 787, 792, 794

\@truefalse 148, 532, 713
\@truefalsemain 533, \underline{915}
\@truefalsestar . . .

…. 155, 535, 714

\@truefalsestarmain

. . . . . . . . 536, \underline{960}

\@whilenum 129, 372,

374, 393, 401, 558

\@wordlist . . . 804, 822
\@wordmain . . . 804,

806, 808, 817, 822 \\ . . . . . . . 575–577, 777

A

\addtolength . . . . . . 73
\afterinstsep 71–73,

441, 473, 514, 866, 886, 910, 937, 986, 1041, 1078

\aftersectsep 67, 68,

435, 467, 508, 859, 880, 903, 931, 979, 1034, 1071

\answer 420, 423, 452, 455, 922, 924, 967, 969, 1016, 1019, 1053, 1056

\answerfalse . . . . . . 383
\answerspace . . . . . \underline{1094}
\answertrue . . . . . . . 388

\append 131, \underline{350}, 362, 408

B

                   \beforeinstsep 69, 70,

439, 471, 512, 864, 884, 908, 935, 984, 1039, 1076

                   \beforesectsep 65, 66,

432, 464, 505, 857, 877, 901, 928, 977, 1032, 1069

\bigskip . . . . . 782, 801 \blank . . . . . . . 486,

491, 498, 501, 834, 839, 846, 849

                   \blank@length . . 61,

486–488, 498, 757, 834–836, 846

                   \blank@multiplier .

. 492–494, 502, 758, 840–842, 850

\block . . . . . . . . . . . \underline{190} block (environment) . . 8

                   \block@wrap@up 196, \underline{199}

\boxfalse . . . . . . 15, 16 \boxtrue . . . . . . . . . 12

                   \Bwrap@up@instructions

. . . . . 98, 109, 113

C

                   \cblanksfalse . . 77, 758
                   \cblankstrue . . . . . . 757

\choice . . . . . . . . . . \underline{719}

                   \choicefalse . . . 74, 739
                   \choicetrue . . . . . . . 721

\class . . . . . . . . . 3, 571

                   \classdata . . . \underline{571}, 777
                   \ConstantBlanks . 3, \underline{757}
                   \current@question .

…. 417, 418, 449, 450, 482, 483, 830, 831, 875, 876, 896, 897, 917, 918, 925, 962, 963, 970, 1013, 1014, 1050, 1051, 1088

                   \current@section . .

. 395–397, 400, 403, 409, 410, 412, 413, 415, 418, 434, 436, 440, 444, 447, 450, 466, 468, 472, 476, 480, 483, 507, 509, 513, 517, 520, 523, 526, 529, 532, 535, 538, 560, 561, 563– 565, 825, 831, 854, 858, 861, 865, 869, 876, 879, 881, 885, 889, 897, 898, 902, 905, 909, 913, 918, 930, 932, 936, 947, 957, 963, 974, 978, 981, 985, 996, 1006, 1014, 1029, 1033, 1036, 1040, 1044, 1051, 1066, 1070, 1073, 1077, 1081

\CurrentOption . . . . 23

D

\DeclareOption . . . .

…. 15–18, 21–23

E

\endanswer 421, 424,

453, 456, 1017, 1020, 1054, 1057

\endblock . . . . . . . . \underline{223}

\endendmatter . . . . . \underline{244}
\endexamclosing . . . \underline{286}
\endexampreface . . . \underline{268}
\endexamtop . . . . . . . \underline{764}
\endfrontmatter . . . \underline{226}
\endkeyclosing . . . . \underline{328}
\endkeypreface . . . . \underline{310}
\endkeytop . . . . . . . \underline{786}
\endmatter . . . . . . . \underline{242}
endmatter (environ-

ment) . . . . . . . 10

\endmatter@wrap@up .

. . . . . . . . 251, \underline{256}

\endquestion \underline{137}, 369,

828, 873, 894,

920, 965, 1011, 1048

                   \endsection . . . 119, 122

environments:

block . . . . . . . . . . 8

                       endmatter . . . . . . 10
                       examclosing . . . . 11
                       exampreface . . . . 11

examtop …. 10, 40 fillin* . . . . . . . \underline{35} fillin . . . . . . . 4, \underline{35} fixed* . . . . . . . . \underline{38} fixed . . . . . . . . 8, \underline{37}

                       frontmatter . . . . 10
                       keyclosing . . . . . 11
                       keypreface . . . . . 11

keytop . . . . . 10, 41

                       multiplechoice*    \underline{37}
                       multiplechoice 7, \underline{37}

section . . . . . . . \underline{17}

                       shortanswer* . . . \underline{36}
                       shortanswer . . . 5, \underline{36}
                       truefalse* . . . . . \underline{36}
                       truefalse . . . . . 6, \underline{35}

\exam 11, \underline{1095}, 1098,

1099, 1101, 1102 \exam@c 83, 357, 359, 360 \exam@m . 85, 86, 402, 403 \exam@n . . . . . . . . . . 84

                   \examclosing . . . . . . \underline{284}
                   examclosing (environ-

ment) . . . . . . . 11

                   \examclosing@wrap@up

. . . . . . . . 293, \underline{298}

                   \examhspace . . . 11, \underline{1100}
                   \examhspace* . . . . . . 11

\examname . . 3, 573, 574

                   \exampreface . . . . . . \underline{266}
                   exampreface (environ-

ment) . . . . . . . 11

                   \exampreface@wrap@up

. . . . . . . . 275, \underline{280} \examtop . . . . . . . . . \underline{762} examtop (environment)

. . . . . . . . . 10, 40 \examtype …. \underline{573}, 778

                   \examvspace . . . 11, \underline{1097}
                   \examvspace* . . . . . . 11

F \fboxsep . . . . . 725, 726 fillin (environment)

. . . . . . . . . 4, \underline{579} fillin* (environment) \underline{592}

                                             \find@answer@end . .

…. 426, 427, 458, 459, 1022, 1023, 1059, 1060

                                             \find@block@end 193, \underline{194}
                                             \find@endmatter@end

. . . . . . . . 247, \underline{248}

                                             \find@examclosing@end

. . . . . . . . 289, \underline{290}

                                             \find@exampreface@end

. . . . . . . . 271, \underline{272}

                                             \find@examtop@end .

. . . . . . . . 767, \underline{768}

                                             \find@frontmatter@end

. . . . . . . . 229, \underline{230}

                                             \find@instructions@end

. . . . . . . . . 91, \underline{92}

                                             \find@keyclosing@end

. . . . . . . . 331, \underline{332}

                                             \find@keypreface@end

. . . . . . . . 313, \underline{314}

                                             \find@keytop@end . .

. . . . . . . . 788, \underline{789}

                                             \find@question@end .

. . . . . . . . 139, \underline{140}

                                             \finish@up 428, 430,

460, 462, 1024, 1026, 1061, 1063

                                             \FirstQuestionInBlocktrue

. . . . . . . . . . . . 80 fixed (environment) 8, \underline{683} fixed* (environment) \underline{696}

                                             \frontmatter . . . . . . \underline{224}
                                             frontmatter (environ-

ment) . . . . . . . 10

                                             \frontmatter@wrap@up

. . . . . . . . 233, \underline{238}

                                             \Fullpages . . . . . . . \underline{749}

G

                                             \get@block@body . . .

…. 191, \underline{192}, 198

                                             \get@endmatter@body

…. 243, \underline{245}, 254

                                             \get@examclosing@body

…. 285, \underline{287}, 296

\get@exampreface@body

…. 267, \underline{269}, 278

\get@examtop@body .

…. 763, \underline{765}, 772

\get@frontmatter@body

…. 225, \underline{227}, 236

\get@instructions .

. . . . . \underline{90}, 101, 590, 603, 616, 629, 642, 655, 668, 681, 694, 707

\get@keyclosing@body

…. 327, \underline{329}, 338

\get@keypreface@body

…. 309, \underline{311}, 320

\get@keytop@body . .

…. 785, \underline{787}, 793

\get@noanswer@body .

. . . . . . . . 423, 426, 429, 455, 458, 461, 1019, 1022, 1025, 1056, 1059, 1062

\get@question@body .

…. 136, \underline{138}, 144

H

\hrulefill . . . 575–578

\hspace … 487, 493, 835, 841, 1101, 1102, 1107, 1108

I

\identifierfalse . . 79
\ifanswer . . . . . 75,

399, 419, 451, 484, 723, 832, 921, 939, 966, 988, 1015, 1052, 1087, 1094–1096

\ifbox . . . . . . . . 12, 725

\ifcblanks . . . . 77,

485, 497, 833, 845 \ifchoice . . . . . 74, 720

\ifFirstQuestionInBlock

. . . . . . . . . . . . 80

\ifidentifier . . . . . 79
\ifincludeform . . . .

. . . . . . 7, 778, 799 \ifmcbold . . . . . . . 9, 27

\ifmcunder . . 10, 28, 34
\ifnotfixed 76, 398, 562
\ifpblanks . . . . 78,

490, 500, 838, 848

\ifsection . . . . . . . \underline{824}
\iftwocolumn . . . . . .

13, 26, 384, 389, 547 \ifulem . . . . . . . . . . 11

\includeformfalse . 21
\includeformtrue . . . 8
\instructions . . . . . \underline{570}

\item . 183, 216, 219, 368, 420, 452, 725, 728, 730, 733, 827, 872, 892, 1010, 1016, 1047, 1053, 1088, 1090, 1092

\itemindent . . . 747,

945, 955, 994, 1004 \itemsep . . . . . 748,

946, 956, 995, 1005

K

\key . 11, \underline{1096}, 1104,

1105, 1107, 1108

\keyclosing . . . . . . . \underline{326}
keyclosing (environ-

ment) . . . . . . . 11

\keyclosing@wrap@up

. . . . . . . . 335, \underline{340}

\keyhspace . . . 12, \underline{1106}
\keyhspace* . . . . . . . 12
\keypreface . . . . . . . \underline{308}
keypreface (environ-

ment) . . . . . . . 11

\keypreface@wrap@up

. . . . . . . . 317, \underline{322} \keytop . . . . . . . . . . \underline{784} keytop (environment)

. . . . . . . . . 10, 41

\keyvspace . . . 12, \underline{1103}
\keyvspace* . . . . . . . 12
\KYtop@wrap@up 791, \underline{794}

L

\labelsep . . . . 746,

944, 954, 993, 1003

\labelwidth . . . 744,

942, 952, 991, 1001

                          \leftmargin . . . 745,

943, 953, 992, 1002 \length … \underline{353}, 396, 410 \let . 95, 98, 101, 366,

808, 811, 814, 817

                          \linewidth . . . 165,

175, 872, 892, 1092

                          \LoadClass . . . . . . . 25

M

                          \make@qlist . . . 122, \underline{123}

\makebox . . . . . . . . .

. 488, 494, 836, 842

                          \mcboldfalse . . . . . . . 9
                          \mcboldtrue . . . . . . . 15

\MCfont 29, 31, 35, 37, 728

                          \mcunderfalse . . . . . 10
                          \mcundertrue . . . . . . 16
                          \medskipamount . . . .

…. 66, 68, 70, 72

                          multiplechoice (envi-

ronment) . 7, \underline{657}

                          multiplechoice* (envi-

ronment) … \underline{670}

N \namedata …. \underline{575}, 781

                          \namedata@vspace . .

. . 64, 575–577, 760

                          \NeedsTeXFormat . . . . 3
                          \newcommand 719, 749, 760

\newcount . . . . . . 83–85

                          \newcounter . . . . . . .

. . 5, 43–56, 58–60

                          \newenvironment . . .

. 579, 592, 605, 618, 631, 644, 657, 670, 683, 696

\newif … 7, 9–13, 74–80

                          \newlength . . . . . . .

. 61–65, 67, 69, 71 \newtoks . . . . . . . . .

81, 82, 87, 126, 127

                          \nextrandom . . . . . . . 15
                          \noexpand . . . . 150,

151, 153, 157, 158, 160, 164– 166, 168–170, 174–176, 178– 180, 183, 184, 186, 203, 204, 206

\notfixedfalse 688, 701
\notfixedtrue . 478,

566, 584, 597, 610, 623, 636, 649, 662, 675, 1083

\NumberOfVersions 3, \underline{568}

P

\parbox . . . . . . 777, 781

\PassOptionsToClass 23
\pblanksfalse . . . . . 757
\pblankstrue . . . 78, 758
\pointless . . . . . . . 15
\ProcessOptions . . . 24
\ProportionalBlanks

. . . . . . . . . 3, \underline{758}

\ProvidesClass . . . . . 4
\ProvidesFile . . . . . . 2

Q

\question . \underline{135}, 368,

827, 872, 892, 919, 964, 1010, 1047

\Qwrap@up@instructions

. . . . . . . . 95, \underline{103}

R

\remove . . . . . . \underline{356}, 403

\RequirePackage . . . 26

\rule . . . . . . . . 486, 492, 498, 502, 834, 840, 846, 850

S

\section . . . . . . . . . 88 section (environment) \underline{88}

\setrandimen . . . . . . 15
\setrannum . 15, 86, 402
\settowidth . . . . . . .

. 491, 501, 839, 849

shortanswer (environ-

ment) …. 5, \underline{631}

shortanswer* (environ-

ment) . . . . . . \underline{644} \stop . 804, 810, 822, 823

\StudentInfoLineSpacing

. . . . . . . . . 3, \underline{760}

T

\temp@@length . . . . . 63

\temp@length 62, 491–

494, 501, 502, 839–842, 849, 850

\temp@toks 82, 351, 352
\temptoks . . . . . . . .

. 81, 358, 362, 365 \textbf . . . . . . . . 29, 31

\theextract . . . . . . . 404
truefalse (environ-

ment) …. 6, \underline{605}

truefalse* (environ-

ment) . . . . . . \underline{618}

\twocolumnfalse . . . 13
\twocolumntrue . . . . 22

\typeout . . . . . . . . . 400

U

\ulemfalse . . . . . . . 11

\uline …. 29, 35, 1088

W

\word . . . . . . . . . 12, \underline{803} \wrap@up . . . . . 142, \underline{145}

X

\XMtop@wrap@up 770, \underline{773}