I'm writing a few multiple choice practice questions and I'd like to store them in a simple plain text data format. I've previously used tab delimited, but that makes editing in a text editor a bit awkward. I'd like to use a format a bit like bibtex.


  title =   "Review of Affective Computing",
  author =  "Aaron Sloman",
  journal = "AI Magazine",
  year =    "1999",
  number =  "1",
  volume =  "20",
  url = "http://dblp.uni-trier.de/db/journals/aim/aim20.html#Sloman99",
  pages =   "127--133",

Important properties seem to be:

  • Data is made up of records
  • Each record has multiple attribute-value pairs
  • Each attribute-value pair can be recorded on a new line, but can span multiple lines
  • Easy to manually enter textual data in a text editor
  • Readily available tools to convert into tabular data

For example, here is something a bit like what might work

id: 1
question: 1 + 1
a: 1
b: 2
c: 3
d: 4
correct: b

id: 2
question: What is the capital city of the country renowned for koalas, 
          emus, and kangaroos?
a: Canberra
b: Melbourne
c: Sydney
d: Australia
correct: a

While I'm interested in the specific context of writing multiple choice questions, I'm also interested in the broader issue of representing data in this or a similar type of format.

Initial Thoughts

My initial thoughts included the following:

  • YAML
  • JSON
  • Delimited data with custom field and record delimiters that permit multi-line records
  • A custom file format with some form of custom parser

I've only had a quick look at YAML and JSON; My first impressions are that they might be over-kill. Custom delimiting might be good, but it would probably require all fields to be present in a consistent order for all records. Writing my own parser sounds a bit fiddly.

  • 1
    $\begingroup$ I agree with thias, that XML might be a good fit. I had a project where I had to interface R with webserver. Exporting data in xml format was very convenient. The only problem is that I did not find any good XML package documentation, so I resorted to writing my own xml writer. Parsing was done with javascript and it was joy to use. $\endgroup$ – mpiktas Oct 4 '11 at 10:59
  • 1
    $\begingroup$ Hm, I take back my statement about good documentation. This looks very similar to what you want to achieve. $\endgroup$ – mpiktas Oct 4 '11 at 11:03
  • $\begingroup$ just a (not entirely serious) thought: You could actually use bibtex with custom fields for your data. All you need to do then is to write a custom .bst file. It is then only a matter of putting \bibliography{multiplechoice} in your latex-document. Writing the .bst is cumbersome, though and you only have access from latex... $\endgroup$ – thias Oct 4 '11 at 12:36
  • $\begingroup$ @macias I admit this is not too on-topic, yet it is also too settled to be migrated. $\endgroup$ – user88 Oct 5 '11 at 7:12

Why not use XML? There are many good parsers that directly translate XML files to data structures, even one for R ( http://cran.r-project.org/web/packages/XML/index.html ).

The format looks like this (example taken from http://www.w3schools.com/xml/default.asp ).

<?xml version="1.0"?>
        <body>Don't forget me this weekend!</body>
        <body>Don't forget me the next weekend!</body>

E.g, using the XML package:


gives access to the complete notes body,


is just the first node and so on...

  • 1
    $\begingroup$ if you could provide example how to write and read the data with R XML package it would be great. $\endgroup$ – mpiktas Oct 4 '11 at 10:56
  • $\begingroup$ good idea; It's been a while since I've used xml. I'll give a try. XML seems fairly verbose, but I imagine I could improve the situation with a few text editor features. $\endgroup$ – Jeromy Anglim Oct 4 '11 at 11:00
  • $\begingroup$ @mpiktas ok, added an example $\endgroup$ – thias Oct 4 '11 at 11:14
  • $\begingroup$ @JeromyAnglim I agree that XML is not all that easy to read but with syntax highlighting, you should be fine, at least for the simple structure you are going to need $\endgroup$ – thias Oct 4 '11 at 11:17
  • $\begingroup$ XML is great. As with violence, if it doesn't solve your problem, you're not using enough of it ;-) $\endgroup$ – xmjx Oct 4 '11 at 19:20

I'd go with YAML. Straight forward to edit and has plenty parsers in different languages:

  question: 1 + 1
    - 1
    - 3
    - 4
  correct: 2
 question: What is the capital city of the country renowned for koalas, emus, and kangaroos?
   - Melbourne
   - Sydney
   - Australia
 correct: Canberra

You could then write a little script to randomly mix the incorrect with correct answers and output the LaTeX suggested in DQdlM's answer.

EDIT: This ruby script:

require 'yaml'

questions = YAML.load(File.read(ARGV.first))
questions.each_with_index do |question,index|
  answers = question['incorrect'].map{|i| '    \choice ' + i.to_s }
  answers << '    \CorrectChoice ' + question['correct'].to_s

  output = ["\\question{#{index + 1}}"]
  output << question['question']
  output << "  \\begin{choices}"
  output << answers.sort_by{rand}
  output << "  \\end{choices}"
  output << "\n"

  puts output.flatten.join("\n")

Will produce the following output

1 + 1
    \choice 4
    \choice 1
    \choice 3
    \CorrectChoice 2

What is the capital city of the country renowned for koalas, emus, and kangaroos?
    \choice Melbourne
    \choice Sydney
    \CorrectChoice Canberra
    \choice Australia

This may not fully address applications beyond your multiple choice questions but there is an exam class available for LaTeX.

Multiple choice questions are formed like this:

The fascile of a nerve is surrounded by what connective tissue layer?
    \choice endoneurium
    \choice epineurium
    \CorrectChoice perineruium
    \choice neurolemma
    \choice none of the above

By including \printanswers in your preamble it highlights the correct answer.

  • $\begingroup$ @DQdIM thanks. That's actually what I use to display the final product, but I have R code to select items from an item database and write the individual items in latex format. $\endgroup$ – Jeromy Anglim Oct 4 '11 at 21:45

Org Mode can do that. One way would be like this:

#+COLUMNS: %id %a %b %c %d %correct

* 1 + 1  
    :id:       1
    :a:        1
    :b:        2
    :c:        3
    :d:        4
    :correct:  b

* What is the capital city of the country renowned for koalas, emus, and kangaroos?
    :id:       2
    :a:        Canberra
    :b:        Melbourne
    :c:        Sydney
    :d:        Australia
    :correct:  a

If you'd like to visually inspect a quick summary table then insert the following

* The column view

  #+BEGIN: columnview :hlines 1 :id global


Put the cursor in the #+BEGIN block and do C-c C-x C-u to get

#+BEGIN: columnview :hlines 1 :id global
| id | a        | b         | c      | d         | correct |
|  1 | 1        | 2         | 3      | 4         | b       |
|  2 | Canberra | Melbourne | Sydney | Australia | a       |
|    |          |           |        |           |         |

and if you'd like to import (to R, for instance) then insert a table name like this:

#+BEGIN: columnview :hlines 1 :id global
#+tblname: simpleDF
| id | a        | b         | c      | d         | correct |
|  1 | 1        | 2         | 3      | 4         | b       |
|  2 | Canberra | Melbourne | Sydney | Australia | a       |

then insert and execute the following R code block with C-c C-c:

#+begin_src R :session *R* :var df=simpleDF :colnames yes

this gives

| id | a        | b         | c      | d         | correct |
|  1 | 1        | 2         | 3      | 4         | b       |
|  2 | Canberra | Melbourne | Sydney | Australia | a       |

The good news is that the data frame df is now stored in the active *R* session and is available to post-process however you like. All of this being said, if it were me, I would probably start with the exams package (in R) for the specific application of storing/writing multiple choice questions, though that YAML example looks really cool.

  • $\begingroup$ +1 nice answer. I was sure org mode could do this but I didn't know how $\endgroup$ – DQdlM Oct 4 '11 at 15:20

Here are a couple of additional ideas:

  1. Use R itself:

    exam = list(question1 = list(
                            question='Here is the first question',
                            answers = list('a' = 'Here is the first answer',
                                           'b' = 'here is the second answer',
                                           'c' = 'Here is the third answer'
    > exam$question1
    > exam$question1$question
    > exam$question1$answers
    > exam$question1$answers$a
  2. Use reStructuredText, which is a lightweight markup language, similar to markdown, that can be parsed into a DOM (Python), e.g.:

    Here is the first question.
    * First answer.
    * Second answer.
    * Third answer.

There is an rst2xml writer that converts the above to:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE document PUBLIC "+//IDN docutils.sourceforge.net//DTD Docutils Generic//EN//XML" "http://docutils.sourceforge.net/docs/ref/docutils.dtd">
  <!-- Generated by Docutils 0.7 -->
  <document source="tmp.rst">
    <paragraph>Here is the first question.</paragraph>
    <bullet_list bullet="*">
        <paragraph>First answer.</paragraph>
        <paragraph>Second answer.</paragraph>
        <paragraph>Third answer.</paragraph>

There is also an rst2latex writer, so your test can be easily formatted for printing, and you can deal with the data using python and the document object model.

The advantage of this option is that rst is easy to read and write, unlike XML, but your data is still structured for use in R, Python, etc.


Not the answer you're looking for? Browse other questions tagged or ask your own question.