comparison content/Coding/003-nl2br-markdown-ext.rst @ 4:7ce6393e6d30

Adding converted blog posts from old blog.
author Brian Neal <bgneal@gmail.com>
date Thu, 30 Jan 2014 21:45:03 -0600
parents
children
comparison
equal deleted inserted replaced
3:c3115da3ff73 4:7ce6393e6d30
1 A newline-to-break Python-Markdown extension
2 ############################################
3
4 :date: 2011-05-09 22:40
5 :tags: Markdown, Python
6 :slug: a-newline-to-break-python-markdown-extension
7 :author: Brian Neal
8
9 When I launched a new version of my website, I decided the new forums would use
10 Markdown_ instead of BBCode_ for the markup. This decision was mainly a personal
11 one for aesthetic reasons. I felt that Markdown was more natural to write compared
12 to the clunky square brackets of BBCode.
13
14 My new site is coded in Python_ using the Django_ framework. For a Markdown implementation
15 I chose `Python-Markdown`_.
16
17 My mainly non-technical users seemed largely ambivalent to the change from
18 BBCode to Markdown. This was probably because I gave them a nice Javascript editor
19 (`MarkItUp!`_) which inserted the correct markup for them.
20
21 However, shortly after launch, one particular feature of Markdown really riled up
22 some users: the default line break behavior. In strict Markdown, to create a new
23 paragraph, you must insert a blank line between paragraphs. Hard returns (newlines)
24 are simply ignored, just like they are in HTML. You can, however, force a break by
25 ending a line with two blank spaces. This isn't very intuitive, unlike the rest of
26 Markdown.
27
28 Now I agree the default behavior is useful if you are creating an online document, like a blog post.
29 However, non-technical users really didn't understand this behavior at all in the context
30 of a forum post. For example, many of my users post radio-show playlists, formatted with
31 one song per line. When such a playlist was pasted into a forum post, Markdown made it
32 all one giant run-together paragraph. This did not please my users. Arguably, they should
33 have used a Markdown list. But it became clear teaching people the new syntax wasn't
34 going to work, especially when it used to work just fine in BBCode and they had created
35 their playlists in the same way for several years.
36
37 It turns out I am not alone in my observations (or on the receiving end of user wrath). Other,
38 much larger sites, like StackOverflow_ and GitHub_, have altered their Markdown parsers
39 to treat newlines as hard breaks. How can this be done with Python-Markdown?
40
41 It turns out this is really easy. Python-Markdown was designed with user customization
42 in mind by offering an extension facility. The `extension documentation`_ is good,
43 and you can find extension writing help on the friendly `mailing list`_.
44
45 Here is a simple extension for Python-Markdown that turns newlines into HTML <br /> tags.
46
47 .. sourcecode:: python
48
49 """
50 A python-markdown extension to treat newlines as hard breaks; like
51 StackOverflow and GitHub flavored Markdown do.
52
53 """
54 import markdown
55
56
57 BR_RE = r'\n'
58
59 class Nl2BrExtension(markdown.Extension):
60
61 def extendMarkdown(self, md, md_globals):
62 br_tag = markdown.inlinepatterns.SubstituteTagPattern(BR_RE, 'br')
63 md.inlinePatterns.add('nl', br_tag, '_end')
64
65
66 def makeExtension(configs=None):
67 return Nl2BrExtension(configs)
68
69 I saved this code in a file called ``mdx_nl2br.py`` and put it on my ``PYTHONPATH``. You can then use
70 it in a Django template like this:
71
72 .. sourcecode:: django
73
74 {{ value|markdown:"nl2br" }}
75
76 To use the extension in Python code, something like this should do the trick:
77
78 .. sourcecode:: python
79
80 import markdown
81 md = markdown.Markdown(safe_mode=True, extensions=['nl2br'])
82 converted_text = md.convert(text)
83
84 **Update (June 21, 2011):** This extension is now being distributed with
85 Python-Markdown! See `issue 13 on github`_ for the details. Thanks to Waylan
86 Limberg for the help in creating the extension and for including it with
87 Python-Markdown.
88
89
90 .. _Markdown: http://daringfireball.net/projects/markdown/
91 .. _BBCode: http://en.wikipedia.org/wiki/BBCode
92 .. _Python: http://python.org
93 .. _Django: http://djangoproject.com
94 .. _MarkItUp!: http://markitup.jaysalvat.com/home/
95 .. _StackOverflow: http://blog.stackoverflow.com/2009/10/markdown-one-year-later/
96 .. _GitHub: http://github.github.com/github-flavored-markdown/
97 .. _Python-Markdown: http://www.freewisdom.org/projects/python-markdown/
98 .. _extension documentation: http://www.freewisdom.org/projects/python-markdown/Writing_Extensions
99 .. _mailing list: http://lists.sourceforge.net/lists/listinfo/python-markdown-discuss
100 .. _issue 13 on github: https://github.com/waylan/Python-Markdown/issues/13