Fix Renaming note fields not updating custom browser appearance (#3245)
* Added methods to parse browser templates * Added method to get parsed browser templates * Make field rename check browser templates for field updates * Update tests * Updated CONTRIBUTORS * Formatting * Refactored cloze field logic for question template into closure * Refactored cloze field logic for answer template into closure
This commit is contained in:
parent
79917bbd2d
commit
930c97b1c7
@ -176,6 +176,7 @@ Wu Yi-Wei <https://github.com/Ianwu0812>
|
|||||||
RRomeroJr <117.rromero@gmail.com>
|
RRomeroJr <117.rromero@gmail.com>
|
||||||
Xidorn Quan <me@upsuper.org>
|
Xidorn Quan <me@upsuper.org>
|
||||||
Alexander Bocken <alexander@bocken.org>
|
Alexander Bocken <alexander@bocken.org>
|
||||||
|
James Elmore <email@jameselmore.org>
|
||||||
|
|
||||||
********************
|
********************
|
||||||
|
|
||||||
|
@ -495,13 +495,18 @@ impl Notetype {
|
|||||||
self.reposition_sort_idx();
|
self.reposition_sort_idx();
|
||||||
|
|
||||||
let mut parsed_templates = self.parsed_templates();
|
let mut parsed_templates = self.parsed_templates();
|
||||||
|
let mut parsed_browser_templates = self.parsed_browser_templates();
|
||||||
let reqs = self.updated_requirements(&parsed_templates);
|
let reqs = self.updated_requirements(&parsed_templates);
|
||||||
|
|
||||||
// handle renamed+deleted fields
|
// handle renamed+deleted fields
|
||||||
if let Some(existing) = existing {
|
if let Some(existing) = existing {
|
||||||
let fields = self.renamed_and_removed_fields(existing);
|
let fields = self.renamed_and_removed_fields(existing);
|
||||||
if !fields.is_empty() {
|
if !fields.is_empty() {
|
||||||
self.update_templates_for_renamed_and_removed_fields(fields, &mut parsed_templates);
|
self.update_templates_for_renamed_and_removed_fields(
|
||||||
|
fields,
|
||||||
|
&mut parsed_templates,
|
||||||
|
&mut parsed_browser_templates,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.config.reqs = reqs;
|
self.config.reqs = reqs;
|
||||||
@ -556,24 +561,49 @@ impl Notetype {
|
|||||||
&mut self,
|
&mut self,
|
||||||
fields: HashMap<String, Option<String>>,
|
fields: HashMap<String, Option<String>>,
|
||||||
parsed: &mut [(Option<ParsedTemplate>, Option<ParsedTemplate>)],
|
parsed: &mut [(Option<ParsedTemplate>, Option<ParsedTemplate>)],
|
||||||
|
parsed_browser: &mut [(Option<ParsedTemplate>, Option<ParsedTemplate>)],
|
||||||
) {
|
) {
|
||||||
let first_remaining_field_name = &self.fields.first().unwrap().name;
|
let first_remaining_field_name = &self.fields.first().unwrap().name;
|
||||||
let is_cloze = self.is_cloze();
|
let is_cloze = self.is_cloze();
|
||||||
for (idx, (q_opt, a_opt)) in parsed.iter_mut().enumerate() {
|
|
||||||
|
let q_update_fields = |q_opt: &mut Option<ParsedTemplate>, template_target: &mut String| {
|
||||||
if let Some(q) = q_opt {
|
if let Some(q) = q_opt {
|
||||||
q.rename_and_remove_fields(&fields);
|
q.rename_and_remove_fields(&fields);
|
||||||
if !q.contains_field_replacement() || is_cloze && !q.contains_cloze_replacement() {
|
if !q.contains_field_replacement() || is_cloze && !q.contains_cloze_replacement() {
|
||||||
q.add_missing_field_replacement(first_remaining_field_name, is_cloze);
|
q.add_missing_field_replacement(first_remaining_field_name, is_cloze);
|
||||||
}
|
}
|
||||||
self.templates[idx].config.q_format = q.template_to_string();
|
*template_target = q.template_to_string();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let a_update_fields = |a_opt: &mut Option<ParsedTemplate>, template_target: &mut String| {
|
||||||
if let Some(a) = a_opt {
|
if let Some(a) = a_opt {
|
||||||
a.rename_and_remove_fields(&fields);
|
a.rename_and_remove_fields(&fields);
|
||||||
if is_cloze && !a.contains_cloze_replacement() {
|
if is_cloze && !a.contains_cloze_replacement() {
|
||||||
a.add_missing_field_replacement(first_remaining_field_name, is_cloze);
|
a.add_missing_field_replacement(first_remaining_field_name, is_cloze);
|
||||||
}
|
}
|
||||||
self.templates[idx].config.a_format = a.template_to_string();
|
*template_target = a.template_to_string();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Update main templates
|
||||||
|
for (idx, (q_opt, a_opt)) in parsed.iter_mut().enumerate() {
|
||||||
|
q_update_fields(q_opt, &mut self.templates[idx].config.q_format);
|
||||||
|
|
||||||
|
a_update_fields(a_opt, &mut self.templates[idx].config.a_format);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update browser templates, if they exist
|
||||||
|
for (idx, (q_browser_opt, a_browser_opt)) in parsed_browser.iter_mut().enumerate() {
|
||||||
|
q_update_fields(
|
||||||
|
q_browser_opt,
|
||||||
|
&mut self.templates[idx].config.q_format_browser,
|
||||||
|
);
|
||||||
|
|
||||||
|
a_update_fields(
|
||||||
|
a_browser_opt,
|
||||||
|
&mut self.templates[idx].config.a_format_browser,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -583,6 +613,17 @@ impl Notetype {
|
|||||||
.map(|t| (t.parsed_question(), t.parsed_answer()))
|
.map(|t| (t.parsed_question(), t.parsed_answer()))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
fn parsed_browser_templates(&self) -> Vec<(Option<ParsedTemplate>, Option<ParsedTemplate>)> {
|
||||||
|
self.templates
|
||||||
|
.iter()
|
||||||
|
.map(|t| {
|
||||||
|
(
|
||||||
|
t.parsed_question_format_for_browser(),
|
||||||
|
t.parsed_answer_format_for_browser(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
fn fix_field_names(&mut self) -> Result<()> {
|
fn fix_field_names(&mut self) -> Result<()> {
|
||||||
self.fields.iter_mut().try_for_each(NoteField::fix_name)
|
self.fields.iter_mut().try_for_each(NoteField::fix_name)
|
||||||
@ -790,12 +831,17 @@ mod test {
|
|||||||
nt_norm.add_template("Card 1", "front {{foo}}", "back {{bar}}");
|
nt_norm.add_template("Card 1", "front {{foo}}", "back {{bar}}");
|
||||||
nt_norm.templates[0].ord = Some(0);
|
nt_norm.templates[0].ord = Some(0);
|
||||||
let mut parsed = nt_norm.parsed_templates();
|
let mut parsed = nt_norm.parsed_templates();
|
||||||
|
let mut parsed_browser = nt_norm.parsed_browser_templates();
|
||||||
|
|
||||||
let mut field_map: HashMap<String, Option<String>> = HashMap::new();
|
let mut field_map: HashMap<String, Option<String>> = HashMap::new();
|
||||||
field_map.insert("foo".to_owned(), None);
|
field_map.insert("foo".to_owned(), None);
|
||||||
field_map.insert("bar".to_owned(), None);
|
field_map.insert("bar".to_owned(), None);
|
||||||
|
|
||||||
nt_norm.update_templates_for_renamed_and_removed_fields(field_map, &mut parsed);
|
nt_norm.update_templates_for_renamed_and_removed_fields(
|
||||||
|
field_map,
|
||||||
|
&mut parsed,
|
||||||
|
&mut parsed_browser,
|
||||||
|
);
|
||||||
assert_eq!(nt_norm.templates[0].config.q_format, "front {{baz}}");
|
assert_eq!(nt_norm.templates[0].config.q_format, "front {{baz}}");
|
||||||
assert_eq!(nt_norm.templates[0].config.a_format, "back ");
|
assert_eq!(nt_norm.templates[0].config.a_format, "back ");
|
||||||
|
|
||||||
@ -815,7 +861,11 @@ mod test {
|
|||||||
field_map.insert("foo".to_owned(), None);
|
field_map.insert("foo".to_owned(), None);
|
||||||
field_map.insert("bar".to_owned(), None);
|
field_map.insert("bar".to_owned(), None);
|
||||||
|
|
||||||
nt_cloze.update_templates_for_renamed_and_removed_fields(field_map, &mut parsed);
|
nt_cloze.update_templates_for_renamed_and_removed_fields(
|
||||||
|
field_map,
|
||||||
|
&mut parsed,
|
||||||
|
&mut parsed_browser,
|
||||||
|
);
|
||||||
assert_eq!(nt_cloze.templates[0].config.q_format, "front {{cloze:baz}}");
|
assert_eq!(nt_cloze.templates[0].config.q_format, "front {{cloze:baz}}");
|
||||||
assert_eq!(nt_cloze.templates[0].config.a_format, "back {{cloze:baz}}");
|
assert_eq!(nt_cloze.templates[0].config.a_format, "back {{cloze:baz}}");
|
||||||
|
|
||||||
@ -837,7 +887,11 @@ mod test {
|
|||||||
let mut field_map: HashMap<String, Option<String>> = HashMap::new();
|
let mut field_map: HashMap<String, Option<String>> = HashMap::new();
|
||||||
field_map.insert("bar".to_owned(), None);
|
field_map.insert("bar".to_owned(), None);
|
||||||
|
|
||||||
nt_cloze.update_templates_for_renamed_and_removed_fields(field_map, &mut parsed);
|
nt_cloze.update_templates_for_renamed_and_removed_fields(
|
||||||
|
field_map,
|
||||||
|
&mut parsed,
|
||||||
|
&mut parsed_browser,
|
||||||
|
);
|
||||||
assert_eq!(nt_cloze.templates[0].config.q_format, "front {{cloze:foo}}");
|
assert_eq!(nt_cloze.templates[0].config.q_format, "front {{cloze:foo}}");
|
||||||
assert_eq!(nt_cloze.templates[0].config.a_format, "back {{cloze:foo}}");
|
assert_eq!(nt_cloze.templates[0].config.a_format, "back {{cloze:foo}}");
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,13 @@ impl CardTemplate {
|
|||||||
ParsedTemplate::from_text(&self.config.a_format).ok()
|
ParsedTemplate::from_text(&self.config.a_format).ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn parsed_question_format_for_browser(&self) -> Option<ParsedTemplate> {
|
||||||
|
ParsedTemplate::from_text(&self.config.q_format_browser).ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn parsed_answer_format_for_browser(&self) -> Option<ParsedTemplate> {
|
||||||
|
ParsedTemplate::from_text(&self.config.a_format_browser).ok()
|
||||||
|
}
|
||||||
pub(crate) fn question_format_for_browser(&self) -> &str {
|
pub(crate) fn question_format_for_browser(&self) -> &str {
|
||||||
if !self.config.q_format_browser.is_empty() {
|
if !self.config.q_format_browser.is_empty() {
|
||||||
&self.config.q_format_browser
|
&self.config.q_format_browser
|
||||||
|
Loading…
Reference in New Issue
Block a user