minirst: improved support for option lists.
authorErik Zielke <ez@aragost.com>
Tue, 02 Nov 2010 17:44:19 +0100
changeset 13011 4936a04b6792
parent 13010 6bdae8ea0b48
child 13012 8b167ee8242f
minirst: improved support for option lists. This enables minirst to parse and print option lists which have both long and short options. Before, we could only parse option lists with long options.
mercurial/minirst.py
tests/test-convert.t
tests/test-minirst.py
tests/test-minirst.py.out
--- a/mercurial/minirst.py	Tue Nov 16 13:29:35 2010 +0100
+++ b/mercurial/minirst.py	Tue Nov 02 17:44:19 2010 +0100
@@ -99,7 +99,8 @@
     return blocks
 
 _bulletre = re.compile(r'(-|[0-9A-Za-z]+\.|\(?[0-9A-Za-z]+\)|\|) ')
-_optionre = re.compile(r'^(--[a-z-]+)((?:[ =][a-zA-Z][\w-]*)?  +)(.*)$')
+_optionre = re.compile(r'^(-([a-zA-Z0-9]), )?(--[a-z0-9-]+)'
+                       r'((.*)  +)(.*)$')
 _fieldre = re.compile(r':(?![: ])([^:]*)(?<! ):[ ]+(.*)')
 _definitionre = re.compile(r'[^ ]')
 
@@ -173,6 +174,42 @@
     return blocks
 
 
+def updateoptionlists(blocks):
+    i = 0
+    while i < len(blocks):
+        if blocks[i]['type'] != 'option':
+            i += 1
+            continue
+
+        optstrwidth = 0
+        j = i
+        while j < len(blocks) and blocks[j]['type'] == 'option':
+            m = _optionre.match(blocks[j]['lines'][0])
+
+            shortoption = m.group(2)
+            group3 = m.group(3)
+            longoption = group3[2:].strip()
+            desc = m.group(6).strip()
+            longoptionarg = m.group(5).strip()
+            blocks[j]['lines'][0] = desc
+
+            noshortop = ''
+            if not shortoption:
+                noshortop = '   '
+
+            opt = "%s%s" %   (shortoption and "-%s " % shortoption or '',
+                            ("%s--%s %s") % (noshortop, longoption,
+                                             longoptionarg))
+            opt = opt.rstrip()
+            blocks[j]['optstr'] = opt
+            optstrwidth = max(optstrwidth, encoding.colwidth(opt))
+            j += 1
+
+        for block in blocks[i:j]:
+            block['optstrwidth'] = optstrwidth
+        i = j + 1
+    return blocks
+
 def prunecontainers(blocks, keep):
     """Prune unwanted containers.
 
@@ -322,6 +359,17 @@
                      'tip': _('Tip:'),
                      'warning': _('Warning!')}
 
+def formatoption(block, width):
+    desc = ' '.join(map(str.strip, block['lines']))
+    colwidth = encoding.colwidth(block['optstr'])
+    usablewidth = width - 1
+    hanging = block['optstrwidth']
+    initindent = '%s%s  ' % (block['optstr'], ' ' * ((hanging - colwidth)))
+    hangindent = ' ' * (encoding.colwidth(initindent) + 1)
+    return ' %s' % (util.wrap(desc, usablewidth,
+                                           initindent=initindent,
+                                           hangindent=hangindent))
+
 def formatblock(block, width):
     """Format a block according to width."""
     if width <= 0:
@@ -378,9 +426,7 @@
             key = key.ljust(_fieldwidth)
         block['lines'][0] = key + block['lines'][0]
     elif block['type'] == 'option':
-        m = _optionre.match(block['lines'][0])
-        option, arg, rest = m.groups()
-        subindent = indent + (len(option) + len(arg)) * ' '
+        return formatoption(block, width)
 
     text = ' '.join(map(str.strip, block['lines']))
     return util.wrap(text, width=width,
@@ -400,6 +446,7 @@
     blocks = hgrole(blocks)
     blocks = splitparagraphs(blocks)
     blocks = updatefieldlists(blocks)
+    blocks = updateoptionlists(blocks)
     blocks = addmargins(blocks)
     blocks = prunecomments(blocks)
     blocks = findadmonitions(blocks)
@@ -427,6 +474,7 @@
     blocks = debug(inlineliterals, blocks)
     blocks = debug(splitparagraphs, blocks)
     blocks = debug(updatefieldlists, blocks)
+    blocks = debug(updateoptionlists, blocks)
     blocks = debug(findsections, blocks)
     blocks = debug(addmargins, blocks)
     blocks = debug(prunecomments, blocks)
--- a/tests/test-convert.t	Tue Nov 16 13:29:35 2010 +0100
+++ b/tests/test-convert.t	Tue Nov 02 17:44:19 2010 +0100
@@ -40,8 +40,8 @@
       have the following effects:
   
       --branchsort  convert from parent to child revision when possible, which
-                    means branches are usually converted one after the other. It
-                    generates more compact repositories.
+                    means branches are usually converted one after the other.
+                    It generates more compact repositories.
       --datesort    sort revisions by date. Converted repositories have good-
                     looking changelogs but are often an order of magnitude
                     larger than the same ones generated by --branchsort.
--- a/tests/test-minirst.py	Tue Nov 16 13:29:35 2010 +0100
+++ b/tests/test-minirst.py	Tue Nov 02 17:44:19 2010 +0100
@@ -120,16 +120,19 @@
 There is support for simple option lists,
 but only with long options:
 
---all      Output all.
---both     Output both (this description is
-           quite long).
---long     Output all day long.
+-X, --exclude  filter  an option with a short and long option with an argument
+-I, --include          an option with both a short option and a long option
+--all                  Output all.
+--both                 Output both (this description is
+                       quite long).
+--long                 Output all day long.
 
---par      This option has two paragraphs in its description.
-           This is the first.
+--par                 This option has two paragraphs in its description.
+                      This is the first.
 
-           This is the second.  Blank lines may be omitted between
-           options (as above) or left in (as here).
+                      This is the second.  Blank lines may be omitted between
+                      options (as above) or left in (as here).
+
 
 The next paragraph looks like an option list, but lacks the two-space
 marker after the option. It is treated as a normal paragraph:
--- a/tests/test-minirst.py.out	Tue Nov 16 13:29:35 2010 +0100
+++ b/tests/test-minirst.py.out	Tue Nov 02 17:44:19 2010 +0100
@@ -180,14 +180,20 @@
 There is support for simple option lists, but only with long
 options:
 
---all      Output all.
---both     Output both (this description is quite long).
---long     Output all day long.
---par      This option has two paragraphs in its
-           description. This is the first.
+ -X --exclude filter  an option with a short and long option
+                      with an argument
+ -I --include         an option with both a short option and
+                      a long option
+    --all             Output all.
+    --both            Output both (this description is quite
+                      long).
+    --long            Output all day long.
+    --par             This option has two paragraphs in its
+                      description. This is the first.
 
-           This is the second.  Blank lines may be omitted
-           between options (as above) or left in (as here).
+                      This is the second.  Blank lines may
+                      be omitted between options (as above)
+                      or left in (as here).
 
 The next paragraph looks like an option list, but lacks the
 two-space marker after the option. It is treated as a normal
@@ -202,23 +208,62 @@
 option lists, but only with
 long options:
 
---all      Output all.
---both     Output both (this
-           description is
-           quite long).
---long     Output all day
-           long.
---par      This option has two
-           paragraphs in its
-           description. This
-           is the first.
+ -X --exclude filter  an
+                      option
+                      with a
+                      short
+                      and
+                      long
+                      option
+                      with an
+                      argumen
+                      t
+ -I --include         an
+                      option
+                      with
+                      both a
+                      short
+                      option
+                      and a
+                      long
+                      option
+    --all             Output
+                      all.
+    --both            Output
+                      both
+                      (this d
+                      escript
+                      ion is
+                      quite
+                      long).
+    --long            Output
+                      all day
+                      long.
+    --par             This
+                      option
+                      has two
+                      paragra
+                      phs in
+                      its des
+                      criptio
+                      n. This
+                      is the
+                      first.
 
-           This is the second.
-           Blank lines may be
-           omitted between
-           options (as above)
-           or left in (as
-           here).
+                      This is
+                      the
+                      second.
+                      Blank
+                      lines
+                      may be
+                      omitted
+                      between
+                      options
+                      (as
+                      above)
+                      or left
+                      in (as
+                      here).
 
 The next paragraph looks like
 an option list, but lacks the