diff --git a/Source/_Tests/LibationFileManager.Tests/TemplatesTests.cs b/Source/_Tests/LibationFileManager.Tests/TemplatesTests.cs index 680c36d1..75fdcb6f 100644 --- a/Source/_Tests/LibationFileManager.Tests/TemplatesTests.cs +++ b/Source/_Tests/LibationFileManager.Tests/TemplatesTests.cs @@ -782,6 +782,32 @@ namespace TemplatesTests .Should().Be(expected); } + [TestMethod] + // a book can be in a series but have no series number. nested inside + // is the way to keep the number's punctuation out of the name in that case. + [DataRow("|. <-has><-if series>", "1", "Series A|1. A Study in Scarlet")] + [DataRow("<if series-><first series>|<has series#-><series#>. <-has><-if series><title short>", "", "Series A|A Study in Scarlet")] + [DataRow("<if series-><first series>|<has series#-><series#>. <-has><-if series><title short>", null, "A Study in Scarlet")] + // without the conditional, a missing number leaves its trailing punctuation behind + [DataRow("<if series-><first series>|<series#>. <-if series><title short>", "", "Series A|. A Study in Scarlet")] + // and a missing number between two spaces leaves a double space, which is then collapsed + [DataRow("<if series-><first series><has series#-> <series#><-has> - <-if series><title short>", "1", "Series A 1 - A Study in Scarlet")] + [DataRow("<if series-><first series><has series#-> <series#><-has> - <-if series><title short>", "", "Series A - A Study in Scarlet")] + [DataRow("<if series-><first series[{N}{ {#}}]> - <-if series><title short>", "1", "Series A 1 - A Study in Scarlet")] + [DataRow("<if series-><first series[{N}{ {#}}]> - <-if series><title short>", "", "Series A - A Study in Scarlet")] + public void HasSeriesNumber_nested_in_IfSeries(string template, string? seriesOrder, string expected) + { + var bookDto = GetLibraryBook(seriesOrder is null ? null : [new SeriesDto("Series A", seriesOrder, "B1")]); + + Templates.TryGetTemplate<Templates.FileTemplate>(template, out var fileTemplate).Should().BeTrue(); + fileTemplate.Errors.Should().HaveCount(0); + fileTemplate.Warnings.Should().HaveCount(0); + fileTemplate + .GetFilename(bookDto, "", "", culture: CultureInfo.InvariantCulture, replacements: 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)] diff --git a/docs/features/naming-templates.md b/docs/features/naming-templates.md index 9120674c..ff6c605f 100644 --- a/docs/features/naming-templates.md +++ b/docs/features/naming-templates.md @@ -102,7 +102,11 @@ As an example, this folder template will place all Liberated podcasts into a "Po This example will add a number if the `<series#>` tag has a value: -`<has series#><series#><-has>` +`<has series#-><series#><-has>` + +Conditionals may be nested. This folder template puts every book under its series, and prefixes the book folder with the series number only for the books that have one, so that books without a number don't end up in a folder starting with `.`: + +`<if series-><first series>/<has series#-><series#>. <-has><-if series><title short>` This example will put non-series books in a "Standalones" folder: