Source code for wheezy.html.ext.parser
""" ``parser`` module
"""
import re
known_functions = ['format']
RE_ARGS = re.compile(
r'\s*(?P<expr>(([\'"]).*?\3|.+?))\s*\,')
RE_KWARGS = re.compile(
r'\s*(?P<name>\w+)\s*=\s*(?P<expr>([\'"].*?[\'"]|.+?))\s*\,')
RE_STR_VALUE = re.compile(
r'^[\'"](?P<value>.+)[\'"]$')
RE_INT_VALUE = re.compile(
r'^(?P<value>(\d+))$')
RE_FUNCTIONS = re.compile(
r'\.(%s)\(' % '|'.join(known_functions))
RE_FUNCTION = re.compile(
r'(?P<context>.+?)\.(?P<name>%s)\((?P<args>(|.+))\)'
% '|'.join(known_functions))
def parse_name(expr):
[docs] """ Parses name from expression of the following form::
[object.]name[.format(...]
>>> parse_name('display_name')
'display_name'
>>> parse_name('account.display_name')
'display_name'
>>> parse_name('account.display_name.format(')
'display_name'
"""
expr = RE_FUNCTIONS.split(expr)[0]
name = expr.rsplit('.', 1)[-1]
return name
def parse_known_function(expr):
[docs] """ Parses known functions.
>>> parse_known_function("dob")
('dob', 'dob')
>>> parse_known_function("dob.format()")
('dob', 'format_value(dob, None)')
>>> parse_known_function("user.dob.format(_('YYYY/MM/DD'))")
('user.dob', "format_value(user.dob, _('YYYY/MM/DD'))")
>>> parse_known_function("user.dob.format(\
format_provider=lambda value, ignore: value.strftime('%m-%d-%y'))")
('user.dob', "format_value(user.dob, format_provider=lambda value, \
ignore: value.strftime('%m-%d-%y'))")
"""
m = RE_FUNCTION.search(expr)
if not m:
return expr, expr
context = m.group('context')
name = m.group('name')
args = m.group('args') or 'None'
return context, "%s_value(%s, %s)" % (name, context, args)
def parse_kwargs(text):
[docs] """ Parses key-value type of parameters.
>>> parse_kwargs('choices=account_types')
{'choices': 'account_types'}
>>> sorted(parse_kwargs('autocomplete="off", maxlength=12').items())
[('autocomplete', '"off"'), ('maxlength', '12')]
"""
kwargs = {}
for m in RE_KWARGS.finditer(text + ','):
groups = m.groupdict()
kwargs[groups['name'].rstrip('_')] = groups['expr']
return kwargs
def parse_args(text):
[docs] """ Parses argument type of parameters.
>>> parse_args('')
[]
>>> parse_args('10, "x"')
['10', '"x"']
>>> parse_args("'x', 100")
["'x'", '100']
>>> parse_args('"Account Type:"')
['"Account Type:"']
"""
args = []
for m in RE_ARGS.finditer(text + ','):
args.append(m.group('expr'))
return args
def parse_params(text):
[docs] """ Parses function parameters.
>>> parse_params('')
([], {})
>>> parse_params('choices=account_types')
([], {'choices': 'account_types'})
>>> parse_params('"Account Type:"')
(['"Account Type:"'], {})
>>> parse_params('"Account Type:", class_="inline"')
(['"Account Type:"'], {'class': '"inline"'})
"""
if '=' in text:
args = text.split('=')[0]
if ',' in args:
args = args.rsplit(',', 1)[0]
kwargs = text[len(args):]
return parse_args(args), parse_kwargs(kwargs)
else:
return [], parse_kwargs(text)
else:
return parse_args(text), {}
def parse_str_or_int(text):
[docs] """ Interpretate ``text`` as string or int expression.
>>> parse_str_or_int('"Hello"')
'Hello'
>>> parse_str_or_int("'Hello'")
'Hello'
>>> parse_str_or_int('100')
'100'
>>> parse_str_or_int('model.username')
"""
m = RE_STR_VALUE.match(text)
if m:
return m.group('value')
else:
m = RE_INT_VALUE.match(text)
if m:
return m.group('value')
else:
return None