1 # markdown is released under the BSD license
2 # Copyright 2007, 2008 The Python Markdown Project (v. 1.7 and later)
3 # Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b)
4 # Copyright 2004 Manfred Stienstra (the original version)
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions are met:
11 # * Redistributions of source code must retain the above copyright
12 # notice, this list of conditions and the following disclaimer.
13 # * Redistributions in binary form must reproduce the above copyright
14 # notice, this list of conditions and the following disclaimer in the
15 # documentation and/or other materials provided with the distribution.
16 # * Neither the name of the <organization> nor the
17 # names of its contributors may be used to endorse or promote products
18 # derived from this software without specific prior written permission.
20 # THIS SOFTWARE IS PROVIDED BY THE PYTHON MARKDOWN PROJECT ''AS IS'' AND ANY
21 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 # DISCLAIMED. IN NO EVENT SHALL ANY CONTRIBUTORS TO THE PYTHON MARKDOWN PROJECT
24 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 # POSSIBILITY OF SUCH DAMAGE.
34 Tables Extension for Python-Markdown
35 ====================================
37 Added parsing of tables to Python-Markdown.
41 First Header | Second Header
42 ------------- | -------------
43 Content Cell | Content Cell
44 Content Cell | Content Cell
46 Copyright 2009 - [Waylan Limberg](http://achinghead.com)
49 from __future__
import absolute_import
50 from __future__
import unicode_literals
51 from . import Extension
52 from ..blockprocessors
import BlockProcessor
53 from ..util
import etree
55 class TableProcessor(BlockProcessor
):
56 """ Process Tables. """
58 def test(self
, parent
, block
):
59 rows
= block
.split('\n')
60 return (len(rows
) > 2 and '|' in rows
[0] and
61 '|' in rows
[1] and '-' in rows
[1] and
62 rows
[1].strip()[0] in ['|', ':', '-'])
64 def run(self
, parent
, blocks
):
65 """ Parse a table block and build table. """
66 block
= blocks
.pop(0).split('\n')
67 header
= block
[0].strip()
68 seperator
= block
[1].strip()
70 # Get format type (bordered by pipes or not)
72 if header
.startswith('|'):
74 # Get alignment of columns
76 for c
in self
._split
_row
(seperator
, border
):
77 if c
.startswith(':') and c
.endswith(':'):
78 align
.append('center')
79 elif c
.startswith(':'):
86 table
= etree
.SubElement(parent
, 'table')
87 thead
= etree
.SubElement(table
, 'thead')
88 self
._build
_row
(header
, thead
, align
, border
)
89 tbody
= etree
.SubElement(table
, 'tbody')
91 self
._build
_row
(row
.strip(), tbody
, align
, border
)
93 def _build_row(self
, row
, parent
, align
, border
):
94 """ Given a row of text, build table cells. """
95 tr
= etree
.SubElement(parent
, 'tr')
97 if parent
.tag
== 'thead':
99 cells
= self
._split
_row
(row
, border
)
100 # We use align here rather than cells to ensure every row
101 # contains the same number of columns.
102 for i
, a
in enumerate(align
):
103 c
= etree
.SubElement(tr
, tag
)
105 c
.text
= cells
[i
].strip()
111 def _split_row(self
, row
, border
):
112 """ split a row of text into list of cells. """
114 if row
.startswith('|'):
116 if row
.endswith('|'):
118 return row
.split('|')
121 class TableExtension(Extension
):
122 """ Add tables to Markdown. """
124 def extendMarkdown(self
, md
, md_globals
):
125 """ Add an instance of TableProcessor to BlockParser. """
126 md
.parser
.blockprocessors
.add('table',
127 TableProcessor(md
.parser
),
131 def makeExtension(configs
={}):
132 return TableExtension(configs
=configs
)