Revisiting Pygments and Markdown

 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

  1. typygmentdown by ubernostrum 6 years, 7 months ago
  2. Multiple querysets by t_rybik 4 years, 1 month ago
  3. ParentModel and ChildManager for Model Inheritance by jpwatts 5 years, 7 months ago
  4. EasyFeed class by limodou 7 years, 1 month ago
  5. Another means of updating a subset of a model's fields by insin 6 years, 4 months ago

Comments

djypsy (on August 8, 2007):

@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.

#

(Forgotten your password?)