Essentially, you write your exam in Markdown, with some special commands to separate questions / question groups and to change settings.
An exam is made up of groups, which each contain questions. Each question can be:
Groups and questions can contain description text written in Markdown, including
Basically anything that works in GitHub Markdown should work here - if it doesn’t work, it should be considered a bug.
The general syntax of this structure looks like:
# BEGIN GROUP Section 1
# BEGIN QUESTION
This is a question
# INPUT SHORT_ANSWER
# END QUESTION
# BEGIN QUESTION
This is another question, that's multiple-choice.
# INPUT OPTION Option 1
# INPUT OPTION Option 2
# END QUESTION
# END GROUP
Each group block is introduced with a
# BEGIN GROUP <title> [<points>]
statement. The title and point values are both optional. For instance,
# BEGIN GROUP Gobears [4]
creates a group of questions called Gobears
worth 4
points. Note that a group title
must be in plain text, not Markdown.
Each group then can have some body text written in Markdown. After this body text comes a sequence of element blocks. Element blocks are either nested group blocks or question blocks. Then a group is ended with
# END GROUP
Groups can also contain config statements. If you include the config statement
# CONFIG PICK <num>
within a group block, then only num
elements (subgroups or questions) will be randomly selected and presented to the student, rather than the entire group.
If you include the config statement
# CONFIG SCRAMBLE
within a group block, then its enclosed elements will be randomly re-ordered.
Each question block is introduced with
# BEGIN QUESTION [<points>]
Note that, unlike groups, questions do not have titles. Then you can provide some question
body text, written in Markdown. Then you must provide at least one INPUT
statement. Then
you can provide SOLUTION
and NOTE
blocks. Then a question is ended with
# END QUESTION
An input statement is written as
# INPUT <type> <content>
All the input statements within a single question must be of the same type
.
For multiple-choice questions, you put one input statement for each possible choice,
with type = OPTION
for select-one, and type = SELECT
for select-all. The value of the choice
is the content
, written in Markdown. For instance, you could write
# INPUT OPTION An option
to provide a single multiple choice option with value An option
.
To fix an option in place even if SCRAMBLE_OPTIONS
is enabled, use the syntax
# INPUT <type> FIXED <content>
and it will not be shuffled.
To indicate a correct option when generating solutions, use the syntax
# INPUT <type> CORRECT <content>
If FIXED
and CORRECT
are used together, use the syntax
# INPUT <type> FIXED CORRECT <content>
Note that the order matters.
For short / long answer questions, you must provide exactly one input statement within that question.
The type
can be SHORT_ANSWER
, SHORT_CODE_ANSWER
, LONG_ANSWER
, or LONG_CODE_ANSWER
. CODE
means that the font will be monospaced and tab will work to indent text typed in a LONG_CODE_ANSWER
.
For short answer questions, the content
should be left blank. For long answer questions, the content
can optionally be an integer representing the number of lines provided in the input field before the user
has to start scrolling. This also affects the height of the box in the generated PDF in a similar way.
Each solution block looks like
# BEGIN SOLUTION
...
# END SOLUTION
and each note block looks like
# BEGIN NOTE
...
# END NOTE
Solutions will be included in the text entry box in the PDF when solutions are generated, and notes will be included after the text entry box (e.g. as further explanations). Notes can be included for any type of question, but solutions can only be included for free-response type questions.
If you want to have some questions that can be filled out before the exam starts, use a
# BEGIN PUBLIC
...
# END PUBLIC
block, just like a group block. This will create a question group that is visible before students start the exam. At most one such block can exist in the exam.
At the beginning of the exam, before anything else, you can provide config statements, written as
# CONFIG <option>
The valid choices of option
are SCRAMBLE_GROUPS
and SCRAMBLE_OPTIONS
. These will
randomize the order of groups and questions or multiple choice options respectively for each student. The tool
will derandomize all of these before grading.
To randomize just groups at a particular depth, write
# CONFIG SCRAMBLE_GROUPS <depth> <depth> ...
to specify the scrambled depths, which are zero-indexed. Questions are one level lower than their parent group.
To fix a particular group or question in its place while scrambling the others, use the syntax
# BEGIN GROUP FIXED
or # BEGIN QUESTION FIXED
. You can still provide titles (for groups) and point values
while using this syntax.
It is also possible to replace particular words or variables in an exam for each student, to prevent cheating. The syntax is
# DEFINE <target> <alt1> <alt2> ...
This will replace all instances of target
with one of the alternatives, chosen randomly. This will be scoped to
the block where it is made i.e. if it is written at the top-level, it will replace the target
everywhere in the document,
if it is written in a group, it will replace the target
everywhere in the group, etc.
If you have a set of variables which should be replaced with a set of another, and you do not want duplicate choices, you can use this define syntax:
# DEFINE MATCH [<target1> <target2> ...] [<alt1> <alt2> ...]
This will uniquely set each target with one of the alts. You may have more alts than targets but you must have at least as many alts as targets.
Note that this syntax does not support Markdown - it is a very naive text substitution in the generated HTML, so don’t try anything too fancy with it!