mdquiz
v0.2.1
Published
Parse markdown quiz files into structured objects. Supports YAML frontmatter, checkbox answers, code blocks, and per-answer explanations.
Maintainers
Readme
mdquiz
Parse markdown quiz files into structured objects. Supports YAML frontmatter, checkbox answers, code blocks, and per-answer explanations.
Install
npm install mdquizUsage
Parse a single file
import { readFileSync } from 'node:fs'
import { parseQuestionFile } from 'mdquiz'
const md = readFileSync('question-001.md', 'utf-8')
const question = parseQuestionFile(md, 'question-001')
console.log(question.question) // "Which syntax defines a job?"
console.log(question.answers) // [{ id: 'a1', text: '...', isCorrect: true, explanation: '...' }, ...]
console.log(question.isMultiSelect) // falseParse a directory
import { parseDirectory } from 'mdquiz'
const questions = parseDirectory('./questions', {
filePrefix: 'question-', // only parse files starting with this prefix
recursive: false, // walk subdirectories (default: false)
})Markdown Format
---
question: "Which GitHub Actions syntax correctly defines a job that runs on Ubuntu?"
---
- [x] `runs-on: ubuntu-latest`
> This is the correct syntax for specifying a runner
- [ ] `os: ubuntu-latest`
- [ ] `platform: ubuntu-latest`
- [ ] `environment: ubuntu-latest`Only the question field is required in frontmatter. Any additional fields you include (e.g. title, category, difficulty) are accessible via question.frontmatter:
---
question: "What is a pull request?"
difficulty: easy
tags: ["git", "collaboration"]
---Structure
| Section | Required | Description |
|---------|----------|-------------|
| Frontmatter | Yes | YAML with question field (and any custom fields) |
| Code block | No | Context code shown before answers |
| Answers | Yes | Checkbox list: - [x] correct, - [ ] incorrect |
| Answer explanation | No | Blockquote (>) after an answer provides a per-answer explanation |
Answer formats
Both ordered and unordered lists work:
- [x] Correct answer
- [ ] Wrong answer
1. [x] Correct answer
1. [ ] Wrong answerMultiple [x] marks make the question multi-select automatically.
Per-answer explanations
Add a blockquote (>) immediately after an answer to provide an explanation. Multi-line explanations are joined with newlines:
- [x] Correct answer
> This is why it's correct
- [ ] Wrong answer
> This is wrong because...
> Here is more detailAPI
parseQuestionFile(content: string, id: string): Question
Parse a markdown string into a Question object.
parseDirectory(dir: string, options?: ParseDirOptions): Question[]
Parse all .md files in a directory. Skips files starting with _.
Types
interface Question {
id: string
question: string
answers: AnswerOption[]
isMultiSelect: boolean
codeBlock?: string
frontmatter: Record<string, unknown>
}
interface AnswerOption {
id: string
text: string
isCorrect: boolean
explanation?: string
}
interface ParseDirOptions {
recursive?: boolean
filePrefix?: string
strict?: boolean
}License
MIT License
