Skip to content

Question spec

Each question line follows this format:

(n) identifier source [source ...] [-- options]
  • (n) — how many times to generate this question
  • identifier — the question type (e.g. multi_direct, divi_euclidean)
  • source — a numrange expression, a content table name (e.g. fractions), or an alternator key
  • -- options — optional key=value pairs or bare flags

Most question types take a single source. A few need more than one — for instance order_of_2ops, which draws a standalone term and a two-operand block, or frac_equal, which draws a base fraction and the number it is multiplied by. Such a type binds its sources by arity, not by the order they are written: 7-19 4-9×4-9 and 4-9×4-9 7-19 mean the same thing, the singleton range feeding the standalone term and the product range the block.

(10) multi_direct 2-9×2-9
(2)  divi_direct 2-9×2-9 -- variant=one_nth_of
(1)  multi_hole fractions -- irreducible=true hidden=fraction
(3)  divi_euclidean 2-9×2-9
(2)  divi_direct 0.001-9.999×10,100,1000
(6)  order_of_2ops 7-19 4-9×4-9 -- variant=plain result=positive
(4)  frac_equal 2-9×2-9 2-9 -- order=ascending

Options

Options follow -- and are whitespace-separated. Values are cast automatically:

Syntax Result
key=text string
key=3 integer
key=0.5 float
key=true / key=yes boolean True
key=false / key=no boolean False
flag boolean True
key=default option ignored — the question type applies its own default

default is a reserved value: writing -- variant=default has exactly the same effect as not writing the option at all. On its own it is not very useful; it earns its keep as one of the alternatives below.

Which option names are accepted

Validation (automath check qspec, check qblock, and the automathon editor) refuses an option name that nothing on the line would read — a misspelled varaint=wording is a typo the render path would silently ignore, leaving you with a sheet that quietly used the default.

What a given line accepts is the union of:

  • the options every question type reads — steps, variant, transduration, answer_layout, note_layout;
  • the options the question type adds — shuffle on the multiplication types and on addi_direct, scale on multi_direct, hidden on multi_hole and on frac_equal (which also reads order), width on the digitplace_* types and on units_conversion, result, decimals and tricks on order_of_2ops, carry, min_result and max_result on addi_direct and subtr_direct (which also reads result);
  • when a source is a content table, that table's columns, which act as row filters — fractions accepts numerator, denominator, irreducible and proper, hence multi_hole fractions -- irreducible=true; unit_pairs accepts quantity, level, gap, direction, everyday, dimension, unit1 and unit2, hence units_conversion unit_pairs -- level=1.

The error message lists what the line does accept, so there is no need to look it up here.

Option alternatives

An option value can offer several alternatives between braces, separated by |. One of them is drawn for each question:

(6) square_of 4-9×4-9 -- variant={default|wording}

Here six questions are generated, each independently drawing its own variant — about half plain, half worded. This is not a single draw applied to the whole line.

The rules mirror the pipe notation of question blocks:

  • the group must be the whole value of a key=value option — variant=pre{a|b} is rejected;
  • no space inside the group — {a | b} is rejected;
  • alternatives must not be empty — write default rather than {|wording};
  • a group cannot be nested inside another {...} group: write square_of {4-9×4-9|5-9×5-9} -- variant={default|wording}, not square_of {4-9×4-9 -- variant={default|wording}|5-9×5-9};
  • a bare flag cannot be turned into a group: -- {shuffle|fast} is not supported.

Option alternatives combine freely with the other notations — the example above draws its source and its variant independently for each of its questions. automath check qspec checks every combination, not a random one, so an invalid value is reported even when it sits in an alternative that a given render did not pick.

Selecting variants

Most question types take a single variant value, listed in Available question types. Types whose variants form a numbered catalogue — currently order_of_2ops — accept a selector instead: comma-separated terms, evaluated left to right, where ^ removes.

Term Meaning
17 one entry, by number
17-24 a range of numbers
a+bxc one entry, by name
plain a family alias
^24 remove what the term designates
-- variant=17-24              numbers 17 to 24
-- variant=a+bxc,a-bxc        two shapes, by name
-- variant=plain,^24          the plain family except number 24
-- variant=^8,^24             everything except 8 and 24

A selector made only of exclusions starts from the whole catalogue, so ^8,^24 needs no base term. A term that changes nothing is an error rather than a silent no-op: 1-24,^11,12 is rejected, because the 12 reads as an inclusion of something already selected — write 1-24,^11,^12.

Names may contain - and + without ambiguity: a term starting with a digit is a number or a range, anything else is a name or an alias.