diff mercurial/minirst.py @ 9293:e48a48b754d3

minirst: parse field lists
author Martin Geisler <mg@lazybytes.net>
date Sun, 02 Aug 2009 23:38:07 +0200
parents 01e580143423
children 4c3fb45123e5
line wrap: on
line diff
--- a/mercurial/minirst.py	Sun Aug 02 21:29:15 2009 +0200
+++ b/mercurial/minirst.py	Sun Aug 02 23:38:07 2009 +0200
@@ -22,6 +22,8 @@
 
 - lists (items must start with '-')
 
+- field lists (colons cannot be escaped)
+
 - literal blocks
 
 - option lists (supports only long options without arguments)
@@ -188,6 +190,43 @@
     return blocks
 
 
+_fieldre = re.compile(r':(?![: ])([^:]*)(?<! ):( +)(.*)')
+def findfieldlists(blocks):
+    """Finds fields lists.
+
+    The blocks must have a 'type' field, i.e., they should have been
+    run through findliteralblocks first.
+    """
+    i = 0
+    while i < len(blocks):
+        # Searching for a paragraph that looks like this:
+        #
+        #
+        # +--------------------+----------------------+
+        # | ":" field name ":" | field body           |
+        # +-------+------------+                      |
+        #         | (body elements)+                  |
+        #         +-----------------------------------+
+        if (blocks[i]['type'] == 'paragraph' and
+            _fieldre.match(blocks[i]['lines'][0])):
+            indent = blocks[i]['indent']
+            fields = []
+            for line in blocks[i]['lines']:
+                m = _fieldre.match(line)
+                if m:
+                    key, spaces, rest = m.groups()
+                    width = 2 + len(key) + len(spaces)
+                    fields.append(dict(type='field', lines=[],
+                                       indent=indent, width=width))
+                    # Turn ":foo: bar" into "foo   bar".
+                    line = '%s  %s%s' % (key, spaces, rest)
+                fields[-1]['lines'].append(line)
+            blocks[i:i+1] = fields
+            i += len(fields) - 1
+        i += 1
+    return blocks
+
+
 def finddefinitionlists(blocks):
     """Finds definition lists.
 
@@ -230,7 +269,7 @@
     i = 1
     while i < len(blocks):
         if (blocks[i]['type'] == blocks[i-1]['type'] and
-            blocks[i]['type'] in ('bullet', 'option', 'definition')):
+            blocks[i]['type'] in ('bullet', 'option', 'field', 'definition')):
             i += 1
         else:
             blocks.insert(i, dict(lines=[''], indent=0, type='margin'))
@@ -261,7 +300,7 @@
         if block['type'] == 'bullet':
             initindent = indent + '- '
             subindent = indent + '  '
-        elif block['type'] == 'option':
+        elif block['type'] in ('option', 'field'):
             subindent = indent + block['width'] * ' '
 
         return textwrap.fill(text, width=width,
@@ -276,6 +315,7 @@
     blocks = findsections(blocks)
     blocks = findbulletlists(blocks)
     blocks = findoptionlists(blocks)
+    blocks = findfieldlists(blocks)
     blocks = finddefinitionlists(blocks)
     blocks = addmargins(blocks)
     return '\n'.join(formatblock(b, width) for b in blocks)
@@ -297,6 +337,7 @@
     blocks = debug(findsections, blocks)
     blocks = debug(findbulletlists, blocks)
     blocks = debug(findoptionlists, blocks)
+    blocks = debug(findfieldlists, blocks)
     blocks = debug(finddefinitionlists, blocks)
     blocks = debug(addmargins, blocks)
     print '\n'.join(formatblock(b, 30) for b in blocks)