mercurial/minirst.py
author FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
Thu, 25 Dec 2014 23:33:26 +0900
changeset 23683 5edb387158a1
parent 22770 de9424647fe4
child 25723 2a8d8b4097c8
permissions -rw-r--r--
posix: quote the specified string only when it may have to be quoted This patch makes "posix.shellquote" examine the specified string and quote it only when it may have to be quoted for safety, like as the previous patch for "windows.shellquote". In fact, on POSIX environment, quoting itself doesn't cause issues like issue4463. But (almost) equivalent quoting policy can avoid examining test result differently on POSIX and Windows (even though showing command line with "%r" causes such examination in "test-extdiff.t"). The last hunk for "test-extdiff.t" in this patch isn't needed for the previous patch for "windows.shellquote", because the code path of it is executed only "#if execbit" (= avoided on Windows).
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
     1
# minirst.py - minimal reStructuredText parser
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
     2
#
10443
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
     3
# Copyright 2009, 2010 Matt Mackall <mpm@selenic.com> and others
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
     4
#
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9741
diff changeset
     6
# GNU General Public License version 2 or any later version.
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
     7
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
     8
"""simplified reStructuredText parser.
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
     9
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    10
This parser knows just enough about reStructuredText to parse the
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    11
Mercurial docstrings.
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    12
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    13
It cheats in a major way: nested blocks are not really nested. They
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    14
are just indented blocks that look like they are nested. This relies
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    15
on the user to keep the right indentation for the blocks.
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    16
12958
8957c39867f6 minirst: link to HelpStyleGuide in docstring
Martin Geisler <mg@aragost.com>
parents: 12867
diff changeset
    17
Remember to update http://mercurial.selenic.com/wiki/HelpStyleGuide
8957c39867f6 minirst: link to HelpStyleGuide in docstring
Martin Geisler <mg@aragost.com>
parents: 12867
diff changeset
    18
when adding support for new constructs.
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    19
"""
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    20
15038
3f4d337cb80a minirst: drop debug code
Matt Mackall <mpm@selenic.com>
parents: 15037
diff changeset
    21
import re
11464
521c8e0c93bf minirst: use unicode string as intermediate form for replacement
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 11297
diff changeset
    22
import util, encoding
12388
75f044d4dbf5 minirst: Support for admonitions
Erik Zielke <ez@aragost.com>
parents: 11464
diff changeset
    23
from i18n import _
75f044d4dbf5 minirst: Support for admonitions
Erik Zielke <ez@aragost.com>
parents: 11464
diff changeset
    24
18750
c9d923f5d8ae minirst: CGI escape strings prior to embedding it in the HTML
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18749
diff changeset
    25
import cgi
c9d923f5d8ae minirst: CGI escape strings prior to embedding it in the HTML
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18749
diff changeset
    26
18748
6e676fb6ea44 help: use a full header for topic titles
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 17424
diff changeset
    27
def section(s):
6e676fb6ea44 help: use a full header for topic titles
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 17424
diff changeset
    28
    return "%s\n%s\n\n" % (s, "\"" * encoding.colwidth(s))
6e676fb6ea44 help: use a full header for topic titles
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 17424
diff changeset
    29
6e676fb6ea44 help: use a full header for topic titles
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 17424
diff changeset
    30
def subsection(s):
6e676fb6ea44 help: use a full header for topic titles
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 17424
diff changeset
    31
    return "%s\n%s\n\n" % (s, '=' * encoding.colwidth(s))
6e676fb6ea44 help: use a full header for topic titles
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 17424
diff changeset
    32
6e676fb6ea44 help: use a full header for topic titles
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 17424
diff changeset
    33
def subsubsection(s):
6e676fb6ea44 help: use a full header for topic titles
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 17424
diff changeset
    34
    return "%s\n%s\n\n" % (s, "-" * encoding.colwidth(s))
6e676fb6ea44 help: use a full header for topic titles
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 17424
diff changeset
    35
6e676fb6ea44 help: use a full header for topic titles
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 17424
diff changeset
    36
def subsubsubsection(s):
6e676fb6ea44 help: use a full header for topic titles
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 17424
diff changeset
    37
    return "%s\n%s\n\n" % (s, "." * encoding.colwidth(s))
6e676fb6ea44 help: use a full header for topic titles
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 17424
diff changeset
    38
11464
521c8e0c93bf minirst: use unicode string as intermediate form for replacement
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 11297
diff changeset
    39
def replace(text, substs):
15393
87bb6b7644f6 minirst: use unicode string as intermediate form for replacement
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15262
diff changeset
    40
    '''
87bb6b7644f6 minirst: use unicode string as intermediate form for replacement
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15262
diff changeset
    41
    Apply a list of (find, replace) pairs to a text.
87bb6b7644f6 minirst: use unicode string as intermediate form for replacement
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15262
diff changeset
    42
87bb6b7644f6 minirst: use unicode string as intermediate form for replacement
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15262
diff changeset
    43
    >>> replace("foo bar", [('f', 'F'), ('b', 'B')])
87bb6b7644f6 minirst: use unicode string as intermediate form for replacement
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15262
diff changeset
    44
    'Foo Bar'
87bb6b7644f6 minirst: use unicode string as intermediate form for replacement
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15262
diff changeset
    45
    >>> encoding.encoding = 'latin1'
87bb6b7644f6 minirst: use unicode string as intermediate form for replacement
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15262
diff changeset
    46
    >>> replace('\\x81\\\\', [('\\\\', '/')])
87bb6b7644f6 minirst: use unicode string as intermediate form for replacement
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15262
diff changeset
    47
    '\\x81/'
87bb6b7644f6 minirst: use unicode string as intermediate form for replacement
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15262
diff changeset
    48
    >>> encoding.encoding = 'shiftjis'
87bb6b7644f6 minirst: use unicode string as intermediate form for replacement
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15262
diff changeset
    49
    >>> replace('\\x81\\\\', [('\\\\', '/')])
87bb6b7644f6 minirst: use unicode string as intermediate form for replacement
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15262
diff changeset
    50
    '\\x81\\\\'
87bb6b7644f6 minirst: use unicode string as intermediate form for replacement
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15262
diff changeset
    51
    '''
87bb6b7644f6 minirst: use unicode string as intermediate form for replacement
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15262
diff changeset
    52
87bb6b7644f6 minirst: use unicode string as intermediate form for replacement
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15262
diff changeset
    53
    # some character encodings (cp932 for Japanese, at least) use
87bb6b7644f6 minirst: use unicode string as intermediate form for replacement
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15262
diff changeset
    54
    # ASCII characters other than control/alphabet/digit as a part of
87bb6b7644f6 minirst: use unicode string as intermediate form for replacement
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15262
diff changeset
    55
    # multi-bytes characters, so direct replacing with such characters
87bb6b7644f6 minirst: use unicode string as intermediate form for replacement
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15262
diff changeset
    56
    # on strings in local encoding causes invalid byte sequences.
87bb6b7644f6 minirst: use unicode string as intermediate form for replacement
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15262
diff changeset
    57
    utext = text.decode(encoding.encoding)
11464
521c8e0c93bf minirst: use unicode string as intermediate form for replacement
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 11297
diff changeset
    58
    for f, t in substs:
21745
4c62478be2ea minirst: explicitly decode substitutions
Matt Mackall <mpm@selenic.com>
parents: 20682
diff changeset
    59
        utext = utext.replace(f.decode("ascii"), t.decode("ascii"))
15393
87bb6b7644f6 minirst: use unicode string as intermediate form for replacement
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15262
diff changeset
    60
    return utext.encode(encoding.encoding)
12651
17f28de168a4 minirst: refactor/simplify findblocks
Martin Geisler <mg@lazybytes.net>
parents: 12620
diff changeset
    61
17f28de168a4 minirst: refactor/simplify findblocks
Martin Geisler <mg@lazybytes.net>
parents: 12620
diff changeset
    62
_blockre = re.compile(r"\n(?:\s*\n)+")
17f28de168a4 minirst: refactor/simplify findblocks
Martin Geisler <mg@lazybytes.net>
parents: 12620
diff changeset
    63
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    64
def findblocks(text):
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    65
    """Find continuous blocks of lines in text.
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    66
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    67
    Returns a list of dictionaries representing the blocks. Each block
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    68
    has an 'indent' field and a 'lines' field.
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    69
    """
12651
17f28de168a4 minirst: refactor/simplify findblocks
Martin Geisler <mg@lazybytes.net>
parents: 12620
diff changeset
    70
    blocks = []
15036
bb96e12a3242 minirst: only strip leading newlines, not indentation
Matt Mackall <mpm@selenic.com>
parents: 15015
diff changeset
    71
    for b in _blockre.split(text.lstrip('\n').rstrip()):
12651
17f28de168a4 minirst: refactor/simplify findblocks
Martin Geisler <mg@lazybytes.net>
parents: 12620
diff changeset
    72
        lines = b.splitlines()
15123
9b41ccb2043e minirst: don't choke on empty text
Matt Mackall <mpm@selenic.com>
parents: 15122
diff changeset
    73
        if lines:
9b41ccb2043e minirst: don't choke on empty text
Matt Mackall <mpm@selenic.com>
parents: 15122
diff changeset
    74
            indent = min((len(l) - len(l.lstrip())) for l in lines)
9b41ccb2043e minirst: don't choke on empty text
Matt Mackall <mpm@selenic.com>
parents: 15122
diff changeset
    75
            lines = [l[indent:] for l in lines]
20682
7f8cbaaa8eea minirst: move from dict() construction to {} literals
Augie Fackler <raf@durin42.com>
parents: 20654
diff changeset
    76
            blocks.append({'indent': indent, 'lines': lines})
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    77
    return blocks
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    78
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    79
def findliteralblocks(blocks):
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    80
    """Finds literal blocks and adds a 'type' field to the blocks.
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    81
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    82
    Literal blocks are given the type 'literal', all other blocks are
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    83
    given type the 'paragraph'.
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    84
    """
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    85
    i = 0
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    86
    while i < len(blocks):
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    87
        # Searching for a block that looks like this:
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    88
        #
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    89
        # +------------------------------+
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    90
        # | paragraph                    |
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    91
        # | (ends with "::")             |
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    92
        # +------------------------------+
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    93
        #    +---------------------------+
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    94
        #    | indented literal block    |
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    95
        #    +---------------------------+
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    96
        blocks[i]['type'] = 'paragraph'
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
    97
        if blocks[i]['lines'][-1].endswith('::') and i + 1 < len(blocks):
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
    98
            indent = blocks[i]['indent']
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
    99
            adjustment = blocks[i + 1]['indent'] - indent
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   100
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   101
            if blocks[i]['lines'] == ['::']:
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   102
                # Expanded form: remove block
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   103
                del blocks[i]
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   104
                i -= 1
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   105
            elif blocks[i]['lines'][-1].endswith(' ::'):
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   106
                # Partially minimized form: remove space and both
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   107
                # colons.
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   108
                blocks[i]['lines'][-1] = blocks[i]['lines'][-1][:-3]
19992
8ac7b85bd8f9 minirst: do not interpret a directive as a literal block
Simon Heimberg <simohe@besonet.ch>
parents: 18752
diff changeset
   109
            elif len(blocks[i]['lines']) == 1 and \
8ac7b85bd8f9 minirst: do not interpret a directive as a literal block
Simon Heimberg <simohe@besonet.ch>
parents: 18752
diff changeset
   110
                 blocks[i]['lines'][0].lstrip(' ').startswith('.. ') and \
8ac7b85bd8f9 minirst: do not interpret a directive as a literal block
Simon Heimberg <simohe@besonet.ch>
parents: 18752
diff changeset
   111
                 blocks[i]['lines'][0].find(' ', 3) == -1:
20549
2025315cfb0c comments: fix minor spelling issues found with spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 19995
diff changeset
   112
                # directive on its own line, not a literal block
19992
8ac7b85bd8f9 minirst: do not interpret a directive as a literal block
Simon Heimberg <simohe@besonet.ch>
parents: 18752
diff changeset
   113
                i += 1
8ac7b85bd8f9 minirst: do not interpret a directive as a literal block
Simon Heimberg <simohe@besonet.ch>
parents: 18752
diff changeset
   114
                continue
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   115
            else:
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   116
                # Fully minimized form: remove just one colon.
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   117
                blocks[i]['lines'][-1] = blocks[i]['lines'][-1][:-1]
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   118
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   119
            # List items are formatted with a hanging indent. We must
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   120
            # correct for this here while we still have the original
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   121
            # information on the indentation of the subsequent literal
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   122
            # blocks available.
9738
f52c4f7a4732 minirst: prepare for general types of bullet lists
Martin Geisler <mg@lazybytes.net>
parents: 9737
diff changeset
   123
            m = _bulletre.match(blocks[i]['lines'][0])
f52c4f7a4732 minirst: prepare for general types of bullet lists
Martin Geisler <mg@lazybytes.net>
parents: 9737
diff changeset
   124
            if m:
f52c4f7a4732 minirst: prepare for general types of bullet lists
Martin Geisler <mg@lazybytes.net>
parents: 9737
diff changeset
   125
                indent += m.end()
f52c4f7a4732 minirst: prepare for general types of bullet lists
Martin Geisler <mg@lazybytes.net>
parents: 9737
diff changeset
   126
                adjustment -= m.end()
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   127
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   128
            # Mark the following indented blocks.
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   129
            while i + 1 < len(blocks) and blocks[i + 1]['indent'] > indent:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   130
                blocks[i + 1]['type'] = 'literal'
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   131
                blocks[i + 1]['indent'] -= adjustment
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   132
                i += 1
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   133
        i += 1
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   134
    return blocks
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   135
10447
e957cc7cbd14 minirst: support line blocks
Martin Geisler <mg@lazybytes.net>
parents: 10444
diff changeset
   136
_bulletre = re.compile(r'(-|[0-9A-Za-z]+\.|\(?[0-9A-Za-z]+\)|\|) ')
13011
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   137
_optionre = re.compile(r'^(-([a-zA-Z0-9]), )?(--[a-z0-9-]+)'
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   138
                       r'((.*)  +)(.*)$')
10065
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   139
_fieldre = re.compile(r':(?![: ])([^:]*)(?<! ):[ ]+(.*)')
9737
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   140
_definitionre = re.compile(r'[^ ]')
15037
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   141
_tablere = re.compile(r'(=+\s+)*=+')
9737
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   142
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   143
def splitparagraphs(blocks):
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   144
    """Split paragraphs into lists."""
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   145
    # Tuples with (list type, item regexp, single line items?). Order
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   146
    # matters: definition lists has the least specific regexp and must
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   147
    # come last.
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   148
    listtypes = [('bullet', _bulletre, True),
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   149
                 ('option', _optionre, True),
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   150
                 ('field', _fieldre, True),
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   151
                 ('definition', _definitionre, False)]
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   152
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   153
    def match(lines, i, itemre, singleline):
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   154
        """Does itemre match an item at line i?
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   155
17424
e7cfe3587ea4 fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents: 16815
diff changeset
   156
        A list item can be followed by an indented line or another list
9737
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   157
        item (but only if singleline is True).
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   158
        """
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   159
        line1 = lines[i]
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   160
        line2 = i + 1 < len(lines) and lines[i + 1] or ''
9737
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   161
        if not itemre.match(line1):
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   162
            return False
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   163
        if singleline:
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   164
            return line2 == '' or line2[0] == ' ' or itemre.match(line2)
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   165
        else:
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   166
            return line2.startswith(' ')
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   167
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   168
    i = 0
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   169
    while i < len(blocks):
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   170
        if blocks[i]['type'] == 'paragraph':
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   171
            lines = blocks[i]['lines']
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   172
            for type, itemre, singleline in listtypes:
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   173
                if match(lines, 0, itemre, singleline):
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   174
                    items = []
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   175
                    for j, line in enumerate(lines):
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   176
                        if match(lines, j, itemre, singleline):
20682
7f8cbaaa8eea minirst: move from dict() construction to {} literals
Augie Fackler <raf@durin42.com>
parents: 20654
diff changeset
   177
                            items.append({'type': type, 'lines': [],
7f8cbaaa8eea minirst: move from dict() construction to {} literals
Augie Fackler <raf@durin42.com>
parents: 20654
diff changeset
   178
                                          'indent': blocks[i]['indent']})
9737
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   179
                        items[-1]['lines'].append(line)
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   180
                    blocks[i:i + 1] = items
9737
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   181
                    break
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   182
        i += 1
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   183
    return blocks
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   184
15861
ee8f5e4ce7b8 minirst: simplify and standardize field list formatting
Olav Reinert <seroton10@gmail.com>
parents: 15393
diff changeset
   185
_fieldwidth = 14
10065
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   186
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   187
def updatefieldlists(blocks):
15861
ee8f5e4ce7b8 minirst: simplify and standardize field list formatting
Olav Reinert <seroton10@gmail.com>
parents: 15393
diff changeset
   188
    """Find key for field lists."""
10065
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   189
    i = 0
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   190
    while i < len(blocks):
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   191
        if blocks[i]['type'] != 'field':
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   192
            i += 1
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   193
            continue
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   194
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   195
        j = i
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   196
        while j < len(blocks) and blocks[j]['type'] == 'field':
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   197
            m = _fieldre.match(blocks[j]['lines'][0])
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   198
            key, rest = m.groups()
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   199
            blocks[j]['lines'][0] = rest
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   200
            blocks[j]['key'] = key
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   201
            j += 1
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   202
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   203
        i = j + 1
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   204
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   205
    return blocks
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   206
13011
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   207
def updateoptionlists(blocks):
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   208
    i = 0
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   209
    while i < len(blocks):
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   210
        if blocks[i]['type'] != 'option':
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   211
            i += 1
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   212
            continue
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   213
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   214
        optstrwidth = 0
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   215
        j = i
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   216
        while j < len(blocks) and blocks[j]['type'] == 'option':
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   217
            m = _optionre.match(blocks[j]['lines'][0])
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   218
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   219
            shortoption = m.group(2)
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   220
            group3 = m.group(3)
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   221
            longoption = group3[2:].strip()
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   222
            desc = m.group(6).strip()
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   223
            longoptionarg = m.group(5).strip()
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   224
            blocks[j]['lines'][0] = desc
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   225
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   226
            noshortop = ''
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   227
            if not shortoption:
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   228
                noshortop = '   '
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   229
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   230
            opt = "%s%s" %   (shortoption and "-%s " % shortoption or '',
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   231
                            ("%s--%s %s") % (noshortop, longoption,
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   232
                                             longoptionarg))
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   233
            opt = opt.rstrip()
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   234
            blocks[j]['optstr'] = opt
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   235
            optstrwidth = max(optstrwidth, encoding.colwidth(opt))
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   236
            j += 1
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   237
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   238
        for block in blocks[i:j]:
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   239
            block['optstrwidth'] = optstrwidth
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   240
        i = j + 1
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   241
    return blocks
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   242
10443
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   243
def prunecontainers(blocks, keep):
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   244
    """Prune unwanted containers.
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   245
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   246
    The blocks must have a 'type' field, i.e., they should have been
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   247
    run through findliteralblocks first.
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   248
    """
10444
e99e0e077bc4 minirst: report pruned container types
Martin Geisler <mg@lazybytes.net>
parents: 10443
diff changeset
   249
    pruned = []
10443
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   250
    i = 0
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   251
    while i + 1 < len(blocks):
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   252
        # Searching for a block that looks like this:
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   253
        #
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   254
        # +-------+---------------------------+
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   255
        # | ".. container ::" type            |
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   256
        # +---+                               |
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   257
        #     | blocks                        |
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   258
        #     +-------------------------------+
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   259
        if (blocks[i]['type'] == 'paragraph' and
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   260
            blocks[i]['lines'][0].startswith('.. container::')):
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   261
            indent = blocks[i]['indent']
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   262
            adjustment = blocks[i + 1]['indent'] - indent
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   263
            containertype = blocks[i]['lines'][0][15:]
22584
19bd8bda6bb2 minirst: allow multiple container types for prune
Matt Mackall <mpm@selenic.com>
parents: 21745
diff changeset
   264
            prune = True
19bd8bda6bb2 minirst: allow multiple container types for prune
Matt Mackall <mpm@selenic.com>
parents: 21745
diff changeset
   265
            for c in keep:
19bd8bda6bb2 minirst: allow multiple container types for prune
Matt Mackall <mpm@selenic.com>
parents: 21745
diff changeset
   266
                if c in containertype.split('.'):
19bd8bda6bb2 minirst: allow multiple container types for prune
Matt Mackall <mpm@selenic.com>
parents: 21745
diff changeset
   267
                    prune = False
10444
e99e0e077bc4 minirst: report pruned container types
Martin Geisler <mg@lazybytes.net>
parents: 10443
diff changeset
   268
            if prune:
e99e0e077bc4 minirst: report pruned container types
Martin Geisler <mg@lazybytes.net>
parents: 10443
diff changeset
   269
                pruned.append(containertype)
10443
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   270
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   271
            # Always delete "..container:: type" block
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   272
            del blocks[i]
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   273
            j = i
15102
a7e375d087f6 minirst: fix container stripping logic
Matt Mackall <mpm@selenic.com>
parents: 15039
diff changeset
   274
            i -= 1
10443
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   275
            while j < len(blocks) and blocks[j]['indent'] > indent:
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   276
                if prune:
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   277
                    del blocks[j]
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   278
                else:
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   279
                    blocks[j]['indent'] -= adjustment
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   280
                    j += 1
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   281
        i += 1
10444
e99e0e077bc4 minirst: report pruned container types
Martin Geisler <mg@lazybytes.net>
parents: 10443
diff changeset
   282
    return blocks, pruned
10443
62d484a81dfe minirst: support containers
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   283
10984
68b7d2d668ce minirst: support all recommended title adornments
Martin Geisler <mg@lazybytes.net>
parents: 10983
diff changeset
   284
_sectionre = re.compile(r"""^([-=`:.'"~^_*+#])\1+$""")
68b7d2d668ce minirst: support all recommended title adornments
Martin Geisler <mg@lazybytes.net>
parents: 10983
diff changeset
   285
15037
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   286
def findtables(blocks):
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   287
    '''Find simple tables
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   288
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   289
       Only simple one-line table elements are supported
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   290
    '''
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   291
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   292
    for block in blocks:
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   293
        # Searching for a block that looks like this:
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   294
        #
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   295
        # === ==== ===
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   296
        #  A    B   C
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   297
        # === ==== ===  <- optional
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   298
        #  1    2   3
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   299
        #  x    y   z
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   300
        # === ==== ===
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   301
        if (block['type'] == 'paragraph' and
15192
3834ca04664a rst: fix detection of single-row tables
Matt Mackall <mpm@selenic.com>
parents: 15145
diff changeset
   302
            len(block['lines']) > 2 and
15037
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   303
            _tablere.match(block['lines'][0]) and
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   304
            block['lines'][0] == block['lines'][-1]):
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   305
            block['type'] = 'table'
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   306
            block['header'] = False
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   307
            div = block['lines'][0]
15144
87bb975a1844 minirst: fix column handling for simple tables
Matt Mackall <mpm@selenic.com>
parents: 15125
diff changeset
   308
87bb975a1844 minirst: fix column handling for simple tables
Matt Mackall <mpm@selenic.com>
parents: 15125
diff changeset
   309
            # column markers are ASCII so we can calculate column
87bb975a1844 minirst: fix column handling for simple tables
Matt Mackall <mpm@selenic.com>
parents: 15125
diff changeset
   310
            # position in bytes
15037
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   311
            columns = [x for x in xrange(len(div))
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   312
                       if div[x] == '=' and (x == 0 or div[x - 1] == ' ')]
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   313
            rows = []
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   314
            for l in block['lines'][1:-1]:
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   315
                if l == div:
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   316
                    block['header'] = True
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   317
                    continue
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   318
                row = []
15144
87bb975a1844 minirst: fix column handling for simple tables
Matt Mackall <mpm@selenic.com>
parents: 15125
diff changeset
   319
                # we measure columns not in bytes or characters but in
87bb975a1844 minirst: fix column handling for simple tables
Matt Mackall <mpm@selenic.com>
parents: 15125
diff changeset
   320
                # colwidth which makes things tricky
87bb975a1844 minirst: fix column handling for simple tables
Matt Mackall <mpm@selenic.com>
parents: 15125
diff changeset
   321
                pos = columns[0] # leading whitespace is bytes
15037
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   322
                for n, start in enumerate(columns):
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   323
                    if n + 1 < len(columns):
15144
87bb975a1844 minirst: fix column handling for simple tables
Matt Mackall <mpm@selenic.com>
parents: 15125
diff changeset
   324
                        width = columns[n + 1] - start
87bb975a1844 minirst: fix column handling for simple tables
Matt Mackall <mpm@selenic.com>
parents: 15125
diff changeset
   325
                        v = encoding.getcols(l, pos, width) # gather columns
87bb975a1844 minirst: fix column handling for simple tables
Matt Mackall <mpm@selenic.com>
parents: 15125
diff changeset
   326
                        pos += len(v) # calculate byte position of end
87bb975a1844 minirst: fix column handling for simple tables
Matt Mackall <mpm@selenic.com>
parents: 15125
diff changeset
   327
                        row.append(v.strip())
15037
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   328
                    else:
15144
87bb975a1844 minirst: fix column handling for simple tables
Matt Mackall <mpm@selenic.com>
parents: 15125
diff changeset
   329
                        row.append(l[pos:].strip())
15037
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   330
                rows.append(row)
15144
87bb975a1844 minirst: fix column handling for simple tables
Matt Mackall <mpm@selenic.com>
parents: 15125
diff changeset
   331
15037
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   332
            block['table'] = rows
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   333
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   334
    return blocks
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   335
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   336
def findsections(blocks):
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   337
    """Finds sections.
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   338
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   339
    The blocks must have a 'type' field, i.e., they should have been
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   340
    run through findliteralblocks first.
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   341
    """
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   342
    for block in blocks:
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   343
        # Searching for a block that looks like this:
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   344
        #
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   345
        # +------------------------------+
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   346
        # | Section title                |
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   347
        # | -------------                |
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   348
        # +------------------------------+
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   349
        if (block['type'] == 'paragraph' and
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   350
            len(block['lines']) == 2 and
12867
eda77c3e246a minirst: use colwidth to match title lengths (issue2455)
Matt Mackall <mpm@selenic.com>
parents: 12819
diff changeset
   351
            encoding.colwidth(block['lines'][0]) == len(block['lines'][1]) and
10984
68b7d2d668ce minirst: support all recommended title adornments
Martin Geisler <mg@lazybytes.net>
parents: 10983
diff changeset
   352
            _sectionre.match(block['lines'][1])):
10983
287a5cdf7743 minirst: correctly format sections containing inline markup
Martin Geisler <mg@lazybytes.net>
parents: 10972
diff changeset
   353
            block['underline'] = block['lines'][1][0]
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   354
            block['type'] = 'section'
10983
287a5cdf7743 minirst: correctly format sections containing inline markup
Martin Geisler <mg@lazybytes.net>
parents: 10972
diff changeset
   355
            del block['lines'][1]
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   356
    return blocks
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   357
9623
32727ce029de minirst: convert ``foo`` into "foo" upon display
Martin Geisler <mg@lazybytes.net>
parents: 9540
diff changeset
   358
def inlineliterals(blocks):
11464
521c8e0c93bf minirst: use unicode string as intermediate form for replacement
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 11297
diff changeset
   359
    substs = [('``', '"')]
9623
32727ce029de minirst: convert ``foo`` into "foo" upon display
Martin Geisler <mg@lazybytes.net>
parents: 9540
diff changeset
   360
    for b in blocks:
10983
287a5cdf7743 minirst: correctly format sections containing inline markup
Martin Geisler <mg@lazybytes.net>
parents: 10972
diff changeset
   361
        if b['type'] in ('paragraph', 'section'):
11464
521c8e0c93bf minirst: use unicode string as intermediate form for replacement
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 11297
diff changeset
   362
            b['lines'] = [replace(l, substs) for l in b['lines']]
9623
32727ce029de minirst: convert ``foo`` into "foo" upon display
Martin Geisler <mg@lazybytes.net>
parents: 9540
diff changeset
   363
    return blocks
32727ce029de minirst: convert ``foo`` into "foo" upon display
Martin Geisler <mg@lazybytes.net>
parents: 9540
diff changeset
   364
10972
0a2c6948f5f4 doc, minirst: support hg interpreted text role
Martin Geisler <mg@aragost.com>
parents: 10937
diff changeset
   365
def hgrole(blocks):
11464
521c8e0c93bf minirst: use unicode string as intermediate form for replacement
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 11297
diff changeset
   366
    substs = [(':hg:`', '"hg '), ('`', '"')]
10972
0a2c6948f5f4 doc, minirst: support hg interpreted text role
Martin Geisler <mg@aragost.com>
parents: 10937
diff changeset
   367
    for b in blocks:
10983
287a5cdf7743 minirst: correctly format sections containing inline markup
Martin Geisler <mg@lazybytes.net>
parents: 10972
diff changeset
   368
        if b['type'] in ('paragraph', 'section'):
11192
babf9a5f5528 minirst: handle line breaks in hg role
Martin Geisler <mg@aragost.com>
parents: 11189
diff changeset
   369
            # Turn :hg:`command` into "hg command". This also works
babf9a5f5528 minirst: handle line breaks in hg role
Martin Geisler <mg@aragost.com>
parents: 11189
diff changeset
   370
            # when there is a line break in the command and relies on
babf9a5f5528 minirst: handle line breaks in hg role
Martin Geisler <mg@aragost.com>
parents: 11189
diff changeset
   371
            # the fact that we have no stray back-quotes in the input
babf9a5f5528 minirst: handle line breaks in hg role
Martin Geisler <mg@aragost.com>
parents: 11189
diff changeset
   372
            # (run the blocks through inlineliterals first).
11464
521c8e0c93bf minirst: use unicode string as intermediate form for replacement
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 11297
diff changeset
   373
            b['lines'] = [replace(l, substs) for l in b['lines']]
10972
0a2c6948f5f4 doc, minirst: support hg interpreted text role
Martin Geisler <mg@aragost.com>
parents: 10937
diff changeset
   374
    return blocks
0a2c6948f5f4 doc, minirst: support hg interpreted text role
Martin Geisler <mg@aragost.com>
parents: 10937
diff changeset
   375
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   376
def addmargins(blocks):
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   377
    """Adds empty blocks for vertical spacing.
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   378
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   379
    This groups bullets, options, and definitions together with no vertical
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   380
    space between them, and adds an empty block between all other blocks.
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   381
    """
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   382
    i = 1
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   383
    while i < len(blocks):
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   384
        if (blocks[i]['type'] == blocks[i - 1]['type'] and
10936
2853c891ac41 minirst: add margin around definition items
Martin Geisler <mg@lazybytes.net>
parents: 10447
diff changeset
   385
            blocks[i]['type'] in ('bullet', 'option', 'field')):
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   386
            i += 1
19995
0f6e360b14f2 minirst: do not add a 2nd empty paragraph
Simon Heimberg <simohe@besonet.ch>
parents: 19994
diff changeset
   387
        elif not blocks[i - 1]['lines']:
20549
2025315cfb0c comments: fix minor spelling issues found with spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 19995
diff changeset
   388
            # no lines in previous block, do not separate
19995
0f6e360b14f2 minirst: do not add a 2nd empty paragraph
Simon Heimberg <simohe@besonet.ch>
parents: 19994
diff changeset
   389
            i += 1
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   390
        else:
20682
7f8cbaaa8eea minirst: move from dict() construction to {} literals
Augie Fackler <raf@durin42.com>
parents: 20654
diff changeset
   391
            blocks.insert(i, {'lines': [''], 'indent': 0, 'type': 'margin'})
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   392
            i += 2
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   393
    return blocks
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   394
12819
5082e2f3f8e0 minirst: ignore comments
Martin Geisler <mg@lazybytes.net>
parents: 12652
diff changeset
   395
def prunecomments(blocks):
5082e2f3f8e0 minirst: ignore comments
Martin Geisler <mg@lazybytes.net>
parents: 12652
diff changeset
   396
    """Remove comments."""
5082e2f3f8e0 minirst: ignore comments
Martin Geisler <mg@lazybytes.net>
parents: 12652
diff changeset
   397
    i = 0
5082e2f3f8e0 minirst: ignore comments
Martin Geisler <mg@lazybytes.net>
parents: 12652
diff changeset
   398
    while i < len(blocks):
5082e2f3f8e0 minirst: ignore comments
Martin Geisler <mg@lazybytes.net>
parents: 12652
diff changeset
   399
        b = blocks[i]
13009
54be08fa4d1d minirst: modified minirst to also recognize empty comments.
Erik Zielke <ez@aragost.com>
parents: 13003
diff changeset
   400
        if b['type'] == 'paragraph' and (b['lines'][0].startswith('.. ') or
54be08fa4d1d minirst: modified minirst to also recognize empty comments.
Erik Zielke <ez@aragost.com>
parents: 13003
diff changeset
   401
                                         b['lines'] == ['..']):
12819
5082e2f3f8e0 minirst: ignore comments
Martin Geisler <mg@lazybytes.net>
parents: 12652
diff changeset
   402
            del blocks[i]
13003
876a931dd230 minirst: better interaction between comments and margins
Martin Geisler <mg@aragost.com>
parents: 12958
diff changeset
   403
            if i < len(blocks) and blocks[i]['type'] == 'margin':
876a931dd230 minirst: better interaction between comments and margins
Martin Geisler <mg@aragost.com>
parents: 12958
diff changeset
   404
                del blocks[i]
12819
5082e2f3f8e0 minirst: ignore comments
Martin Geisler <mg@lazybytes.net>
parents: 12652
diff changeset
   405
        else:
5082e2f3f8e0 minirst: ignore comments
Martin Geisler <mg@lazybytes.net>
parents: 12652
diff changeset
   406
            i += 1
5082e2f3f8e0 minirst: ignore comments
Martin Geisler <mg@lazybytes.net>
parents: 12652
diff changeset
   407
    return blocks
5082e2f3f8e0 minirst: ignore comments
Martin Geisler <mg@lazybytes.net>
parents: 12652
diff changeset
   408
12620
9a9312e84e4e minirst: small code cleanup
Martin Geisler <mg@lazybytes.net>
parents: 12388
diff changeset
   409
_admonitionre = re.compile(r"\.\. (admonition|attention|caution|danger|"
9a9312e84e4e minirst: small code cleanup
Martin Geisler <mg@lazybytes.net>
parents: 12388
diff changeset
   410
                           r"error|hint|important|note|tip|warning)::",
9a9312e84e4e minirst: small code cleanup
Martin Geisler <mg@lazybytes.net>
parents: 12388
diff changeset
   411
                           flags=re.IGNORECASE)
9a9312e84e4e minirst: small code cleanup
Martin Geisler <mg@lazybytes.net>
parents: 12388
diff changeset
   412
12388
75f044d4dbf5 minirst: Support for admonitions
Erik Zielke <ez@aragost.com>
parents: 11464
diff changeset
   413
def findadmonitions(blocks):
75f044d4dbf5 minirst: Support for admonitions
Erik Zielke <ez@aragost.com>
parents: 11464
diff changeset
   414
    """
75f044d4dbf5 minirst: Support for admonitions
Erik Zielke <ez@aragost.com>
parents: 11464
diff changeset
   415
    Makes the type of the block an admonition block if
75f044d4dbf5 minirst: Support for admonitions
Erik Zielke <ez@aragost.com>
parents: 11464
diff changeset
   416
    the first line is an admonition directive
75f044d4dbf5 minirst: Support for admonitions
Erik Zielke <ez@aragost.com>
parents: 11464
diff changeset
   417
    """
75f044d4dbf5 minirst: Support for admonitions
Erik Zielke <ez@aragost.com>
parents: 11464
diff changeset
   418
    i = 0
75f044d4dbf5 minirst: Support for admonitions
Erik Zielke <ez@aragost.com>
parents: 11464
diff changeset
   419
    while i < len(blocks):
12620
9a9312e84e4e minirst: small code cleanup
Martin Geisler <mg@lazybytes.net>
parents: 12388
diff changeset
   420
        m = _admonitionre.match(blocks[i]['lines'][0])
12388
75f044d4dbf5 minirst: Support for admonitions
Erik Zielke <ez@aragost.com>
parents: 11464
diff changeset
   421
        if m:
75f044d4dbf5 minirst: Support for admonitions
Erik Zielke <ez@aragost.com>
parents: 11464
diff changeset
   422
            blocks[i]['type'] = 'admonition'
75f044d4dbf5 minirst: Support for admonitions
Erik Zielke <ez@aragost.com>
parents: 11464
diff changeset
   423
            admonitiontitle = blocks[i]['lines'][0][3:m.end() - 2].lower()
75f044d4dbf5 minirst: Support for admonitions
Erik Zielke <ez@aragost.com>
parents: 11464
diff changeset
   424
75f044d4dbf5 minirst: Support for admonitions
Erik Zielke <ez@aragost.com>
parents: 11464
diff changeset
   425
            firstline = blocks[i]['lines'][0][m.end() + 1:]
12620
9a9312e84e4e minirst: small code cleanup
Martin Geisler <mg@lazybytes.net>
parents: 12388
diff changeset
   426
            if firstline:
9a9312e84e4e minirst: small code cleanup
Martin Geisler <mg@lazybytes.net>
parents: 12388
diff changeset
   427
                blocks[i]['lines'].insert(1, '   ' + firstline)
12388
75f044d4dbf5 minirst: Support for admonitions
Erik Zielke <ez@aragost.com>
parents: 11464
diff changeset
   428
75f044d4dbf5 minirst: Support for admonitions
Erik Zielke <ez@aragost.com>
parents: 11464
diff changeset
   429
            blocks[i]['admonitiontitle'] = admonitiontitle
75f044d4dbf5 minirst: Support for admonitions
Erik Zielke <ez@aragost.com>
parents: 11464
diff changeset
   430
            del blocks[i]['lines'][0]
75f044d4dbf5 minirst: Support for admonitions
Erik Zielke <ez@aragost.com>
parents: 11464
diff changeset
   431
        i = i + 1
75f044d4dbf5 minirst: Support for admonitions
Erik Zielke <ez@aragost.com>
parents: 11464
diff changeset
   432
    return blocks
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   433
12652
3c31c0e42b11 minirst: pull admonition titles out formatblock function
Martin Geisler <mg@lazybytes.net>
parents: 12651
diff changeset
   434
_admonitiontitles = {'attention': _('Attention:'),
3c31c0e42b11 minirst: pull admonition titles out formatblock function
Martin Geisler <mg@lazybytes.net>
parents: 12651
diff changeset
   435
                     'caution': _('Caution:'),
3c31c0e42b11 minirst: pull admonition titles out formatblock function
Martin Geisler <mg@lazybytes.net>
parents: 12651
diff changeset
   436
                     'danger': _('!Danger!')  ,
3c31c0e42b11 minirst: pull admonition titles out formatblock function
Martin Geisler <mg@lazybytes.net>
parents: 12651
diff changeset
   437
                     'error': _('Error:'),
3c31c0e42b11 minirst: pull admonition titles out formatblock function
Martin Geisler <mg@lazybytes.net>
parents: 12651
diff changeset
   438
                     'hint': _('Hint:'),
3c31c0e42b11 minirst: pull admonition titles out formatblock function
Martin Geisler <mg@lazybytes.net>
parents: 12651
diff changeset
   439
                     'important': _('Important:'),
3c31c0e42b11 minirst: pull admonition titles out formatblock function
Martin Geisler <mg@lazybytes.net>
parents: 12651
diff changeset
   440
                     'note': _('Note:'),
3c31c0e42b11 minirst: pull admonition titles out formatblock function
Martin Geisler <mg@lazybytes.net>
parents: 12651
diff changeset
   441
                     'tip': _('Tip:'),
3c31c0e42b11 minirst: pull admonition titles out formatblock function
Martin Geisler <mg@lazybytes.net>
parents: 12651
diff changeset
   442
                     'warning': _('Warning!')}
3c31c0e42b11 minirst: pull admonition titles out formatblock function
Martin Geisler <mg@lazybytes.net>
parents: 12651
diff changeset
   443
13011
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   444
def formatoption(block, width):
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   445
    desc = ' '.join(map(str.strip, block['lines']))
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   446
    colwidth = encoding.colwidth(block['optstr'])
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   447
    usablewidth = width - 1
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   448
    hanging = block['optstrwidth']
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   449
    initindent = '%s%s  ' % (block['optstr'], ' ' * ((hanging - colwidth)))
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   450
    hangindent = ' ' * (encoding.colwidth(initindent) + 1)
15125
bdc595059108 minirst: end all blocks with newlines
Matt Mackall <mpm@selenic.com>
parents: 15123
diff changeset
   451
    return ' %s\n' % (util.wrap(desc, usablewidth,
13011
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   452
                                           initindent=initindent,
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   453
                                           hangindent=hangindent))
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   454
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   455
def formatblock(block, width):
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   456
    """Format a block according to width."""
9417
4c3fb45123e5 util, minirst: do not crash with COLUMNS=0
Martin Geisler <mg@lazybytes.net>
parents: 9293
diff changeset
   457
    if width <= 0:
4c3fb45123e5 util, minirst: do not crash with COLUMNS=0
Martin Geisler <mg@lazybytes.net>
parents: 9293
diff changeset
   458
        width = 78
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   459
    indent = ' ' * block['indent']
12388
75f044d4dbf5 minirst: Support for admonitions
Erik Zielke <ez@aragost.com>
parents: 11464
diff changeset
   460
    if block['type'] == 'admonition':
12652
3c31c0e42b11 minirst: pull admonition titles out formatblock function
Martin Geisler <mg@lazybytes.net>
parents: 12651
diff changeset
   461
        admonition = _admonitiontitles[block['admonitiontitle']]
19993
03ec85b9cfc4 minirst: do not fail on an empty admonition block
Simon Heimberg <simohe@besonet.ch>
parents: 19992
diff changeset
   462
        if not block['lines']:
03ec85b9cfc4 minirst: do not fail on an empty admonition block
Simon Heimberg <simohe@besonet.ch>
parents: 19992
diff changeset
   463
            return indent + admonition + '\n'
12388
75f044d4dbf5 minirst: Support for admonitions
Erik Zielke <ez@aragost.com>
parents: 11464
diff changeset
   464
        hang = len(block['lines'][-1]) - len(block['lines'][-1].lstrip())
75f044d4dbf5 minirst: Support for admonitions
Erik Zielke <ez@aragost.com>
parents: 11464
diff changeset
   465
75f044d4dbf5 minirst: Support for admonitions
Erik Zielke <ez@aragost.com>
parents: 11464
diff changeset
   466
        defindent = indent + hang * ' '
75f044d4dbf5 minirst: Support for admonitions
Erik Zielke <ez@aragost.com>
parents: 11464
diff changeset
   467
        text = ' '.join(map(str.strip, block['lines']))
15125
bdc595059108 minirst: end all blocks with newlines
Matt Mackall <mpm@selenic.com>
parents: 15123
diff changeset
   468
        return '%s\n%s\n' % (indent + admonition,
bdc595059108 minirst: end all blocks with newlines
Matt Mackall <mpm@selenic.com>
parents: 15123
diff changeset
   469
                             util.wrap(text, width=width,
bdc595059108 minirst: end all blocks with newlines
Matt Mackall <mpm@selenic.com>
parents: 15123
diff changeset
   470
                                       initindent=defindent,
bdc595059108 minirst: end all blocks with newlines
Matt Mackall <mpm@selenic.com>
parents: 15123
diff changeset
   471
                                       hangindent=defindent))
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   472
    if block['type'] == 'margin':
15125
bdc595059108 minirst: end all blocks with newlines
Matt Mackall <mpm@selenic.com>
parents: 15123
diff changeset
   473
        return '\n'
9735
97d0d910fa5d minirst: remove unnecessary "elif:" statements
Martin Geisler <mg@lazybytes.net>
parents: 9623
diff changeset
   474
    if block['type'] == 'literal':
9291
cd5b6a11b607 minirst: indent literal blocks with two spaces
Martin Geisler <mg@lazybytes.net>
parents: 9156
diff changeset
   475
        indent += '  '
15125
bdc595059108 minirst: end all blocks with newlines
Matt Mackall <mpm@selenic.com>
parents: 15123
diff changeset
   476
        return indent + ('\n' + indent).join(block['lines']) + '\n'
9735
97d0d910fa5d minirst: remove unnecessary "elif:" statements
Martin Geisler <mg@lazybytes.net>
parents: 9623
diff changeset
   477
    if block['type'] == 'section':
12867
eda77c3e246a minirst: use colwidth to match title lengths (issue2455)
Matt Mackall <mpm@selenic.com>
parents: 12819
diff changeset
   478
        underline = encoding.colwidth(block['lines'][0]) * block['underline']
15125
bdc595059108 minirst: end all blocks with newlines
Matt Mackall <mpm@selenic.com>
parents: 15123
diff changeset
   479
        return "%s%s\n%s%s\n" % (indent, block['lines'][0],indent, underline)
15037
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   480
    if block['type'] == 'table':
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   481
        table = block['table']
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   482
        # compute column widths
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   483
        widths = [max([encoding.colwidth(e) for e in c]) for c in zip(*table)]
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   484
        text = ''
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   485
        span = sum(widths) + len(widths) - 1
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   486
        indent = ' ' * block['indent']
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   487
        hang = ' ' * (len(indent) + span - widths[-1])
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   488
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   489
        for row in table:
15144
87bb975a1844 minirst: fix column handling for simple tables
Matt Mackall <mpm@selenic.com>
parents: 15125
diff changeset
   490
            l = []
87bb975a1844 minirst: fix column handling for simple tables
Matt Mackall <mpm@selenic.com>
parents: 15125
diff changeset
   491
            for w, v in zip(widths, row):
87bb975a1844 minirst: fix column handling for simple tables
Matt Mackall <mpm@selenic.com>
parents: 15125
diff changeset
   492
                pad = ' ' * (w - encoding.colwidth(v))
87bb975a1844 minirst: fix column handling for simple tables
Matt Mackall <mpm@selenic.com>
parents: 15125
diff changeset
   493
                l.append(v + pad)
87bb975a1844 minirst: fix column handling for simple tables
Matt Mackall <mpm@selenic.com>
parents: 15125
diff changeset
   494
            l = ' '.join(l)
15037
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   495
            l = util.wrap(l, width=width, initindent=indent, hangindent=hang)
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   496
            if not text and block['header']:
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   497
                text = l + '\n' + indent + '-' * (min(width, span)) + '\n'
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   498
            else:
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   499
                text += l + "\n"
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   500
        return text
9735
97d0d910fa5d minirst: remove unnecessary "elif:" statements
Martin Geisler <mg@lazybytes.net>
parents: 9623
diff changeset
   501
    if block['type'] == 'definition':
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   502
        term = indent + block['lines'][0]
9737
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   503
        hang = len(block['lines'][-1]) - len(block['lines'][-1].lstrip())
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   504
        defindent = indent + hang * ' '
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   505
        text = ' '.join(map(str.strip, block['lines'][1:]))
15125
bdc595059108 minirst: end all blocks with newlines
Matt Mackall <mpm@selenic.com>
parents: 15123
diff changeset
   506
        return '%s\n%s\n' % (term, util.wrap(text, width=width,
bdc595059108 minirst: end all blocks with newlines
Matt Mackall <mpm@selenic.com>
parents: 15123
diff changeset
   507
                                             initindent=defindent,
bdc595059108 minirst: end all blocks with newlines
Matt Mackall <mpm@selenic.com>
parents: 15123
diff changeset
   508
                                             hangindent=defindent))
10937
a9d5943d2a30 minirst: removed unnecessary initindent variable
Martin Geisler <mg@lazybytes.net>
parents: 10936
diff changeset
   509
    subindent = indent
9735
97d0d910fa5d minirst: remove unnecessary "elif:" statements
Martin Geisler <mg@lazybytes.net>
parents: 9623
diff changeset
   510
    if block['type'] == 'bullet':
10447
e957cc7cbd14 minirst: support line blocks
Martin Geisler <mg@lazybytes.net>
parents: 10444
diff changeset
   511
        if block['lines'][0].startswith('| '):
e957cc7cbd14 minirst: support line blocks
Martin Geisler <mg@lazybytes.net>
parents: 10444
diff changeset
   512
            # Remove bullet for line blocks and add no extra
e957cc7cbd14 minirst: support line blocks
Martin Geisler <mg@lazybytes.net>
parents: 10444
diff changeset
   513
            # indention.
e957cc7cbd14 minirst: support line blocks
Martin Geisler <mg@lazybytes.net>
parents: 10444
diff changeset
   514
            block['lines'][0] = block['lines'][0][2:]
e957cc7cbd14 minirst: support line blocks
Martin Geisler <mg@lazybytes.net>
parents: 10444
diff changeset
   515
        else:
e957cc7cbd14 minirst: support line blocks
Martin Geisler <mg@lazybytes.net>
parents: 10444
diff changeset
   516
            m = _bulletre.match(block['lines'][0])
e957cc7cbd14 minirst: support line blocks
Martin Geisler <mg@lazybytes.net>
parents: 10444
diff changeset
   517
            subindent = indent + m.end() * ' '
9737
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   518
    elif block['type'] == 'field':
10065
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   519
        key = block['key']
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   520
        subindent = indent + _fieldwidth * ' '
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   521
        if len(key) + 2 > _fieldwidth:
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   522
            # key too large, use full line width
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   523
            key = key.ljust(width)
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   524
        else:
15861
ee8f5e4ce7b8 minirst: simplify and standardize field list formatting
Olav Reinert <seroton10@gmail.com>
parents: 15393
diff changeset
   525
            # key fits within field width
10065
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   526
            key = key.ljust(_fieldwidth)
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   527
        block['lines'][0] = key + block['lines'][0]
9737
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   528
    elif block['type'] == 'option':
13011
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   529
        return formatoption(block, width)
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   530
9737
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   531
    text = ' '.join(map(str.strip, block['lines']))
11297
d320e70442a5 replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 11192
diff changeset
   532
    return util.wrap(text, width=width,
d320e70442a5 replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 11192
diff changeset
   533
                     initindent=indent,
15125
bdc595059108 minirst: end all blocks with newlines
Matt Mackall <mpm@selenic.com>
parents: 15123
diff changeset
   534
                     hangindent=subindent) + '\n'
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   535
15261
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   536
def formathtml(blocks):
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   537
    """Format RST blocks as HTML"""
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   538
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   539
    out = []
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   540
    headernest = ''
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   541
    listnest = []
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   542
18750
c9d923f5d8ae minirst: CGI escape strings prior to embedding it in the HTML
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18749
diff changeset
   543
    def escape(s):
c9d923f5d8ae minirst: CGI escape strings prior to embedding it in the HTML
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18749
diff changeset
   544
        return cgi.escape(s, True)
c9d923f5d8ae minirst: CGI escape strings prior to embedding it in the HTML
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18749
diff changeset
   545
15261
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   546
    def openlist(start, level):
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   547
        if not listnest or listnest[-1][0] != start:
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   548
            listnest.append((start, level))
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   549
            out.append('<%s>\n' % start)
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   550
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   551
    blocks = [b for b in blocks if b['type'] != 'margin']
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   552
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   553
    for pos, b in enumerate(blocks):
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   554
        btype = b['type']
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   555
        level = b['indent']
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   556
        lines = b['lines']
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   557
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   558
        if btype == 'admonition':
18750
c9d923f5d8ae minirst: CGI escape strings prior to embedding it in the HTML
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18749
diff changeset
   559
            admonition = escape(_admonitiontitles[b['admonitiontitle']])
c9d923f5d8ae minirst: CGI escape strings prior to embedding it in the HTML
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18749
diff changeset
   560
            text = escape(' '.join(map(str.strip, lines)))
15261
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   561
            out.append('<p>\n<b>%s</b> %s\n</p>\n' % (admonition, text))
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   562
        elif btype == 'paragraph':
18750
c9d923f5d8ae minirst: CGI escape strings prior to embedding it in the HTML
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18749
diff changeset
   563
            out.append('<p>\n%s\n</p>\n' % escape('\n'.join(lines)))
15261
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   564
        elif btype == 'margin':
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   565
            pass
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   566
        elif btype == 'literal':
18750
c9d923f5d8ae minirst: CGI escape strings prior to embedding it in the HTML
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18749
diff changeset
   567
            out.append('<pre>\n%s\n</pre>\n' % escape('\n'.join(lines)))
15261
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   568
        elif btype == 'section':
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   569
            i = b['underline']
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   570
            if i not in headernest:
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   571
                headernest += i
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   572
            level = headernest.index(i) + 1
18750
c9d923f5d8ae minirst: CGI escape strings prior to embedding it in the HTML
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18749
diff changeset
   573
            out.append('<h%d>%s</h%d>\n' % (level, escape(lines[0]), level))
15261
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   574
        elif btype == 'table':
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   575
            table = b['table']
18752
fabbaa250977 minirst: optimize HTML table generation a bit
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18751
diff changeset
   576
            out.append('<table>\n')
15261
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   577
            for row in table:
18752
fabbaa250977 minirst: optimize HTML table generation a bit
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18751
diff changeset
   578
                out.append('<tr>')
18750
c9d923f5d8ae minirst: CGI escape strings prior to embedding it in the HTML
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18749
diff changeset
   579
                for v in row:
18752
fabbaa250977 minirst: optimize HTML table generation a bit
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18751
diff changeset
   580
                    out.append('<td>')
fabbaa250977 minirst: optimize HTML table generation a bit
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18751
diff changeset
   581
                    out.append(escape(v))
fabbaa250977 minirst: optimize HTML table generation a bit
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18751
diff changeset
   582
                    out.append('</td>')
fabbaa250977 minirst: optimize HTML table generation a bit
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18751
diff changeset
   583
                    out.append('\n')
fabbaa250977 minirst: optimize HTML table generation a bit
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18751
diff changeset
   584
                out.pop()
fabbaa250977 minirst: optimize HTML table generation a bit
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18751
diff changeset
   585
                out.append('</tr>\n')
fabbaa250977 minirst: optimize HTML table generation a bit
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18751
diff changeset
   586
            out.append('</table>\n')
15261
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   587
        elif btype == 'definition':
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   588
            openlist('dl', level)
18750
c9d923f5d8ae minirst: CGI escape strings prior to embedding it in the HTML
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18749
diff changeset
   589
            term = escape(lines[0])
c9d923f5d8ae minirst: CGI escape strings prior to embedding it in the HTML
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18749
diff changeset
   590
            text = escape(' '.join(map(str.strip, lines[1:])))
15261
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   591
            out.append(' <dt>%s\n <dd>%s\n' % (term, text))
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   592
        elif btype == 'bullet':
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   593
            bullet, head = lines[0].split(' ', 1)
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   594
            if bullet == '-':
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   595
                openlist('ul', level)
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   596
            else:
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   597
                openlist('ol', level)
18750
c9d923f5d8ae minirst: CGI escape strings prior to embedding it in the HTML
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18749
diff changeset
   598
            out.append(' <li> %s\n' % escape(' '.join([head] + lines[1:])))
15261
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   599
        elif btype == 'field':
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   600
            openlist('dl', level)
18750
c9d923f5d8ae minirst: CGI escape strings prior to embedding it in the HTML
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18749
diff changeset
   601
            key = escape(b['key'])
c9d923f5d8ae minirst: CGI escape strings prior to embedding it in the HTML
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18749
diff changeset
   602
            text = escape(' '.join(map(str.strip, lines)))
15261
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   603
            out.append(' <dt>%s\n <dd>%s\n' % (key, text))
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   604
        elif btype == 'option':
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   605
            openlist('dl', level)
18750
c9d923f5d8ae minirst: CGI escape strings prior to embedding it in the HTML
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18749
diff changeset
   606
            opt = escape(b['optstr'])
c9d923f5d8ae minirst: CGI escape strings prior to embedding it in the HTML
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18749
diff changeset
   607
            desc = escape(' '.join(map(str.strip, lines)))
15261
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   608
            out.append(' <dt>%s\n <dd>%s\n' % (opt, desc))
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   609
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   610
        # close lists if indent level of next block is lower
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   611
        if listnest:
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   612
            start, level = listnest[-1]
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   613
            if pos == len(blocks) - 1:
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   614
                out.append('</%s>\n' % start)
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   615
                listnest.pop()
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   616
            else:
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   617
                nb = blocks[pos + 1]
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   618
                ni = nb['indent']
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   619
                if (ni < level or
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   620
                    (ni == level and
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   621
                     nb['type'] not in 'definition bullet field option')):
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   622
                    out.append('</%s>\n' % start)
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   623
                    listnest.pop()
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   624
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   625
    return ''.join(out)
e2df5b866d22 minirst: add basic HTML formatting support
Matt Mackall <mpm@selenic.com>
parents: 15192
diff changeset
   626
15012
ee766af457ed minirst: add parse method to get document structure
Matt Mackall <mpm@selenic.com>
parents: 14433
diff changeset
   627
def parse(text, indent=0, keep=None):
ee766af457ed minirst: add parse method to get document structure
Matt Mackall <mpm@selenic.com>
parents: 14433
diff changeset
   628
    """Parse text into a list of blocks"""
ee766af457ed minirst: add parse method to get document structure
Matt Mackall <mpm@selenic.com>
parents: 14433
diff changeset
   629
    pruned = []
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   630
    blocks = findblocks(text)
9540
cad36e496640 help: un-indent help topics
Martin Geisler <mg@lazybytes.net>
parents: 9417
diff changeset
   631
    for b in blocks:
cad36e496640 help: un-indent help topics
Martin Geisler <mg@lazybytes.net>
parents: 9417
diff changeset
   632
        b['indent'] += indent
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   633
    blocks = findliteralblocks(blocks)
15037
df47381b41d6 minirst: add simple table support
Matt Mackall <mpm@selenic.com>
parents: 15036
diff changeset
   634
    blocks = findtables(blocks)
10444
e99e0e077bc4 minirst: report pruned container types
Martin Geisler <mg@lazybytes.net>
parents: 10443
diff changeset
   635
    blocks, pruned = prunecontainers(blocks, keep or [])
10983
287a5cdf7743 minirst: correctly format sections containing inline markup
Martin Geisler <mg@lazybytes.net>
parents: 10972
diff changeset
   636
    blocks = findsections(blocks)
9623
32727ce029de minirst: convert ``foo`` into "foo" upon display
Martin Geisler <mg@lazybytes.net>
parents: 9540
diff changeset
   637
    blocks = inlineliterals(blocks)
10972
0a2c6948f5f4 doc, minirst: support hg interpreted text role
Martin Geisler <mg@aragost.com>
parents: 10937
diff changeset
   638
    blocks = hgrole(blocks)
9737
5f101af4a921 minirst: combine list parsing in one function
Martin Geisler <mg@lazybytes.net>
parents: 9735
diff changeset
   639
    blocks = splitparagraphs(blocks)
10065
a1ae0ed78d1a minirst: improve layout of field lists
Martin Geisler <mg@lazybytes.net>
parents: 10064
diff changeset
   640
    blocks = updatefieldlists(blocks)
13011
4936a04b6792 minirst: improved support for option lists.
Erik Zielke <ez@aragost.com>
parents: 13009
diff changeset
   641
    blocks = updateoptionlists(blocks)
19994
fc251b1a1dad minirst: find admonitions before pruning comments and adding margins
Simon Heimberg <simohe@besonet.ch>
parents: 19993
diff changeset
   642
    blocks = findadmonitions(blocks)
13003
876a931dd230 minirst: better interaction between comments and margins
Martin Geisler <mg@aragost.com>
parents: 12958
diff changeset
   643
    blocks = addmargins(blocks)
12819
5082e2f3f8e0 minirst: ignore comments
Martin Geisler <mg@lazybytes.net>
parents: 12652
diff changeset
   644
    blocks = prunecomments(blocks)
15012
ee766af457ed minirst: add parse method to get document structure
Matt Mackall <mpm@selenic.com>
parents: 14433
diff changeset
   645
    return blocks, pruned
ee766af457ed minirst: add parse method to get document structure
Matt Mackall <mpm@selenic.com>
parents: 14433
diff changeset
   646
15013
4a1e3c761ec7 minirst: add formatblocks helper
Matt Mackall <mpm@selenic.com>
parents: 15012
diff changeset
   647
def formatblocks(blocks, width):
15125
bdc595059108 minirst: end all blocks with newlines
Matt Mackall <mpm@selenic.com>
parents: 15123
diff changeset
   648
    text = ''.join(formatblock(b, width) for b in blocks)
15013
4a1e3c761ec7 minirst: add formatblocks helper
Matt Mackall <mpm@selenic.com>
parents: 15012
diff changeset
   649
    return text
4a1e3c761ec7 minirst: add formatblocks helper
Matt Mackall <mpm@selenic.com>
parents: 15012
diff changeset
   650
22587
c3c3dd31fe1c help: basic support for showing only specified topic sections
Matt Mackall <mpm@selenic.com>
parents: 22584
diff changeset
   651
def format(text, width=80, indent=0, keep=None, style='plain', section=None):
15012
ee766af457ed minirst: add parse method to get document structure
Matt Mackall <mpm@selenic.com>
parents: 14433
diff changeset
   652
    """Parse and format the text according to width."""
ee766af457ed minirst: add parse method to get document structure
Matt Mackall <mpm@selenic.com>
parents: 14433
diff changeset
   653
    blocks, pruned = parse(text, indent, keep or [])
22587
c3c3dd31fe1c help: basic support for showing only specified topic sections
Matt Mackall <mpm@selenic.com>
parents: 22584
diff changeset
   654
    if section:
c3c3dd31fe1c help: basic support for showing only specified topic sections
Matt Mackall <mpm@selenic.com>
parents: 22584
diff changeset
   655
        sections = getsections(blocks)
c3c3dd31fe1c help: basic support for showing only specified topic sections
Matt Mackall <mpm@selenic.com>
parents: 22584
diff changeset
   656
        blocks = []
22770
de9424647fe4 help: show all nested subsections of a section with `hg help foo.section`
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22769
diff changeset
   657
        i = 0
de9424647fe4 help: show all nested subsections of a section with `hg help foo.section`
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22769
diff changeset
   658
        while i < len(sections):
de9424647fe4 help: show all nested subsections of a section with `hg help foo.section`
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22769
diff changeset
   659
            name, nest, b = sections[i]
22587
c3c3dd31fe1c help: basic support for showing only specified topic sections
Matt Mackall <mpm@selenic.com>
parents: 22584
diff changeset
   660
            if name == section:
22770
de9424647fe4 help: show all nested subsections of a section with `hg help foo.section`
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22769
diff changeset
   661
                blocks.extend(b)
de9424647fe4 help: show all nested subsections of a section with `hg help foo.section`
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22769
diff changeset
   662
de9424647fe4 help: show all nested subsections of a section with `hg help foo.section`
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22769
diff changeset
   663
                ## Also show all subnested sections
de9424647fe4 help: show all nested subsections of a section with `hg help foo.section`
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22769
diff changeset
   664
                while i + 1 < len(sections) and sections[i + 1][1] > nest:
de9424647fe4 help: show all nested subsections of a section with `hg help foo.section`
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22769
diff changeset
   665
                    i += 1
de9424647fe4 help: show all nested subsections of a section with `hg help foo.section`
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22769
diff changeset
   666
                    blocks.extend(sections[i][2])
de9424647fe4 help: show all nested subsections of a section with `hg help foo.section`
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22769
diff changeset
   667
            i += 1
de9424647fe4 help: show all nested subsections of a section with `hg help foo.section`
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22769
diff changeset
   668
15262
e8076af14498 minirst: add style flag to format
Matt Mackall <mpm@selenic.com>
parents: 15261
diff changeset
   669
    if style == 'html':
e8076af14498 minirst: add style flag to format
Matt Mackall <mpm@selenic.com>
parents: 15261
diff changeset
   670
        text = formathtml(blocks)
e8076af14498 minirst: add style flag to format
Matt Mackall <mpm@selenic.com>
parents: 15261
diff changeset
   671
    else:
e8076af14498 minirst: add style flag to format
Matt Mackall <mpm@selenic.com>
parents: 15261
diff changeset
   672
        text = ''.join(formatblock(b, width) for b in blocks)
10444
e99e0e077bc4 minirst: report pruned container types
Martin Geisler <mg@lazybytes.net>
parents: 10443
diff changeset
   673
    if keep is None:
e99e0e077bc4 minirst: report pruned container types
Martin Geisler <mg@lazybytes.net>
parents: 10443
diff changeset
   674
        return text
e99e0e077bc4 minirst: report pruned container types
Martin Geisler <mg@lazybytes.net>
parents: 10443
diff changeset
   675
    else:
e99e0e077bc4 minirst: report pruned container types
Martin Geisler <mg@lazybytes.net>
parents: 10443
diff changeset
   676
        return text, pruned
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   677
15014
a814e986859f minirst: add getsections helper
Matt Mackall <mpm@selenic.com>
parents: 15013
diff changeset
   678
def getsections(blocks):
a814e986859f minirst: add getsections helper
Matt Mackall <mpm@selenic.com>
parents: 15013
diff changeset
   679
    '''return a list of (section name, nesting level, blocks) tuples'''
a814e986859f minirst: add getsections helper
Matt Mackall <mpm@selenic.com>
parents: 15013
diff changeset
   680
    nest = ""
a814e986859f minirst: add getsections helper
Matt Mackall <mpm@selenic.com>
parents: 15013
diff changeset
   681
    level = 0
a814e986859f minirst: add getsections helper
Matt Mackall <mpm@selenic.com>
parents: 15013
diff changeset
   682
    secs = []
22587
c3c3dd31fe1c help: basic support for showing only specified topic sections
Matt Mackall <mpm@selenic.com>
parents: 22584
diff changeset
   683
c3c3dd31fe1c help: basic support for showing only specified topic sections
Matt Mackall <mpm@selenic.com>
parents: 22584
diff changeset
   684
    def getname(b):
c3c3dd31fe1c help: basic support for showing only specified topic sections
Matt Mackall <mpm@selenic.com>
parents: 22584
diff changeset
   685
        x = b['lines'][0]
c3c3dd31fe1c help: basic support for showing only specified topic sections
Matt Mackall <mpm@selenic.com>
parents: 22584
diff changeset
   686
        x = x.lower().strip('"')
c3c3dd31fe1c help: basic support for showing only specified topic sections
Matt Mackall <mpm@selenic.com>
parents: 22584
diff changeset
   687
        if '(' in x:
c3c3dd31fe1c help: basic support for showing only specified topic sections
Matt Mackall <mpm@selenic.com>
parents: 22584
diff changeset
   688
            x = x.split('(')[0]
c3c3dd31fe1c help: basic support for showing only specified topic sections
Matt Mackall <mpm@selenic.com>
parents: 22584
diff changeset
   689
        return x
c3c3dd31fe1c help: basic support for showing only specified topic sections
Matt Mackall <mpm@selenic.com>
parents: 22584
diff changeset
   690
15014
a814e986859f minirst: add getsections helper
Matt Mackall <mpm@selenic.com>
parents: 15013
diff changeset
   691
    for b in blocks:
a814e986859f minirst: add getsections helper
Matt Mackall <mpm@selenic.com>
parents: 15013
diff changeset
   692
        if b['type'] == 'section':
a814e986859f minirst: add getsections helper
Matt Mackall <mpm@selenic.com>
parents: 15013
diff changeset
   693
            i = b['underline']
a814e986859f minirst: add getsections helper
Matt Mackall <mpm@selenic.com>
parents: 15013
diff changeset
   694
            if i not in nest:
a814e986859f minirst: add getsections helper
Matt Mackall <mpm@selenic.com>
parents: 15013
diff changeset
   695
                nest += i
a814e986859f minirst: add getsections helper
Matt Mackall <mpm@selenic.com>
parents: 15013
diff changeset
   696
            level = nest.index(i) + 1
a814e986859f minirst: add getsections helper
Matt Mackall <mpm@selenic.com>
parents: 15013
diff changeset
   697
            nest = nest[:level]
22587
c3c3dd31fe1c help: basic support for showing only specified topic sections
Matt Mackall <mpm@selenic.com>
parents: 22584
diff changeset
   698
            secs.append((getname(b), level, [b]))
22769
3f808549d426 help: fix output of sections in `hg help foo.somesection`
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 22587
diff changeset
   699
        elif b['type'] == 'definition':
22587
c3c3dd31fe1c help: basic support for showing only specified topic sections
Matt Mackall <mpm@selenic.com>
parents: 22584
diff changeset
   700
            i = ' '
c3c3dd31fe1c help: basic support for showing only specified topic sections
Matt Mackall <mpm@selenic.com>
parents: 22584
diff changeset
   701
            if i not in nest:
c3c3dd31fe1c help: basic support for showing only specified topic sections
Matt Mackall <mpm@selenic.com>
parents: 22584
diff changeset
   702
                nest += i
c3c3dd31fe1c help: basic support for showing only specified topic sections
Matt Mackall <mpm@selenic.com>
parents: 22584
diff changeset
   703
            level = nest.index(i) + 1
c3c3dd31fe1c help: basic support for showing only specified topic sections
Matt Mackall <mpm@selenic.com>
parents: 22584
diff changeset
   704
            nest = nest[:level]
c3c3dd31fe1c help: basic support for showing only specified topic sections
Matt Mackall <mpm@selenic.com>
parents: 22584
diff changeset
   705
            secs.append((getname(b), level, [b]))
15014
a814e986859f minirst: add getsections helper
Matt Mackall <mpm@selenic.com>
parents: 15013
diff changeset
   706
        else:
a814e986859f minirst: add getsections helper
Matt Mackall <mpm@selenic.com>
parents: 15013
diff changeset
   707
            if not secs:
a814e986859f minirst: add getsections helper
Matt Mackall <mpm@selenic.com>
parents: 15013
diff changeset
   708
                # add an initial empty section
a814e986859f minirst: add getsections helper
Matt Mackall <mpm@selenic.com>
parents: 15013
diff changeset
   709
                secs = [('', 0, [])]
a814e986859f minirst: add getsections helper
Matt Mackall <mpm@selenic.com>
parents: 15013
diff changeset
   710
            secs[-1][2].append(b)
a814e986859f minirst: add getsections helper
Matt Mackall <mpm@selenic.com>
parents: 15013
diff changeset
   711
    return secs
9156
c9c7e8cdac9c minimal reStructuredText parser
Martin Geisler <mg@lazybytes.net>
parents:
diff changeset
   712
15015
ee6988aea74e minirst: add decorateblocks search helper
Matt Mackall <mpm@selenic.com>
parents: 15014
diff changeset
   713
def decorateblocks(blocks, width):
ee6988aea74e minirst: add decorateblocks search helper
Matt Mackall <mpm@selenic.com>
parents: 15014
diff changeset
   714
    '''generate a list of (section name, line text) pairs for search'''
ee6988aea74e minirst: add decorateblocks search helper
Matt Mackall <mpm@selenic.com>
parents: 15014
diff changeset
   715
    lines = []
ee6988aea74e minirst: add decorateblocks search helper
Matt Mackall <mpm@selenic.com>
parents: 15014
diff changeset
   716
    for s in getsections(blocks):
ee6988aea74e minirst: add decorateblocks search helper
Matt Mackall <mpm@selenic.com>
parents: 15014
diff changeset
   717
        section = s[0]
ee6988aea74e minirst: add decorateblocks search helper
Matt Mackall <mpm@selenic.com>
parents: 15014
diff changeset
   718
        text = formatblocks(s[2], width)
ee6988aea74e minirst: add decorateblocks search helper
Matt Mackall <mpm@selenic.com>
parents: 15014
diff changeset
   719
        lines.append([(section, l) for l in text.splitlines(True)])
ee6988aea74e minirst: add decorateblocks search helper
Matt Mackall <mpm@selenic.com>
parents: 15014
diff changeset
   720
    return lines
15039
c981f4a9ea74 minirst: add a helper function to build an RST table from an array
Matt Mackall <mpm@selenic.com>
parents: 15038
diff changeset
   721
c981f4a9ea74 minirst: add a helper function to build an RST table from an array
Matt Mackall <mpm@selenic.com>
parents: 15038
diff changeset
   722
def maketable(data, indent=0, header=False):
16815
e740746ea557 minirst: generate tables as a list of joined lines
Olav Reinert <seroton10@gmail.com>
parents: 15861
diff changeset
   723
    '''Generate an RST table for the given table data as a list of lines'''
15039
c981f4a9ea74 minirst: add a helper function to build an RST table from an array
Matt Mackall <mpm@selenic.com>
parents: 15038
diff changeset
   724
c981f4a9ea74 minirst: add a helper function to build an RST table from an array
Matt Mackall <mpm@selenic.com>
parents: 15038
diff changeset
   725
    widths = [max(encoding.colwidth(e) for e in c) for c in zip(*data)]
c981f4a9ea74 minirst: add a helper function to build an RST table from an array
Matt Mackall <mpm@selenic.com>
parents: 15038
diff changeset
   726
    indent = ' ' * indent
c981f4a9ea74 minirst: add a helper function to build an RST table from an array
Matt Mackall <mpm@selenic.com>
parents: 15038
diff changeset
   727
    div = indent + ' '.join('=' * w for w in widths) + '\n'
c981f4a9ea74 minirst: add a helper function to build an RST table from an array
Matt Mackall <mpm@selenic.com>
parents: 15038
diff changeset
   728
c981f4a9ea74 minirst: add a helper function to build an RST table from an array
Matt Mackall <mpm@selenic.com>
parents: 15038
diff changeset
   729
    out = [div]
c981f4a9ea74 minirst: add a helper function to build an RST table from an array
Matt Mackall <mpm@selenic.com>
parents: 15038
diff changeset
   730
    for row in data:
15144
87bb975a1844 minirst: fix column handling for simple tables
Matt Mackall <mpm@selenic.com>
parents: 15125
diff changeset
   731
        l = []
87bb975a1844 minirst: fix column handling for simple tables
Matt Mackall <mpm@selenic.com>
parents: 15125
diff changeset
   732
        for w, v in zip(widths, row):
20654
af9d9b778550 minirst: create valid output when table data contains a newline
Simon Heimberg <simohe@besonet.ch>
parents: 20549
diff changeset
   733
            if '\n' in v:
af9d9b778550 minirst: create valid output when table data contains a newline
Simon Heimberg <simohe@besonet.ch>
parents: 20549
diff changeset
   734
                # only remove line breaks and indentation, long lines are
af9d9b778550 minirst: create valid output when table data contains a newline
Simon Heimberg <simohe@besonet.ch>
parents: 20549
diff changeset
   735
                # handled by the next tool
af9d9b778550 minirst: create valid output when table data contains a newline
Simon Heimberg <simohe@besonet.ch>
parents: 20549
diff changeset
   736
                v = ' '.join(e.lstrip() for e in v.split('\n'))
15144
87bb975a1844 minirst: fix column handling for simple tables
Matt Mackall <mpm@selenic.com>
parents: 15125
diff changeset
   737
            pad = ' ' * (w - encoding.colwidth(v))
87bb975a1844 minirst: fix column handling for simple tables
Matt Mackall <mpm@selenic.com>
parents: 15125
diff changeset
   738
            l.append(v + pad)
87bb975a1844 minirst: fix column handling for simple tables
Matt Mackall <mpm@selenic.com>
parents: 15125
diff changeset
   739
        out.append(indent + ' '.join(l) + "\n")
15039
c981f4a9ea74 minirst: add a helper function to build an RST table from an array
Matt Mackall <mpm@selenic.com>
parents: 15038
diff changeset
   740
    if header and len(data) > 1:
c981f4a9ea74 minirst: add a helper function to build an RST table from an array
Matt Mackall <mpm@selenic.com>
parents: 15038
diff changeset
   741
        out.insert(2, div)
c981f4a9ea74 minirst: add a helper function to build an RST table from an array
Matt Mackall <mpm@selenic.com>
parents: 15038
diff changeset
   742
    out.append(div)
16815
e740746ea557 minirst: generate tables as a list of joined lines
Olav Reinert <seroton10@gmail.com>
parents: 15861
diff changeset
   743
    return out