We use definition list markup for wiki dicts, but we don't parse them as we parse definition lists, but use a separate regex. If we change the markup, we have two places to change in the code.

This is an example of using the parser-formatter interface to collect a definition list. It's not small, but it can work with any markup, not only wiki markup, and when we change the markup, the wiki dicts automatically get the new features, for example, supporting multiple lines per description.

It's also probably much slower than the single re search, but we parse pages only once, then cache in the dicts cache.

Here is the dicts formatter:

   1 # It's not possible to use FormatterBase, because it implements almost
   2 # anything with raise NotImplementedError. The pagelinks formatter fixes this
   3 # problem.
   4 from MoinMoin.formatter import pagelinks
   5 
   6 class Formatter(pagelinks.Formatter):
   7     """ Collect definition lists and format nothing :-) """        
   8     
   9     def __init__(self, request, **kw):
  10         pagelinks.Formatter.__init__(self, request, **kw)
  11         self.dict = {}
  12         self.term = []
  13         self.description = []
  14         self.current = None
  15         
  16     def definition_term(self, on):
  17         if on:
  18             self.term = []
  19             self.current = 'term'
  20         else:
  21             self.current = None
  22         return self.null()
  23     
  24     def definition_desc(self, on):
  25         if on:
  26             self.description = []
  27             self.current = 'description'
  28         else:
  29             term = ' '.join(self.term)
  30             description = ' '.join(self.description)
  31             self.dict[term] = description
  32             self.current = None
  33         return self.null()
  34         
  35     def text(self, text):
  36         if self.current:
  37             text = text.strip()
  38             if text:
  39                 attr = getattr(self, self.current)
  40                 attr.append(text)
  41         return self.null()

And the patch to use it:

* looking for arch@arch.thinkmo.de--2003-archives/moin--main--1.3--patch-870 to compare with
* comparing to arch@arch.thinkmo.de--2003-archives/moin--main--1.3--patch-870
M  MoinMoin/_tests/test_wikidicts.py
M  MoinMoin/wikidicts.py

* modified files

--- orig/MoinMoin/_tests/test_wikidicts.py
+++ mod/MoinMoin/_tests/test_wikidicts.py
@@ -27,7 +27,7 @@
  * CamelCase2
 '''
         group = wikidicts.Group(self.request, '')
-        group.initFromText(text)
+        group.initFromText(self.request, text)
         members = group.members()
         members.sort()
         expected =  ['CamelCase1', 'CamelCase2', 'extended link', 'extended name']
@@ -51,7 +51,7 @@
  Last:: last item
 '''
         d = wikidicts.Dict(self.request, '')
-        d.initFromText(text)        
+        d.initFromText(self.request, text)
         self.assertEqual(d['First'], 'first item')
         self.assertEqual(d['text with spaces'], 'second item')
         self.assertEqual(d['Empty string'], '')        


--- orig/MoinMoin/wikidicts.py
+++ mod/MoinMoin/wikidicts.py
@@ -55,8 +55,9 @@
 
         # Get text from page named 'name'
         p = Page.Page(request, name)
+        request.page = p
         text = p.get_raw_body()
-        self.initFromText(text)
+        self.initFromText(request, text)
 
     def initFromText(self, text):
         raise NotImplementedError('sub classes should override this')
@@ -93,15 +94,24 @@
     # Key:: Value - ignore all but key:: value pairs, strip whitespace
     regex = r'^\s(?P<key>.+?)::\s(?P<val>.*?)\s*$'
 
-    def initFromText(self, text):
+    def initFromText(self, request, text):
         """ Create dict from keys and values in text
 
         Invoked by __init__, also useful for testing without a page.
         """
-        self._dict = {}
-        for match in self.regex.finditer(text):
-            key, val = match.groups()
-            self._dict[key] = val
+        # XXX Should import plugin here, not the built in modules
+        from MoinMoin.formatter.dicts import Formatter
+        from MoinMoin.parser.wiki import Parser
+        class Null:
+            def write(self, str): pass
+        request.redirect(Null())
+        try:
+            formatter = Formatter(request)
+            formatter.setPage(request.page)
+            Parser(text, request).format(formatter)
+        finally:
+            request.redirect()
+        self._dict = formatter.dict
     
 
 class Group(DictBase):
@@ -124,7 +134,7 @@
     # Strip free links markup if exists
     regex = r'^\s\*\s(?:\[\")?(?P<member>.+?)(?:\"\])?\s*$'
 
-    def initFromText(self, text):
+    def initFromText(self, request, text):
         """ Create dict from group members in text
 
         Invoked by __init__, also useful for testing without a page.

After this patch, all the tests run fine, and this dict markup will work just like definition list markup works:

 KEY:: Value
 Next line

We can use a similar formatter to get groups, instead of using a second list re.

MoinMoin: DictsFormatter (last edited 2008-06-09 16:13:48 by CPE-65-29-169-203)