Short description At the moment plugins do use very different parameter and keywords resolving mechanisms. They destinguish very different between boths. I would like to have added a common function on wikiutil which could be used for further development of plugins parameter and keywords.

For a first idea copied from the recent ImageLink.

if args:
        args = args.split(',')
        args = [arg.strip() for arg in args]
    else:
        args = []

    argc = len(args)
    kw_count = 0
    kw = {} # create a dictionary for the formatter.image call
    for arg in args :
        if '=' in arg:
            kw_count += 1
            key, value = arg.split('=', 1)
            kw[str(key)] = wikiutil.escape(value, quote=1)

    argc -= kw_count

If this become a generic routine we should have the posibility to mix the order of keywords and parameters in the call. At the moment imho all plugins have a strict order of parameters and then keywords.

-- ReimarBauer 2006-03-12 09:11:47

Note that there are already three different argument parsers hidden in MoinMoin code. So refactoring should take place first.

We do often use in parsers and macros a similiar routine like this one. This is mostly derived from the ImageLink macro. This one is now more generic and I believe a lot of routines could use it. For further enhancement e.g. keyword inheritance unused keywords for the callers routine are saved too. I like to add this to wikiutil. -- ReimarBauer 2007-01-14 09:54:38

minor change for no keywords (kwAllowed=None) so that function could be called with one parameter -- ReimarBauer 2007-01-14 19:04:18

   1 def argParser(args, kwAllowed=None, separator=','):
   2     '''returns a dict of given parameters, keywords '''
   3     if args:
   4         args = args.split(separator)
   5         args = [arg.strip() for arg in args]
   6     else:
   7         args = []
   8 
   9     argc = len(args)
  10     kw_count = 0
  11     pp_count = 0
  12     kw = {} # keywords
  13     ukw = {} # unused keywords
  14     pp = {} # positional parameters
  15     for arg in args:
  16         if '=' in arg:
  17             key, value = arg.split('=', 1)
  18             if key.lower() not in kwAllowed: 
  19                 ukw[str(key.lower())] = escape(value, quote=1)
  20                 continue
  21             kw_count += 1
  22             kw[str(key.lower())] = escape(value, quote=1)
  23         else:
  24             pp_count += 1
  25             pp["%d" % pp_count] = escape(arg, quote=1)
  26 
  27     return {"keywords": kw, "unused_keywords": ukw, "positional_parameters": pp, "kw_count": kw_count, "pp_count": pp_count}

This is an example to show what to do with this arg parser

   1 # -*- coding: iso-8859-1 -*-
   2 """
   3     Macro - TestParam to test the argParser function
   4 
   5     @copyright :Reimar Bauer 
   6     @license: GNU GPL, see COPYING for details.
   7 """
   8 from MoinMoin import wikiutil
   9 
  10 def execute(macro, args):
  11     request = macro.request
  12     kwAllowed = ['width', 'height', 'alt']
  13     result = wikiutil.argParser(args, kwAllowed)
  14     kw_count = result['kw_count']
  15     pp_count = result['pp_count']
  16     request.write('valid keyword_count: %s | ' % kw_count)
  17     request.write('parameter_count: %s | ' % pp_count)
  18 
  19     if kw_count:
  20         keywords = result["keywords"]
  21         for tag in keywords.keys():
  22             request.write("Keyword: %s, value %s | " % (tag, keywords[tag]))
  23 
  24     if pp_count:
  25         pp = result["positional_parameters"]
  26         for tag in pp.keys():
  27             request.write("positional %s parameter: value %s | " % (tag, pp[tag]))
  28 
  29     ukw = result["unused_keywords"]
  30     for tag in ukw.keys():
  31         request.write("unused keyword %s, value %s | " % (tag, ukw[tag]))

Example call of a routine using this argParser:

 * {{{[[TestParam]]}}} [[TestParam]]
 * {{{[[TestParam(a,b)]]}}} [[TestParam(a,b)]]
 * {{{[[TestParam(a,b,alt='DDD')]]}}} [[TestParam(a,b,alt='DDD')]]
 * {{{[[TestParam(alt='DDD')]]}}} [[TestParam(alt='DDD')]]
 * {{{[[TestParam(height=200,width=300,alt='DDD')]]}}} [[TestParam(height=200,width=300,alt='DDD')]]
 * {{{[[TestParam(a,b,height=200,width=300,alt='DDD')]]}}} [[TestParam(a,b,height=200,width=300,alt='DDD')]]
 * {{{[[TestParam(a,b,height=200,width=300,alt='DDD',background='yellow')]]}}} [[TestParam(a,b,height=200,width=300,alt='DDD',background='yellow')]]

Result:

argParser.png

Would be great to have that arg parser. As far as I can see, a lot of people use similar code like above, propably taken from macro/action.py. However, as Reimar said already elsewhere, code dublication is not that fine and everything is in the code above you normally need... -- OliverSiemoneit 2007-01-14 12:32:25

Annotation: Not quite sure whether it is always good to separate between keywords and positional parameters. Maybe my suggestion for a new User.py macro is an example for that (see FeatureRequests/WelcomeNewUserPage). There you can write User(homepage) and User(homepage=Create homepage now). But maybe that's bad coding style..However a separation there would make it more difficult to parse the args. It personally would prefer to rename "args" in "given_args" and "kwAllowed" in "allowed_args". That would be more intuitiv for me. But I don't have an overview on the naming conventions in Moin..


CategoryFeatureImplemented (slightly different implemented in 1.6)

MoinMoin: FeatureRequests/WikiutilFunctionToSeparatePluginParameterAndKeywords (last edited 2008-03-23 19:55:04 by ReimarBauer)