mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 14:02:21 -04:00
don't hide static template text when card is empty
This commit is contained in:
parent
826cbb0108
commit
12b8fe6147
4 changed files with 38 additions and 17 deletions
|
@ -178,10 +178,8 @@ class Card:
|
|||
total = int((time.time() - self.timerStarted) * 1000)
|
||||
return min(total, self.timeLimit())
|
||||
|
||||
def isEmpty(self) -> Optional[bool]:
|
||||
ords = self.col.models.availOrds(self.model(), joinFields(self.note().fields))
|
||||
if self.ord not in ords:
|
||||
return True
|
||||
# legacy
|
||||
def isEmpty(self) -> bool:
|
||||
return False
|
||||
|
||||
def __repr__(self) -> str:
|
||||
|
|
|
@ -520,7 +520,7 @@ class ModelManager:
|
|||
# Required field/text cache
|
||||
##########################################################################
|
||||
|
||||
# fixme: clayout, importing, cards.isEmpty
|
||||
# fixme: clayout, importing
|
||||
def availOrds(self, m: NoteType, flds: str) -> List:
|
||||
"Given a joined field string, return available template ordinals."
|
||||
if m["type"] == MODEL_CLOZE:
|
||||
|
|
|
@ -180,14 +180,7 @@ class Reviewer:
|
|||
self.typedAnswer: str = None
|
||||
c = self.card
|
||||
# grab the question and play audio
|
||||
if c.isEmpty():
|
||||
q = _(
|
||||
"""\
|
||||
The front of this card is empty. Please run Tools>Empty Cards."""
|
||||
)
|
||||
else:
|
||||
q = c.q()
|
||||
|
||||
q = c.q()
|
||||
# play audio?
|
||||
if c.autoplay():
|
||||
av_player.play_tags(c.question_av_tags())
|
||||
|
|
|
@ -532,19 +532,19 @@ pub fn render_card(
|
|||
};
|
||||
|
||||
// question side
|
||||
let (qnodes, qtmpl) = ParsedTemplate::from_text(qfmt)
|
||||
let (mut qnodes, qtmpl) = ParsedTemplate::from_text(qfmt)
|
||||
.and_then(|tmpl| Ok((tmpl.render(&context)?, tmpl)))
|
||||
.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) {
|
||||
let info = format!(
|
||||
"{}<br><a href='{}'>{}</a>",
|
||||
"<div>{}<br><a href='{}'>{}</a></div>",
|
||||
i18n.tr(TR::CardTemplateRenderingEmptyFront),
|
||||
TEMPLATE_BLANK_LINK,
|
||||
i18n.tr(TR::CardTemplateRenderingMoreInfo)
|
||||
);
|
||||
return Err(AnkiError::TemplateError { info });
|
||||
qnodes.push(RenderedNode::Text { text: info });
|
||||
};
|
||||
|
||||
// answer side
|
||||
|
@ -728,7 +728,11 @@ fn nodes_to_string(buf: &mut String, nodes: &[ParsedNode]) {
|
|||
mod test {
|
||||
use super::{FieldMap, ParsedNode::*, ParsedTemplate as PT};
|
||||
use crate::err::TemplateError;
|
||||
use crate::template::{field_is_empty, nonempty_fields, FieldRequirements, RenderContext};
|
||||
use crate::{
|
||||
i18n::I18n,
|
||||
log,
|
||||
template::{field_is_empty, nonempty_fields, FieldRequirements, RenderContext},
|
||||
};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::iter::FromIterator;
|
||||
|
||||
|
@ -1012,4 +1016,30 @@ mod test {
|
|||
}]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn render_card() {
|
||||
let map: HashMap<_, _> = vec![("E", "")]
|
||||
.into_iter()
|
||||
.map(|r| (r.0, r.1.into()))
|
||||
.collect();
|
||||
|
||||
let i18n = I18n::new(&[""], "", log::terminal());
|
||||
use crate::template::RenderedNode as FN;
|
||||
|
||||
let qnodes = super::render_card("test{{E}}", "", &map, 1, &i18n)
|
||||
.unwrap()
|
||||
.0;
|
||||
assert_eq!(
|
||||
qnodes[0],
|
||||
FN::Text {
|
||||
text: "test".into()
|
||||
}
|
||||
);
|
||||
if let FN::Text { ref text } = qnodes[1] {
|
||||
assert!(text.contains("card is blank"));
|
||||
} else {
|
||||
assert!(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue