diff --git a/picard/script/functions.py b/picard/script/functions.py index 2d6debc35..46f419a4c 100644 --- a/picard/script/functions.py +++ b/picard/script/functions.py @@ -1536,13 +1536,16 @@ def func_cleanmulti(parser, multi): def _type_args(_type, *args): - haystack = set((args)) + haystack = set() + # Automatically expand multi-value arguments + for item in args: + haystack = haystack.union(set(x for x in item.split('; '))) _typer = None if _type == 'int': _typer = int elif _type == 'float': _typer = float - elif _type == 'text': + elif _type in ('text', 'ncase'): pass else: # Unknown processing type @@ -1554,19 +1557,30 @@ def _type_args(_type, *args): def _extract(_func, _type, *args): try: - return str(_func(_type_args(_type, *args))) + haystack = _type_args(_type, *args) except ValueError: return "" + if _type == 'ncase': + op = operator.lt if _func == min else operator.gt + val = None + for item in haystack: + if val is None or op(item.lower(), val.lower()): + val = item + return str(val) + + return str(_func(haystack)) + @script_function(documentation=N_( """$min(type,x,...) Returns the minimum value using the comparison specified in `type`. -Possible values of `type` are "int" (integer), "float" (floating point) and -"text" (case-sensitive text). +Possible values of `type` are "int" (integer), "float" (floating point), +"text" (case-sensitive text) and "ncase" (case-insensitive text). -Can be used with an arbitrary number of arguments. +Can be used with an arbitrary number of arguments. Multi-value arguments +will be expanded automatically. _Since Picard 3.0_""" )) @@ -1578,10 +1592,11 @@ def func_min(parser, _type, x, *args): """$max(type,x,...) Returns the maximum value using the comparison specified in `type`. -Possible values of `type` are "int" (integer), "float" (floating point) and -"text" (case-sensitive text). +Possible values of `type` are "int" (integer), "float" (floating point), +"text" (case-sensitive text) and "ncase" (case-insensitive text). -Can be used with an arbitrary number of arguments. +Can be used with an arbitrary number of arguments. Multi-value arguments +will be expanded automatically. _Since Picard 3.0_""" )) diff --git a/test/test_script.py b/test/test_script.py index 79aaacc8b..07e358a65 100644 --- a/test/test_script.py +++ b/test/test_script.py @@ -2242,14 +2242,28 @@ class ScriptParserTest(PicardTestCase): self.assertScriptResultEquals("$min(float,2,3)", "2.0", context) self.assertScriptResultEquals("$min(float,2,1,3)", "1.0", context) self.assertScriptResultEquals("$min(float,2,1.1,3)", "1.1", context) + self.assertScriptResultEquals("$min(float,1.11,1.1,1.111)", "1.1", context) self.assertScriptResultEquals("$min(float,2,1,a)", "", context) self.assertScriptResultEquals("$min(float,2,,1)", "", context) self.assertScriptResultEquals("$min(float,2,1,)", "", context) - # Test case sensitive arguments + # Test 'ncase' processing + self.assertScriptResultEquals("$min(ncase,a,B)", "a", context) + self.assertScriptResultEquals("$min(ncase,c,A,b)", "A", context) + + # Test case sensitive arguments with 'text' processing self.assertScriptResultEquals("$min(text,A,a)", "A", context) self.assertScriptResultEquals("$min(text,a,B)", "B", context) + # Test multi-value arguments + context['mv'] = ['y', 'z', 'x'] + self.assertScriptResultEquals("$min(text,%mv%)", "x", context) + self.assertScriptResultEquals("$min(text,y; z; x)", "x", context) + self.assertScriptResultEquals("$min(text,a,%mv%)", "a", context) + self.assertScriptResultEquals("$min(text,a,y; z; x)", "a", context) + self.assertScriptResultEquals("$min(int,5,4; 6; 3)", "3", context) + self.assertScriptResultEquals("$min(float,5.9,4.2; 6; 3.35)", "3.35", context) + # Test invalid processing types self.assertScriptResultEquals("$min(,A,a)", "", context) self.assertScriptResultEquals("$min(unknown,a,B)", "", context) @@ -2297,14 +2311,28 @@ class ScriptParserTest(PicardTestCase): self.assertScriptResultEquals("$max(float,2,3)", "3.0", context) self.assertScriptResultEquals("$max(float,2,1.1,3)", "3.0", context) self.assertScriptResultEquals("$max(float,2,1,3.1)", "3.1", context) + self.assertScriptResultEquals("$max(float,2.1,2.11,2.111)", "2.111", context) self.assertScriptResultEquals("$max(float,2,1,a)", "", context) self.assertScriptResultEquals("$max(float,2,,1)", "", context) self.assertScriptResultEquals("$max(float,2,1,)", "", context) - # Test case sensitive arguments + # Test 'ncase' processing + self.assertScriptResultEquals("$max(ncase,a,B)", "B", context) + self.assertScriptResultEquals("$max(ncase,c,a,B)", "c", context) + + # Test case sensitive arguments with 'text' processing self.assertScriptResultEquals("$max(text,A,a)", "a", context) self.assertScriptResultEquals("$max(text,a,B)", "a", context) + # Test multi-value arguments + context['mv'] = ['y', 'z', 'x'] + self.assertScriptResultEquals("$max(text,%mv%)", "z", context) + self.assertScriptResultEquals("$max(text,y; z; x)", "z", context) + self.assertScriptResultEquals("$max(text,a,%mv%)", "z", context) + self.assertScriptResultEquals("$max(text,a,y; z; x)", "z", context) + self.assertScriptResultEquals("$max(int,5,4; 6; 3)", "6", context) + self.assertScriptResultEquals("$max(float,5.9,4.2; 6; 3.35)", "6.0", context) + # Test invalid processing types self.assertScriptResultEquals("$max(,A,a)", "", context) self.assertScriptResultEquals("$max(unknown,a,B)", "", context)