Merge pull request #1705 from rmcrackan/rmcrackan/fix-template-esc

fix escaped html tags
This commit is contained in:
rmcrackan
2026-03-30 11:27:51 -04:00
committed by GitHub

View File

@@ -56,7 +56,7 @@ To change how these properties are displayed, [read about custom formatters](#ta
### Conditional Tags
Anything between the opening tag (`\<tagname-\>`) and closing tag (`\<-tagname\>`) will only appear in the name if the condition evaluates to true.
Anything between the opening tag (`<tagname->`) and closing tag (`<-tagname>`) will only appear in the name if the condition evaluates to true.
| Tag | Description | Type |
| ------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------- | ----------- |
@@ -72,7 +72,7 @@ Anything between the opening tag (`\<tagname-\>`) and closing tag (`\<-tagname\>
**†** Only affects the podcast series folder naming if "Save all podcast episodes to the series parent folder" option is checked.
For example, `\<if podcast-\>\<series\>\<-if podcast\>` will evaluate to the podcast's series name if the file is a podcast. For audiobooks that are not podcasts, that tag will be blank.
For example, `<if podcast-><series><-if podcast>` will evaluate to the podcast's series name if the file is a podcast. For audiobooks that are not podcasts, that tag will be blank.
You can invert the condition (instead of displaying the text when the condition is true, display the text when it is false) by playing a `!` symbol before the opening tag name.
@@ -89,19 +89,19 @@ You can invert the condition (instead of displaying the text when the condition
As an example, this folder template will place all Liberated podcasts into a "Podcasts" folder and all liberated books (not podcasts) into a "Books" folder.
`\<if podcast-\>Podcasts\<-if podcast\>\<!if podcast-\>Books\<-if podcast\>\<title\>`
`<if podcast->Podcasts<-if podcast><!if podcast->Books<-if podcast><title>`
This example will add a number if the `\<series#\>` tag has a value:
This example will add a number if the `<series#>` tag has a value:
`\<has series#\>\<series#\>\<-has\>`
`<has series#><series#><-has>`
This example will put non-series books in a "Standalones" folder:
`\<!if series-\>Standalones/\<-if series\>`
`<!if series->Standalones/<-if series>`
And this example will customize the title based on whether the book has a subtitle:
`\<audible title\>\<has audible subtitle-\>-\<audible subtitle\>\<-has\>`
`<audible title><has audible subtitle->-<audible subtitle><-has>`
## Tag Formatters
@@ -124,47 +124,47 @@ Text formatting can change length and case of the text. Use \<#\>, \<#\>\<case\>
| Formatter | Description | Example Usage | Example Result |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |--------------------------------------------- | ---------------------------------------------|
| separator() | Specify the text used to join<br>multiple entries.<br><br>Default is ", " | `\<tag[separator(_)]\>` | Tag1_Tag2_Tag3_Tag4_Tag5 |
| format(\{S\}) | Formats the entries by placing their values into the specified template.<br>Use {S:[Text_Formatter](#text-formatters)} to place the entry and optionally apply a format. | `\<tag[format(Tag={S:l})`<br>`separator(;)]\>` | Tag=tag1;Tag=tag2;Tag=tag3;Tag=tag4;Tag=tag5 |
| sort(S) | Sorts the elements by their value.<br><br>*Sorting direction:*<br>uppercase = ascending<br>lowercase = descending<br><br>Default is unsorted | `\<tag[sort(s)`<br>`separator(;)]\>` | Tag5;Tag4;Tag3;Tag2;Tag1 |
| max(#) | Only use the first # of entries | `\<tag[max(1)]\>` | Tag1 |
| slice(#) | Only use the nth entry of the list | `\<tag[slice(2)]\>` | Tag2 |
| slice(#..) | Only use entries of the list starting from # | `\<tag[slice(2..)]\>` | Tag2, Tag3, Tag4, Tag5 |
| slice(..#) | Like max(#). Only use the first # of entries | `\<tag[slice(..1)]\>` | Tag1 |
| slice(#..#) | Only use entries of the list starting from # and ending at # (inclusive) | `\<tag[slice(2..4)]\>` | Tag2, Tag3, Tag4 |
| slice(-#..-#) | Numbers may be specified negative. In that case positions ar counted from the end with -1 pointing at the last member | `\<tag[slice(-3..-2)]\>` | Tag3, Tag4 |
| separator() | Specify the text used to join<br>multiple entries.<br><br>Default is ", " | `<tag[separator(_)]>` | Tag1_Tag2_Tag3_Tag4_Tag5 |
| format(\{S\}) | Formats the entries by placing their values into the specified template.<br>Use {S:[Text_Formatter](#text-formatters)} to place the entry and optionally apply a format. | `<tag[format(Tag={S:l})`<br>`separator(;)]>` | Tag=tag1;Tag=tag2;Tag=tag3;Tag=tag4;Tag=tag5 |
| sort(S) | Sorts the elements by their value.<br><br>*Sorting direction:*<br>uppercase = ascending<br>lowercase = descending<br><br>Default is unsorted | `<tag[sort(s)`<br>`separator(;)]>` | Tag5;Tag4;Tag3;Tag2;Tag1 |
| max(#) | Only use the first # of entries | `<tag[max(1)]>` | Tag1 |
| slice(#) | Only use the nth entry of the list | `<tag[slice(2)]>` | Tag2 |
| slice(#..) | Only use entries of the list starting from # | `<tag[slice(2..)]>` | Tag2, Tag3, Tag4, Tag5 |
| slice(..#) | Like max(#). Only use the first # of entries | `<tag[slice(..1)]>` | Tag1 |
| slice(#..#) | Only use entries of the list starting from # and ending at # (inclusive) | `<tag[slice(2..4)]>` | Tag2, Tag3, Tag4 |
| slice(-#..-#) | Numbers may be specified negative. In that case positions ar counted from the end with -1 pointing at the last member | `<tag[slice(-3..-2)]>` | Tag3, Tag4 |
### Series Formatters
| Formatter | Description | Example Usage | Example Result |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| \{N \| # \| ID\} | Formats the series using<br>the series part tags.<br>\{N:[Text_Formatter](#text-formatters)\} = Series Name<br>\{#:[Number_Formatter](#number-formatters)\} = Number order in series<br>\{ID:[Text_Formatter](#text-formatters)\} = Audible Series ID<br><br>Formatter parts are optional and introduced by the colon. If specified the string will be used to format the part using the corresponding formatter.<br><br>Default is \{N\} | `\<first series\>`\<hr\>`\<first series[{N:l}]\>`\<hr\>`\<first series[{N}, {#}, {ID}]\>`\<hr\>`\<first series[{N:10U}, {ID}, {#:00.0}]\>` | Sherlock Holmes\<hr\>sherlock holmes\<hr\>Sherlock Holmes, 1-6, B08376S3R2\<hr\>SHERLOCK H, B08376S3R2, 01.0-06.0 |
| \{N \| # \| ID\} | Formats the series using<br>the series part tags.<br>\{N:[Text_Formatter](#text-formatters)\} = Series Name<br>\{#:[Number_Formatter](#number-formatters)\} = Number order in series<br>\{ID:[Text_Formatter](#text-formatters)\} = Audible Series ID<br><br>Formatter parts are optional and introduced by the colon. If specified the string will be used to format the part using the corresponding formatter.<br><br>Default is \{N\} | `<first series>`\<hr\>`<first series[{N:l}]>`\<hr\>`<first series[{N}, {#}, {ID}]>`\<hr\>`<first series[{N:10U}, {ID}, {#:00.0}]>` | Sherlock Holmes\<hr\>sherlock holmes\<hr\>Sherlock Holmes, 1-6, B08376S3R2\<hr\>SHERLOCK H, B08376S3R2, 01.0-06.0 |
### Series List Formatters
| Formatter | Description | Example Usage | Example Result |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| separator() | Specify the text used to join<br>multiple series names.<br><br>Default is ", " | `\<series[separator(; )]\>` | Sherlock Holmes; Some Other Series |
| format(\{N \| # \| ID\}) | Formats the series properties<br>using the name series tags.<br>See [Series Formatter Usage](#series-formatters) above. | `\<series[format({N}, {#})`<br>`separator(; )]\>`\<hr\>`\<series[format({ID}-{N}, {#:00.0})]\>` | Sherlock Holmes, 1-6; Book Collection, 1\<hr\>B08376S3R2-Sherlock Holmes, 01.0-06.0, B000000000-Book Collection, 01.0 |
| sort(N \| # \| ID) | Sorts the series by name, number or ID.<br><br>These terms define the primary, secondary, tertiary, … sorting order.<br>You may combine multiple terms in sequence to specify multilevel sorting.<br><br>*Sorting direction:*<br>uppercase = ascending<br>lowercase = descending<br><br>Default is unsorted | `\<series[sort(N)`<br>`separator(; )]\>` | Book Collection, 1; Sherlock Holmes, 1-6 |
| max(#) | Only use the first # of series | `\<series[max(1)]\>` | Sherlock Holmes |
| slice(#..#) | Only use entries of the series list starting from # and ending at # (inclusive)<br><br>See [Text List Formatter Usage](#Text-List-Formatters) above for details on all the variants of `slice()` | `\<series[slice(..-2)]\>` | Sherlock Holmes |
| separator() | Specify the text used to join<br>multiple series names.<br><br>Default is ", " | `<series[separator(; )]>` | Sherlock Holmes; Some Other Series |
| format(\{N \| # \| ID\}) | Formats the series properties<br>using the name series tags.<br>See [Series Formatter Usage](#series-formatters) above. | `<series[format({N}, {#})`<br>`separator(; )]>`\<hr\>`<series[format({ID}-{N}, {#:00.0})]>` | Sherlock Holmes, 1-6; Book Collection, 1\<hr\>B08376S3R2-Sherlock Holmes, 01.0-06.0, B000000000-Book Collection, 01.0 |
| sort(N \| # \| ID) | Sorts the series by name, number or ID.<br><br>These terms define the primary, secondary, tertiary, … sorting order.<br>You may combine multiple terms in sequence to specify multilevel sorting.<br><br>*Sorting direction:*<br>uppercase = ascending<br>lowercase = descending<br><br>Default is unsorted | `<series[sort(N)`<br>`separator(; )]>` | Book Collection, 1; Sherlock Holmes, 1-6 |
| max(#) | Only use the first # of series | `<series[max(1)]>` | Sherlock Holmes |
| slice(#..#) | Only use entries of the series list starting from # and ending at # (inclusive)<br><br>See [Text List Formatter Usage](#Text-List-Formatters) above for details on all the variants of `slice()` | `<series[slice(..-2)]>` | Sherlock Holmes |
### Name Formatters
| Formatter | Description | Example Usage | Example Result |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | --------------------------------------- |
| \{T \| F \| M \| L \| S \| ID\} | Formats the human name using<br>the name part tags.<br>\{T:[Text_Formatter](#text-formatters)\} = Title (e.g. "Dr.")<br>\{F:[Text_Formatter](#Text-Formatters)\} = First name<br>\{M:[Text_Formatter](#text-formatters)\} = Middle name<br>\{L:[Text_Formatter](#text-formatters)\} = Last Name<br>\{S:[Text_Formatter](#text-formatters)\} = Suffix (e.g. "PhD")<br>\{ID:[Text_Formatter](#text-formatters)\} = Audible Contributor ID<br><br>Formatter parts are optional and introduced by the colon. If specified the string will be used to format the part using the correspoing formatter.<br><br>Default is \{T\} \{F\} \{M\} \{L\} \{S\} | `\<first narrator[{L}, {F:1}.]\>`\<hr\>`\<first author[{L:u}, {F} _{ID}_]\>` | Fry, S.\<hr\>DOYLE, Arthur \_B000AQ43GQ\_ |
| \{T \| F \| M \| L \| S \| ID\} | Formats the human name using<br>the name part tags.<br>\{T:[Text_Formatter](#text-formatters)\} = Title (e.g. "Dr.")<br>\{F:[Text_Formatter](#Text-Formatters)\} = First name<br>\{M:[Text_Formatter](#text-formatters)\} = Middle name<br>\{L:[Text_Formatter](#text-formatters)\} = Last Name<br>\{S:[Text_Formatter](#text-formatters)\} = Suffix (e.g. "PhD")<br>\{ID:[Text_Formatter](#text-formatters)\} = Audible Contributor ID<br><br>Formatter parts are optional and introduced by the colon. If specified the string will be used to format the part using the correspoing formatter.<br><br>Default is \{T\} \{F\} \{M\} \{L\} \{S\} | `<first narrator[{L}, {F:1}.]>`\<hr\>`<first author[{L:u}, {F} _{ID}_]>` | Fry, S.\<hr\>DOYLE, Arthur \_B000AQ43GQ\_ |
### Name List Formatters
| Formatter | Description | Example Usage | Example Result |
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| separator() | Specify the text used to join<br>multiple people's names.<br><br>Default is ", " | `\<author[separator(; )]\>` | Arthur Conan Doyle; Stephen Fry |
| format(\{T \| F \| M \| L \| S \| ID\}) | Formats the human name using<br>the name part tags.<br>See [Name Formatter Usage](#name-formatters) above. | `\<author[format({L:u}, {F})`<br>`separator(; )]\>`\<hr\>`\<author[format({L}, {F:1}.`<br>`_{ID}_) separator(; )]\>` | DOYLE, Arthur; FRY, Stephen\<hr\>Doyle, A. \_B000AQ43GQ\_;<br>Fry, S. \_B000APAGVS\_ |
| sort(T \| F \| M \| L \| S \| ID) | Sorts the names by title,<br> first, middle, or last name,<br>suffix or Audible Contributor ID<br><br>These terms define the primary, secondary, tertiary, … sorting order.<br>You may combine multiple terms in sequence to specify multilevel sorting.<br><br>*Sorting direction:*<br>uppercase = ascending<br>lowercase = descending<br><br>Default is unsorted | `\<author[sort(M)]\>`\<hr\>`\<author[sort(Fl)]\>`\<hr\>\<author[sort(L FM ID)]\> | Stephen Fry, Arthur Conan Doyle\<hr\>Stephen King, Stephen Fry\<hr\>John P. Smith \_B000TTTBBB\_, John P. Smith \_B000TTTCCC\_, John S. Smith \_B000HHHVVV\_ |
| max(#) | Only use the first # of names<br><br>Default is all names | `\<author[max(1)]\>` | Arthur Conan Doyle |
| slice(#..#) | Only use entries of the names list starting from # and ending at # (inclusive)<br><br>See [Text List Formatter Usage](#Text-List-Formatters) above for details on all the variants of `slice()` | `\<author[slice(..-2)]\>` | Arthur Conan Doyle |
| separator() | Specify the text used to join<br>multiple people's names.<br><br>Default is ", " | `<author[separator(; )]>` | Arthur Conan Doyle; Stephen Fry |
| format(\{T \| F \| M \| L \| S \| ID\}) | Formats the human name using<br>the name part tags.<br>See [Name Formatter Usage](#name-formatters) above. | `<author[format({L:u}, {F})`<br>`separator(; )]>`\<hr\>`<author[format({L}, {F:1}.`<br>`_{ID}_) separator(; )]>` | DOYLE, Arthur; FRY, Stephen\<hr\>Doyle, A. \_B000AQ43GQ\_;<br>Fry, S. \_B000APAGVS\_ |
| sort(T \| F \| M \| L \| S \| ID) | Sorts the names by title,<br> first, middle, or last name,<br>suffix or Audible Contributor ID<br><br>These terms define the primary, secondary, tertiary, … sorting order.<br>You may combine multiple terms in sequence to specify multilevel sorting.<br><br>*Sorting direction:*<br>uppercase = ascending<br>lowercase = descending<br><br>Default is unsorted | `<author[sort(M)]>`\<hr\>`<author[sort(Fl)]>`\<hr\>`<author[sort(L FM ID)]>` | Stephen Fry, Arthur Conan Doyle\<hr\>Stephen King, Stephen Fry\<hr\>John P. Smith \_B000TTTBBB\_, John P. Smith \_B000TTTCCC\_, John S. Smith \_B000HHHVVV\_ |
| max(#) | Only use the first # of names<br><br>Default is all names | `<author[max(1)]>` | Arthur Conan Doyle |
| slice(#..#) | Only use entries of the names list starting from # and ending at # (inclusive)<br><br>See [Text List Formatter Usage](#Text-List-Formatters) above for details on all the variants of `slice()` | `<author[slice(..-2)]>` | Arthur Conan Doyle |
### TimeSpan Formatters
For more custom formatters and examples, [see this guide from Microsoft](https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-timespan-format-strings).
@@ -241,8 +241,8 @@ You can use custom formatters to construct customized DateTime string. For more
This example will truncate the title to 4 characters and check its (trimmed) value to be "the" in any case:
`\<is title[4][=the]\>`
`<is title[4][=the]>`
Here the second to fourth tag is taken and joined with a colon. The result is then checked to be equal to "Tag2:Tag3:Tag4":
`\<is tag[separator(:)slice(2..4)][=Tag2:Tag3:Tag4]-\>`
`<is tag[separator(:)slice(2..4)][=Tag2:Tag3:Tag4]->`