From 1f4ada604ad34c9ff6c4e8b6f0eee940effd4d51 Mon Sep 17 00:00:00 2001 From: Mbucari Date: Fri, 10 Feb 2023 14:32:49 -0700 Subject: [PATCH] Make suggested changes --- Source/LibationFileManager/Templates.cs | 57 +++++++----- .../TemplatesTests.cs | 92 +++++++++++++++---- 2 files changed, 108 insertions(+), 41 deletions(-) diff --git a/Source/LibationFileManager/Templates.cs b/Source/LibationFileManager/Templates.cs index 4e4c34c2..198e74b5 100644 --- a/Source/LibationFileManager/Templates.cs +++ b/Source/LibationFileManager/Templates.cs @@ -72,6 +72,7 @@ namespace LibationFileManager (_, e) => _chapterTitle = GetTemplate((string)e.NewValue); HumanName.Suffixes.Add("ret"); + HumanName.Titles.Add("professor"); } #endregion @@ -202,9 +203,9 @@ namespace LibationFileManager { TemplateTags.Id, lb => lb.AudibleProductId, v => v }, { TemplateTags.Title, lb => lb.Title }, { TemplateTags.TitleShort, lb => getTitleShort(lb.Title) }, - { TemplateTags.Author, lb => lb.Authors, NameFormatter }, + { TemplateTags.Author, lb => lb.Authors, NameListFormatter }, { TemplateTags.FirstAuthor, lb => lb.FirstAuthor }, - { TemplateTags.Narrator, lb => lb.Narrators, NameFormatter }, + { TemplateTags.Narrator, lb => lb.Narrators, NameListFormatter }, { TemplateTags.FirstNarrator, lb => lb.FirstNarrator }, { TemplateTags.Series, lb => lb.SeriesName }, { TemplateTags.SeriesNumber, lb => lb.SeriesNumber }, @@ -249,17 +250,7 @@ namespace LibationFileManager #endregion - #region Tag Formatters - - private static readonly string[] suffixes = { "introductions", "introduction", "adaptation", "translator", "contributor", "illustrator", "director", "foreword", "editor", "preface", "adaptor", "afterword", "interviewer", "introductions", "essay", "editor/introduction" }; - - private static string removeSuffix(string namesString) - { - foreach (var suffix in suffixes) - namesString = namesString.Replace($" - {suffix}", ""); - - return namesString.Replace('’', '\'').Replace(" - Ret.", ", Ret.").Trim(); - } + #region Tag Formatters //Format must have at least one of the string {T}, {F}, {M}, {L}, or {S} private static readonly Regex FormatRegex = new(@"[Ff]ormat\((.*?(?:{[TFMLS]})+.*?)\)", RegexOptions.Compiled); @@ -270,20 +261,12 @@ namespace LibationFileManager //Separator can be anything private static readonly Regex SeparatorRegex = new(@"[Ss]eparator\((.*?)\)", RegexOptions.Compiled); - private static string NameFormatter(ITemplateTag templateTag, IEnumerable value, string formatString) + private static string NameListFormatter(ITemplateTag templateTag, IEnumerable value, string formatString) { var names = value.Select(n => new HumanName(removeSuffix(n), Prefer.FirstOverPrefix)); var formatMatch = FormatRegex.Match(formatString); - string nameFormatString - = formatMatch.Success - ? formatMatch.Groups[1].Value - .Replace("{T}", "{0}") - .Replace("{F}", "{1}") - .Replace("{M}", "{2}") - .Replace("{L}", "{3}") - .Replace("{S}", "{4}") - : "{0} {1} {2} {3} {4}"; // T F M L S + string nameFormatString = formatMatch.Success ? formatMatch.Groups[1].Value : "{T} {F} {M} {L} {S}"; var maxMatch = MaxRegex.Match(formatString); int maxNames = maxMatch.Success && int.TryParse(maxMatch.Groups[1].Value, out var max) ? int.Max(1, max) : int.MaxValue; @@ -306,13 +289,37 @@ namespace LibationFileManager separatorString, sortedNames .Take(int.Min(sortedNames.Count(), maxNames)) - .Select(n => string.Format(nameFormatString, n.Title, n.First, n.Middle, n.Last, n.Suffix).Trim()) - ); + .Select(n => formatName(n, nameFormatString))); while (formattedNames.Contains(" ")) formattedNames = formattedNames.Replace(" ", " "); return formattedNames; + + static string removeSuffix(string namesString) + { + namesString = namesString.Replace('’', '\'').Replace(" - Ret.", ", Ret."); + + int dashIndex = namesString.IndexOf(" - "); + + return (dashIndex > 0 ? namesString[..dashIndex] : namesString).Trim(); + } + + static string formatName(HumanName humanName, string nameFormatString) + { + //Single-word names parse as first names. Use it as last name. + var lastName = string.IsNullOrWhiteSpace(humanName.Last) ? humanName.First : humanName.Last; + + nameFormatString + = nameFormatString + .Replace("{T}", "{0}") + .Replace("{F}", "{1}") + .Replace("{M}", "{2}") + .Replace("{L}", "{3}") + .Replace("{S}", "{4}"); + + return string.Format(nameFormatString, humanName.Title, humanName.First, humanName.Middle, lastName, humanName.Suffix).Trim(); + } } private static string getTitleShort(string title) diff --git a/Source/_Tests/LibationFileManager.Tests/TemplatesTests.cs b/Source/_Tests/LibationFileManager.Tests/TemplatesTests.cs index f3ffa23e..691db140 100644 --- a/Source/_Tests/LibationFileManager.Tests/TemplatesTests.cs +++ b/Source/_Tests/LibationFileManager.Tests/TemplatesTests.cs @@ -239,28 +239,88 @@ namespace TemplatesTests } [TestMethod] - [DataRow("", "Arthur Conan Doyle, Stephen Fry")] - [DataRow("", "Arthur Conan Doyle, Stephen Fry")] - [DataRow("", "Arthur Conan Doyle, Stephen Fry")] - [DataRow("", "Arthur Conan Doyle, Stephen Fry")] - [DataRow("", "Stephen Fry, Arthur Conan Doyle")] - [DataRow("", "Arthur Conan Doyle, Stephen Fry")] - [DataRow("", "Arthur Conan Doyle")] - [DataRow("", "Arthur Conan Doyle, Stephen Fry")] - [DataRow("", "Arthur Conan Doyle, Stephen Fry")] - [DataRow("", "Doyle, Arthur, Fry, Stephen")] - [DataRow("", "Arthur Conan Doyle, Stephen Fry")] - [DataRow("", "First=Arthur, Last=Doyle, First=Stephen, Last=Fry")] - [DataRow("", "Doyle, Arthur - Fry, Stephen")] - public void NameFormat(string template, string expected) + [DataRow("Bruce Bueno de Mesquita", "Title=, First=Bruce, Middle=Bueno Last=de Mesquita, Suffix=")] + [DataRow("Ramon de Ocampo", "Title=, First=Ramon, Middle= Last=de Ocampo, Suffix=")] + [DataRow("Ramon De Ocampo", "Title=, First=Ramon, Middle= Last=De Ocampo, Suffix=")] + [DataRow("Jennifer Van Dyck", "Title=, First=Jennifer, Middle= Last=Van Dyck, Suffix=")] + [DataRow("Carla Naumburg PhD", "Title=, First=Carla, Middle= Last=Naumburg, Suffix=PhD")] + [DataRow("Doug Stanhope and Friends", "Title=, First=Doug, Middle= Last=Stanhope and Friends, Suffix=")] + [DataRow("Tamara Lovatt-Smith", "Title=, First=Tamara, Middle= Last=Lovatt-Smith, Suffix=")] + [DataRow("Common", "Title=, First=Common, Middle= Last=Common, Suffix=")] + [DataRow("Doug Tisdale Jr.", "Title=, First=Doug, Middle= Last=Tisdale, Suffix=Jr")] + [DataRow("Robert S. Mueller III", "Title=, First=Robert, Middle=S. Last=Mueller, Suffix=III")] + [DataRow("Frank T Vertosick Jr. MD", "Title=, First=Frank, Middle=T Last=Vertosick, Suffix=Jr. MD")] + [DataRow("The Arabian Nights", "Title=, First=The Arabian, Middle= Last=Nights, Suffix=")] + [DataRow("The Great Courses", "Title=, First=The Great, Middle= Last=Courses, Suffix=")] + [DataRow("The Laurie Berkner Band", "Title=, First=The Laurie, Middle=Berkner Last=Band, Suffix=")] + [DataRow("Committee on Foreign Affairs", "Title=, First=Committee, Middle=on Last=Foreign Affairs, Suffix=")] + [DataRow("House Permanent Select Committee on Intelligence", "Title=, First=House, Middle=Permanent Select Committee on Last=Intelligence, Suffix=")] + [DataRow("Professor David K. Johnson PhD University of Oklahoma", "Title=Professor, First=David, Middle=K. Johnson PhD Last=University of Oklahoma, Suffix=")] + [DataRow("Festival of the Spoken Nerd", "Title=, First=Festival of the Spoken, Middle= Last=Nerd, Suffix=")] + [DataRow("Audible Original", "Title=, First=Audible, Middle= Last=Original, Suffix=")] + [DataRow("Audible Originals", "Title=, First=Audible, Middle= Last=Originals, Suffix=")] + [DataRow("Patrick O'Brian", "Title=, First=Patrick, Middle= Last=O'Brian, Suffix=")] + [DataRow("Patrick O’Connell", "Title=, First=Patrick, Middle= Last=O'Connell, Suffix=")] + [DataRow("L.E. Modesitt", "Title=, First=L.E., Middle= Last=Modesitt, Suffix=")] + [DataRow("L. E. Modesitt Jr.", "Title=, First=L., Middle=E. Last=Modesitt, Suffix=Jr")] + [DataRow("LE Modesitt, Jr.", "Title=, First=LE, Middle= Last=Modesitt, Suffix=Jr")] + [DataRow("Marine Le Pen", "Title=, First=Marine, Middle= Last=Le Pen, Suffix=")] + [DataRow("L. Sprague de Camp", "Title=, First=L., Middle=Sprague Last=de Camp, Suffix=")] + [DataRow("Lt. Col. - Ret. Douglas L. Bland", "Title=, First=Ret., Middle=Douglas L. Bland Last=Lt. Col., Suffix=")] + [DataRow("Col. Lee Ellis - Ret. - foreword", "Title=Col., First=Lee, Middle= Last=Ellis, Suffix=Ret")] + public void NameFormat_unusual(string author, string expected) { - Templates.TryGetTemplate(template, out var fileTemplate).Should().BeTrue(); + var bookDto = GetLibraryBook(); + bookDto.Authors = new List { author }; + Templates.TryGetTemplate("", out var fileTemplate).Should().BeTrue(); fileTemplate - .GetFilename(GetLibraryBook(), "", "", Replacements) + .GetFilename(bookDto, "", "", Replacements) .PathWithoutPrefix .Should().Be(expected); } + [TestMethod] + [DataRow("", "Jill Conner Browne, Charles E. Gannon, Christopher John Fetherolf, Lucy Maud Montgomery, Jon Bon Jovi, Paul Van Doren")] + [DataRow("", "Jill Conner Browne, Charles E. Gannon, Christopher John Fetherolf, Lucy Maud Montgomery, Jon Bon Jovi, Paul Van Doren")] + [DataRow("", "Charles E. Gannon, Christopher John Fetherolf, Jill Conner Browne, Jon Bon Jovi, Lucy Maud Montgomery, Paul Van Doren")] + [DataRow("", "Jon Bon Jovi, Jill Conner Browne, Christopher John Fetherolf, Charles E. Gannon, Lucy Maud Montgomery, Paul Van Doren")] + [DataRow("", "Jon Bon Jovi, Paul Van Doren, Jill Conner Browne, Charles E. Gannon, Christopher John Fetherolf, Lucy Maud Montgomery")] + [DataRow("", "Jill Conner Browne, Charles E. Gannon, Christopher John Fetherolf, Lucy Maud Montgomery, Jon Bon Jovi, Paul Van Doren")] + [DataRow("", "Jill Conner Browne, Charles E. Gannon, Christopher John Fetherolf, Lucy Maud Montgomery, Jon Bon Jovi, Paul Van Doren")] + [DataRow("", "Jill Conner Browne, Charles E. Gannon, Christopher John Fetherolf, Lucy Maud Montgomery, Jon Bon Jovi, Paul Van Doren")] + [DataRow("", "Jill Conner Browne")] + [DataRow("", "Jill Conner Browne, Charles E. Gannon")] + [DataRow("", "Jill Conner Browne, Charles E. Gannon, Christopher John Fetherolf")] + [DataRow("", "Browne, Jill, Gannon, Charles, Fetherolf, Christopher, Montgomery, Lucy, Bon Jovi, Jon, Van Doren, Paul")] + [DataRow("", "Jill Conner Browne, Charles E. Gannon, Christopher John Fetherolf, Lucy Maud Montgomery, Jon Bon Jovi, Paul Van Doren")] + [DataRow("", "First=Jill, Last=Browne, First=Charles, Last=Gannon, First=Christopher, Last=Fetherolf, First=Lucy, Last=Montgomery, First=Jon, Last=Bon Jovi, First=Paul, Last=Van Doren")] + [DataRow("", "Browne, Jill - Gannon, Charles - Fetherolf, Christopher")] + [DataRow("", "Charles; Christopher")] + [DataRow("", "Bon Jovi; Browne")] + //Jon Bon Jovi and Paul Van Doren don't have middle names, so they are sorted to the top. + //Since only the middle names of the first 2 names are to be displayed, the name string is empty. + [DataRow("", ";")] + public void NameFormat_formatters(string template, string expected) + { + var bookDto = GetLibraryBook(); + bookDto.Authors = new List + { + "Jill Conner Browne", + "Charles E. Gannon", + "Christopher John Fetherolf", + "Lucy Maud Montgomery", + "Jon Bon Jovi", + "Paul Van Doren" + }; + + Templates.TryGetTemplate(template, out var fileTemplate).Should().BeTrue(); + fileTemplate + .GetFilename(bookDto, "", "", Replacements) + .PathWithoutPrefix + .Should().Be(expected); + } + + [TestMethod] [DataRow(@"C:\a\b", @"C:\a\b\foobar.ext", PlatformID.Win32NT)] [DataRow(@"/a/b", @"/a/b/foobar.ext", PlatformID.Unix)]