From: philipp Date: Sat, 8 Mar 2014 19:42:48 +0000 (+0000) Subject: Created to_python function of new validator TemplateValidator. X-Git-Url: https://git.toastfreeware.priv.at/philipp/winterrodeln/wrpylib.git/commitdiff_plain/e0b652529508fea655083f3228ced5f30bdfc464?hp=2f98695a90deab75f6584760d931d1b48bb2c1b1 Created to_python function of new validator TemplateValidator. git-svn-id: http://www.winterrodeln.org/svn/wrpylib/trunk@1911 7aebc617-e5e2-0310-91dc-80fb5f6d2477 --- diff --git a/tests/test_mwmarkup.py b/tests/test_mwmarkup.py index 456ffa6..1f17ca5 100644 --- a/tests/test_mwmarkup.py +++ b/tests/test_mwmarkup.py @@ -35,6 +35,16 @@ def test_find_template(): assert end == wikitext.find(u'}}')+2 +def test_TemplateValidator(): + v = wrpylib.mwmarkup.TemplateValidator() + value = u'{{Rodelbahnbox | Unbenannt | Position = 47.309820 N 9.986508 E | Aufstieg möglich = Ja }}' + title, anonym_params, named_params = v.to_python(value) + assert title == u'Rodelbahnbox' + assert anonym_params == [u'Unbenannt'] + assert named_params.keys() == [u'Position', u'Aufstieg möglich'] + assert named_params.values() == ['47.309820 N 9.986508 E', 'Ja'] + + def test_split_template(): wikitext = u'''== Allgemeines == {{Rodelbahnbox diff --git a/wrpylib/mwmarkup.py b/wrpylib/mwmarkup.py index ace7362..2f8faea 100644 --- a/wrpylib/mwmarkup.py +++ b/wrpylib/mwmarkup.py @@ -11,6 +11,8 @@ that convinced me. However, here are the links: """ import re import xml.etree.ElementTree +import collections +import formencode class ParseError(RuntimeError): @@ -47,44 +49,67 @@ def find_template(wikitext, template_title): return match.start(), match.end() +class TemplateValidator(formencode.FancyValidator): + def to_python(self, value, state=None): + """Takes a template, like u'{{Color|red|text=Any text}}' and translates it to a Python tuple + (title, anonym_params, named_params) where title is the template title, + anonym_params is a list of anonymous parameters and named_params is a OrderedDict + of named parameters. Whitespace of the parameters is stripped.""" + if not value.startswith(u'{{'): + raise formencode.Invalid(u'Template does not start with "{{"', value, state) + if not value.endswith(u'}}'): + raise formencode.Invalid(u'Template does not end with "}}"', value, state) + parts = value[2:-2].split(u'|') + + # template name + title = parts[0].strip() + if len(title) == 0: + raise formencode.Invalid(u'Empty template tilte.', value, state) + del parts[0] + + # anonymous parameters + anonym_params = [] + while len(parts) > 0: + equalsign_pos = parts[0].find(u'=') + if equalsign_pos >= 0: break # named parameter + anonym_params.append(parts[0].strip()) + del parts[0] + + # named or numbered parameters + named_params = collections.OrderedDict() + while len(parts) > 0: + equalsign_pos = parts[0].find(u'=') + if equalsign_pos < 0: + raise formencode.Invalid(u'Anonymous parameter after named parameter.', value, state) + key, sep, value = parts[0].partition(u'=') + key = key.strip() + if len(key) == 0: + raise formencode.Invalid(u'Empty key.', value, state) + if named_params.has_key(key): + raise formencode.Invalid(u'Duplicate key: "{0}"'.format(key), value, state) + named_params[key] = value.strip() + del parts[0] + + return title, anonym_params, named_params + + def split_template(template): - """Takes a template, like u'{{Color|red|text=Any text}}' and translates it to a Python tuple + """Deprecated legacy function. + + Takes a template, like u'{{Color|red|text=Any text}}' and translates it to a Python tuple (template_title, parameters) where parameters is a Python dictionary {u'1': u'red', u'text'=u'Any text'}. Anonymous parameters get integer keys (converted to unicode) starting with 1 like in MediaWiki, named parameters are unicode strings. Whitespace is stripped. If an unexpected format is encountered, a ValueError is raised.""" - if not template.startswith(u'{{'): raise ValueError(u'Template does not start with "{{"') - if not template.endswith(u'}}'): raise ValueError(u'Template does not end with "}}"') - parts = template[2:-2].split(u'|') - - # template name - template_title = parts[0].strip() - if len(template_title) == 0: raise ValueError(u'Empty template tilte.') - del parts[0] - - # anonymous parameters - params = {} # result dictionary - param_num = 1 - while len(parts) > 0: - equalsign_pos = parts[0].find(u'=') - if equalsign_pos >= 0: break # named parameter - params[unicode(param_num)] = parts[0].strip() - del parts[0] - param_num += 1 - - # named or numbered parameters - while len(parts) > 0: - equalsign_pos = parts[0].find(u'=') - if equalsign_pos < 0: raise ValueError(u'Anonymous parameter after named parameter.') - key, sep, value = parts[0].partition(u'=') - key = key.strip() - if len(key) == 0: raise ValueError(u'Empty key.') - if params.has_key(key): raise ValueError(u'Duplicate key: "{0}"'.format(key)) - params[key] = value.strip() - del parts[0] - - return template_title, params + try: + title, anonym_params, named_params = TemplateValidator().to_python(template) + parameters = dict(named_params) + for i in xrange(len(anonym_params)): + parameters[unicode(i+1)] = anonym_params[i] + except formencode.Invalid as e: + raise ValueError(e[0]) + return title, parameters def create_template(template_title, anonym_params=[], named_param_keys=[], named_param_values=[], as_table=False, as_table_keylen=None):