> Human-readable guide: https://repeatme.co/guides/card-authoring # RepeatMe card format v2 — 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 the older deck JSON, which they still accept. 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, accepted forms, wrong options, a sentence with a blank — and never its modes: those are assembled from the facts and the deck's mode menu (see the facets table below). ```cards deck: English basics description: Core vocabulary, first 100 words. front-language: ru back-language: en modes: Flip | ReverseFlip | Match | Type | Choice | ClozeType | ClozeChoice --- front: яблоко back: apple wrong: 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. cloze-wrong: 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** — `wrong`, `accept`, `front-wrong`, `front-accept`, `cloze-wrong`, `tags`, `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:** | 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 | `modes` | the deck's **mode menu**: every mode a card may get. A card gets those of them its facts and the size rules allow | — | | 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 typed forms of the back the learner may enter (`accept: go for a walk`) | `Type` → `answers` | | case | `front-accept` | other typed forms of the front | `ReverseType` → `answers` | | case | `wrong` | three wrong options in the back language | `Choice` → `distractors` | | case | `front-wrong` | three wrong options in the front language | `ReverseChoice` → `distractors` | | case | `cloze` | one sentence with the answer inside `{{ }}` — see the blanks rules | `sentence` + `answers` | | case | `cloze-wrong` | three wrong options for the blank | `ClozeChoice` → `distractors` | 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). Where a rule below speaks in the JSON names, read it through the last column: a "slot" is a `{{a|b}}` group in `cloze`, or the `back` together with its `accept` list; "distractors" are `wrong`, `front-wrong` and `cloze-wrong`; "sentence" is `cloze`; `explanation` is `note`; a mode's "data" is these facts. **How facts become modes.** A card never lists its modes. From the deck's `modes` menu each case gets: | Fact on the case | Mode it enables | Only when | |---|---|---| | — | `Flip`, `ReverseFlip` | in the menu; `ReverseFlip` needs a non-empty back | | — | `Match` | in the menu and both sides are word-sized | | `back` (+ `accept`) | `Type` | in the menu and the back is a word or a short phrase — never a whole sentence | | `front` (+ `front-accept`) | `ReverseType` | in the menu and the front is a word or a short phrase | | `wrong` | `Choice` | in the menu | | `front-wrong` | `ReverseChoice` | in the menu | | `cloze` | `ClozeType` | in the menu | | `cloze` + `cloze-wrong` | `ClozeChoice` | in the menu | | `cloze` + `wrong`, no `cloze-wrong` | `Choice` **and** `ClozeChoice` share the `wrong` list | the blank's answer is the back itself | So a sentence-sized card (a grammar rule drilled by example sentences) naturally gets the cloze modes and `Flip` but no typed side, and a word card gets `Flip` / `ReverseFlip` / `Match` / `Type` plus whatever its facts add. To keep a mode off one card, leave its fact out: no `wrong:` — no `Choice`. Give a fact only when you can fill it **well** — three plausible wrong options, a natural sentence with the blank at the decision point; a weak fact is worse than none. **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? cloze-wrong: 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 «ярмарка») behave like synonyms, but only on the side where the question does not tell them apart: each sense is its own case with its own front, and the reverse side accepts every sense (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. **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}}`; - senses of a polysemous word the prompt does not tell apart; - 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`). For the front side it is `front-accept`. **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: wrong: a | an | the cloze: She lives in {{}} France. ``` Its sibling cases (`back: the` for *the UK*, `back: a` for *a doctor*) carry `""` among their `wrong` options 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 string, never a stand-in token. - **L2.** When the in-context form differs from the source word, include **both**, the in-context form first. - **L3.** Synonyms/variants are **separate slot elements** — never joined with commas inside one element. - **L4.** A discontinuous expression gets **one blank/slot per part**. - **L5.** Distractors 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 `explanation` — 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: `"язык"` → 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, `context` MUST stay null — null 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 `explanation`. A learner who does not know the rule must learn nothing from `context`. - `context` is shown only when the prompt is the `front` side (direct modes: `Flip`, `Type`, `Choice`, `ClozeType`, `ClozeChoice`); reverse 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), the senses are listed in the `answers` of the reverse modes — 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 reverse modes, choice options, typed answers and term listings. `front` holds the clean term only. - **`explanation`** 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); `explanation` and `title` belong to the **whole card**. Set them only when they genuinely help — empty values are the norm. When unsure, omit them. **`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 `title` is null. **Validity checklist:** - **E1.** Every case has a `front` and at least one mode (`back` may be empty — see E16). - **E2.** The number of `{{answer}}` blanks in `sentence` equals the number of slots in `answers`. - **E3.** Every slot is a non-empty **array** of strings, the **in-context form first**. A string in it may be empty — that is the answer "no word belongs here" (E16). - **E4.** Synonyms are separate slot elements — never `"a, b"` as one string. - **E5.** The in-context form is grammatical in its sentence (no "we often to go", no "is be keen on"). - **E6.** Distractors are wrong and never coincide with any accepted variant. - **E7.** Self-assessment cards (only `Flip`/`ReverseFlip`) carry no distractors/sentences in `data`. - **E8.** Answer texts contain no `|` character (it is a reserved separator). - **E9.** Typed answers (`Type`/`ReverseType`, cloze slots) are a word or short phrase — never a whole sentence. To test a decision inside a sentence, use `ClozeType`/`ClozeChoice` with the 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.** `Choice`/`ClozeChoice` distractors are minimal pairs of the tested decision (`do`/`does`/`did`) — wrong here, yet plausibly confusable; never random unrelated words. - **E12.** A distinction typed grading cannot see — letter case alone (`English` vs `english`) or `ё`/`е` alone (`всё` vs `все`) — is tested with `Choice`/`ClozeChoice`, never with `Type`/`ClozeType`: typed answers are graded case-insensitively and with `ё` folded to `е`, so the wrong form would be accepted. - **E13.** Every case and every mode of a card tests the card's **one** decision. A *do/does* card never blanks the main verb in one of its modes — 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 `data`. 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 `ReverseChoice` options, and in typed modes it would have to be typed out in full, semicolons and all. Equally good wordings are variants of the slot (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 `explanation`). - **E16.** When the correct answer is the absence of a word (zero article, zero preposition), it is written as the **empty string** — in `back` and in the answer slot alike, consistently across every mode of the case. Never a stand-in token (`—`, `0`, `no article`): the app supplies its own label. - **E17.** Every form the author would accept is its own variant of the slot: politeness (`успокойтесь`/`успокойся`), gender and number (`оба`/`обе`), equally good synonyms (`till`/`until`). Listing them inside one string (`"оба, обе"`) does not work — the learner would have to type that list verbatim, comma and all. 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** variant and must not be split. - **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. On the forward side (same `front`, different `back`) a distinct `context` per case settles it (E15). On the reverse side (same `back`, different `front` — a polysemous word) `context` cannot: reverse modes never render it. There the `ReverseType` of each such case lists **all** senses in its slot (its own first), and `ReverseChoice` never takes a sibling sense as a distractor. When neither is done, leave those cases with direct modes only. - **E19.** Never invent a picture link. `frontImage`/`backImage` take either a `/media/card/…` url the site itself issued on upload, or an `https` url the user handed you — nothing else. 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 modes: Flip | ReverseFlip | Match | Type | ReverseType | Choice | ReverseChoice | ClozeType | ClozeChoice --- front: яблоко back: apple wrong: banana | orange | grape cloze: I eat an {{apple}} every day. --- front: язык back: tongue context: орган front-wrong: зуб | нос | ухо --- 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. cloze-wrong: 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 front-accept: он устал ```