Skip to content

Exercise Standards

This document is the authoritative specification for exercise content in the Berean Bible Bots project. scripts/validate_exercises.py enforces these rules automatically; if a rule is not yet validated, that is a gap in the validator, not an exception to the standard.

Contents


Three-Format Rule

Every exercise must ship in exactly three formats. Never create an exercise without all three.

File Purpose
<name>.md Static reference copy with full answer key at the bottom
<name>.html Self-contained interactive HTML (fillable, self-grading)
<name>.pdf AcroForm fillable PDF for print/download

The exercise directory also contains a README.md with a description, conjugation coverage table, and a files table linking all three formats.

Enforced by: validate_exercises.pycheck_three_formats


Exercise Directory Layout

data/lessons/<course>/ch<N>/exercises/<exercise-name>/
    <exercise-name>.md        ← static reference + answer key
    <exercise-name>.html      ← interactive HTML
    <exercise-name>.pdf       ← fillable PDF
    README.md                 ← description, coverage table, files table

The exercise name (<exercise-name>) must match the directory name exactly — no spaces, lowercase with hyphens.


HTML Exercise Format

The .html file is fully self-contained — no external dependencies, no CDN links, no separate CSS or JS files.

Structure requirements

  • <input class="parse-field"> in every parse cell (for free-text fields; see Input Field Types for when to use <select> instead)
  • ▶ Answer button per verb/item row — clicking reveals a green answer row beneath it; clicking again hides it
  • Three global controls at the top of the form: Show All Answers, Hide All Answers, Clear All Inputs
  • @media print block: hides all buttons; makes <input> elements render as underlines
  • All answers, styles, and JavaScript embedded inline in the single .html file

Hebrew/Aramaic/Greek text

  • RTL text: direction:rtl; unicode-bidi:embed on the element
  • Never put a verse range and Hebrew text on the same line. RTL reordering renders it backwards. Put the verse reference on its own line or in its own cell.

PDF Generation

All PDFs are generated by src/bible_grammar/exercise_pdf.py.

Chapter range Base class Key method
Ch24+ passage exercises PassageExercise (Template Method) _render_passages(show_answers: bool)
Ch1–Ch23 Plain ExercisePDF subclass add_generic_table()

Each exercise has a build_ch<N>_<exercise>() function that saves the PDF to the correct output path. All builders are called from the if __name__ == '__main__': block.

Key data classes: - VerbEntry — 6 fields: num, verb, conj, pgn, root, func - PassageBlock — fields: ref, hebrew, english, watchout

To regenerate all PDFs:

python3 src/bible_grammar/exercise_pdf.py


Input Field Types

Fields with a constrained set of valid answers must use <select> dropdowns, not free-text <input> elements. This prevents ambiguous answers and makes grading unambiguous.

Field type Required control
Stem (Qal, Niphal, Hiphil …) <select>
Conjugation (Perfect, Imperfect, Imperative …) <select>
PGN (3ms, 2fp …) <select>
Yes / No answers <select>
Function / Role labels <select>
Free-text (root, translation, gloss) <input class="parse-field">

For paradigm fill-in drills (<select>-based): present four options, all from the same root. Answer rows must include morphological notes (stem + conjugation + PGN label).


Answer Row Layout

Every .answer-row <td> must align cell-for-cell with the corresponding columns in the table header. Do not collapse multiple cells into td[0] or use colspan on answer rows.

<!-- Header row -->
<tr>
  <th>#</th><th>Verb</th><th>Stem</th><th>Conj</th><th>PGN</th><th>Root</th><th>Function</th>
</tr>

<!-- Answer row — same column count -->
<tr class="answer-row">
  <td>1</td><td>יִשְׁמֹר</td><td>Qal</td><td>Imperfect</td><td>3ms</td><td>שׁמר</td><td>Prefix conjugation</td>
</tr>

Distractor Policy (Ch24+ Passage Exercises)

"Spot the [Stem]" passage exercises must include distractor verbs from every stem learned before the target chapter's stem, ordered by chapter introduction. Students label every numbered verb with "[Stem]? Yes / No."

  • Distractors must be drawn from real verbs appearing in the same passage quotations where possible.
  • The coverage table in the exercise README.md must list every stem tested and its distractor status.

Stem introduction order follows the BBH chapter map in CLAUDE.md.