- Why this exists
- Features: QTI question support, comment support, and validation
- Quick usage example
- Markdown question format examples
- Requirements
- Command-line usage
- macOS droplets
- Future work
- License
Convert between a pure-Markdown quiz format and text2qti plaintext so you can author Canvas-compatible QTI quizzes in Markdown, preview them anywhere, and still interoperate with text2qti.
This repo provides:
md2t2qti.py: Markdown → text2qtit2qti2md.py: text2qti → Markdown- Ready-to-use macOS droplets/apps that wrap those scripts for drag-and-drop conversion.
The text2qti package has been a valuable tool for streamlining the construction of quizzes for learning management systems like Canvas that support the QTI format. Rather than requiring instructors to build quizzes within the native LMS interface, text2qti has enabled managing quizzes offline in a flat format. It has leveraged MarkDown to provide formatting options for quiz questions, answers, and feedback. However, the meta data about quizzes and their questions is encoded in a proprietary format that prevents modern text editors from properly preview or easily share the quizzes with other instructors and teaching staff.
Thus, md2qti is meant to provide a wrapper around text2qti that embeds all quiz metadata within MarkDown itself. The Markdown schema is deliberately simple and preview friendly. Question metadata (type, points, etc.) are embedded in headers; all prompts and rich content live in normal Markdown (including inline LaTeX with $...$, which text2qti supports).
- Write quizzes in one readable MarkDown file you can lint, diff, and preview.
- Keep fidelity with
text2qtiwhile adding stricter validation and better handling of comments, spacing, and multi-line content. - Support round-trip editing:
Markdown → text2qti → Markdownwith whitespace and comments preserved sensibly.
-
Question types: multiple choice (
mc), multiple answer (ma), numeric (num), fill/short-answer (fill), essay (essay), file upload (file), and text regions (textstimulus blocks). -
Question-level feedback:
Correct,Incorrect, andGeneral, placed after answers/specs in Markdown and mapped to...,+, and-blocks in text2qti. -
Per-choice feedback via indented blockquotes in Markdown.
-
LaTeX:
$...$math is passed through. -
Comments preserved:
- text2qti
% line→<!-- line -->in Markdown COMMENT ... END_COMMENT→ multi-line HTML comment block- Spacing around comments is preserved: if the source had a blank line before a comment, the output has one (and only one).
- text2qti
-
Quiz-level options (after the description):
shuffle answers,show correct answers,one question at a time,can't go backRepresented as blockquoted lines in Markdown:> shuffle answers: true > show correct answers: false ...
-
Strict validation: malformed input raises clear
ValueErrors with line numbers rather than silently dropping content (e.g., unindented wrapped stems, stray lines after choices, invalidmcwith more than 1 correct answer). -
Round-trip friendly: multi-line prompts/choices/answers preserve intentional blank lines within continuation blocks.
Convert a Markdown quiz to Canvas-importable QTI:
./md2t2qti.py examples/quiz.md -o quiz.txt
text2qti quiz.txtThen import the generated QTI ZIP into your LMS (e.g., Canvas).
Tip: The
MDtoText2QTI.appmacOS droplet will attempt to do both steps for you in one pass.
Below are examples of all supported question types in the pure-Markdown format used by md2qti.
## 1. Basic addition (points: 1) {type=mc}
What is $2+3$?
- [ ] 4
> Too low.
- [x] 5
- [ ] 6
> Too high.
> Correct: Well done!
> Incorrect: Try adding again.## 2. Dinosaurs (points: 2) {type=ma}
Which of the following are dinosaurs?
- [ ] Mammoth
> A mammoth is not a dinosaur. It is an elephant-like mammal.
- [x] *Tyrannosaurus rex*
> This dinosaur was a carnivore too.
- [x] Triceratops
- [ ] *Smilodon fatalis*
> _Smilodon_ is the genus for saber-toothed cats.
> General: To understand these answers, look up the precise definition of a dinosaur.## 3. Square root (points: 1) {type=num}
What is $\sqrt{2}$?
### Answer
= 1.4142 +- 0.0001## 4. North Pole resident (points: 1) {type=fill}
Who lives at the North Pole?
### Answers
- Santa
- Santa Claus## 5. Essay on selection (points: 5) {type=essay}
Explain how natural selection influences quantitative traits.## 6. Upload figure (points: 1) {type=file}
Upload your plot as a single PDF.## Formulas {type=text}
You may find the following formulas useful:
* p + q = 1
* h² = Vₐ / VₚTo run the Python conversion scripts directly, you’ll need:
- Python 3.8+ (available on most modern systems)
- The
text2qtipackage installed and accessible on yourPATH(e.g.,pip install text2qti)
Optional but recommended:
- A local LaTeX installation if you plan to render complex formulas in previews or PDF exports.
- A Markdown editor with built-in preview (e.g., VSCode, Typora) for easier quiz editing.
macOS users can instead use the prebuilt droplet apps from Releases, which bundle the Python logic for drag-and-drop use (but still require having Python and
text2qtialready installed).
./md2t2qti.py quiz.md -o quiz.txt- Validates the Markdown schema.
- Emits text2qti plaintext suitable for
text2qti→ QTI packaging.
./t2qti2md.py quiz.txt -o quiz.md- Validates text2qti structure.
- Preserves comments and spacing semantics.
- Enforces: for MC items there must be exactly one correct choice.
Errors are hard stops with line numbers (e.g., unindented wrapped stems, stray text after choices, invalid mc correctness count).
Prebuilt macOS droplet apps are available as release assets (download information below).
- MDtoText2QTI.app — Drop one or more
.mdquiz files to generate.txt(text2qti) output automatically. - Text2QTI2MD.app — Drop one or more
.txt(text2qti) files to convert back to.md.
Each app bundles the relevant Python and AppleScript code used in this repository.
Developers: If you’d like to build the apps yourself, see
macos/build_macos.sh, which packages and signs both droplets for distribution.
You can always get the latest macOS droplet builds here:
➡️ Download the latest release
Each release includes:
MDtoText2QTI.app.zipText2QTI2MD.app.zip
- Direct Markdown → QTI XML conversion (bypassing
text2qti).- Incorporation of
qti-package-maker - Support for QTI question types beyond
text2qti, like matching and ordering questions supported byqti-package-maker.
- Incorporation of
- Unit tests and sample round-trip fixtures.
This project is licensed under the MIT License.
Copyright (c) 2025 Theodore P. Pavlic.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the conditions in the LICENSE file.