diff --git a/i2p2www/__init__.py b/i2p2www/__init__.py index d24dbc0b..953ee517 100644 --- a/i2p2www/__init__.py +++ b/i2p2www/__init__.py @@ -43,7 +43,12 @@ MIRRORS_FILE = os.path.join(TEMPLATE_DIR, 'downloads/mirrors') ################### # Application setup -app = application = Flask('i2p2www', template_folder=TEMPLATE_DIR, static_url_path='/_static', static_folder=STATIC_DIR) +class MyFlask(Flask): + jinja_options = dict(Flask.jinja_options) + jinja_options.setdefault('extensions', + []).append('i2p2www.extensions.HighlightExtension') + +app = application = MyFlask('i2p2www', template_folder=TEMPLATE_DIR, static_url_path='/_static', static_folder=STATIC_DIR) app.debug = bool(os.environ.get('APP_DEBUG', 'False')) babel = Babel(app) cache = Cache(app, config={ diff --git a/i2p2www/extensions.py b/i2p2www/extensions.py new file mode 100644 index 00000000..ec723140 --- /dev/null +++ b/i2p2www/extensions.py @@ -0,0 +1,61 @@ +# -*- coding: utf8 -*- + +import sys +from jinja2 import nodes +from jinja2.ext import Extension, Markup + +from pygments import highlight +from pygments.lexers import get_lexer_by_name, guess_lexer +from pygments.formatters import HtmlFormatter +from pygments.util import ClassNotFound + +class HighlightExtension(Extension): + """Highlight code blocks using Pygments + + Example:: + + {% highlight 'python' %} + + from fridge import Beer + + pint_glass = Beer() + pint_glass.drink() + + {% endhighlight %} + """ + tags = set(['highlight']) + + def parse(self, parser): + lineno = parser.stream.next().lineno + + # TODO: + # add support to show line numbers + + # extract the language if available + if not parser.stream.current.test('block_end'): + lang = parser.parse_expression() + else: + lang = nodes.Const(None) + + # body of the block + body = parser.parse_statements(['name:endhighlight'], drop_needle=True) + + return nodes.CallBlock(self.call_method('_highlight', [lang]), + [], [], body).set_lineno(lineno) + + def _highlight(self, lang, caller=None): + # highlight code using Pygments + body = caller() + try: + if lang is None: + lexer = guess_lexer(body) + else: + lexer = get_lexer_by_name(lang, stripall=False) + except ClassNotFound as e: + print(e) + sys.exit(1) + + formatter = HtmlFormatter() + code = highlight(Markup(body).unescape(), lexer, formatter) + return code + diff --git a/reqs.txt b/reqs.txt index 9bdbcceb..df74394b 100644 --- a/reqs.txt +++ b/reqs.txt @@ -2,5 +2,6 @@ Flask==0.9 Flask-Babel==0.8 Flask-Cache==0.10.1 Jinja2==2.6 +Pygments==1.6 docutils==0.9.1 gunicorn==0.17.2