matthayes / anki_cloze_anything

Add cloze deletions to any existing Anki notes without any modification to Anki
https://ankiweb.net/shared/info/330680661
Apache License 2.0
52 stars 10 forks source link

Is it supposed to work this way? Unexpected (but welcome) experience with Cloze Anything. #20

Closed JoanEliot closed 2 years ago

JoanEliot commented 3 years ago

The instructions page says at the bottom that for each subsequent card type you create (ExpressionCloze2, ExpressionCloze3 etc), you must change the template for that card by swapping in the corresponding name for what I'm calling the "cloze activation" field:

Now repeat this for the remaining cloze fields. That is, if you have field ExpressionCloze2, then create a card template named ExpressionCloze2 with the same content as ExpressionCloze1 except with {{#ExpressionCloze1}} replaced with {{#ExpressionCloze2}} and {{//ExpressionCloze1}} replaced with {{//ExpressionCloze2}}. )

But in my tests today, each card type I added picked up the next cloze automatically, without my having to make that change. Which I thought was great. I found that you can use any of the cloze activation fields in the templates and you'll still get the "correct" cloze deletion/display, meaning the one corresponding to the number at the end of the card type name. In other words, it's the card type name that determines which cloze is 'activated' on a given card, not the cloze activation field name. That's a bit confusing, but convenient if you're as sloppy as I am.

I've since figured out that the reason you should go on to match up the field name in the template to the card type name is so you can turn off card production for any given cloze (by deleting all content from that cloze's activation field). If there is (arbitrary) content in the field, the cards for that cloze will be displayed; if there is no content, they won't be.

Do I have all that right?

One more question: Does it matter where you put the js reference in the card template? I'd rather put it up at the very top of the template, and when I moved it there nothing seemed to break—it didn't seem to need to be inside the conditional wrappers.

Finally, I'm hoping I won't need to keep a separate copy of the "expression" without clozes in its own field. I find that I can display the text of ExpressionCloze minus the cloze-related extra characters simply by leaving out the conditional wrappers. Your js strips out the double parens and the cloze markers (c1:: etc.). However, this only works, I think, when the ExpressionCloze field is on the front side of the card (it also has to be in a tag with id="cloze" and a 'data-card' attribute ="{{Card}}"). If you put ExpressionCloze on the back, you get all that cloze-related junk. I'm guessing it won't be too hard to modify the code to clean up the field when it's on the back. But if you have time, I'd appreciate a hint or two about how I might go about to make those changes.

matthayes commented 2 years ago

In other words, it's the card type name that determines which cloze is 'activated' on a given card, not the cloze activation field name. That's a bit confusing, but convenient if you're as sloppy as I am.

This is correct. The card type name determines which of the clozes, c1 through cn is the active cloze number. However the note's field determines whether the card gets generated, and if you don't wrap the content in the conditional like {{#ExpressionCloze1}} then you could render useless cards that have no clozes.

I've since figured out that the reason you should go on to match up the field name in the template to the card type name is so you can turn off card production for any given cloze (by deleting all content from that cloze's activation field). If there is (arbitrary) content in the field, the cards for that cloze will be displayed; if there is no content, they won't be.

Yep you've got it.

Does it matter where you put the js reference in the card template? I'd rather put it up at the very top of the template, and when I moved it there nothing seemed to break—it didn't seem to need to be inside the conditional wrappers.

If it isn't inside the conditional wrappers then it means each card will have content regardless of those conditions, and therefore each cloze card will be rendered. However the position within the conditionals shouldn't matter assuming you are using the latest version of the template that uses. It waits until the page is parsed before executing, so position shouldn't matter.

<script defer src="_cloze_anything_0.3.js"></script>

Finally, I'm hoping I won't need to keep a separate copy of the "expression" without clozes in its own field.

I think it depends on your use case. I find it convenient to have a non-cloze version of the field. That's usually my starting point and I add cloze cards later. One option is to add a cloze element with the data-card set to a really high cloze like ExpressionCloze100. Since no c100 exists it will just remove all the cloze markup.

<script defer type="text/javascript" src="cloze_anything.js"></script>
<div id="not-back">
<div id="cloze" data-card="ExpressionCloze100">
((c1::Ik)) ((c2::heb)) ((c3::honger)).
</div>
</div>

Alternatively you could copy the JS from the plugin that processes the cloze markup and modify it, something like:

    var newContent = expContent.replace(/\(\(c(\d+)::([\s\S]+?\)*)\)\)/g,function(match, clozeNum, content) {
      return content;
    }