Back Home

Markdown with fenced code in a Flask application (backend implementation)

Fenced Code - Essentially multi-line code blocks.

The current Python Markdown library (3.3.4) does not have fenced code enabled by default, this means that it will surround the corresponding code block in <p>..</p> paragraph containers.

Consider the following:

(venv) julio@obsidian-order:techfuel-website/frontend <master*>$ python
Python 3.9.4 (default, Apr  4 2021, 17:42:23)
[Clang 12.0.0 (clang-1200.0.32.29)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import markdown
>>> fenced_code="""```
... def test():
...     return True
... ```"""
>>> markdown.markdown(fenced_code)
'<p><code>def test():\n    return True</code></p>'

Resulting in the following being rendered:

<p><code>def test(): return True</code></p>

Luckily, the solution is rather simple:

>>> markdown.markdown(fenced_code, extensions=['fenced_code'])
'<pre><code>def test():\n    return True\n</code></pre>'
>>>

Resulting in the actual code being rendered properly:

def test():
    return True

Flask provides a wrapper class Flask-Markdown to integrate within the application to allow among many other things to be able to render markdown from within its templates, this means that every time you'd need to render Markdown code, you'd have to programatically add the extension to your response or variable assignment.

Registering the fenced code extension

Here's a snippet of a Flask app.py showcasing the enabling of the fenced code extension:

from flask import Flask
from flaskext.markdown import Markdown
from markdown.extensions.fenced_code import FencedCodeExtension

app = Flask(__name__)
m_app = Markdown(app)
m_app.register_extension(FencedCodeExtension)
...

And now you should be able to do something like this in your templates:

{{ response.data|markdown }}

Or as a filter block:

{% filter markdown %}
{{ response.data }}
{% endfilter %}

Happy coding!.

Comments (0)