django-markdown-deux
django-markdown-deux copied to clipboard
Fenced code blocks do not receive pre tag
Suppose I have a database entry where I have the following "fenced code block"
(triple back tick) some fenced code block another line (triple back tick)
I also have the following model method in django models.py
def get_markdown(self):
return mark_safe(markdown(self.body))
where body = models.TextField()
Then the result being returned by the method is the following html code...
<p><code>
some fenced code block
another line
</code></p>
The <pre> tag is missing and it also displays inline rather than receiving the line break.
Hello,
Same problem here. Even with 4 spaces and a blank line before the content, the code is not well formated.
I think the owner of the package / repository is no longer maintaining it at all... There are open issues which have not received any feedback from him since 2014.
Anyway, I found another solution :
- I uninstalled django-markdown-deux
- I follow this tuto : Using Markdown with Django 1.7
- Adding this extension in the return of the template tag function : Fenced Code Blocks
So my templatetags/markdown_parser.py looks like this :
from django import template
import markdown
register = template.Library()
@register.filter
def parse_md(text):
# safe_mode governs how the function handles raw HTML
return markdown.markdown(
text,
safe_mode='escape',
extensions=[
'markdown.extensions.nl2br',
'markdown.extensions.fenced_code'
]
)
Hope it helps
Thanks for the find, it is certainly helpful. However, processing markdown at the template level is not a good idea, furthermore, safe_mode is deprecated
Python-Markdown 2.6 Release Notes
http://pythonhosted.org/Markdown/reference.html#safe_mode
I do suggest reading the comments and links on your link, they elaborate on my above comments.
Ok, thanks you for the tips, I'll fix my code and post back the final function here.
PS : Your links lead to 404 when clicked, I had to c/p.
It's the link you posted, I dragged it from your post into mine... hahaha, I guess it didn't work... I corrected it
Here is my solution using the above information...
this is the model.py file
from django.utils.safestring import mark_safe
from markdown import markdown
from markdown.extensions import Extension
class EscapeHtml(Extension):
def extendMarkdown(self, md, md_globals):
del md.preprocessors['html_block']
del md.inlinePatterns['html']
class Post(models.Model):
body = models.TextField()
def get_markdown(self):
return mark_safe(markdown(
self.body,
extensions=[
EscapeHtml(),
'markdown.extensions.nl2br',
'markdown.extensions.fenced_code'
]
)
)
... then in the template I just use {{ post.get_markdown }}
There is no need for template tags.
Waw, your solution is great !
Thank you for sharing !
Héhé, no need django-markdown-deux anymore. = P You rule !
Credit goes to you... you found the original post, I just read a little more into it... =)
It works like a charm and in a secure way.
We should create a new Repository. = P
@contstantine AMazing solution, thanks!
Does anyone know whether the "markdown" package is still supported in Python 3?
for those who use the tag {% markdown %} ... MD content ... {% endmarkdown %} in the template this is my solution
- followed @Ljz7's solution on adding the template tag on my app
- use markdown deux original
markdown_deux_tags.pyas model - create myapp/templatetags/markdown_filter.py
from django import template
import markdown
register = template.Library()
@register.tag(name="markdown")
def markdown_tag(parser, token):
nodelist = parser.parse(('endmarkdown',))
bits = token.split_contents()
if len(bits) == 1:
style = "default"
elif len(bits) == 2:
style = bits[1]
else:
raise template.TemplateSyntaxError("`markdown` tag requires exactly "
"zero or one arguments")
parser.delete_first_token() # consume '{% endmarkdown %}'
return MarkdownNode(style, nodelist)
class MarkdownNode(template.Node):
def __init__(self, style, nodelist):
self.style = style
self.nodelist = nodelist
def render(self, context):
value = self.nodelist.render(context)
try:
return markdown.markdown(value,
extensions=[
'markdown.extensions.nl2br',
'markdown.extensions.fenced_code'
])
except ImportError:
if settings.DEBUG:
raise template.TemplateSyntaxError("Error in `markdown` tag: "
"The python-markdown2 library isn't installed.")
return force_text(value)
so now my template can be used like this
{% load markdown_filter %}
{% markdown %}
markdown content with fenced_code
{% endmarkdown %}
Thank you!! it's displaying the code blocks, but the code section is weirdly wide, anyone else find this?