From ec9ab02e6953b43d1d14bb4e13b3814ce2dc91e2 Mon Sep 17 00:00:00 2001 From: James Elmore Date: Wed, 19 Jun 2024 18:31:44 -0400 Subject: [PATCH 1/8] Added methods to parse browser templates --- rslib/src/notetype/templates.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/rslib/src/notetype/templates.rs b/rslib/src/notetype/templates.rs index aba9afb7af4..26f6c3de2d0 100644 --- a/rslib/src/notetype/templates.rs +++ b/rslib/src/notetype/templates.rs @@ -24,6 +24,13 @@ impl CardTemplate { ParsedTemplate::from_text(&self.config.a_format).ok() } + pub(crate) fn parsed_question_format_for_browser(&self) -> Option { + ParsedTemplate::from_text(&self.config.q_format_browser).ok() + } + + pub(crate) fn parsed_answer_format_for_browser(&self) -> Option { + ParsedTemplate::from_text(&self.config.a_format_browser).ok() + } pub(crate) fn question_format_for_browser(&self) -> &str { if !self.config.q_format_browser.is_empty() { &self.config.q_format_browser From d84e850c5142a34a3d7edd68f1f28689521256ba Mon Sep 17 00:00:00 2001 From: James Elmore Date: Wed, 19 Jun 2024 18:33:05 -0400 Subject: [PATCH 2/8] Added method to get parsed browser templates --- rslib/src/notetype/mod.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/rslib/src/notetype/mod.rs b/rslib/src/notetype/mod.rs index 7afae3741ed..2f9033b2fbd 100644 --- a/rslib/src/notetype/mod.rs +++ b/rslib/src/notetype/mod.rs @@ -583,6 +583,17 @@ impl Notetype { .map(|t| (t.parsed_question(), t.parsed_answer())) .collect() } + fn parsed_browser_templates(&self) -> Vec<(Option, Option)> { + 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<()> { self.fields.iter_mut().try_for_each(NoteField::fix_name) From be01ea24277cf9eab8e97d9a8091701230a2e0ec Mon Sep 17 00:00:00 2001 From: James Elmore Date: Wed, 19 Jun 2024 18:37:00 -0400 Subject: [PATCH 3/8] Make field rename check browser templates for field updates --- rslib/src/notetype/mod.rs | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/rslib/src/notetype/mod.rs b/rslib/src/notetype/mod.rs index 2f9033b2fbd..d37147cb7fd 100644 --- a/rslib/src/notetype/mod.rs +++ b/rslib/src/notetype/mod.rs @@ -495,13 +495,18 @@ impl Notetype { self.reposition_sort_idx(); let mut parsed_templates = self.parsed_templates(); + let mut parsed_browser_templates = self.parsed_browser_templates(); let reqs = self.updated_requirements(&parsed_templates); // handle renamed+deleted fields if let Some(existing) = existing { let fields = self.renamed_and_removed_fields(existing); 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; @@ -556,9 +561,12 @@ impl Notetype { &mut self, fields: HashMap>, parsed: &mut [(Option, Option)], + parsed_browser: &mut [(Option, Option)], ) { let first_remaining_field_name = &self.fields.first().unwrap().name; let is_cloze = self.is_cloze(); + + // Update main templates for (idx, (q_opt, a_opt)) in parsed.iter_mut().enumerate() { if let Some(q) = q_opt { q.rename_and_remove_fields(&fields); @@ -575,6 +583,26 @@ impl Notetype { self.templates[idx].config.a_format = a.template_to_string(); } } + + // Update browser templates, if they exist + for (idx, (q_browser_opt, a_browser_opt)) in parsed_browser.iter_mut().enumerate() { + if let Some(q_browser) = q_browser_opt { + q_browser.rename_and_remove_fields(&fields); + if !q_browser.contains_field_replacement() + || is_cloze && !q_browser.contains_cloze_replacement() + { + q_browser.add_missing_field_replacement(first_remaining_field_name, is_cloze); + } + self.templates[idx].config.q_format_browser = q_browser.template_to_string(); + } + if let Some(a_browser) = a_browser_opt { + a_browser.rename_and_remove_fields(&fields); + if is_cloze && !a_browser.contains_cloze_replacement() { + a_browser.add_missing_field_replacement(first_remaining_field_name, is_cloze); + } + self.templates[idx].config.a_format_browser = a_browser.template_to_string(); + } + } } fn parsed_templates(&self) -> Vec<(Option, Option)> { From fdd260ec5ebd6be9ba877dafd12806785ed6423b Mon Sep 17 00:00:00 2001 From: James Elmore Date: Wed, 19 Jun 2024 18:37:08 -0400 Subject: [PATCH 4/8] Update tests --- rslib/src/notetype/mod.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/rslib/src/notetype/mod.rs b/rslib/src/notetype/mod.rs index d37147cb7fd..2151447dc65 100644 --- a/rslib/src/notetype/mod.rs +++ b/rslib/src/notetype/mod.rs @@ -829,12 +829,13 @@ mod test { nt_norm.add_template("Card 1", "front {{foo}}", "back {{bar}}"); nt_norm.templates[0].ord = Some(0); let mut parsed = nt_norm.parsed_templates(); + let mut parsed_browser = nt_norm.parsed_browser_templates(); let mut field_map: HashMap> = HashMap::new(); field_map.insert("foo".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.a_format, "back "); @@ -854,7 +855,7 @@ mod test { field_map.insert("foo".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.a_format, "back {{cloze:baz}}"); @@ -876,7 +877,7 @@ mod test { let mut field_map: HashMap> = HashMap::new(); 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.a_format, "back {{cloze:foo}}"); } From e3a31077ba2cafed481bc1aa054b6a9a13b09224 Mon Sep 17 00:00:00 2001 From: James Elmore Date: Wed, 19 Jun 2024 18:42:03 -0400 Subject: [PATCH 5/8] Updated CONTRIBUTORS --- CONTRIBUTORS | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index ffc7bb7af16..d1db7eebc08 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -176,6 +176,7 @@ Wu Yi-Wei RRomeroJr <117.rromero@gmail.com> Xidorn Quan Alexander Bocken +James Elmore ******************** From d6d284aa70de3382c62a13554662218fed7e4120 Mon Sep 17 00:00:00 2001 From: James Elmore Date: Wed, 19 Jun 2024 18:45:57 -0400 Subject: [PATCH 6/8] Formatting --- rslib/src/notetype/mod.rs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/rslib/src/notetype/mod.rs b/rslib/src/notetype/mod.rs index 2151447dc65..df2090530de 100644 --- a/rslib/src/notetype/mod.rs +++ b/rslib/src/notetype/mod.rs @@ -835,7 +835,11 @@ mod test { field_map.insert("foo".to_owned(), None); field_map.insert("bar".to_owned(), None); - nt_norm.update_templates_for_renamed_and_removed_fields(field_map, &mut parsed, &mut parsed_browser); + 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.a_format, "back "); @@ -855,7 +859,11 @@ mod test { field_map.insert("foo".to_owned(), None); field_map.insert("bar".to_owned(), None); - nt_cloze.update_templates_for_renamed_and_removed_fields(field_map, &mut parsed, &mut parsed_browser); + 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.a_format, "back {{cloze:baz}}"); @@ -877,7 +885,11 @@ mod test { let mut field_map: HashMap> = HashMap::new(); field_map.insert("bar".to_owned(), None); - nt_cloze.update_templates_for_renamed_and_removed_fields(field_map, &mut parsed, &mut parsed_browser); + 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.a_format, "back {{cloze:foo}}"); } From e18ecfb818ee0cfa29cb47784f425cb0cba9bb8e Mon Sep 17 00:00:00 2001 From: James Elmore Date: Sun, 23 Jun 2024 23:35:18 -0400 Subject: [PATCH 7/8] Refactored cloze field logic for question template into closure --- rslib/src/notetype/mod.rs | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/rslib/src/notetype/mod.rs b/rslib/src/notetype/mod.rs index df2090530de..4ba55cf6c4d 100644 --- a/rslib/src/notetype/mod.rs +++ b/rslib/src/notetype/mod.rs @@ -566,15 +566,20 @@ impl Notetype { let first_remaining_field_name = &self.fields.first().unwrap().name; let is_cloze = self.is_cloze(); - // Update main templates - for (idx, (q_opt, a_opt)) in parsed.iter_mut().enumerate() { + let q_update_fields = |q_opt: &mut Option, template_target: &mut String| { if let Some(q) = q_opt { q.rename_and_remove_fields(&fields); if !q.contains_field_replacement() || is_cloze && !q.contains_cloze_replacement() { 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(); } + }; + + // 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); + if let Some(a) = a_opt { a.rename_and_remove_fields(&fields); if is_cloze && !a.contains_cloze_replacement() { @@ -586,15 +591,11 @@ impl Notetype { // Update browser templates, if they exist for (idx, (q_browser_opt, a_browser_opt)) in parsed_browser.iter_mut().enumerate() { - if let Some(q_browser) = q_browser_opt { - q_browser.rename_and_remove_fields(&fields); - if !q_browser.contains_field_replacement() - || is_cloze && !q_browser.contains_cloze_replacement() - { - q_browser.add_missing_field_replacement(first_remaining_field_name, is_cloze); - } - self.templates[idx].config.q_format_browser = q_browser.template_to_string(); - } + q_update_fields( + q_browser_opt, + &mut self.templates[idx].config.q_format_browser, + ); + if let Some(a_browser) = a_browser_opt { a_browser.rename_and_remove_fields(&fields); if is_cloze && !a_browser.contains_cloze_replacement() { From 400401232fbb377c1f8734656243f25bee154c5c Mon Sep 17 00:00:00 2001 From: James Elmore Date: Sun, 23 Jun 2024 23:50:21 -0400 Subject: [PATCH 8/8] Refactored cloze field logic for answer template into closure --- rslib/src/notetype/mod.rs | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/rslib/src/notetype/mod.rs b/rslib/src/notetype/mod.rs index 4ba55cf6c4d..52489e618f1 100644 --- a/rslib/src/notetype/mod.rs +++ b/rslib/src/notetype/mod.rs @@ -576,17 +576,21 @@ impl Notetype { } }; - // 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); - + let a_update_fields = |a_opt: &mut Option, template_target: &mut String| { if let Some(a) = a_opt { a.rename_and_remove_fields(&fields); if is_cloze && !a.contains_cloze_replacement() { 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 @@ -596,13 +600,10 @@ impl Notetype { &mut self.templates[idx].config.q_format_browser, ); - if let Some(a_browser) = a_browser_opt { - a_browser.rename_and_remove_fields(&fields); - if is_cloze && !a_browser.contains_cloze_replacement() { - a_browser.add_missing_field_replacement(first_remaining_field_name, is_cloze); - } - self.templates[idx].config.a_format_browser = a_browser.template_to_string(); - } + a_update_fields( + a_browser_opt, + &mut self.templates[idx].config.a_format_browser, + ); } }