The googlemap extension tag is googlemap, not googlemaps.
[philipp/winterrodeln/wrpylib.git] / wrpylib / mwmarkup.py
index 88f8add9c055cc1af1a5197224439be0e41e51c2..30b2f654fa4236190a17fb3b631a116a2c304365 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python2.6
+#!/usr/bin/python2.7
 # -*- coding: iso-8859-15 -*-
 # $Id$
 # $HeadURL$
@@ -28,7 +28,8 @@ def find_template(wikitext, template_title):
     >>> print wikitext.__getslice__(*find_template(wikitext, u'Color'))
     {{Color|red|red text}}
 
-    The search is done with regular expression.
+    The search is done with regular expression. It gives wrong results when parsing a template
+    containing the characters "}}"
 
     :param wikitext: The text (preferalbe unicode) that has the template in it.
     :param template_title: The page title of the template with or without namespace (but as in the wikitext).
@@ -36,15 +37,14 @@ def find_template(wikitext, template_title):
         (start, end) of the first occurence with start >= 0 and end > start.
         (None, None) if the template is not found.
     """ 
-    match = re.search(u"\{\{" + template_title + "[^\}]*\}\}", wikitext,  re.DOTALL)
+    match = re.search(u"\{\{" + template_title + "\s*(\|[^\}]*)?\}\}", wikitext,  re.DOTALL)
     if match is None: return None, None
     return match.start(), match.end()
 
 
-
 def split_template(template):
     """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 {1: u'red', u'text'=u'Any text'}.
+    (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.
@@ -98,17 +98,22 @@ def create_template(template_title, anonym_params=[], named_param_keys=[], named
         as_table_keylen = max([len(k) for k in named_param_keys])
     for i in xrange(len(named_param_keys)):
         key = named_param_keys[i]
-        if as_table: key = key.ljust(as_table_keylen)
-        parts.append(key + equal_char + named_param_values[i])
+        if as_table: 
+            key = key.ljust(as_table_keylen)
+            parts.append((key + equal_char + named_param_values[i]).rstrip())
+        else:
+            parts.append(key + equal_char + named_param_values[i])
     return pipe_char.join(parts) + end_char
 
 
-def parse_googlemap(wikitext):
+def parse_googlemap(wikitext, detail=False):
     """Parses the (unicode) u'<googlemap ...>content</googlemap>' of the googlemap extension
-    out of a page. If wikitext does not contain the googlemaps extension text None is returned.
+    out of a page. If wikitext does not contain the googlemap extension text None is returned.
     If the googlemap contains invalid formatted lines, a RuntimeError is raised.
 
     :param wikitext: wikitext containing the template. Example:
+    :param detail: bool. If True, start and end position of <googlemap>...</googlemap> is
+        returned additionally.
 
     wikitext = '''
     <googlemap version="0.9" lat="47.113291" lon="11.272337" zoom="15">
@@ -129,7 +134,8 @@ def parse_googlemap(wikitext):
         zoom is the google zoom level as integer or None if not provided
         coords is a list of (lon, lat, symbol, title) tuples.
         paths is a list of (style, coords) tuples.
-        coords is again a list of (lot, lat, symbol, title) tuples."""
+        coords is again a list of (lot, lat, symbol, title) tuples.
+        If detail is True, (center, zoom, coords, paths, start, end) is returned."""
 
     def is_coord(line):
         """Returns True if the line contains a coordinate."""
@@ -143,19 +149,21 @@ def parse_googlemap(wikitext):
 
     def parse_coord(line):
         """Returns (lon, lat, symbol, title). If symbol or text is not present, None is returned."""
-        match = re.match(u'\(([^)]+)\) ?([0-9]{1,2}\.[0-9]+), ?([0-9]{1,2}\.[0-9]+),(.*)', line)
+        match = re.match(u'\(([^)]+)\) ?([0-9]{1,2}\.[0-9]+), ?([0-9]{1,2}\.[0-9]+), ?(.*)', line)
         if not match is None: return (float(match.group(3)), float(match.group(2)), match.group(1), match.group(4))
         match = re.match(u'\(([^)]+)\) ?([0-9]{1,2}\.[0-9]+), ?([0-9]{1,2}\.[0-9]+)', line)
         if not match is None: return (float(match.group(3)), float(match.group(2)), match.group(1), None)
-        match = re.match(u'([0-9]{1,2}\.[0-9]+), ?([0-9]{1,2}\.[0-9]+),(.*)', line)
+        match = re.match(u'([0-9]{1,2}\.[0-9]+), ?([0-9]{1,2}\.[0-9]+), ?(.*)', line)
         if not match is None: return (float(match.group(2)), float(match.group(1)), None, match.group(3))
         match = re.match(u'([0-9]{1,2}\.[0-9]+), ?([0-9]{1,2}\.[0-9]+)', line)
         if not match is None: return (float(match.group(2)), float(match.group(1)), None, None)
         return RuntimeError(u'Could not parse line ' + line)
 
-    regexp = re.compile(u"(<googlemap[^>]*>)(.*)(</googlemap>)", re.DOTALL)
+    regexp = re.compile(u"(<googlemap[^>]*>)(.*?)(</googlemap>)", re.DOTALL)
     match = regexp.search(wikitext)
     if match is None: return None
+    start = match.start()
+    end = match.end()
     content = match.group(2)
     gm = xml.etree.ElementTree.XML((match.group(1)+match.group(3)).encode('UTF8'))
     zoom = gm.get('zoom')
@@ -197,15 +205,18 @@ def parse_googlemap(wikitext):
         # Handle a coordinate
         if is_coord(line):
             lon, lat, symbol, title = parse_coord(line)
-            coords.append((lon, lat, symbol, title))
             while i < len(lines):
                 line = lines[i].strip()
                 i += 1
                 if is_path(line) or is_coord(line):
                     i -= 1
                     break
+                if len(line) > 0 and title is None: title = line
+            coords.append((lon, lat, symbol, title))
             continue
 
         raise RuntimeError(u'Unknown line syntax: ' + line)
+    if detail:
+        return (center, zoom, coords, paths, start, end)
     return (center, zoom, coords, paths)