diff --git a/docs/configuration.rst b/docs/configuration.rst index 74a71b29..25ce8761 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -3710,6 +3710,20 @@ Description this cache. +format-separator +---------------- +Type + ``string`` +Default + ``"/"`` +Description + Character(s) used as argument separator in format string + `format specifiers `__. + + For example, setting this option to ``"#"`` would allow a replacement + operation to be ``Rold#new#`` instead of the default ``Rold/new/`` + + signals-ignore -------------- Type diff --git a/gallery_dl/__init__.py b/gallery_dl/__init__.py index 9e274172..04ea54c5 100644 --- a/gallery_dl/__init__.py +++ b/gallery_dl/__init__.py @@ -177,6 +177,12 @@ def main(): extractor.modules = modules extractor._module_iter = iter(modules) + # format string separator + separator = config.get((), "format-separator") + if separator: + from . import formatter + formatter._SEPARATOR = separator + # loglevels output.configure_logging(args.loglevel) if args.loglevel >= logging.ERROR: diff --git a/gallery_dl/formatter.py b/gallery_dl/formatter.py index 04ec1c4a..bc4d837a 100644 --- a/gallery_dl/formatter.py +++ b/gallery_dl/formatter.py @@ -264,7 +264,7 @@ def _build_format_func(format_spec, default): def _parse_optional(format_spec, default): - before, after, format_spec = format_spec.split("/", 2) + before, after, format_spec = format_spec.split(_SEPARATOR, 2) before = before[1:] fmt = _build_format_func(format_spec, default) @@ -284,7 +284,7 @@ def _parse_slice(format_spec, default): def _parse_maxlen(format_spec, default): - maxlen, replacement, format_spec = format_spec.split("/", 2) + maxlen, replacement, format_spec = format_spec.split(_SEPARATOR, 2) maxlen = text.parse_int(maxlen[1:]) fmt = _build_format_func(format_spec, default) @@ -295,7 +295,7 @@ def _parse_maxlen(format_spec, default): def _parse_join(format_spec, default): - separator, _, format_spec = format_spec.partition("/") + separator, _, format_spec = format_spec.partition(_SEPARATOR) separator = separator[1:] fmt = _build_format_func(format_spec, default) @@ -305,7 +305,7 @@ def _parse_join(format_spec, default): def _parse_replace(format_spec, default): - old, new, format_spec = format_spec.split("/", 2) + old, new, format_spec = format_spec.split(_SEPARATOR, 2) old = old[1:] fmt = _build_format_func(format_spec, default) @@ -315,7 +315,7 @@ def _parse_replace(format_spec, default): def _parse_datetime(format_spec, default): - dt_format, _, format_spec = format_spec.partition("/") + dt_format, _, format_spec = format_spec.partition(_SEPARATOR) dt_format = dt_format[1:] fmt = _build_format_func(format_spec, default) @@ -325,7 +325,7 @@ def _parse_datetime(format_spec, default): def _parse_offset(format_spec, default): - offset, _, format_spec = format_spec.partition("/") + offset, _, format_spec = format_spec.partition(_SEPARATOR) offset = offset[1:] fmt = _build_format_func(format_spec, default) @@ -363,6 +363,7 @@ class Literal(): _literal = Literal() _CACHE = {} +_SEPARATOR = "/" _GLOBALS = { "_env": lambda: os.environ, "_lit": lambda: _literal, diff --git a/test/test_formatter.py b/test/test_formatter.py index b86f0bdb..aec091a5 100644 --- a/test/test_formatter.py +++ b/test/test_formatter.py @@ -236,6 +236,26 @@ class TestFormatter(unittest.TestCase): # parse and format datetime self._run_test("{ds:D%Y-%m-%dT%H:%M:%S%z/%Y%m%d}", "20100101") + def test_separator(self): + orig_separator = formatter._SEPARATOR + try: + formatter._SEPARATOR = "|" + self._run_test("{a:Rh|C|RE|e|RL|l|}", "Cello wOrld") + self._run_test("{d[b]!s:R1|Q|R2|A|R0|Y|}", "Y") + + formatter._SEPARATOR = "##" + self._run_test("{l:J-##Rb##E##}", "a-E-c") + self._run_test("{l:J-##[1:-1]}", "-b-") + + formatter._SEPARATOR = "\0" + self._run_test("{d[a]:?<\0>\0L1\0too long\0}", "") + self._run_test("{d[c]:?<\0>\0L5\0too long\0}", "") + + formatter._SEPARATOR = "?" + self._run_test("{ds:D%Y-%m-%dT%H:%M:%S%z?%Y%m%d}", "20100101") + finally: + formatter._SEPARATOR = orig_separator + def test_globals_env(self): os.environ["FORMATTER_TEST"] = value = self.kwdict["a"]