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
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?
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.
@TRIAEIOU you are evil I wanted to contribute to anki /s
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);
here is someone who has already done it if you insist on writing it
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.
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.
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.