[formatter] implement slice operator as format specifier

this allows using a slice operator alongside other (special) format
specifiers like J, to first join list elements to a string and then
trimming that with a slice.

{tags:J, /[:50]}
This commit is contained in:
Mike Fährmann
2022-06-25 16:45:34 +02:00
parent 241e82e18d
commit 54525d2e21
3 changed files with 48 additions and 7 deletions

View File

@@ -232,12 +232,7 @@ def parse_field_name(field_name):
func = operator.itemgetter
try:
if ":" in key:
start, _, stop = key.partition(":")
stop, _, step = stop.partition(":")
start = int(start) if start else None
stop = int(stop) if stop else None
step = int(step) if step else None
key = slice(start, stop, step)
key = _slice(key)
except TypeError:
pass # key is an integer
@@ -246,6 +241,16 @@ def parse_field_name(field_name):
return first, funcs
def _slice(indices):
start, _, stop = indices.partition(":")
stop, _, step = stop.partition(":")
return slice(
int(start) if start else None,
int(stop) if stop else None,
int(step) if step else None,
)
def parse_format_spec(format_spec, conversion):
fmt = build_format_func(format_spec)
if not conversion:
@@ -283,6 +288,8 @@ def build_format_func(format_spec):
fmt = format_spec[0]
if fmt == "?":
return _parse_optional(format_spec)
if fmt == "[":
return _parse_slice(format_spec)
if fmt == "L":
return _parse_maxlen(format_spec)
if fmt == "J":
@@ -305,6 +312,16 @@ def _parse_optional(format_spec):
return optional
def _parse_slice(format_spec):
indices, _, format_spec = format_spec.partition("]")
slice = _slice(indices[1:])
fmt = build_format_func(format_spec)
def apply_slice(obj):
return fmt(obj[slice])
return apply_slice
def _parse_maxlen(format_spec):
maxlen, replacement, format_spec = format_spec.split("/", 2)
maxlen = text.parse_int(maxlen[1:])