Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fenced code blocks do not receive pre tag #20

Open
constantinevitt opened this issue Jul 12, 2016 · 13 comments
Open

Fenced code blocks do not receive pre tag #20

constantinevitt opened this issue Jul 12, 2016 · 13 comments

Comments

@constantinevitt
Copy link

constantinevitt commented Jul 12, 2016

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.

@constantinevitt constantinevitt changed the title Fenced code blocks do not received pre tag Fenced code blocks do not receive pre tag Jul 12, 2016
@Ljz7
Copy link

Ljz7 commented Jul 25, 2016

Hello,

Same problem here. Even with 4 spaces and a blank line before the content, the code is not well formated.

@constantinevitt
Copy link
Author

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.

@Ljz7
Copy link

Ljz7 commented Jul 26, 2016

Anyway, I found another solution :

  1. I uninstalled django-markdown-deux
  2. I follow this tuto : Using Markdown with Django 1.7
  3. 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

@constantinevitt
Copy link
Author

constantinevitt commented Jul 27, 2016

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.

@Ljz7
Copy link

Ljz7 commented Jul 27, 2016

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.

@constantinevitt
Copy link
Author

constantinevitt commented Jul 27, 2016

It's the link you posted, I dragged it from your post into mine... hahaha, I guess it didn't work... I corrected it

@constantinevitt
Copy link
Author

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.

@Ljz7
Copy link

Ljz7 commented Jul 27, 2016

Waw, your solution is great !

Thank you for sharing !

Héhé, no need django-markdown-deux anymore. = P You rule !

@constantinevitt
Copy link
Author

Credit goes to you... you found the original post, I just read a little more into it... =)

@Ljz7
Copy link

Ljz7 commented Jul 27, 2016

It works like a charm and in a secure way.

We should create a new Repository. = P

@lek-tin
Copy link

lek-tin commented Oct 6, 2016

@contstantine AMazing solution, thanks!

Does anyone know whether the "markdown" package is still supported in Python 3?

@ldelriof
Copy link

for those who use the tag {% markdown %} ... MD content ... {% endmarkdown %} in the template this is my solution

  1. followed @Ljz7's solution on adding the template tag on my app
  2. use markdown deux original markdown_deux_tags.py as model
  3. 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 %}

@jtank38
Copy link

jtank38 commented Aug 4, 2017

Thank you!! it's displaying the code blocks, but the code section is weirdly wide, anyone else find this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants