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:
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)