This is a rewrite of anki-simple-cloze-overlapper in modern JS. For an overview of features, please take a look at a usage example in that repository.
In addition to anki-simple-cloze-overlapper
features, support was added for:
- Nested clozes.
- Clozes in MathJax.
- Cloze Generator.
The code was tested on Anki Desktop and AnkiDroid; the latter requires the latest Android System WebView to be installed. (Nested clozes don't work on AnkiDroid, see ankidroid/Anki-Android#13770.)
In principle, it should be usable on Anki Web and Anki Mobile (but it hasn't been tested).
Place the _cloze-overlapper.mjs into Anki's collection.media folder.
Create a new note type by cloning the built-in Cloze.
Add a rendering configuration field named
Before|After|OnlyContext|RevealAll|InactiveHints
.Put the content of front.template.anki into note's Front Template.
Put the content of back.template.anki into note's Back Template.
(Optional AnkiDroid compatibility) Add
.android .card:not(.mathjax-rendered) { visibility: hidden; }
to note's Styling to hide everything until
onUpdateHook
is executed. See AnkiDroid's Advanced formatting for details.
Template's field Before|After|OnlyContext|RevealAll|InactiveHints
controls the rendering
of clozes. Individual parameters are separated by either spaces, commas, pipes or dots.
Omitted rightmost parameters all take default values.
The parameters are as follows:
Before
(non-negative integer, defaults to 1)- The number of clozes before the currently active ones to uncover.
After
(non-negative integer, defaults to 0)- The number of clozes after the currently active ones to uncover.
OnlyContext
(Booleantrue
orfalse
, defaults tofalse
)- Show clozes only within the context (before + current + after).
Set to
true
for e.g. long lyrics/poems. RevelAll
(Booleantrue
orfalse
, defaults tofalse
)- Reveal all clozes on the back of the card. By default, only currently active clozes are revealed. (Context clozes are revealed even on cards' fronts.)
InactiveHints
(Booleantrue
orfalse
, defaults tofalse
)- Use user-provided hints (i.e.
{{c#::...::user provided hint}}
) for all clozes. By default, only the currently active clozes use provided hints, others use[...]
.
Context takes nesting of clozes into account: only clozes at the same level of nesting or above can be considered before of after the current one. In the following example:
{{c1::outer 1 {{c2::inner {{c3::deep 1}} {{c4::deep 2}} }} }} {{c5::outer 2}}
c1
,c2
andc3
have no clozes before,c5
has no clozes after,c3
is beforec4
, and similarly,c4
is afterc3
,c5
is afterc1
,c2
andc4
, but onlyc1
is beforec5
.
If you need an extra card that asks you for all the clozes at once, add another cloze
with ask-all
in its content, e.g. {{c99::ask-all}}
.
CSS .cloze
class doesn't apply inside MathJax. The styling of MathJax clozes is relegated
to TeX macros: \AnkiClozeQ
on the front of the card, and \AnkiClozeA
on the back
of the card.
By default, \AnkiClozeA
is identical to \AnkiClozeQ
. The style of \AnkiClozeQ
is taken
from the .cloze
class:
- If
cloze { color: ... }
is parsable as RGB,\AnkiClozeQ
will have\color[RGB]{RRR, GGG, BBB}
. - If
cloze { font-style: ... }
is either oblique or italic,\AnkiClozeQ
will have\mathit
. - If
cloze { font-weight: ... }
is bold or greater or equal to 700,\AnkiClozeQ
will have\boldsymbol
.
You can always uncomment the following block in both front.template.anki
and back.template.anki
, and redefine \AnkiClozeA
and \AnkiClozeA
as you see fit.
<!--
Uncomment and adjust if MathJax style autodetection doesn't work for you.
\[
\renewcommand\AnkiClozeQ[1]{\boldsymbol{\color{blue} #1}}
\renewcommand\AnkiClozeA[1]{\AnkiClozeQ{#1}}
\]
-->
If you make changes to _cloze-overlapper.mjs
, you'll have to restart Anki.
_cloze-overlapper.mjs
defines a custom element <cloze-generator>
and any attempt
to redefine it (e.g. by loading _cloze-overlapper.mjs?dev=1
) will throw an error.
JavaScript modules, such as _cloze-overlapper.mjs
, are loaded exactly once and never reloaded
(unless you restart Anki). However, you can use a dummy query parameter, such as ?dev=1
,
to reload the module without restarting Anki:
const ClozeOverlapper = await import(`${mediaRoot}/_cloze-overlapper.mjs?dev=1`);
dev
-counter must be incremented after every modification of _cloze-overlapper.mjs
.
When the development is complete, dev
query parameter can be removed and Anki restarted.