Mercurial > public > pelican-blog
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 |