mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 14:02:21 -04:00
Modify card rendering output to specify if rendered card is empty (#3890)
* modify render_card to return whether card was empty * plumbing * add flag to proto message * plumbing: pass flag along to PartiallyRenderedCard * add tests * Use a custom return type for clarity (dae)
This commit is contained in:
parent
1798620d64
commit
ccab18b7ba
5 changed files with 39 additions and 14 deletions
|
@ -127,6 +127,7 @@ message RenderCardResponse {
|
|||
repeated RenderedTemplateNode answer_nodes = 2;
|
||||
string css = 3;
|
||||
bool latex_svg = 4;
|
||||
bool is_empty = 5;
|
||||
}
|
||||
|
||||
message RenderedTemplateNode {
|
||||
|
|
|
@ -60,6 +60,7 @@ class PartiallyRenderedCard:
|
|||
anodes: TemplateReplacementList
|
||||
css: str
|
||||
latex_svg: bool
|
||||
is_empty: bool
|
||||
|
||||
@classmethod
|
||||
def from_proto(
|
||||
|
@ -68,7 +69,9 @@ class PartiallyRenderedCard:
|
|||
qnodes = cls.nodes_from_proto(out.question_nodes)
|
||||
anodes = cls.nodes_from_proto(out.answer_nodes)
|
||||
|
||||
return PartiallyRenderedCard(qnodes, anodes, out.css, out.latex_svg)
|
||||
return PartiallyRenderedCard(
|
||||
qnodes, anodes, out.css, out.latex_svg, out.is_empty
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def nodes_from_proto(
|
||||
|
|
|
@ -219,6 +219,7 @@ impl From<RenderCardOutput> for anki_proto::card_rendering::RenderCardResponse {
|
|||
answer_nodes: rendered_nodes_to_proto(o.anodes),
|
||||
css: o.css,
|
||||
latex_svg: o.latex_svg,
|
||||
is_empty: o.is_empty,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ pub struct RenderCardOutput {
|
|||
pub anodes: Vec<RenderedNode>,
|
||||
pub css: String,
|
||||
pub latex_svg: bool,
|
||||
pub is_empty: bool,
|
||||
}
|
||||
|
||||
impl RenderCardOutput {
|
||||
|
@ -136,7 +137,7 @@ impl Collection {
|
|||
)
|
||||
};
|
||||
|
||||
let (qnodes, anodes) = render_card(RenderCardRequest {
|
||||
let response = render_card(RenderCardRequest {
|
||||
qfmt,
|
||||
afmt,
|
||||
field_map: &field_map,
|
||||
|
@ -147,10 +148,11 @@ impl Collection {
|
|||
partial_render,
|
||||
})?;
|
||||
Ok(RenderCardOutput {
|
||||
qnodes,
|
||||
anodes,
|
||||
qnodes: response.qnodes,
|
||||
anodes: response.anodes,
|
||||
css: nt.config.css.clone(),
|
||||
latex_svg: nt.config.latex_svg,
|
||||
is_empty: response.is_empty,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -592,6 +592,13 @@ pub struct RenderCardRequest<'a> {
|
|||
pub partial_render: bool,
|
||||
}
|
||||
|
||||
pub struct RenderCardResponse {
|
||||
pub qnodes: Vec<RenderedNode>,
|
||||
pub anodes: Vec<RenderedNode>,
|
||||
pub is_empty: bool,
|
||||
}
|
||||
|
||||
/// Returns `(qnodes, anodes, is_empty)`
|
||||
pub fn render_card(
|
||||
RenderCardRequest {
|
||||
qfmt,
|
||||
|
@ -603,7 +610,7 @@ pub fn render_card(
|
|||
tr,
|
||||
partial_render: partial_for_python,
|
||||
}: RenderCardRequest<'_>,
|
||||
) -> Result<(Vec<RenderedNode>, Vec<RenderedNode>)> {
|
||||
) -> Result<RenderCardResponse> {
|
||||
// prepare context
|
||||
let mut context = RenderContext {
|
||||
fields: field_map,
|
||||
|
@ -638,7 +645,11 @@ pub fn render_card(
|
|||
};
|
||||
if let Some(text) = empty_message {
|
||||
qnodes.push(RenderedNode::Text { text: text.clone() });
|
||||
return Ok((qnodes, vec![RenderedNode::Text { text }]));
|
||||
return Ok(RenderCardResponse {
|
||||
qnodes,
|
||||
anodes: vec![RenderedNode::Text { text }],
|
||||
is_empty: true,
|
||||
});
|
||||
}
|
||||
|
||||
// answer side
|
||||
|
@ -654,7 +665,11 @@ pub fn render_card(
|
|||
.and_then(|tmpl| tmpl.render(&context, tr))
|
||||
.map_err(|e| template_error_to_anki_error(e, false, browser, tr))?;
|
||||
|
||||
Ok((qnodes, anodes))
|
||||
Ok(RenderCardResponse {
|
||||
qnodes,
|
||||
anodes,
|
||||
is_empty: false,
|
||||
})
|
||||
}
|
||||
|
||||
fn cloze_is_empty(field_map: &HashMap<&str, Cow<str>>, card_ord: u16) -> bool {
|
||||
|
@ -1338,14 +1353,15 @@ mod test {
|
|||
tr: &tr,
|
||||
partial_render: true,
|
||||
};
|
||||
let qnodes = super::render_card(req.clone()).unwrap().0;
|
||||
let response = super::render_card(req.clone()).unwrap();
|
||||
assert_eq!(
|
||||
qnodes[0],
|
||||
response.qnodes[0],
|
||||
FN::Text {
|
||||
text: "test".into()
|
||||
}
|
||||
);
|
||||
if let FN::Text { ref text } = qnodes[1] {
|
||||
assert!(response.is_empty);
|
||||
if let FN::Text { ref text } = response.qnodes[1] {
|
||||
assert!(text.contains("card is blank"));
|
||||
} else {
|
||||
unreachable!();
|
||||
|
@ -1354,9 +1370,9 @@ mod test {
|
|||
// a popular card template expects {{FrontSide}} to resolve to an empty
|
||||
// string on the front side :-(
|
||||
req.qfmt = "{{FrontSide}}{{N}}";
|
||||
let qnodes = super::render_card(req.clone()).unwrap().0;
|
||||
let response = super::render_card(req.clone()).unwrap();
|
||||
assert_eq!(
|
||||
&qnodes,
|
||||
&response.qnodes,
|
||||
&[
|
||||
FN::Replacement {
|
||||
field_name: "FrontSide".into(),
|
||||
|
@ -1366,8 +1382,10 @@ mod test {
|
|||
FN::Text { text: "N".into() }
|
||||
]
|
||||
);
|
||||
assert!(!response.is_empty);
|
||||
req.partial_render = false;
|
||||
let qnodes = super::render_card(req.clone()).unwrap().0;
|
||||
assert_eq!(&qnodes, &[FN::Text { text: "N".into() }]);
|
||||
let response = super::render_card(req.clone()).unwrap();
|
||||
assert_eq!(&response.qnodes, &[FN::Text { text: "N".into() }]);
|
||||
assert!(!response.is_empty);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue