# Ability to generate nested cloze

**URL:** <https://forums.ankiweb.net/t/ability-to-generate-nested-cloze/9743>\
**Category:** Suggestions\
**Created:** [May 4, 2021, 10:16am UTC](https://forums.ankiweb.net/t/ability-to-generate-nested-cloze/9743 "2021-05-04T10:16:08Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![AnkiQueen](https://avatars.discourse-cdn.com/v4/letter/a/f475e1/32.png) [@AnkiQueen](https://forums.ankiweb.net/u/AnkiQueen)\
**Post date:** [May 4, 2021, 10:16am UTC](https://forums.ankiweb.net/t/ability-to-generate-nested-cloze/9743/1 "2021-05-04T10:16:08Z")

</div>

It would be great if it was possible to create nested clozes. For example if I wanted to learn “The first three letters of the alphabet are abc”

I would create a nested cloze for {{c4:: {{c1::a}}{{c2::b}}{{c3::c}} }} . Which would generate four, three where only one letter is hidden, and one where all are hidden

---

<div class="post-metadata">

**Author:** ![TRIAEIOU](https://avatars.discourse-cdn.com/v4/letter/t/df788c/32.png) [@TRIAEIOU](https://forums.ankiweb.net/u/TRIAEIOU)\
**Post date:** [October 16, 2022, 7:52am UTC](https://forums.ankiweb.net/t/ability-to-generate-nested-cloze/9743/2 "2022-10-16T07:52:46Z")

</div>

I just wanted to bump this thread and also ask the devs if a PR to this end would be welcome? From glancing at the code it seems it would only require some changes in clozes.rs?

---

<div class="post-metadata">

**Author:** ![dae](https://sea2.discourse-cdn.com/flex002/user_avatar/forums.ankiweb.net/dae/32/65_2.png) [@dae](https://forums.ankiweb.net/u/dae)\
**Post date:** [October 17, 2022, 3:55am UTC](https://forums.ankiweb.net/t/ability-to-generate-nested-cloze/9743/3 "2022-10-17T03:55:01Z")

</div>

While this feels like a bit of a niche feature to me, if the PR is clean and does not introduce regressions, I can’t see a strong reason for rejecting it.

---

<div class="post-metadata">

**Author:** ![TRIAEIOU](https://avatars.discourse-cdn.com/v4/letter/t/df788c/32.png) [@TRIAEIOU](https://forums.ankiweb.net/u/TRIAEIOU)\
**Post date:** [October 19, 2022, 2:06pm UTC](https://forums.ankiweb.net/t/ability-to-generate-nested-cloze/9743/4 "2022-10-19T14:06:51Z")

</div>

Ok, I have started to sketch on one, will make a PR once I’ve had the time to finish it.

---

<div class="post-metadata">

**Author:** ![AnkiQueen](https://avatars.discourse-cdn.com/v4/letter/a/f475e1/32.png) [@AnkiQueen](https://forums.ankiweb.net/u/AnkiQueen)\
**Post date:** [October 19, 2022, 2:35pm UTC](https://forums.ankiweb.net/t/ability-to-generate-nested-cloze/9743/5 "2022-10-19T14:35:37Z")

</div>

@TRIAEIOU you are evil I wanted to contribute to anki ☹ /s

```javascript
let string1 =
   "The war was {{c3::{{c2::19::it was the last century}}{{c1::42}}}}";
let string2 = "The war was {{c2::{{c3::19}}{{c1::42}}}}";
let string3 = "The war was {{c1::{{c2::19}}{{c3::42}}}}";
let string4 =
   "The first world war begon {{c1::{{c2::19}}{{c3::36}}}} and ended {{c4::{{c5::19}}{{c6::42}}}}";
let string5 = "This is a {{c2::cloze}} not a {{c1::question}}";
let string6 = "This is a {{c1::cloze}} not a {{c2::question}}";

let is_nested_cloze = /{{c\d+::.*?}}}}/g;
let remove_cloze = /{{c\d+::|((::.*?)?}})/g;
let get_cloze_answer = /(?<={{c\d+::).*?((?=::)|(?=}}))/g;

function generate_cloze(string) {
   let nested_cloze = string.match(is_nested_cloze);
   if (nested_cloze) {
      for (let i = 0; i < nested_cloze.length; i++) {
         let clozes = nested_cloze[i].slice(6);
         clozes = clozes.match(get_cloze_answer);
         console.log({ clozes });
         clozes.forEach((answer) => {
            let get_cloze = new RegExp(`({{c\\d+::)${answer}.*?(}})`, "g");
            let match = string.match(get_cloze);
            let question = string.replaceAll(get_cloze, "[...]");
            question = question.replaceAll(remove_cloze, "");
            console.log({ question, answer, match, get_cloze });
         });
         let answer = clozes.reduce((result, element) => result + element, "");
         let question = string.replace(nested_cloze, "[...]");
         question = question.replaceAll(remove_cloze, "");
         console.log({ nested_cloze, answer, question });
      }
   }
}

generate_cloze(string1);
generate_cloze(string2);
generate_cloze(string3);
generate_cloze(string4);
generate_cloze(string5);
generate_cloze(string6);

```

> **[Overlapping and Nested Clozes](https://eshapard.github.io/anki/learning/code/python/overlapping-clozes.html)**
>
> Being able to use overlapping and nested cloze deletions is super useful in a flashcard application. It’s something that I felt was sorely missing from the flashcard applications that I’ve used. \[These are overlapping\] cloze deletions These are...

here is someone who has already done it if you insist on writing it

---

<div class="post-metadata">

**Author:** ![TRIAEIOU](https://avatars.discourse-cdn.com/v4/letter/t/df788c/32.png) [@TRIAEIOU](https://forums.ankiweb.net/u/TRIAEIOU)\
**Post date:** [October 19, 2022, 2:47pm UTC](https://forums.ankiweb.net/t/ability-to-generate-nested-cloze/9743/6 "2022-10-19T14:47:20Z")

</div>

Unless I am mistaken that is JavaScript, so for “client side” parsing of the note `{{Text}}`?

I was looking at doing it in the rust backend, through a simplistic state machine to parse the clozes in [cloze.rs](https://github.com/ankitects/anki/blob/main/rslib/src/cloze.rs).

Cheers

---

<div class="post-metadata">

**Author:** ![AnkiQueen](https://avatars.discourse-cdn.com/v4/letter/a/f475e1/32.png) [@AnkiQueen](https://forums.ankiweb.net/u/AnkiQueen)\
**Post date:** [October 19, 2022, 2:48pm UTC](https://forums.ankiweb.net/t/ability-to-generate-nested-cloze/9743/7 "2022-10-19T14:48:55Z")

</div>

I also planned of doing it in rust. But I used javascript to prototype the algorithm. Since programming with rust takes more time.

---

<div class="post-metadata">

**Author:** ![TRIAEIOU](https://avatars.discourse-cdn.com/v4/letter/t/df788c/32.png) [@TRIAEIOU](https://forums.ankiweb.net/u/TRIAEIOU)\
**Post date:** [October 19, 2022, 3:00pm UTC](https://forums.ankiweb.net/t/ability-to-generate-nested-cloze/9743/8 "2022-10-19T15:00:10Z")

</div>

If you want to do it you are more than welcome to run with the ball 🙂 I simply wanted the functionality! FWIW I am not sure regex is the way to go, as far as I understand the rust implementation lacks recursive patterns which I think would be needed to make it clean. Let me know if you decide to run with it - then I wont.

Cheers

---

<div class="post-metadata">

**Author:** ![AnkiQueen](https://avatars.discourse-cdn.com/v4/letter/a/f475e1/32.png) [@AnkiQueen](https://forums.ankiweb.net/u/AnkiQueen)\
**Post date:** [October 19, 2022, 3:12pm UTC](https://forums.ankiweb.net/t/ability-to-generate-nested-cloze/9743/9 "2022-10-19T15:12:06Z")

</div>

I am struggling a lot. It would be better if you implemented it.

---

<div class="post-metadata">

**Author:** ![relevartt](https://avatars.discourse-cdn.com/v4/letter/r/e79b87/32.png) [@relevartt](https://forums.ankiweb.net/u/relevartt)\
**Post date:** [October 20, 2022, 10:17pm UTC](https://forums.ankiweb.net/t/ability-to-generate-nested-cloze/9743/10 "2022-10-20T22:17:22Z")

</div>

Love this, I’ve been waiting for this for years 🙂

---

<div class="post-metadata">

**Author:** ![AnkiQueen](https://avatars.discourse-cdn.com/v4/letter/a/f475e1/32.png) [@AnkiQueen](https://forums.ankiweb.net/u/AnkiQueen)\
**Post date:** [December 12, 2022, 12:45pm UTC](https://forums.ankiweb.net/t/ability-to-generate-nested-cloze/9743/11 "2022-12-12T12:45:34Z")

</div>

I was able to do it in javascript without using recursive patterns. If you want you can convert it to rust, just mention me. [nested\_cloze\_deletion/index.js at main · Vilhelm-Ian/nested\_cloze\_deletion · GitHub](https://github.com/Vilhelm-Ian/nested_cloze_deletion/blob/main/index.js)

---

<div class="post-metadata">

**Author:** ![TRIAEIOU](https://avatars.discourse-cdn.com/v4/letter/t/df788c/32.png) [@TRIAEIOU](https://forums.ankiweb.net/u/TRIAEIOU)\
**Post date:** [December 12, 2022, 1:50pm UTC](https://forums.ankiweb.net/t/ability-to-generate-nested-cloze/9743/12 "2022-12-12T13:50:02Z")

</div>

Thanks but there’s already an accepted PR which will be included in 2.1.56 ([Nested clozes and increased cloze meta data by TRIAEIOU · Pull Request #2141 · ankitects/anki · GitHub](https://github.com/ankitects/anki/pull/2141)). To be clear, I may have started the PR but practically all of the code is Damien’s.

Cheers!

---

<div class="post-metadata">

**Author:** ![AnkiQueen](https://avatars.discourse-cdn.com/v4/letter/a/f475e1/32.png) [@AnkiQueen](https://forums.ankiweb.net/u/AnkiQueen)\
**Post date:** [December 12, 2022, 2:05pm UTC](https://forums.ankiweb.net/t/ability-to-generate-nested-cloze/9743/14 "2022-12-12T14:05:57Z")

</div>

thank you very much. I am excited for the feature. What do you think of my approach

---

<div class="post-metadata">

**Author:** ![TRIAEIOU](https://avatars.discourse-cdn.com/v4/letter/t/df788c/32.png) [@TRIAEIOU](https://forums.ankiweb.net/u/TRIAEIOU)\
**Post date:** [December 12, 2022, 7:21pm UTC](https://forums.ankiweb.net/t/ability-to-generate-nested-cloze/9743/15 "2022-12-12T19:21:54Z")

</div>

Looks good, it’s a similar approach to what’s in the PR. I don’t know how efficient slice and other substring functions are in JS so I don’t know if there are any performance gains to be made by reducing the amount of string copying.

---

<div class="post-metadata">

**Author:** ![relevartt](https://avatars.discourse-cdn.com/v4/letter/r/e79b87/32.png) [@relevartt](https://forums.ankiweb.net/u/relevartt)\
**Post date:** [January 27, 2023, 3:47pm UTC](https://forums.ankiweb.net/t/ability-to-generate-nested-cloze/9743/16 "2023-01-27T15:47:23Z")

</div>

Another interesting feature would be to be able to cloze a piece of text on multiple cards, f.e. like: {{c1,c2::this cloze}} would be hidden on card 1 and 2 and {{c2,c3::this}} on card 2 and 3.

Edit: although you can probably do that by nesting them, which is just a bit less handy.
