File: wiki-tables-to-tables.py

package info (click to toggle)
python-markdown2 2.5.4-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 6,492 kB
  • sloc: python: 6,201; perl: 1,493; php: 865; makefile: 37
file content (112 lines) | stat: -rwxr-xr-x 3,497 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/usr/bin/env python

"""
Convert a Markdown document using
[wiki-tables](https://github.com/trentm/python-markdown2/wiki/wiki-tables)
to a Markdown document using
[tables](https://github.com/trentm/python-markdown2/wiki/tables)

Limitations:
- Doesn't handle tables inside blockquotes.
- "tables" require a head section, "wiki-tables" does not. That creates an
  ambiguity on conversion: what to use for the head row? We'll do the
  following.

  First we'll look at the first row, and if the cells are em'd or strong'd
  like this:

        ||**Param**||**Type**||**Description**||
        ||kernel_args||Object||Boot parms to update||
        ||boot_modules||Array||List of boot module objects||
        ||kernel_flags||Object||Kernel flags to update||
        ||platform||String||Set platform as the bootable platform||

        ||*Code*||*Type*||*Description*||
        ||204||None||Boot parameters successfully set||
        ||404||None||No such Server||

  Then we'll use that as the header row. If not we'll bail. This is "strict"
  mode... and the only supported mode for now.
"""



__version__ = "1.0.0"

import codecs
import re
import sys

p = print
def e(*args, **kwargs):
    kwargs['file'] = sys.stderr
    p(*args, **kwargs)



#---- internal support stuff

def wiki_tables_to_tables(path):
    def _wiki_table_sub(match):
        ttext = match.group(0).strip()
        #e('wiki table: %r' % match.group(0))
        rows = []
        for line in ttext.splitlines(0):
            line = line.strip()[2:-2].strip()
            row = [c.strip() for c in re.split(r'(?<!\\)\|\|', line)]
            rows.append(row)
        #e(pformat(rows))

        head = []
        for cell in rows[0]:
            if cell.startswith('**') and cell.endswith('**'):
                head.append(cell[2:-2].strip())
            elif cell.startswith('*') and cell.endswith('*'):
                head.append(cell[1:-1].strip())
            else:
                raise RuntimeError(
                    'wiki-table in "%s" has no header row, bailing: %r'
                    % (path, ttext))

        underline = []
        for cell in head:
            underline.append('-' * max(1, len(cell)))

        body = rows[1:]
        table = [head, underline] + body
        table_str = '\n'.join(('| ' + ' | '.join(r) + ' |') for r in table)
        return table_str + '\n'

    text = codecs.open(path, 'rb', 'utf8').read()

    # If there is a leading markdown2 metadata block with;
    #    markdown2extras: ..., wiki-tables, ...
    # then update that to 'tables'.
    _metadata_pat = re.compile("""^---[ \t]*\n((?:[ \t]*[^ \t:]+[ \t]*:[^\n]*\n)+)---[ \t]*\n""")
    match = _metadata_pat.match(text)
    if match:
        metadata_str = match.group(0)
        if re.search(r'^markdown2extras\s*:.*?\bwiki-tables\b', metadata_str, re.M):
            text = text.replace('wiki-tables', 'tables', 1)

    less_than_tab = 3
    wiki_table_re = re.compile(r'''
        (?:(?<=\n\n)|\A\n?)            # leading blank line
        ^([ ]{0,%d})\|\|.+?\|\|[ ]*\n  # first line
        (^\1\|\|.+?\|\|\n)*        # any number of subsequent lines
        ''' % less_than_tab, re.M | re.X)
    return wiki_table_re.sub(_wiki_table_sub, text)




#---- mainline

def main(argv):
    for path in argv[1:]:
        tables = wiki_tables_to_tables(path)
        sys.stdout.write(tables.encode(
            sys.stdout.encoding or "utf-8", 'xmlcharrefreplace'))

if __name__ == "__main__":
    sys.exit( main(sys.argv) )