Check for clozes when saving notetype
Error if: - Cloze notetype lacks a cloze field on either template side. - Non-cloze notetype has a cloze field on any template.
This commit is contained in:
parent
6fae0ea21f
commit
3dfa1de68b
@ -22,6 +22,8 @@ card-templates-add-mobile-class = Add Mobile Class
|
||||
card-templates-preview-settings = Options
|
||||
card-templates-invalid-template-number = Card template { $number } in notetype '{ $notetype }' has a problem.
|
||||
card-templates-identical-front = Its front side is identical with the one of card template { $number }.
|
||||
card-templates-missing-cloze = The 'cloze' filter must be used on both sides of a cloze template.
|
||||
card-templates-extraneous-cloze = The 'cloze' filter can only be used on cloze templates.
|
||||
card-templates-see-preview = See the render preview for more information.
|
||||
card-templates-changes-saved = Changes saved.
|
||||
card-templates-discard-changes = Discard changes?
|
||||
|
@ -67,6 +67,10 @@ impl AnkiError {
|
||||
let details = match err.details {
|
||||
TemplateSaveErrorDetails::TemplateError => tr.card_templates_see_preview(),
|
||||
TemplateSaveErrorDetails::Duplicate(i) => tr.card_templates_identical_front(i),
|
||||
TemplateSaveErrorDetails::MissingCloze => tr.card_templates_missing_cloze(),
|
||||
TemplateSaveErrorDetails::ExtraneousCloze => {
|
||||
tr.card_templates_extraneous_cloze()
|
||||
}
|
||||
};
|
||||
format!("{}<br>{}", header, details)
|
||||
}
|
||||
@ -146,6 +150,8 @@ pub struct TemplateSaveError {
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum TemplateSaveErrorDetails {
|
||||
Duplicate(usize),
|
||||
TemplateError,
|
||||
Duplicate(usize),
|
||||
MissingCloze,
|
||||
ExtraneousCloze,
|
||||
}
|
||||
|
@ -287,6 +287,28 @@ impl Notetype {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn ensure_cloze_if_and_only_if_cloze_notetype(
|
||||
&self,
|
||||
parsed_templates: &[(Option<ParsedTemplate>, Option<ParsedTemplate>)],
|
||||
) -> Result<()> {
|
||||
if self.is_cloze() {
|
||||
if missing_cloze_filter(parsed_templates) {
|
||||
return Err(AnkiError::TemplateSaveError(TemplateSaveError {
|
||||
notetype: self.name.clone(),
|
||||
ordinal: 0,
|
||||
details: TemplateSaveErrorDetails::MissingCloze,
|
||||
}));
|
||||
}
|
||||
} else if let Some(i) = find_cloze_filter(parsed_templates) {
|
||||
return Err(AnkiError::TemplateSaveError(TemplateSaveError {
|
||||
notetype: self.name.clone(),
|
||||
ordinal: i,
|
||||
details: TemplateSaveErrorDetails::ExtraneousCloze,
|
||||
}));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn normalize_names(&mut self) {
|
||||
ensure_string_in_nfc(&mut self.name);
|
||||
for f in &mut self.fields {
|
||||
@ -349,6 +371,7 @@ impl Notetype {
|
||||
details: TemplateSaveErrorDetails::TemplateError,
|
||||
}));
|
||||
}
|
||||
self.ensure_cloze_if_and_only_if_cloze_notetype(&parsed_templates)?;
|
||||
let reqs = self.updated_requirements(&parsed_templates);
|
||||
|
||||
// handle renamed+deleted fields
|
||||
@ -448,6 +471,35 @@ impl Notetype {
|
||||
}
|
||||
}
|
||||
|
||||
/// True if the slice is empty or either template of the first tuple doesn't have a cloze field.
|
||||
fn missing_cloze_filter(
|
||||
parsed_templates: &[(Option<ParsedTemplate>, Option<ParsedTemplate>)],
|
||||
) -> bool {
|
||||
parsed_templates
|
||||
.get(0)
|
||||
.map_or(true, |t| !has_cloze(&t.0) || !has_cloze(&t.1))
|
||||
}
|
||||
|
||||
/// Return the index of the first tuple with a cloze field on either template.
|
||||
fn find_cloze_filter(
|
||||
parsed_templates: &[(Option<ParsedTemplate>, Option<ParsedTemplate>)],
|
||||
) -> Option<usize> {
|
||||
parsed_templates.iter().enumerate().find_map(|(i, t)| {
|
||||
if has_cloze(&t.0) || has_cloze(&t.1) {
|
||||
Some(i)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// True if the template is non-empty and has a cloze field.
|
||||
fn has_cloze(template: &Option<ParsedTemplate>) -> bool {
|
||||
template
|
||||
.as_ref()
|
||||
.map_or(false, |t| !t.cloze_fields().is_empty())
|
||||
}
|
||||
|
||||
impl From<Notetype> for NotetypeProto {
|
||||
fn from(nt: Notetype) -> Self {
|
||||
NotetypeProto {
|
||||
|
Loading…
Reference in New Issue
Block a user