Created to_python function of new validator TemplateValidator.
authorphilipp <philipp@7aebc617-e5e2-0310-91dc-80fb5f6d2477>
Sat, 8 Mar 2014 19:42:48 +0000 (19:42 +0000)
committerphilipp <philipp@7aebc617-e5e2-0310-91dc-80fb5f6d2477>
Sat, 8 Mar 2014 19:42:48 +0000 (19:42 +0000)
git-svn-id: http://www.winterrodeln.org/svn/wrpylib/trunk@1911 7aebc617-e5e2-0310-91dc-80fb5f6d2477

tests/test_mwmarkup.py
wrpylib/mwmarkup.py

index 456ffa69e8aae735078ceba44572d1f73f0f22e5..1f17ca54b205f1bafe07ee1d70d1419e1f4c7eaf 100644 (file)
@@ -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
index ace7362f78bd0322fa3d8eddbf6b8bb74bf6b962..2f8faea2850cf8a7a7dd42a03a2b15b460fce4b7 100644 (file)
@@ -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):