check for empty cloze cards when rendering as well

This commit is contained in:
Damien Elmes 2020-05-14 21:56:45 +10:00
parent 782911471b
commit 24ffb6ab76
5 changed files with 39 additions and 9 deletions

View file

@ -169,9 +169,7 @@ class AddCards(QDialog):
showWarning(problem, help="AddItems#AddError")
return None
if note.model()["type"] == MODEL_CLOZE:
if not self.mw.col.models._availClozeOrds(
note.model(), note.joinedFields(), False
):
if not note.cloze_numbers_in_fields():
if not askUser(
_(
"You have a cloze deletion note type "

View file

@ -37,3 +37,6 @@ card-template-rendering-no-such-field =
# either due to a badly-designed template, or because required fields
# are missing.
card-template-rendering-empty-front = The front of this card is blank.
card-template-rendering-missing-cloze = No cloze { $number } found on card.
Please either add a cloze deletion, or use the Empty Cards tool.

View file

@ -312,6 +312,10 @@ impl NoteType {
})
.next()
}
pub(crate) fn is_cloze(&self) -> bool {
matches!(self.config.kind(), NoteTypeKind::Cloze)
}
}
impl From<NoteType> for NoteTypeProto {

View file

@ -109,7 +109,8 @@ impl Collection {
)
};
let (qnodes, anodes) = render_card(qfmt, afmt, &field_map, card.ord, &self.i18n)?;
let (qnodes, anodes) =
render_card(qfmt, afmt, &field_map, card.ord, nt.is_cloze(), &self.i18n)?;
Ok(RenderCardOutput { qnodes, anodes })
}

View file

@ -2,8 +2,8 @@
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
use crate::err::{AnkiError, Result, TemplateError};
use crate::i18n::{tr_strs, I18n, TR};
use crate::template_filters::apply_filters;
use crate::i18n::{tr_args, tr_strs, I18n, TR};
use crate::{cloze::add_cloze_numbers_in_string, template_filters::apply_filters};
use lazy_static::lazy_static;
use nom::branch::alt;
use nom::bytes::complete::{tag, take_until};
@ -23,6 +23,8 @@ static TEMPLATE_ERROR_LINK: &str =
"https://anki.tenderapp.com/kb/problems/card-template-has-a-problem";
static TEMPLATE_BLANK_LINK: &str =
"https://anki.tenderapp.com/kb/card-appearance/the-front-of-this-card-is-blank";
static TEMPLATE_BLANK_CLOZE_LINK: &str =
"https://anki.tenderapp.com/kb/problems/no-cloze-found-on-card";
// Lexing
//----------------------------------------
@ -521,6 +523,7 @@ pub fn render_card(
afmt: &str,
field_map: &HashMap<&str, Cow<str>>,
card_ord: u16,
is_cloze: bool,
i18n: &I18n,
) -> Result<(Vec<RenderedNode>, Vec<RenderedNode>)> {
// prepare context
@ -537,7 +540,20 @@ pub fn render_card(
.map_err(|e| template_error_to_anki_error(e, true, i18n))?;
// check if the front side was empty
if !qtmpl.renders_with_fields(context.nonempty_fields) {
if is_cloze {
if cloze_is_empty(field_map, card_ord) {
let info = format!(
"<div>{}<br><a href='{}'>{}</a></div>",
i18n.trn(
TR::CardTemplateRenderingMissingCloze,
tr_args!["number"=>card_ord+1]
),
TEMPLATE_BLANK_CLOZE_LINK,
i18n.tr(TR::CardTemplateRenderingMoreInfo)
);
qnodes.push(RenderedNode::Text { text: info });
}
} else if !qtmpl.renders_with_fields(context.nonempty_fields) {
let info = format!(
"<div>{}<br><a href='{}'>{}</a></div>",
i18n.tr(TR::CardTemplateRenderingEmptyFront),
@ -545,7 +561,7 @@ pub fn render_card(
i18n.tr(TR::CardTemplateRenderingMoreInfo)
);
qnodes.push(RenderedNode::Text { text: info });
};
}
// answer side
context.question_side = false;
@ -556,6 +572,14 @@ pub fn render_card(
Ok((qnodes, anodes))
}
fn cloze_is_empty(field_map: &HashMap<&str, Cow<str>>, card_ord: u16) -> bool {
let mut set = HashSet::with_capacity(4);
for field in field_map.values() {
add_cloze_numbers_in_string(field.as_ref(), &mut set);
}
!set.contains(&(card_ord + 1))
}
// Field requirements
//----------------------------------------
@ -1063,7 +1087,7 @@ mod test {
let i18n = I18n::new(&[""], "", log::terminal());
use crate::template::RenderedNode as FN;
let qnodes = super::render_card("test{{E}}", "", &map, 1, &i18n)
let qnodes = super::render_card("test{{E}}", "", &map, 1, false, &i18n)
.unwrap()
.0;
assert_eq!(