diff --git a/docs/formatting.md b/docs/formatting.md
index b81069cf..7adfee88 100644
--- a/docs/formatting.md
+++ b/docs/formatting.md
@@ -293,6 +293,16 @@ Format specifiers can be used for advanced formatting by using the options provi
{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> |
diff --git a/gallery_dl/formatter.py b/gallery_dl/formatter.py
index 04f5cc8d..0f4f35ee 100644
--- a/gallery_dl/formatter.py
+++ b/gallery_dl/formatter.py
@@ -413,12 +413,20 @@ def _parse_conversion(format_spec, default):
def _parse_maxlen(format_spec, default):
maxlen, replacement, format_spec = format_spec.split(_SEPARATOR, 2)
- maxlen = text.parse_int(maxlen[1:])
fmt = _build_format_func(format_spec, default)
- def mlen(obj):
- obj = fmt(obj)
- return obj if len(obj) <= maxlen else replacement
+ if maxlen[1] == "b":
+ maxlen = text.parse_int(maxlen[2:])
+
+ def mlen(obj):
+ obj = fmt(obj)
+ return obj if len(obj.encode(_ENCODING)) <= maxlen else replacement
+ else:
+ maxlen = text.parse_int(maxlen[1:])
+
+ def mlen(obj):
+ obj = fmt(obj)
+ return obj if len(obj) <= maxlen else replacement
return mlen
@@ -501,13 +509,12 @@ def _parse_sort(format_spec, default):
fmt = _build_format_func(format_spec, default)
if "d" in args or "r" in args:
- def sort_desc(obj):
+ def sort(obj):
return fmt(sorted(obj, reverse=True))
- return sort_desc
else:
- def sort_asc(obj):
+ def sort(obj):
return fmt(sorted(obj))
- return sort_asc
+ return sort
def _parse_limit(format_spec, default):
diff --git a/test/test_formatter.py b/test/test_formatter.py
index b4603c06..0ad9461b 100644
--- a/test/test_formatter.py
+++ b/test/test_formatter.py
@@ -248,6 +248,19 @@ class TestFormatter(unittest.TestCase):
self._run_test("{a:L50/foo/>51}", "foo")
self._run_test("{a:Lab/foo/}", "foo")
+ def test_specifier_maxlen_bytes(self):
+ v = self.kwdict["a"]
+ self._run_test("{a:Lb5/foo/}" , "foo")
+ self._run_test("{a:Lb50/foo/}", v)
+ self._run_test("{a:Lb50/foo/>50}", " " * 39 + v)
+ self._run_test("{a:Lb50/foo/>51}", "foo")
+ self._run_test("{a:Lbab/foo/}", "foo")
+
+ v = self.kwdict["j"]
+ self._run_test("{j:Lb5/foo/}" , "foo")
+ self._run_test("{j:Lb50/foo/}", v)
+ self._run_test("{j:Lbab/foo/}", "foo")
+
def test_specifier_join(self):
self._run_test("{l:J}" , "abc")
self._run_test("{l:J,}" , "a,b,c")