allow adjusting tag case in rename

https://forums.ankiweb.net/t/2-1-46-renaming-tags-to-tags-not-working/12426
This commit is contained in:
Damien Elmes 2021-08-19 11:46:01 +10:00
parent d92913eb8c
commit d333d0da74
2 changed files with 21 additions and 14 deletions

View File

@ -73,11 +73,7 @@ impl Collection {
/// Create a tag object, normalize text, and match parents/existing case if available.
/// True if tag is new.
pub(super) fn prepare_tag_for_registering(&self, tag: &mut Tag) -> Result<bool> {
let normalized_name = normalize_tag_name(&tag.name);
if normalized_name.is_empty() {
// this should not be possible
return Err(AnkiError::invalid_input("blank tag"));
}
let normalized_name = normalize_tag_name(&tag.name)?;
if let Some(existing_tag) = self.storage.get_tag(&normalized_name)? {
tag.name = existing_tag.name;
Ok(false)
@ -99,7 +95,7 @@ impl Collection {
impl Collection {
/// If parent tag(s) exist and differ in case, return a rewritten tag.
fn adjusted_case_for_parents(&self, tag: &str) -> Result<Option<String>> {
pub(super) fn adjusted_case_for_parents(&self, tag: &str) -> Result<Option<String>> {
if let Some(parent_tag) = self.first_existing_parent_tag(tag)? {
let child_split: Vec<_> = tag.split("::").collect();
let parent_count = parent_tag.matches("::").count() + 1;
@ -144,8 +140,8 @@ fn normalized_tag_name_component(comp: &str) -> Cow<str> {
}
}
fn normalize_tag_name(name: &str) -> Cow<str> {
if name
pub(super) fn normalize_tag_name(name: &str) -> Result<Cow<str>> {
let normalized_name: Cow<str> = if name
.split("::")
.any(|comp| matches!(normalized_tag_name_component(comp), Cow::Owned(_)))
{
@ -157,6 +153,12 @@ fn normalize_tag_name(name: &str) -> Cow<str> {
} else {
// no changes required
name.into()
};
if normalized_name.is_empty() {
// this should not be possible
Err(AnkiError::invalid_input("blank tag"))
} else {
Ok(normalized_name)
}
}

View File

@ -1,8 +1,9 @@
// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
use super::{is_tag_separator, matcher::TagMatcher, Tag};
use super::{is_tag_separator, matcher::TagMatcher};
use crate::prelude::*;
use crate::tags::register::normalize_tag_name;
impl Collection {
/// Rename a given tag and its children on all notes that reference it, returning changed
@ -29,10 +30,14 @@ impl Collection {
let usn = self.usn()?;
// match existing case if available, and ensure normalized.
let mut tag = Tag::new(new_prefix.to_string(), usn);
self.prepare_tag_for_registering(&mut tag)?;
let new_prefix = &tag.name;
// ensure normalized+matching parent case, but not case of existing tag.
// The matching of parent case is mainly to be consistent with the way
// decks are handled.
let new_prefix = normalize_tag_name(new_prefix)?;
let new_prefix = self
.adjusted_case_for_parents(&new_prefix)?
.map(Into::into)
.unwrap_or(new_prefix);
// gather tags that need replacing
let mut re = TagMatcher::new(old_prefix)?;
@ -53,7 +58,7 @@ impl Collection {
// replace tags
for mut note in matched_notes {
let original = note.clone();
note.tags = re.replace(&note.tags, new_prefix);
note.tags = re.replace(&note.tags, &new_prefix);
note.set_modified(usn);
self.update_note_tags_undoable(&note, original)?;
}