Skip to content

Instantly share code, notes, and snippets.

@grantmacken
Last active August 29, 2015 13:56
Show Gist options
  • Save grantmacken/8794746 to your computer and use it in GitHub Desktop.
Save grantmacken/8794746 to your computer and use it in GitHub Desktop.
Markdown2 fenced blocks and Pygments. Out of the I box I just couldn't get it work. So I don't use fenced blocks and hacked my own solution.
from lxml.html import tostring, fromstring, html5parser
from pygments import highlight
from pygments.formatters import HtmlFormatter
from pygments.lexers import guess_lexer, get_lexer_by_name
from pygments.filters import VisibleWhitespaceFilter
# hack hack ...
# ignore code contained in pre. I just want the text in the pre
def flatten(elem, include_tail=0):
text = elem.text or ""
for e in elem:
text += flatten(e, 1)
if include_tail and elem.tail: text += elem.tail
return text
# hack hack ...
eDiv = fromstring( '<div xmlns="http://www.w3.org/1999/xhtml" >' + html + '</div>', parser=parser)
formatter = HtmlFormatter(lineseparator="<br/>",cssclass='codehilite')
for element in eDiv.iter("pre"):
language = ''
mdPre = ''
element.text = flatten(element); del element[:]
match=re.search(r'^(\w+)\s', element.text)
if match:
language += match.group(1)
try:
lexer = get_lexer_by_name(language, tabsize="1", stripnl=True, encoding='UTF-8')
mdPre += re.sub(r'^\w+', '', element.text)
except ValueError, e:
try:
# Guess a lexer by the contents of the block.
mdPre += element.text
lexer = guess_lexer(mdPre)
except ValueError, e:
# Just make it plain text.
language = 'text'
mdPre += element.text
lexer = get_lexer_by_name(language, tabsize="1", stripnl=True, encoding='UTF-8')
lexer.add_filter(VisibleWhitespaceFilter(spaces=True, newlines=True, tabs=True, wstokentype=True ))
pygmented = fromstring(highlight(mdPre, lexer, formatter))
element.getparent().replace(element, pygmented)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment