Skip to content
This repository has been archived by the owner on Aug 17, 2023. It is now read-only.

Commit

Permalink
Better error handling in markdown and pygment filters
Browse files Browse the repository at this point in the history
  • Loading branch information
rowanseymour committed Dec 5, 2016
1 parent b309e66 commit 0da9739
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 17 deletions.
18 changes: 10 additions & 8 deletions hamlpy/parser/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,6 @@
_markdown_available = False


class NotAvailableError(Exception):
pass


ELEMENT = '%'
ID = '#'
CLASS = '.'
Expand Down Expand Up @@ -632,15 +628,19 @@ class PygmentsFilterNode(FilterNode):
def _render(self):
if self.children:
if not _pygments_available:
raise NotAvailableError("Pygments is not available")
raise ParseException("Pygments is not available")

self.before = self.render_newlines()
indent_offset = len(self.children[0].spaces)
text = ''.join(''.join([c.spaces[indent_offset:], c.haml, c.render_newlines()]) for c in self.children)

# let Pygments try to guess syntax but default to Python
try:
self.before += highlight(text, guess_lexer(self.haml), HtmlFormatter())
lexer = guess_lexer(self.haml)
except ClassNotFound:
self.before += highlight(text, PythonLexer(), HtmlFormatter())
lexer = PythonLexer()

self.before += highlight(text, lexer, HtmlFormatter())
else:
self.after = self.render_newlines()

Expand All @@ -649,7 +649,8 @@ class MarkdownFilterNode(FilterNode):
def _render(self):
if self.children:
if not _markdown_available:
raise NotAvailableError("Markdown is not available")
raise ParseException("Markdown is not available")

self.before = self.render_newlines()[1:]
indent_offset = len(self.children[0].spaces)
lines = []
Expand All @@ -659,5 +660,6 @@ def _render(self):
haml = haml[:-1]
lines.append(c.spaces[indent_offset:] + haml + c.render_newlines())
self.before += markdown(''.join(lines))
self.before += '\n'
else:
self.after = self.render_newlines()
2 changes: 1 addition & 1 deletion hamlpy/test/templates/filtersMarkdown.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
follow</p>
<p>New paragraph</p>
<pre><code>code block
</code></pre>
</code></pre>
39 changes: 31 additions & 8 deletions hamlpy/test/test_compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,32 @@ def test_plain_filter(self):
self._test(":plain\n \\Something", "\\Something")

def test_python_filter(self):
self._test(":python\n", '\n') # empty
self._test(":python\n for i in range(0, 5): print(\"<p>item \%s</p>\" % i)",
'<p>item \\0</p>\n<p>item \\1</p>\n<p>item \\2</p>\n<p>item \\3</p>\n<p>item \\4</p>')

self._test_error(":python\n print(10 / 0)", "Error whilst executing python filter node", ZeroDivisionError)

def test_pygments_filter(self):
self._test(":highlight\n", '\n') # empty
self._test(":highlight\n print(1)\n", '\n<div class="highlight"><pre><span></span><span class="k">print</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>\n</pre></div>') # noqa

nodes._pygments_available = False

self._test_error(":highlight\n print(1)\n", "Pygments is not available")

nodes._pygments_available = True

def test_markdown_filter(self):
self._test(":markdown\n", '\n') # empty
self._test(":markdown\n *Title*\n", '<p><em>Title</em></p>')

nodes._markdown_available = False

self._test_error(":markdown\n *Title*\n", "Markdown is not available")

nodes._markdown_available = True

def test_doctypes(self):
self._test('!!! 5', '<!DOCTYPE html>')
self._test('!!!', '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">') # noqa
Expand Down Expand Up @@ -170,25 +191,27 @@ def test_attr_wrapper(self):
<script type="text/javascript">
// <![CDATA[
// ]]>
</script>''', options={'attr_wrapper': '"'})
</script>''', compiler_options={'attr_wrapper': '"'})

def _test(self, haml, expected_html, options=None):
def _test(self, haml, expected_html, compiler_options=None):
nodes._inline_variable_regexes = None # clear cached regexes

compiler = hamlpy.Compiler(options)
compiler = hamlpy.Compiler(compiler_options)
result = compiler.process(haml)

self.assertEqual(result, expected_html + '\n')

def _test_error(self, haml, expected_message, expected_cause, options=None):
def _test_error(self, haml, expected_message, expected_cause=None, compiler_options=None):
nodes._inline_variable_regexes = None # clear cached regexes

compiler = hamlpy.Compiler(options)

self.assertRaisesRegexp(ParseException, expected_message, compiler.process, haml)
compiler = hamlpy.Compiler(compiler_options)

try:
compiler.process(haml)
self.fail("Expected exception to be raised")
except Exception as e:
self.assertEqual(type(e.__cause__), expected_cause)
self.assertIsInstance(e, ParseException)
self.assertEqual(str(e), expected_message)

if expected_cause:
self.assertEqual(type(e.__cause__), expected_cause)

0 comments on commit 0da9739

Please sign in to comment.