diff --git a/docs/formatting.md b/docs/formatting.md index d75ba1ba..f01e4193 100644 --- a/docs/formatting.md +++ b/docs/formatting.md @@ -197,6 +197,11 @@ Starting a format string with '\f ' allows to set a different format strin A template file containing the actual format string \fT ~/.templates/booru.txt + + F + An f-string literal + \fF '{title.strip()}' by {artist.capitalize()} + E An arbitrary Python expression diff --git a/gallery_dl/formatter.py b/gallery_dl/formatter.py index c2b4d99e..da79213b 100644 --- a/gallery_dl/formatter.py +++ b/gallery_dl/formatter.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -# Copyright 2021 Mike Fährmann +# Copyright 2021-2022 Mike Fährmann # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as @@ -43,6 +43,8 @@ def parse(format_string, default=None): cls = ExpressionFormatter elif kind == "M": cls = ModuleFormatter + elif kind == "F": + cls = FStringFormatter formatter = _CACHE[key] = cls(format_string, default) return formatter @@ -206,6 +208,13 @@ class ModuleFormatter(): self.format_map = getattr(module, function_name) +class FStringFormatter(): + """Generate text by evaluaring an f-string literal""" + + def __init__(self, fstring, default=None): + self.format_map = util.compile_expression("f'''" + fstring + "'''") + + def parse_field_name(field_name): first, rest = _string.formatter_field_name_split(field_name) funcs = [] diff --git a/test/test_formatter.py b/test/test_formatter.py index 8464b1b6..4cce8a38 100644 --- a/test/test_formatter.py +++ b/test/test_formatter.py @@ -232,6 +232,14 @@ class TestFormatter(unittest.TestCase): self._run_test("\fE name * 2 + ' ' + a", "{}{} {}".format( self.kwdict["name"], self.kwdict["name"], self.kwdict["a"])) + @unittest.skipIf(sys.hexversion < 0x3060000, "no fstring support") + def test_fstring(self): + self._run_test("\fF {a}", self.kwdict["a"]) + self._run_test("\fF {name}{name} {a}", "{}{} {}".format( + self.kwdict["name"], self.kwdict["name"], self.kwdict["a"])) + self._run_test("\fF foo-'\"{a.upper()}\"'-bar", + """foo-'"{}"'-bar""".format(self.kwdict["a"].upper())) + def test_module(self): with tempfile.TemporaryDirectory() as tmpdirname: path = os.path.join(tmpdirname, "testmod.py")