#2983: Proposal to add util.parseargs
-------------------------+--------------------------------------------------
 Reporter:  athomas      |        Owner:  athomas
     Type:  enhancement  |       Status:  new    
 Priority:  normal       |    Milestone:  0.10   
Component:  general      |      Version:  0.9.4  
 Severity:  normal       |   Resolution:         
 Keywords:  macro        |  
-------------------------+--------------------------------------------------
Changes (by cboos):

  * priority:  high => normal

Comment:

 Well, I did some additional testing, and it appears
 that this needs some more work before it can really
 be used on a bigger scale:
 {{{
 #!diff
 Index: macros.py
 ===================================================================
 --- macros.py   (revision 3234)
 +++ macros.py   (working copy)
 @@ -54,6 +54,89 @@
          raise NotImplementedError


 +def parse_args(args):
 +    """Utility for parsing the `content` parameter in `render_macro`.
 +
 +    This follows the usual Python convention for parsing function
 +    arguments, including named arguments:
 +
 +    >>> parse_args('')
 +    ([], {})
 +    >>> parse_args('1, text')
 +    ([1, 'text'], {})
 +    >>> parse_args('option=yes')
 +    ([], {'option': 'yes'})
 +    >>> parse_args('1, text, option=yes')
 +    ([1, 'text'], {'option': 'yes'})
 +
 +    List and tuple arguments are supported too:
 +
 +    >>> parse_args('[1,2,3], list=(a,b)')
 +    ([(1, 2, 3)], {'list': ('a', 'b')})
 +
 +    It's also very useful for handling quotes the expected way:
 +
 +    >>> parse_args('"foo, bar", color="rgb(ff,00,00)", separator=","')
 +    (['foo, bar'], {'color': 'rgb(ff,00,00)', 'separator': ','})
 +
 +    '''However'''
 +
 +    A big limitation of this approach is that any unquoted text argument
 +    has to be a proper Python identifier.
 +    i.e. it can't contain space, start with a digit, etc.
 +
 +    A lot of expected usage of macros wouldn't work.
 +
 +    >>> parse_args('Hello world!')
 +    Traceback (most recent call last):
 +         ...
 +    SyntaxError: invalid syntax
 +
 +    >>> parse_args('Prefix%%')             # NB: second % for doctest's
 sake
 +    Traceback (most recent call last):
 +         ...
 +    SyntaxError: invalid syntax
 +
 +    >>> parse_args('TracDev/')
 +    Traceback (most recent call last):
 +         ...
 +    SyntaxError: unexpected EOF while parsing
 +
 +    >>> parse_args('OtherPage:foo.bmp')
 +    Traceback (most recent call last):
 +         ...
 +    SyntaxError: invalid syntax
 +
 +    >>> parse_args('photo.jpg, align=right')
 +    Traceback (most recent call last):
 +         ...
 +    ValueError: invalid arguments near Getattr(Name('photo'), 'jpg')
 +    """
 +    import compiler
 +
 +    def get_value(node):
 +        if isinstance(node, compiler.ast.Name):
 +            return node.name
 +        elif isinstance(node, compiler.ast.Const):
 +            return node.value
 +        elif isinstance(node, compiler.ast.Tuple) or \
 +             isinstance(node, compiler.ast.List):
 +            return tuple([get_value(el) for el in node.nodes])
 +        elif isinstance(node, compiler.ast.Dict):
 +            return dict([(get_value(k), get_value(v)) for k, v in
 node.items])
 +        raise ValueError('invalid arguments near %s' % str(node))
 +
 +    largs = []
 +    kwargs = {}
 +    expr = compiler.parse('mock(%s)' % args, 'eval')
 +    for node in expr.getChildNodes()[0].args:
 +        if isinstance(node, compiler.ast.Keyword):
 +            kwargs[node.name] = get_value(node.expr)
 +        else:
 +            largs.append(get_value(node))
 +    return largs, kwargs
 +
 +
  class TitleIndexMacro(WikiMacroBase):
      """Inserts an alphabetic list of all wiki pages into the output.
 }}}

-- 
Ticket URL: <http://projects.edgewall.com/trac/ticket/2983>
The Trac Project <http://trac.edgewall.com/>
_______________________________________________
Trac-Tickets mailing list
[email protected]
http://lists.edgewall.com/mailman/listinfo/trac-tickets

Reply via email to