minirst: Support for admonitions
authorErik Zielke <ez@aragost.com>
Wed, 22 Sep 2010 15:51:59 +0200
changeset 12388 75f044d4dbf5
parent 12387 4f8067c94729
child 12389 4ac734b9b3fd
minirst: Support for admonitions The old asciidoc format supported something like this, this is why there is NOTE: scattered here and there.
mercurial/minirst.py
tests/test-minirst.py
tests/test-minirst.py.out
--- a/mercurial/minirst.py	Thu Sep 23 00:02:31 2010 -0500
+++ b/mercurial/minirst.py	Wed Sep 22 15:51:59 2010 +0200
@@ -24,6 +24,8 @@
 
 - definition lists
 
+- specific admonitions
+
 - bullet lists (items must start with '-')
 
 - enumerated lists (no autonumbering)
@@ -37,6 +39,8 @@
 
 import re, sys
 import util, encoding
+from i18n import _
+
 
 def replace(text, substs):
     utext = text.decode(encoding.encoding)
@@ -292,12 +296,58 @@
             i += 2
     return blocks
 
+def findadmonitions(blocks):
+    """
+    Makes the type of the block an admonition block if
+    the first line is an admonition directive
+    """
+
+    i = 0
+
+    pattern = (r"\.\. (admonition|attention|caution|danger|error|hint|"
+               r"important|note|tip|warning)::")
+
+    prog = re.compile(pattern, flags=re.IGNORECASE)
+    while i < len(blocks):
+        m = prog.match(blocks[i]['lines'][0])
+        if m:
+            blocks[i]['type'] = 'admonition'
+            admonitiontitle = blocks[i]['lines'][0][3:m.end() - 2].lower()
+
+            firstline = blocks[i]['lines'][0][m.end() + 1:]
+            if firstline != '':
+                blocks[i]['lines'].insert(1, '   ' + firstline + '')
+
+
+            blocks[i]['admonitiontitle'] = admonitiontitle
+            del blocks[i]['lines'][0]
+        i = i + 1
+    return blocks
 
 def formatblock(block, width):
     """Format a block according to width."""
     if width <= 0:
         width = 78
     indent = ' ' * block['indent']
+    if block['type'] == 'admonition':
+        titles = {'attention': _('Attention:'),
+                  'caution': _('Caution:'),
+                  'danger': _('!Danger!')  ,
+                  'error': _('Error:'),
+                  'hint': _('Hint:'),
+                  'important': _('Important:'),
+                  'note': _('Note:'),
+                  'tip': _('Tip:'),
+                  'warning': _('Warning!')}
+
+        admonition = titles[block['admonitiontitle']]
+        hang = len(block['lines'][-1]) - len(block['lines'][-1].lstrip())
+
+        defindent = indent + hang * ' '
+        text = ' '.join(map(str.strip, block['lines']))
+        return '%s\n%s' % (indent + admonition, util.wrap(text, width=width,
+                                           initindent=defindent,
+                                           hangindent=defindent))
     if block['type'] == 'margin':
         return ''
     if block['type'] == 'literal':
@@ -363,6 +413,7 @@
     blocks = splitparagraphs(blocks)
     blocks = updatefieldlists(blocks)
     blocks = addmargins(blocks)
+    blocks = findadmonitions(blocks)
     text = '\n'.join(formatblock(b, width) for b in blocks)
     if keep is None:
         return text
@@ -389,4 +440,5 @@
     blocks = debug(updatefieldlists, blocks)
     blocks = debug(findsections, blocks)
     blocks = debug(addmargins, blocks)
+    blocks = debug(findadmonitions, blocks)
     print '\n'.join(formatblock(b, 30) for b in blocks)
--- a/tests/test-minirst.py	Thu Sep 23 00:02:31 2010 -0500
+++ b/tests/test-minirst.py	Wed Sep 22 15:51:59 2010 +0200
@@ -197,3 +197,20 @@
 ------------------------------
 """
 debugformat('sections', sections, 20)
+
+
+admonitions = """
+.. note::
+   This is a note
+
+   - Bullet 1
+   - Bullet 2
+
+   .. warning:: This is a warning Second
+      input line of warning
+
+.. danger::
+   This is danger
+"""
+
+debugformat('admonitions', admonitions, 30)
--- a/tests/test-minirst.py.out	Thu Sep 23 00:02:31 2010 -0500
+++ b/tests/test-minirst.py.out	Wed Sep 22 15:51:59 2010 +0200
@@ -318,3 +318,19 @@
 ---------------------------
 ----------------------------------------------------------------------
 
+admonitions formatted to fit within 30 characters:
+----------------------------------------------------------------------
+Note:
+   This is a note
+
+   - Bullet 1
+   - Bullet 2
+
+   Warning!
+      This is a warning Second
+      input line of warning
+
+!Danger!
+   This is danger
+----------------------------------------------------------------------
+