# HG changeset patch # User Paul Boddie # Date 1360971584 -3600 # Node ID adbec4d2e93e6b46d972aa429afe341c1cb219ff # Parent 251544e20a377b9001ef0d4df8a387c46d6c6695 Changed macro argument parsing to produce (name, value) pairs and to quote them in form output. Added some tests of argument parsing and quoting. diff -r 251544e20a37 -r adbec4d2e93e MoinForms.py --- a/MoinForms.py Fri Feb 15 00:39:42 2013 +0100 +++ b/MoinForms.py Sat Feb 16 00:39:44 2013 +0100 @@ -679,9 +679,13 @@ # Substitute the macro and modified arguments. else: - result.append("<>" % (type, ",".join( - adjustMacroArguments(parseMacroArguments(match), path, fragment, repeating, index) - ))) + result.append("<>" % (type, + quoteMacroArguments( + adjustMacroArguments( + parseMacroArguments(match), path, fragment, repeating, index + ) + ) + )) return "".join(result) @@ -702,27 +706,28 @@ old_path = None found_name = None - for arg in args: - if arg.startswith("path="): - old_path = arg[5:] - elif arg.startswith("fragment=") and fragment: + for name, value in args: + if name == "path": + old_path = value + elif name == "fragment" and fragment: pass else: - result.append(arg) - if arg.startswith("name="): - found_name = arg[5:] - elif found_name is None: - found_name = arg + result.append((name, value)) + + # Remember any explicitly given name or where a keyword appears. + + if name == "name" or name is None and found_name is None: + found_name = value if path: qualified = old_path and ("%s/%s" % (old_path, path)) or path - result.append("path=%s" % qualified) + result.append(("path", qualified)) if fragment: - result.append("fragment=%s" % fragment) + result.append(("fragment", fragment)) if repeating and repeating == found_name: - result.append("index=%s" % index) + result.append(("index", index)) return result @@ -740,45 +745,75 @@ except AttributeError: parsed_args = args.split(",") - return [arg for arg in parsed_args if arg] + pairs = [] + for arg in parsed_args: + if arg: + pair = arg.split("=", 1) + if len(pair) < 2: + pairs.append((None, arg)) + else: + pairs.append(tuple(pair)) + + return pairs + +def quoteMacroArguments(args): + + """ + Quote the given 'args' - a collection of (name, value) tuples - returning a + string containing the comma-separated, quoted arguments. + """ + + quoted = [] + + for name, value in args: + value = value.replace('"', '""') + if name is None: + quoted.append('"%s"' % value) + else: + quoted.append('"%s=%s"' % (name, value)) + + return ",".join(quoted) def getMacroArguments(parsed_args): "Return the macro arguments decoded from 'parsed_args'." - name = None + found_name = None path = None dictpage = None label = None section = None fragment = None - for arg in parsed_args: - if arg.startswith("name="): - name = arg[5:] + for name, value in parsed_args: + if name == "name": + found_name = value - elif arg.startswith("path="): - path = arg[5:] + elif name == "path": + path = value + + elif name == "dict": + dictpage = value - elif arg.startswith("dict="): - dictpage = arg[5:] - - elif arg.startswith("label="): - label = arg[6:] + elif name == "label": + label = value - elif arg.startswith("section="): - section = arg[8:] + elif name == "section": + section = value - elif arg.startswith("fragment="): - fragment = arg[9:] + elif name == "fragment": + fragment = value + + # Keywords are interpreted as certain kinds of values. elif name is None: - name = arg + if found_name is None: + found_name = value - elif dictpage is None: - dictpage = arg + elif dictpage is None: + dictpage = value - return name, path, dictpage, label, section, fragment + return found_name, path, dictpage, label, section, fragment def getFields(d, remove=False): diff -r 251544e20a37 -r adbec4d2e93e macros/FormMessage.py --- a/macros/FormMessage.py Fri Feb 15 00:39:42 2013 +0100 +++ b/macros/FormMessage.py Sat Feb 16 00:39:44 2013 +0100 @@ -44,21 +44,21 @@ fragment = None index = None - for arg in parsed_args: - if arg.startswith("name="): - name = arg[5:] + for argname, argvalue in parsed_args: + if argname == "name": + name = argvalue - elif arg.startswith("path="): - path = arg[5:] + elif argname == "path": + path = argvalue - if arg.startswith("fragment="): - fragment = arg[9:] + if argname == "fragment": + fragment = argvalue - elif arg.startswith("index="): - index = arg[6:] + elif argname == "index": + index = argvalue - elif name is None: - name = arg + elif argname is None and name is None: + name = argvalue if not name: return showError(_("No field name specified."), request) diff -r 251544e20a37 -r adbec4d2e93e tests/arguments.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/arguments.py Sat Feb 16 00:39:44 2013 +0100 @@ -0,0 +1,19 @@ +#!/usr/bin/env python + +from MoinForms import parseMacroArguments, quoteMacroArguments + +tests = [ + (u'a=b,b=c', 2), + (u'"a=b","b=c"', 2), + (u'"a=""b""",b=c', 2), + (u'"a=b,b=c"', 1) + ] + +for args, n in tests: + parsed_args = parseMacroArguments(args) + print len(parsed_args) == n, n, parsed_args + quoted_args = quoteMacroArguments(parsed_args) + parsed_again = parseMacroArguments(quoted_args) + print parsed_args == parsed_again, parsed_args, parsed_again + +# vim: tabstop=4 expandtab shiftwidth=4