A variation on a theme, inspired by snippet 39 and snippet 119. The
intent is to provide a more generic and simple mechanism for combining
Markdown with Pygments. Common scenarios could include blogging or commenting. Snippet 119 seemed too specific and perhaps not as
efficient, needing to process the HTML twice to accomplish it's ends. The one snag in the implementation is the need to use a tag other than code
as a wrapper. See the comments for details.
You will need the BeautifulSoup module installed.
Sample usage:
from django.db import models
class Blog(models.Model):
'''Bare bones blogging model'''
title = models.CharField(maxlength=255)
slug = models.SlugField(maxlength=255, prepopulate_from=('title',))
pub_date = models.DateTimeField()
# the cooked view, cached for quick retrieval
blog = models.TextField()
# the raw markdown-encoded text, saved for subsequent edits
markdown = models.TextField()
def save(self):
from datetime import datetime
if not self.id and not self.pub_date:
self.pub_date = datetime.now()
self.blog = pygmented_markdown(self.markdown)
super(Blog, self).save()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | from pygments.lexers import LEXERS, get_lexer_by_name
from pygments import highlight
from pygments.formatters import HtmlFormatter
from BeautifulSoup import BeautifulSoup
from markdown import markdown
# a tuple of known lexer names
_lexer_names = reduce(lambda a,b: a + b[2], LEXERS.itervalues(), ())
# default formatter
_formatter = HtmlFormatter(cssclass='source')
def pygmented_markdown(raw):
'''
Accepts raw markdown text for markup processing. Using BeatifuleSoup on the
results of markdown processing, the following constructs will be replaced
by with pygmented highlighting. E.g.::
<pre class="???">
...
</pre>
Where ``???`` is the name of a supported pygments lexer, e.g.: ``python``,
``css``, ``html``.
Note: Semantically, it would make more sense to wrap the code in a
``<code>...</code>`` tag; however, my tests using markdown.py - as well as
markdown.pl from John Gruber - have shown that the inner HTML of the
``<code>`` tag is not immune to translation.
'''
soup = BeautifulSoup(markdown(raw))
for tag in soup.findAll('pre'):
lexer_name = tag.get('class')
if lexer_name and lexer_name in _lexer_names:
lexer = get_lexer_by_name(lexer_name, stripnl=True, encoding='UTF-8')
tag.replaceWith(highlight(tag.renderContents(), lexer, _formatter))
return unicode(soup)
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 11 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 6 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 7 months ago
- Help text hyperlinks by sa2812 1 year, 7 months ago
Comments
@waylan:
Thanks for the feedback. I was unaware of this extension, and will make use of it for my own personal site. However, in a few other work-related scenarios, I don't have this option open to me, so I'm stuck using the brute force mechanism shown here.
#
Please login first before commenting.