> Human-readable guide: https://repeatme.co/guides/card-authoring # RepeatMe card format v3 — text contract **Deck text contract (the `cards` format).** What the "Import deck" dialog, the "Your AI" paste boxes and the lesson result read — next to deck JSON, which they accept too. A document is a **header** (deck keys) followed by **cards**. Every line is `key: value` with the key in column 0. A card names the **facts** it knows — its sides, the other accepted forms of its answer, wrong options, a sentence with a blank — and never its study modes: the app derives the modes from the facts (see the table below). ```cards deck: English basics description: Core vocabulary, first 100 words. front-language: ru back-language: en --- front: яблоко back: apple distractors: banana | orange | grape cloze: I eat an {{apple}} every day. --- note: till and until are interchangeable; from opens the interval. front: с … до … back: from … till … cloze: The shop is open {{from}} 9 a.m. {{till|until}} 6 p.m. distractors: at | on | in ``` **Grammar:** - `---` on a line of its own starts a **new card**. `case:` (its value is an optional label) starts **another case of the same card** — a rule card with many example sentences, a word with several senses. A second `front:` with neither in between is read as a new card. - A value **continues** on the following lines when they are indented by at least one space (Markdown inside a side, a multi-line note). A line with no key and no indent is ignored. - **Lists** — `accept`, `distractors`, `tags`, `disabled-modes` — separate items with ` | `. Write `""` for the empty option ("no word belongs here"). - Nothing else is escaped or quoted. Reserved: a key in column 0, `---` in column 0, `|` inside a list, `{{ }}` inside `cloze`. - Print the whole document inside **one** fenced ```cards block; anything outside the fence is ignored, so no other text belongs inside it. **Keys** (the last column is the field's name in deck JSON — the same facts, written as JSON): | Where | Key | Meaning | JSON name | |---|---|---|---| | header | `deck` | deck name (required) | `title` | | header | `description` | one or two sentences about the deck | `description` | | header | `front-language`, `back-language` | language codes (`ru`, `en`, …) of the question side — the learner's own language — and of the studied side, which drives pronunciation | `frontLanguage`, `backLanguage` | | header | `disabled-modes` | study modes the deck switches off for every card, e.g. `disabled-modes: ReverseType, ReverseChoice`; leave it out to keep every mode the facts allow | `disabledModes` | | header | `tags`, `visibility` (`private` / `unlisted` / `public`) | optional | `tags`, `visibility` | | card | `title` | optional label (a grammar tag, a topic); never a copy of the front | `title` | | card | `note` | note shown **after** the answer — a rule recap, a mnemonic; it may name the answer | `explanation` | | card | `format` | `markdown` when a side uses Markdown; plain text by default | `contentFormat` | | case | `front` | question side (required) — the one clean term, no asides in brackets | `front` | | case | `back` | answer side — **one** canonical form; empty when the answer is "no word" | `back` | | case | `context` | cue shown **with** the question — ONLY when the front admits more than one correct answer; never hints the answer or the rule | `context` | | case | `accept` | other forms of the back the learner may type (`accept: go for a walk`) | `accept` | | case | `distractors` | three plausible wrong options for what the case asks — the back, or the blank when the `cloze` blanks only part of the back | `distractors` | | case | `cloze` | one sentence in the studied language with the answer inside `{{ }}` — see the blanks rules | `cloze` | In deck JSON a card is `{ "title", "explanation", "cases": [ { "front", "back", "context", "accept", "distractors", "cloze" } ] }`; each `case:` of the text is one more element of `cases`. Never write `front-image`, `back-image`, `back-audio` or `front-audio`: pictures are uploaded by the deck owner, pronunciation is attached by the server — an invented link is a broken one (E19). **How facts become modes.** A card never lists its modes: the app derives them from the facts and the deck, for every case, and a new mode reaches old cards by itself. Each case is shown in: | Mode | When | Built from | |---|---|---| | `Flip` | always | `front` → `back`, self-assessed | | `ReverseFlip` | the back is not empty and no other card of the deck has the same back | `back` → `front`, self-assessed | | `Match` | both sides are word-sized (5 words or fewer) and the deck has enough such cards | pairs of sides | | `Type` | the back is a word or a short phrase, not a whole sentence | typing the `back`; its parts separated by `,` or `;` and every `accept` item count | | `ReverseType` | as `ReverseFlip`, and the front is a word or a short phrase | typing the `front`; the fronts of the card's other cases with the same back count too | | `Choice` | there are `distractors`, or the deck's other cards give three | the back among wrong options — yours first, the rest from other cards' backs | | `ReverseChoice` | as `ReverseFlip`, and the deck's other cards give three fronts | the front among other cards' fronts | | `ClozeType` | there is a `cloze` | typing the blank(s) | | `ClozeChoice` | there is a `cloze` and options for its blank | the blank among `distractors` (or, when the blank is the back word itself, other cards' backs) | The deck's `disabled-modes` switches a mode off for every card; the learner can switch modes off for themselves too. **Whose wrong options.** `distractors` are wrong options for **what the case asks**. Without a `cloze` — for the back. With a `cloze` whose blank is the back word itself (`back: apple` / `cloze: I eat an {{apple}} every day.`) — for both. With a `cloze` that blanks only **part** of the back (`back: Does she live in Poland?` / `cloze: {{Does}} she live in Poland?`) — for the blank only: `Do | Did | Is`; the whole-sentence options then come from the deck. So a sentence-sized case (a rule drilled by example sentences) gets `Flip` and the cloze modes but no typed side, and a word case gets `Flip`, `ReverseFlip`, `Match`, `Type`, `Choice` plus whatever its `cloze` adds. The reverse modes need no facts at all: the app takes them from the card and the deck. Give a fact only when you can fill it **well** — three plausible wrong options, a natural sentence with the blank at the decision point, every accepted typed form; a weak fact is worse than none, and without `distractors` the options still come from the deck. **Blanks and accepted forms (important).** The answer of a blank sits **inside the sentence**: ```cards front: Она живёт в Польше? back: Does she live in Poland? cloze: {{Does}} she live in Poland? distractors: Do | Did | Is ``` Two different meanings of "several answers" — do not mix them up: - **Synonyms / alternatives** — ANY of them counts as correct (`till` / `until`; `оба` / `обе`) → one group, separated by `|`, the **in-context form first**: `{{till|until}}`. The first one is what the card reveals as the correct answer. - **Sequence / separate blanks** — ALL parts are required, each in its own place (the three forms of an irregular verb; a discontinuous `from … till …`) → **one group per blank**: `cloze: The shop is open {{from}} 9 a.m. {{till|until}} 6 p.m.` - **Different senses of one word** (`fair` = «справедливый» and «ярмарка») are one card with a case per sense, each with its own front; the reversed prompt `fair` then accepts every sense by itself (E18). A group exists **only** for a blank — nothing that stays visible in the sentence is an answer, and nothing outside `{{ }}` is. `Our team {{develops|builds}} new features.` has one blank and one group. When a sentence has **several blanks**, its `distractors` serve all of them: never put one blank's answer among them (it is a right answer in the sentence), and never accept a mere letter-case variant in a group (`{{Polish|polish}}`) — letter case is not an answer, it is what the wrong options test. **Every equally valid form goes into the group — not just one "canonical" one.** Typing is graded character by character: a correct form you did not list is marked wrong and drops the card into relearning. So list everything you would accept yourself: - politeness and who is addressed: `{{успокойтесь|успокойся}}`; - gender and number when the prompt does not fix them: `{{оба|обе}}`, `{{рад|рада}}`; - aspect where both fit: `{{остыть|остывать}}`; - equally good translations: `{{till|until}}`; - a function word that may be dropped: `{{go for a walk|to go for a walk}}`. Letter case, `ё`/`е`, the flavour of a quote and trailing punctuation are not answers — the app levels those itself, so do not spell such spellings out. The same rule holds for the typed answer of the card itself: `back` holds **one** canonical form and `accept` lists the others (`back: Успокойтесь` / `accept: Успокойся`; `back: to go for a walk` / `accept: go for a walk`). The front needs no list: typing it in reverse accepts the front, the front without a bracketed gloss and the card's other senses. **When the correct answer is "no word belongs here"** — the zero article, the zero preposition — the blank is **empty** and `back` is empty too, consistently in every fact of the case. Never invent a stand-in token (`—`, `0`, `no article`): the app renders the empty answer with its own label, so the learner leaves the field empty in typed modes and picks a "no word" option in choice modes. ```cards front: article with most country names (France, Russia) back: distractors: a | an | the cloze: She lives in {{}} France. ``` Its sibling cases (`back: the` for *the UK*, `back: a` for *a doctor*) carry `""` among their `distractors` for the same reason: "no article" has to stay a live option everywhere, or the learner picks the right article by elimination. Answers and options must not contain the `|` character — it separates alternatives and list items. **Generation rules (Lexical):** - **L1.** Write every blank/answer in the form it takes **in the sentence** (drop the dictionary "to", conjugate for the subject, drop an article the sentence already provides) — per the grammar of the language in question. When the form the sentence takes is **no word at all** (zero article, zero preposition), write the empty blank `{{}}`, never a stand-in token. - **L2.** When the in-context form differs from the source word, include **both**, the in-context form first: `{{go for a walk|to go for a walk}}`. - **L3.** Synonyms/variants are **separate `|` items** — never joined with commas inside one item. - **L4.** A discontinuous expression gets **one blank per part**. - **L5.** Wrong options are plausible but **wrong**, the same kind of word as the answer, and never duplicate any accepted variant. - **L6.** The sentence is natural and grammatical. **`context` and `note` — two different hints; do not confuse them:** - **`context`** is shown **with the question, before answering**. Its only job is to resolve genuine ambiguity: set it when the front alone admits **more than one correct answer**, to pick the intended reading. A homonym front: `front: язык` → `context: орган` ⇒ the expected answer is `tongue`, not `language`. An article case: `front: Я вижу птицу.`, `back: I see a bird.` — *the bird* is an equally correct translation, so `context: какую-то, не конкретную` selects *a*. The litmus test: **would a different answer also be correct without the cue?** If not, leave `context` out — no cue is the default. - `context` clarifies what the front **means**, never how the answer is **formed**: it MUST NOT contain the answer or any part of it, and it MUST NOT hint at the rule being drilled. On an *a/an* card, `context: university starts with the consonant sound [j]` recites the very rule under test and turns recall into reading — that sentence belongs in `note`. A learner who does not know the rule must learn nothing from `context`. - `context` is shown only when the prompt is the `front` side; the reversed modes and `Match` do not display it. So `context` cannot resolve ambiguity on the **reverse** side: when one `back` answers several different fronts (a polysemous word), make them the cases of one card — see E18. Keep the cue in `context` only — **never bake it into `front` itself** (`front: высокий` / `context: о росте` — NOT `front: высокий (о росте)`): anything inside `front` becomes part of the term in the reversed modes, choice options, typed answers and term listings. `front` holds the clean term only. - **`note`** (`explanation` in deck JSON) is shown **after the answer** (a lightbulb button): a rule recap, breakdown or mnemonic; it MAY reference the answer and the rule. `context` sits **on the case** (each case of a rule card can carry its own cue); `note` and `title` belong to the **whole card**. Set them only when they genuinely help — empty values are the norm. When unsure, leave them out. **`title`**: set it only when it adds information not already conveyed by `front` and `context` — a grammatical tag ("Phrasal verb"), a topic category, a register note. Never copy `front` verbatim into `title`: that just duplicates what the learner sees. In the vast majority of cards there is no `title`. **Validity checklist:** - **E1.** Every case has a `front` (`back` may be empty — see E16). - **E2.** A `cloze` holds at least one `{{ }}` blank — exactly one group per blank. - **E3.** Every answer set — a `{{ }}` group, the `back` with its `accept` — is non-empty, the **in-context form first**. An item in it may be empty — that is the answer "no word belongs here" (E16). - **E4.** Synonyms are separate items — never `a, b` as one item. - **E5.** The in-context form is grammatical in its sentence (no "we often to go", no "is be keen on"). - **E6.** Wrong options are wrong and never coincide with any accepted variant — with several blanks in one sentence, with the answer of any of them. - **E7.** A fact is given only when it can be filled well: no filler `distractors`, no stilted `cloze`. A card meant only to be flipped carries neither — its other modes come from the deck. - **E8.** Answers and options contain no `|` character (it is a reserved separator). - **E9.** Typed answers — the `back` of a word card with its `accept`, every blank — are a word or a short phrase. A sentence-sized `back` is fine (the app does not ask to type it), but a decision inside it is tested with a `cloze` blank at that exact point. - **E10.** A rule/pattern card carries several cases (aim for 6+), each a different example sentence; one rule is never split into one card per sentence. - **E11.** `distractors` are minimal pairs of the tested decision (`do`/`does`/`did`) — wrong here, yet plausibly confusable; never random unrelated words. - **E12.** A distinction typing cannot see — letter case alone (`English` vs `english`) or `ё`/`е` alone (`всё` vs `все`) — is tested with `distractors` that differ by exactly that. The app then shows the case in choice modes only (typing folds case and `ё`, so it would accept the wrong form); never put such a variant into `accept`. - **E13.** Every case and every fact of a card tests the card's **one** decision. A *do/does* card never blanks the main verb in one of its cases — a different decision is a different card. - **E14.** Word cards keep `front`/`back` to the word itself (word ↔ meaning), never a whole sentence; the context sentences go into `cloze`. That keeps `Flip` clean and unlocks `Match`. And to **one** form, not a list: `upside down; inverted; wrong way up` reaches the learner as an enumeration in `Match` and in the choice options. Equally good wordings are `accept` items (E17); different senses are different cases with a `context` (E15). - **E15.** `context` is set only when the front admits more than one correct answer; it picks the intended reading and never hints at the answer or the rule being drilled (rule recaps live in `note`). - **E16.** When the correct answer is the absence of a word (zero article, zero preposition), it is written as **empty** — in `back` and in the blank (`{{}}`) alike, consistently across the case. Never a stand-in token (`—`, `0`, `no article`): the app supplies its own label. - **E17.** Every form you would accept is its own item: politeness (`успокойтесь`/`успокойся`), gender and number (`оба`/`обе`), equally good synonyms (`till`/`until`). Listing them inside one string (`оба, обе` as one `accept` item) does not work — the learner would have to type that list verbatim. Letter case, `ё`/`е` and edge punctuation need no listing. The converse holds too: an answer the learner owes in full (`red, green, blue`) and a single slashed term (`and/or`) are **one** item. - **E18.** One question, one set of right answers. Two cases of a card (or two cards of a deck) must not answer the same prompt differently — the learner would be guessing which one is being asked. Same `front`, different `back`: a distinct `context` per case settles it (E15). Same `back`, different `front` (a polysemous word): `context` cannot, the reversed modes never show it — make the senses the cases of **one** card, and the reversed prompt accepts every sense by itself. Two separate cards with one `back` lose their reversed modes. - **E19.** Never invent a picture or audio link: no `front-image`, `back-image`, `back-audio`, `front-audio`. Pictures are uploaded by the deck owner and pronunciation is attached by the server; a guessed url is a broken picture, and a broken picture is worse than none. **Example — every key in one small deck:** ```cards deck: English basics — sample description: A tiny sample deck showing every key. front-language: ru back-language: en --- front: яблоко back: apple distractors: banana | orange | grape cloze: I eat an {{apple}} every day. --- front: язык back: tongue context: орган --- title: Phrasal verb front: идти на прогулку back: to go for a walk accept: go for a walk cloze: After dinner we often {{go for a walk|to go for a walk}} in the park. --- note: till и until взаимозаменяемы; from задаёт начало интервала. front: с … до … back: from … till … cloze: The shop is open {{from}} 9 a.m. {{till|until}} 6 p.m. distractors: at | on | in --- note: be – was/were – been. front: быть (3 формы) back: be – was/were – been cloze: {{be}}, {{was|were}}, {{been}} case: front: он устал (Present Simple, to be) back: he is tired ```