Format strings in gallery-dl follow the general rules of str.format() (PEP 3101) plus several extras.
The syntax for replacement fields is
{<field-name>!<conversion>:<format-specifiers>} where <field-name> selects a value
and the optional !<conversion> & :<format-specifiers> specify how to transform it.
Examples:
{title}{content!W}{date:Olocal/%Y%m%d %H%M}Field names select the metadata value to use in a replacement field.
While simple names are usually enough, more complex forms like accessing values by attribute, element index, or slicing are also supported.
| Example | Result | |
|---|---|---|
| Name | {title} | Hello World |
| Element Index | {title[6]} | W |
| Slicing | {title[3:8]} | lo Wo |
| Slicing (Bytes) | {title_ja[b3:18]} | ロー・ワー |
| Alternatives | {empty|title} | Hello World |
| Attribute Access | {extractor.url} | https://example.org/ |
| Element Access | {user[name]} | John Doe |
{user['name']} | John Doe |
All of these methods can be combined.
For example {title[24]|empty|extractor.url[15:-1]} would result in .org.
Conversion specifiers allow to convert the value to a different form or type. Such a specifier must only consist of 1 character. gallery-dl supports the default three (s, r, a) as well as several others:
| Conversion | Description | Example | Result |
|---|---|---|---|
l | Convert a string to lowercase | {foo!l} | foo bar |
u | Convert a string to uppercase | {foo!u} | FOO BAR |
c | Capitalize a string, i.e. convert the first character to uppercase and all others to lowercase | {foo!c} | Foo bar |
C | Capitalize each word in a string | {foo!C} | Foo Bar |
g | Slugify a value | {foo!g} | foo-bar |
j | Serialize value to a JSON formatted string | {tags!j} | ["sun", "tree", "water"] |
L | Convert an ISO 639-1 language code to its full name | {lang!L} | English |
n | Return the length of a value | {foo!n} | 7 |
W | Sanitize whitespace - Remove leading and trailing whitespace characters and replace all whitespace (sequences) with a single space character | {space!W} | Foo Bar |
t | Trim a string, i.e. remove leading and trailing whitespace characters | {bar!t} | FooBar |
T | Convert a datetime object to a Unix timestamp | {date!T} | 1262304000 |
d | Convert a Unix timestamp to a datetime object | {created!d} | 2010-01-01 00:00:00 |
D | Convert a Unix timestamp or ISO 8601 string to a datetime object | {created!D} | 2010-01-01 00:00:00 |
q | URL-encode a value | {jpn!q} | %E6%A3%AE |
Q | URL-decode a value | {jpn_url!Q} | 森 |
U | Convert HTML entities | {html!U} | <p>foo & bar</p> |
H | Convert HTML entities & remove HTML tags | {html!H} | foo & bar |
R | Extract URLs | {lorem!R} | ["https://example.org/"] |
s | Convert value to str | {tags!s} | ['sun', 'tree', 'water'] |
S | Convert value to str while providing a human-readable representation for lists | {tags!S} | sun, tree, water |
r | Convert value to str using repr() | ||
a | Convert value to str using ascii() | ||
i | Convert value to int | ||
f | Convert value to float |
Format specifiers can be used for advanced formatting by using the options provided by Python (see Format Specification Mini-Language) like zero-filling a number ({num:>03}) or formatting a datetime object ({date:%Y%m%d}), or with gallery-dl’s extra formatting specifiers:
| Format Specifier | Description | Example | Result |
|---|---|---|---|
?<start>/<end>/ | Adds <start> and <end> to the actual value if it evaluates to True. Otherwise the whole replacement field becomes an empty string. | {foo:?[/]/} | [Foo Bar] |
{empty:?[/]/} | | ||
[<start>:<stop>] | Applies a Slicing operation to the current value, similar to Field Names | {foo:[1:-1]} | oo Ba |
[b<start>:<stop>] | Same as above, but applies to the bytes() representation of a string in filesystem encoding | {foo_ja:[b3:-1]} | ー・バ |
L<maxlen>/<repl>/ | Replaces the entire output with <repl> if its length exceeds <maxlen> | {foo:L15/long/} | Foo Bar |
{foo:L3/long/} | long | ||
Lb<maxlen>/<ext>/ | Same as L, but applies to the bytes() representation of a string in filesystem encoding | {foo_ja:Lb15/長い/} | フー・バー |
{foo_ja:Lb8/長い/} | 長い | ||
X<maxlen>/<ext>/ | Limit output to <maxlen> characters. Cut output and add <ext> to its end if its length exceeds <maxlen> | {foo:X15/ .../} | Foo Bar |
{foo:X6/ .../} | Fo ... | ||
Xb<maxlen>/<ext>/ | Same as X, but applies to the bytes() representation of a string in filesystem encoding | {foo_ja:Xb15/〜/} | フー・バー |
{foo_ja:Xb8/〜/} | フ〜 | ||
J<separator>/ | Concatenates elements of a list with <separator> using str.join() | {tags:J - /} | sun - tree - water |
M<key>/ | Maps a list of objects to a list of corresponding values by looking up <key> in each object | {users:Mname/} | ["John", "David", "Max"] |
R<old>/<new>/ | Replaces all occurrences of <old> with <new> using str.replace() | {foo:Ro/()/} | F()() Bar |
A<op><value>/ | Apply arithmetic operation <op> (+, -, *) to the current value | {num:A+1/} | "2" |
C<conversion(s)>/ | Apply Conversions to the current value | {tags:CSgc/} | "Sun-tree-water" |
S<order>/ | Sort a list. <order> can be either ascending or descending/reverse. (default: a) | {tags:Sd} | ['water', 'tree', 'sun'] |
D<format>/ | Parse a string value to a datetime object according to <format> | {updated:D%b %d %Y %I:%M %p/} | 2010-01-01 00:00:00 |
O<offset>/ | Apply <offset> to a datetime object, either as ±HH:MM or local for local UTC offset | {date:O-06:30/} | 2009-12-31 17:30:00 |
{date:Olocal/} | 2010-01-01 01:00:00 | ||
I | Return the current value as is. Do not convert it to str | {num:I} | 1 |
All special format specifiers (?, L, J, R, D, O, etc) can be chained and combined with one another, but must always appear before any standard format specifiers:
For example {foo:?//RF/B/Ro/e/> 10} -> Bee Bar
?// - Tests if foo has a valueRF/B/ - Replaces F with BRo/e/ - Replaces o with e> 10 - Left-fills the string with spaces until it is 10 characters longReplacement field names that are available in all format strings.
| Field Name | Description | Example | Result |
|---|---|---|---|
_env | Environment variables | {_env[HOME]} | /home/john |
_now | Current local date and time | {_now:%Y-%m} | 2022-08 |
_nul | Universal null value | {date|_nul:%Y-%m} | None |
_lit | String literals | {_lit[foo]} | foo |
{'bar'} | bar |
Starting a format string with \f<Type> allows to set a different format string type than the default. Available ones are:
| Type | Description | Usage |
|---|---|---|
E | An arbitrary Python expression | \fE title.upper().replace(' ', '-') |
F | An f-string literal | \fF '{title.strip()}' by {artist.capitalize()} |
J | A Jinja template | \fJ '{{title | trim}}' by {{artist | capitalize}} |
T | Path to a template file containing a regular format string | \fT ~/.templates/booru.txt |
TF | Path to a template file containing an f-string literal | \fTF ~/.templates/fstr.txt |
TJ | Path to a template file containing a Jinja template | \fTF ~/.templates/jinja.txt |
M | Path or name of a Python module followed by the name of one of its functions. This function gets called with the current metadata dict as argument and should return a string. | \fM my_module:generate_text |