Feature appends prepends 1010 (#1015)

* Added appends, prepends filters, #1010

* Fixed initialization of field_arg
This commit is contained in:
Rhet Turnbull
2023-03-09 06:22:24 -08:00
committed by GitHub
parent a08680ed02
commit cfb623d19b
3 changed files with 29 additions and 13 deletions

View File

@@ -54,6 +54,8 @@ Valid filters are:
- `join(x)`: Join list of values with delimiter x, e.g. join(,): ['a', 'b', 'c'] => 'a,b,c'; the DELIM option functions similar to join(x) but with DELIM, the join happens before being passed to any filters.May optionally be used without an argument, that is 'join()' which joins values together with no delimiter. e.g. join(): ['a', 'b', 'c'] => 'abc'. - `join(x)`: Join list of values with delimiter x, e.g. join(,): ['a', 'b', 'c'] => 'a,b,c'; the DELIM option functions similar to join(x) but with DELIM, the join happens before being passed to any filters.May optionally be used without an argument, that is 'join()' which joins values together with no delimiter. e.g. join(): ['a', 'b', 'c'] => 'abc'.
- `append(x)`: Append x to list of values, e.g. append(d): ['a', 'b', 'c'] => ['a', 'b', 'c', 'd']. - `append(x)`: Append x to list of values, e.g. append(d): ['a', 'b', 'c'] => ['a', 'b', 'c', 'd'].
- `prepend(x)`: Prepend x to list of values, e.g. prepend(d): ['a', 'b', 'c'] => ['d', 'a', 'b', 'c']. - `prepend(x)`: Prepend x to list of values, e.g. prepend(d): ['a', 'b', 'c'] => ['d', 'a', 'b', 'c'].
- `appends(x)`: [append s(tring)] Append x to each value of list of values, e.g. appends(d): ['a', 'b', 'c'] => ['ad', 'bd', 'cd'].
- `prepends(x)`: [prepend s(tring)] Prepend x to each value of list of values, e.g. prepends(d): ['a', 'b', 'c'] => ['da', 'db', 'dc'].
- `remove(x)`: Remove x from list of values, e.g. remove(b): ['a', 'b', 'c'] => ['a', 'c']. - `remove(x)`: Remove x from list of values, e.g. remove(b): ['a', 'b', 'c'] => ['a', 'c'].
- `slice(start:stop:step)`: Slice list using same semantics as Python's list slicing, e.g. slice(1:3): ['a', 'b', 'c', 'd'] => ['b', 'c']; slice(1:4:2): ['a', 'b', 'c', 'd'] => ['b', 'd']; slice(1:): ['a', 'b', 'c', 'd'] => ['b', 'c', 'd']; slice(:-1): ['a', 'b', 'c', 'd'] => ['a', 'b', 'c']; slice(::-1): ['a', 'b', 'c', 'd'] => ['d', 'c', 'b', 'a']. See also sslice(). - `slice(start:stop:step)`: Slice list using same semantics as Python's list slicing, e.g. slice(1:3): ['a', 'b', 'c', 'd'] => ['b', 'c']; slice(1:4:2): ['a', 'b', 'c', 'd'] => ['b', 'd']; slice(1:): ['a', 'b', 'c', 'd'] => ['b', 'c', 'd']; slice(:-1): ['a', 'b', 'c', 'd'] => ['a', 'b', 'c']; slice(::-1): ['a', 'b', 'c', 'd'] => ['d', 'c', 'b', 'a']. See also sslice().
- `sslice(start:stop:step)`: [s(tring) slice] Slice values in a list using same semantics as Python's string slicing, e.g. sslice(1:3):'abcd => 'bc'; sslice(1:4:2): 'abcd' => 'bd', etc. See also slice(). - `sslice(start:stop:step)`: [s(tring) slice] Slice values in a list using same semantics as Python's string slicing, e.g. sslice(1:3):'abcd => 'bc'; sslice(1:4:2): 'abcd' => 'bd', etc. See also slice().

View File

@@ -285,6 +285,8 @@ FILTER_VALUES = {
+ "e.g. join(): ['a', 'b', 'c'] => 'abc'.", + "e.g. join(): ['a', 'b', 'c'] => 'abc'.",
"append(x)": "Append x to list of values, e.g. append(d): ['a', 'b', 'c'] => ['a', 'b', 'c', 'd'].", "append(x)": "Append x to list of values, e.g. append(d): ['a', 'b', 'c'] => ['a', 'b', 'c', 'd'].",
"prepend(x)": "Prepend x to list of values, e.g. prepend(d): ['a', 'b', 'c'] => ['d', 'a', 'b', 'c'].", "prepend(x)": "Prepend x to list of values, e.g. prepend(d): ['a', 'b', 'c'] => ['d', 'a', 'b', 'c'].",
"appends(x)": "Append s[tring] Append x to each value of list of values, e.g. appends(d): ['a', 'b', 'c'] => ['ad', 'bd', 'cd'].",
"prepends(x)": "Prepend s[tring] x to each value of list of values, e.g. prepends(d): ['a', 'b', 'c'] => ['da', 'db', 'dc'].",
"remove(x)": "Remove x from list of values, e.g. remove(b): ['a', 'b', 'c'] => ['a', 'c'].", "remove(x)": "Remove x from list of values, e.g. remove(b): ['a', 'b', 'c'] => ['a', 'c'].",
"slice(start:stop:step)": "Slice list using same semantics as Python's list slicing, " "slice(start:stop:step)": "Slice list using same semantics as Python's list slicing, "
+ "e.g. slice(1:3): ['a', 'b', 'c', 'd'] => ['b', 'c']; slice(1:4:2): ['a', 'b', 'c', 'd'] => ['b', 'd']; " + "e.g. slice(1:3): ['a', 'b', 'c', 'd'] => ['b', 'c']; slice(1:4:2): ['a', 'b', 'c', 'd'] => ['b', 'd']; "
@@ -543,6 +545,8 @@ class PhotoTemplate:
# process field arguments # process field arguments
if ts.template.fieldarg is not None: if ts.template.fieldarg is not None:
field_arg = ts.template.fieldarg.value field_arg = ts.template.fieldarg.value
else:
field_arg = None
# process delim # process delim
if ts.template.delim is not None: if ts.template.delim is not None:
@@ -1007,15 +1011,17 @@ class PhotoTemplate:
raise SyntaxError(f"Unknown filter: {filter_}") raise SyntaxError(f"Unknown filter: {filter_}")
if filter_ in [ if filter_ in [
"split",
"chop",
"chomp",
"append", "append",
"appends",
"chomp",
"chop",
"filter",
"prepend", "prepend",
"prepends",
"remove", "remove",
"slice", "slice",
"split",
"sslice", "sslice",
"filter",
] and (args is None or not len(args)): ] and (args is None or not len(args)):
raise SyntaxError(f"{filter_} requires arguments") raise SyntaxError(f"{filter_} requires arguments")
@@ -1032,15 +1038,13 @@ class PhotoTemplate:
elif filter_ == "braces": elif filter_ == "braces":
value = ["{" + v + "}" for v in values] value = ["{" + v + "}" for v in values]
elif filter_ == "parens": elif filter_ == "parens":
value = ["(" + v + ")" for v in values] value = [f"({v})" for v in values]
elif filter_ == "brackets": elif filter_ == "brackets":
value = ["[" + v + "]" for v in values] value = [f"[{v}]" for v in values]
elif filter_ == "shell_quote": elif filter_ == "shell_quote":
value = [shlex.quote(v) for v in values] value = [shlex.quote(v) for v in values]
elif filter_ == "split": elif filter_ == "split":
# split on delimiter if delim := args:
delim = args
if delim:
new_values = [] new_values = []
for v in values: for v in values:
new_values.extend(v.split(delim)) new_values.extend(v.split(delim))
@@ -1051,15 +1055,15 @@ class PhotoTemplate:
# chop off characters from the end # chop off characters from the end
try: try:
chop = int(args) chop = int(args)
except ValueError: except ValueError as e:
raise SyntaxError(f"Invalid value for chop: {args}") raise SyntaxError(f"Invalid value for chop: {args}") from e
value = [v[:-chop] for v in values] if chop else values value = [v[:-chop] for v in values] if chop else values
elif filter_ == "chomp": elif filter_ == "chomp":
# chop off characters from the beginning # chop off characters from the beginning
try: try:
chomp = int(args) chomp = int(args)
except ValueError: except ValueError as e:
raise SyntaxError(f"Invalid value for chomp: {args}") raise SyntaxError(f"Invalid value for chomp: {args}") from e
value = [v[chomp:] for v in values] if chomp else values value = [v[chomp:] for v in values] if chomp else values
elif filter_ == "autosplit": elif filter_ == "autosplit":
# try to split keyword strings automatically # try to split keyword strings automatically
@@ -1094,6 +1098,12 @@ class PhotoTemplate:
elif filter_ == "prepend": elif filter_ == "prepend":
# prepend value to list # prepend value to list
value = [args] + values value = [args] + values
elif filter_ == "appends":
# append value to each item in list
value = [f"{v}{args}" for v in values]
elif filter_ == "prepends":
# prepend value to each item in list
value = [f"{args}{v}" for v in values]
elif filter_ == "remove": elif filter_ == "remove":
# remove value from list # remove value from list
value = [v for v in values if v != args] value = [v for v in values if v != args]

View File

@@ -78,11 +78,15 @@ TEMPLATE_VALUES_MULTI_KEYWORDS = {
"{; +keyword}": ["flowers; wedding"], "{; +keyword}": ["flowers; wedding"],
"{; +keyword|titlecase}": ["Flowers; Wedding"], "{; +keyword|titlecase}": ["Flowers; Wedding"],
"{; +keyword|titlecase|parens}": ["(Flowers; Wedding)"], "{; +keyword|titlecase|parens}": ["(Flowers; Wedding)"],
"{keyword|appends(:keyword)}": ["flowers:keyword", "wedding:keyword"],
"{keyword|prepends(keyword:)}": ["keyword:flowers", "keyword:wedding"],
} }
UUID_TITLE = "6191423D-8DB8-4D4C-92BE-9BBBA308AAC4" UUID_TITLE = "6191423D-8DB8-4D4C-92BE-9BBBA308AAC4"
TEMPLATE_VALUES_TITLE = { TEMPLATE_VALUES_TITLE = {
"{title}": ["Tulips tied together at a flower shop"], "{title}": ["Tulips tied together at a flower shop"],
"{title|appends(:title)}": ["Tulips tied together at a flower shop:title"],
"{title|prepends(title:)}": ["title:Tulips tied together at a flower shop"],
"{title|titlecase}": ["Tulips Tied Together At A Flower Shop"], "{title|titlecase}": ["Tulips Tied Together At A Flower Shop"],
"{title|upper}": ["TULIPS TIED TOGETHER AT A FLOWER SHOP"], "{title|upper}": ["TULIPS TIED TOGETHER AT A FLOWER SHOP"],
"{title|titlecase|lower|upper}": ["TULIPS TIED TOGETHER AT A FLOWER SHOP"], "{title|titlecase|lower|upper}": ["TULIPS TIED TOGETHER AT A FLOWER SHOP"],