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
54 stars 12 forks source link

Can't style backs of cards freely — please add a class to display expression fields with their cloze markup hidden #27

Closed JoanEliot closed 2 years ago

JoanEliot commented 2 years ago

Please support putting expression fields as such, independently, on the backs of cards, so that they appear without their Cloze Anywhere markup, and showing color highlighting of the current cloze. (In other words, the way they do now when you display them using {{FrontSide}}.)

By CA markup I mean substrings such as ((c1::cloze text))

Although the Cloze Anything instructions don't explicitly say so, it seems that the only way to display the contents of an "expression field" on the back of a card, without the CA markup, is through use of the {{FrontSide}} "special field." But there are lots of situations where you might want stuff on the front of the card that you don't want on the back, or you otherwise want to change the layout and/or styling on the back. (Note also that per the manual, "FrontSide will not automatically play any audio that was on the front side of the card. If you wish to have the same audio play automatically on both the front and back of the card, you’ll need to manually include the audio fields on the back as well.")

One workaround is to maintain two separate fields for the expression, one with and one without the CA markup, and use the field without the markup on the back of the card. Two problems: you don't get color highlighting of the particular cloze you're drilling on, and there's the maintenance burden and risk of error involved in keeping the two fields in sync when you make corrections or do other updates.

The following post suggests a direction for getting rid of the markup, but the regex seems incorrect, at least for fields with more than one cloze (maybe this is better: /\({2}c\d::([^\0]+?)\){2}/g). It also doesn't color highlight the current close. https://www.ojisanseiuchi.com/2021/04/16/extending-the-anki-cloze-anything-script-for-language-learners/

JoanEliot commented 2 years ago

Here's a solution that works in my early tests, in the back template, based on the code shown in the post I linked in my first comment. Seems clunky to call RegExp twice and .replace three times, but this way I can sort of understand what's going on as I read through it. Perhaps something similar could be integrated into Cloze Anything.

<div class="expression">
{{ExpressionCloze}}
</div>

<script>
var cardtypenumber = "{{Card}}"
cardtypenumber = cardtypenumber.slice(cardtypenumber.length - 1)
$('.expression').each(function() {
   var expression_html = $(this).html();
   var regexobject = new RegExp("\\({2}c" + cardtypenumber + "::([^\0]+?)\\){2}", 'gi');
   expression_html = expression_html.replace(regexobject, "<span class=current-cloze>" + "$1" + "</span>");
    regexobject = new RegExp("\\({2}c\\d::([^\0]+?)\\){2}", 'gi');
   expression_html = expression_html.replace(regexobject, "$1");
   expression_html = expression_html.replace(new RegExp('`', 'g'),"");
   $(this).html(expression_html);   
});
</script>
matthayes commented 2 years ago

Although the Cloze Anything instructions don't explicitly say so, it seems that the only way to display the contents of an "expression field" on the back of a card, without the CA markup, is through use of the {{FrontSide}} "special field."

You don't have to use the {{FrontSide}} special field. You can copy the contents from the front side template to the backside template and customize how you like. You just need to ensure there is an element with a back id somewhere in the document. This is how the JS detects if it is the backside. For example:

<div id="back">
<!-- copy contents of front side here and customize -->
</div>

The only other element the JS looks for is one with id cloze. Whatever is inside that element will be processed as cloze content. Otherwise you should be pretty free to customize the template how you want.

and showing color highlighting of the current cloze.

The current cloze has a span around it with class current-cloze, so you can use CSS styling. Example here.

So considering the above, I'm not sure if you need to do any processing to remove the markup. Does this meet your needs?

JoanEliot commented 2 years ago

Thanks for your reply.

Guessing that the "back" id might be the trick I had tried wrapping content in a "back" div but that didn't work. I had also tried adding the script reference to the back template but that didn't help either. I somehow must not have tried both together. After those failures and without seeing any reference to independent placement of fields in your instructions, I then found the above-referenced link where he notes the same (non-) issue and sets about to correct it.

But now with both the "back" div and the CA script reference, I find that individual cloze fields do display properly on card backs.

So my revised request is for clarification in the instructions—an explicit statement that card backs can be laid out freely, without reference to the fronts, with cloze content fields placed and styled independently. Instructions on how to accomplish that and an example would be a good addition to the how-to page, I think.

I'm delighted to be able to stick with Cloze Anything for cloze functionality. With modification or when used on non-cloze anything card types, the above script will serve if I want to display a plain-text version of a cloze content field. Plus I learned a little JS and am now equipped in case I need to search and replace in a field for display, for other reasons.

[Noting that my draft solution doesn't support proper handling of hints, but that's now moot.]

matthayes commented 2 years ago

Good suggestion, I have updated the instructions in a series of commits:

https://github.com/matthayes/anki_cloze_anything/compare/916562aab9a41c9d8c1bc07b38149d99dd0c9c25..4227b4e077cc0525ee986e5a46439669d9e03291

JoanEliot commented 2 years ago

Thanks a lot!