Skip to content

Commit

Permalink
馃悰 fixed: render_table crashing when iterating token.children (#12)
Browse files Browse the repository at this point in the history
  • Loading branch information
miyuchina committed Jan 11, 2018
1 parent 5c0f337 commit 5436e70
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 26 deletions.
9 changes: 5 additions & 4 deletions mistletoe/block_token.py
Expand Up @@ -327,13 +327,14 @@ class Table(BlockToken):
children (tuple): inner tokens (TableRows).
"""
def __init__(self, lines):
self.has_header = lines[1].find('---') != -1
if self.has_header:
if lines[1].find('---') != -1:
self.column_align = [self.parse_align(column)
for column in self.split_delimiter(lines.pop(1))]
for column in self.split_delimiter(lines[1])]
self.header = TableRow(lines[0], self.column_align)
self._children = (TableRow(line, self.column_align) for line in lines[2:])
else:
self.column_align = [None]
self._children = (TableRow(line, self.column_align) for line in lines)
self._children = (TableRow(line) for line in lines)

@staticmethod
def split_delimiter(delimiter):
Expand Down
5 changes: 2 additions & 3 deletions mistletoe/html_renderer.py
Expand Up @@ -125,10 +125,9 @@ def render_table(self, token):
# The primary difficulty seems to be passing down alignment options to
# reach individual cells.
template = '<table>\n{inner}</table>\n'
if token.has_header:
if hasattr(token, 'header'):
head_template = '<thead>\n{inner}</thead>\n'
header = next(token.children)
head_inner = self.render_table_row(header, True)
head_inner = self.render_table_row(token.header, is_header=True)
head_rendered = head_template.format(inner=head_inner)
else: head_rendered = ''
body_template = '<tbody>\n{inner}</tbody>\n'
Expand Down
5 changes: 2 additions & 3 deletions mistletoe/latex_renderer.py
Expand Up @@ -124,10 +124,9 @@ def get_align(col):
template = ('\\begin{{tabular}}{align}\n'
'{inner}'
'\\end{{tabular}}\n')
if token.has_header:
if hasattr(token, 'header'):
head_template = '{inner}\\hline\n'
header = next(token.children)
head_inner = self.render_table_row(header)
head_inner = self.render_table_row(token.header)
head_rendered = head_template.format(inner=head_inner)
else: head_rendered = ''
inner = self.render_inner(token)
Expand Down
2 changes: 1 addition & 1 deletion test/test_block_token.py
Expand Up @@ -183,7 +183,7 @@ def test_match(self):
with patch('mistletoe.block_token.TableRow') as mock:
token = next(block_token.tokenize(lines))
self.assertIsInstance(token, block_token.Table)
self.assertEqual(token.has_header, True)
self.assertTrue(hasattr(token, 'header'))
self.assertEqual(token.column_align, [None, None, None])
token.children
calls = [call(line, [None, None, None]) for line in lines[:1]+lines[2:]]
Expand Down
16 changes: 10 additions & 6 deletions test/test_html_renderer.py
Expand Up @@ -9,10 +9,14 @@ def setUp(self):
self.renderer.__enter__()
self.addCleanup(self.renderer.__exit__, None, None, None)

def _test_token(self, token_name, output, children=True, **kwargs):
def _test_token(self, token_name, output, children=True,
without_attrs=None, **kwargs):
render_func = self.renderer.render_map[token_name]
children = mock.MagicMock() if children else None
children = mock.MagicMock(spec=list) if children else None
mock_token = mock.Mock(children=children, **kwargs)
without_attrs = without_attrs or []
for attr in without_attrs:
delattr(mock_token, attr)
self.assertEqual(render_func(mock_token), output)


Expand Down Expand Up @@ -79,22 +83,22 @@ def test_list_item(self):
output = '<li>inner</li>\n'
self._test_token('ListItem', output)

def test_table_with_heading(self):
def test_table_with_header(self):
func_path = 'mistletoe.html_renderer.HTMLRenderer.render_table_row'
with mock.patch(func_path, autospec=True) as mock_func:
mock_func.return_value = 'row'
output = ('<table>\n'
'<thead>\nrow</thead>\n'
'<tbody>\ninner</tbody>\n'
'</table>\n')
self._test_token('Table', output, has_header=True)
self._test_token('Table', output)

def test_table_without_heading(self):
def test_table_without_header(self):
func_path = 'mistletoe.html_renderer.HTMLRenderer.render_table_row'
with mock.patch(func_path, autospec=True) as mock_func:
mock_func.return_value = 'row'
output = '<table>\n<tbody>\ninner</tbody>\n</table>\n'
self._test_token('Table', output, has_header=False)
self._test_token('Table', output, without_attrs=['header',])

def test_table_row(self):
self._test_token('TableRow', '<tr>\n</tr>\n')
Expand Down
23 changes: 14 additions & 9 deletions test/test_latex_renderer.py
Expand Up @@ -10,10 +10,14 @@ def setUp(self):
self.renderer.__enter__()
self.addCleanup(self.renderer.__exit__, None, None, None)

def _test_token(self, token_name, output, children=True, **kwargs):
def _test_token(self, token_name, output, children=True,
without_attrs=None, **kwargs):
render_func = self.renderer.render_map[token_name]
children = mock.MagicMock() if children else None
children = mock.MagicMock(spec=list) if children else None
mock_token = mock.Mock(children=children, **kwargs)
without_attrs = without_attrs or []
for attr in without_attrs:
delattr(mock_token, attr)
self.assertEqual(render_func(mock_token), output)

def test_strong(self):
Expand Down Expand Up @@ -73,15 +77,16 @@ def test_list(self):
def test_list_item(self):
self._test_token('ListItem', '\\item inner\n')

def test_table_with_heading(self):
output = '\\begin{tabular}{l c r}\n\n\\hline\ninner\\end{tabular}\n'
self._test_token('Table', output,
has_header=True, column_align=[None, 0, 1])
def test_table_with_header(self):
func_path = 'mistletoe.latex_renderer.LaTeXRenderer.render_table_row'
with mock.patch(func_path, autospec=True, return_value='row\n'):
output = '\\begin{tabular}{l c r}\nrow\n\\hline\ninner\\end{tabular}\n'
self._test_token('Table', output, column_align=[None, 0, 1])

def test_table_without_heading(self):
def test_table_without_header(self):
output = ('\\begin{tabular}\ninner\\end{tabular}\n')
self._test_token('Table', output,
has_header=False, column_align=[None])
self._test_token('Table', output, without_attrs=['header'],
column_align=[None])

def test_table_row(self):
self._test_token('TableRow', '\n')
Expand Down

0 comments on commit 5436e70

Please sign in to comment.