diff --git a/docs/formatting.md b/docs/formatting.md
index 72cf0bed..87023540 100644
--- a/docs/formatting.md
+++ b/docs/formatting.md
@@ -189,6 +189,18 @@ Conversion specifiers allow to *convert* the value to a different form or type.
{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 |
diff --git a/gallery_dl/formatter.py b/gallery_dl/formatter.py
index e4fed428..1afea5a4 100644
--- a/gallery_dl/formatter.py
+++ b/gallery_dl/formatter.py
@@ -606,6 +606,8 @@ _CONVERSIONS = {
"T": dt.to_ts_string,
"d": dt.parse_ts,
"D": dt.convert,
+ "q": text.quote,
+ "Q": text.unquote,
"U": text.unescape,
"H": lambda s: text.unescape(text.remove_html(s)),
"g": text.slugify,
diff --git a/test/test_formatter.py b/test/test_formatter.py
index 28654a3d..dfc88535 100644
--- a/test/test_formatter.py
+++ b/test/test_formatter.py
@@ -32,6 +32,7 @@ class TestFormatter(unittest.TestCase):
"a": "hElLo wOrLd",
"b": "äöü",
"j": "げんそうきょう",
+ "J": "%E3%81%92%E3%82%93%E3%81%9D",
"d": {"a": "foo", "b": 0, "c": None},
"i": 2,
"l": ["a", "b", "c"],
@@ -109,9 +110,13 @@ class TestFormatter(unittest.TestCase):
self._run_test("{i_str!i}", 12345)
self._run_test("{i_str!f}", 12345.0)
self._run_test("{f_str!f}", 12.45)
+ self._run_test("{j!q}", "%E3%81%92%E3%82%93%E3%81%9D"
+ "%E3%81%86%E3%81%8D%E3%82%87%E3%81%86")
+ self._run_test("{J!Q}", "げんそ")
+ # undefined conversion
with self.assertRaises(KeyError):
- self._run_test("{a!q}", "hello world")
+ self._run_test("{a!z}", "hello world")
def test_optional(self):
self._run_test("{name}{title1}", "NameTitle")