Add {series_sort} to the download template
It gives the series with a leading article at the end, as Calibre's default does for {series}.
This commit is contained in:
@@ -459,8 +459,9 @@ gives `The Saga - 02 - The Book - Ann Writer.epub`.
|
|||||||
|
|
||||||
In Calibre, `{title}` and `{series}` give the title sort in a file name, for example `Book, The`.
|
In Calibre, `{title}` and `{series}` give the title sort in a file name, for example `Book, The`.
|
||||||
In Bindery, they keep the article. This is the same as Calibre with the tweak
|
In Bindery, they keep the article. This is the same as Calibre with the tweak
|
||||||
`save_template_title_series_sorting` set to `strictly_alphabetic`. Use `{title_sort}` for the title
|
`save_template_title_series_sorting` set to `strictly_alphabetic`. Use `{title_sort}` and
|
||||||
with the article at the end.
|
`{series_sort}` for the title and the series with the article at the end. `{series_sort}` is a
|
||||||
|
Bindery field. Calibre does not have it, and gives empty text for it.
|
||||||
|
|
||||||
| Field | Value |
|
| Field | Value |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
@@ -469,6 +470,7 @@ with the article at the end.
|
|||||||
| `{authors}`, `{author}` | The authors, with ` & ` between them. |
|
| `{authors}`, `{author}` | The authors, with ` & ` between them. |
|
||||||
| `{author_sort}` | The authors with the last name first: `Writer, Ann`. |
|
| `{author_sort}` | The authors with the last name first: `Writer, Ann`. |
|
||||||
| `{series}` | The series. |
|
| `{series}` | The series. |
|
||||||
|
| `{series_sort}` | The series with a leading article at the end: `Saga, The`. |
|
||||||
| `{series_index}` | The series number: `2`, or `2.5`. |
|
| `{series_index}` | The series number: `2`, or `2.5`. |
|
||||||
| `{tags}` | The tags in sorted order, with `, ` between them. |
|
| `{tags}` | The tags in sorted order, with `, ` between them. |
|
||||||
| `{languages}` | The language, as Bindery stores it. |
|
| `{languages}` | The language, as Bindery stores it. |
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ the order of titles and series as an argument. Dates take a strftime format, wit
|
|||||||
default. Bindery takes {field}, {field[0]}, {field:format|prefix|suffix} and {{ }}. It refuses template
|
default. Bindery takes {field}, {field[0]}, {field:format|prefix|suffix} and {{ }}. It refuses template
|
||||||
functions and the program modes. It never runs template text as code.
|
functions and the program modes. It never runs template text as code.
|
||||||
|
|
||||||
|
{series_sort} is a Bindery field. It is to {series} what {title_sort} is to {title}. Calibre has no such field.
|
||||||
|
|
||||||
The tags sort close to Calibre's ICU rules, but their order can differ for characters outside ASCII.
|
The tags sort close to Calibre's ICU rules, but their order can differ for characters outside ASCII.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -34,6 +36,8 @@ FIELDS = {
|
|||||||
"author": "The authors",
|
"author": "The authors",
|
||||||
"author_sort": "The author sort string. To use only the first letter of the name, use {author_sort[0]}",
|
"author_sort": "The author sort string. To use only the first letter of the name, use {author_sort[0]}",
|
||||||
"series": "The series",
|
"series": "The series",
|
||||||
|
"series_sort": 'The series with a leading "The", "A" or "An" at the end, such as "Saga, The". '
|
||||||
|
"Calibre does not have this field",
|
||||||
"series_index": "The series number. To get leading zeros, use {series_index:0>3s}",
|
"series_index": "The series number. To get leading zeros, use {series_index:0>3s}",
|
||||||
"tags": "The tags",
|
"tags": "The tags",
|
||||||
"languages": "The language",
|
"languages": "The language",
|
||||||
@@ -207,7 +211,8 @@ def prepare(
|
|||||||
values["authors"] = values["author"] = " & ".join(a.replace("&", "&&") for a in authors)
|
values["authors"] = values["author"] = " & ".join(a.replace("&", "&&") for a in authors)
|
||||||
values["author_sort"] = " & ".join(author_sort(a) for a in authors)
|
values["author_sort"] = " & ".join(author_sort(a) for a in authors)
|
||||||
if series:
|
if series:
|
||||||
values["series"] = title_sort(series) if library else series.strip()
|
values["series_sort"] = title_sort(series)
|
||||||
|
values["series"] = values["series_sort"] if library else series.strip()
|
||||||
if meta.get("series_index") is not None:
|
if meta.get("series_index") is not None:
|
||||||
values["series_index"] = series_index(meta["series_index"])
|
values["series_index"] = series_index(meta["series_index"])
|
||||||
values["tags"] = ", ".join(sorted(meta.get("tags") or [], key=_tag_key)).removeprefix("/")
|
values["tags"] = ", ".join(sorted(meta.get("tags") or [], key=_tag_key)).removeprefix("/")
|
||||||
|
|||||||
@@ -208,7 +208,8 @@ export function settingsPage(main, _params, config) {
|
|||||||
h(
|
h(
|
||||||
'li',
|
'li',
|
||||||
{},
|
{},
|
||||||
'{title} and {series} keep a leading "The", "A" or "An". {title_sort} moves it to the end, so ' +
|
'{title} and {series} keep a leading "The", "A" or "An". {title_sort} and {series_sort} move it to the ' +
|
||||||
|
'end, so ' +
|
||||||
'"The Book" becomes "Book, The". Calibre puts the title sort in {title} as well, unless you set its ' +
|
'"The Book" becomes "Book, The". Calibre puts the title sort in {title} as well, unless you set its ' +
|
||||||
'tweak save_template_title_series_sorting to strictly_alphabetic.',
|
'tweak save_template_title_series_sorting to strictly_alphabetic.',
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -164,6 +164,8 @@ def test_download_template_names_the_file(client, story):
|
|||||||
# The default moves the article to the end, as Calibre's default does.
|
# The default moves the article to the end, as Calibre's default does.
|
||||||
client.put("/api/settings", json={"download_template": ""}, headers=H)
|
client.put("/api/settings", json={"download_template": ""}, headers=H)
|
||||||
assert 'filename="Book, The - Ann Writer.epub"' in download_name(client, sid)
|
assert 'filename="Book, The - Ann Writer.epub"' in download_name(client, sid)
|
||||||
|
client.put("/api/settings", json={"download_template": "{series_sort} - {title} - {id}"}, headers=H)
|
||||||
|
assert f'filename="Saga, The - The Book - {sid}.epub"' in download_name(client, sid)
|
||||||
# The ID is that of the CWA book, when the story has one.
|
# The ID is that of the CWA book, when the story has one.
|
||||||
o.store.update_story(sid, calibre_id=77, pinned={"title": "Caf\u00e9", "series": ["", None]})
|
o.store.update_story(sid, calibre_id=77, pinned={"title": "Caf\u00e9", "series": ["", None]})
|
||||||
client.put("/api/settings", json={"download_template": "{series:|| - }{title} - {id}"}, headers=H)
|
client.put("/api/settings", json={"download_template": "{series:|| - }{title} - {id}"}, headers=H)
|
||||||
|
|||||||
@@ -55,6 +55,11 @@ def test_reference_cases_for_a_missing_series_and_for_alphabetic_order():
|
|||||||
assert expand("{series}", "strictly_alphabetic") == "The Saga"
|
assert expand("{series}", "strictly_alphabetic") == "The Saga"
|
||||||
|
|
||||||
|
|
||||||
|
def test_series_sort_is_a_bindery_field():
|
||||||
|
assert expand("{series_sort}") == expand("{series_sort}", "strictly_alphabetic") == "Saga, The"
|
||||||
|
assert ft.expand("x{series_sort}x", ft.prepare(NO_SERIES, 42)) == "xx"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"template,expected",
|
"template,expected",
|
||||||
[
|
[
|
||||||
|
|||||||
Reference in New Issue
Block a user