0

My jinja2 template receives a code block which may contain any number of different languages. I would like to pass the correct lexer to the template and render it accordingly using the jinja2-highlight plugin (pygments). I render my template using the 'command' variable, which is a dictionary holding all data necessary in the rest of the template. Ideally I'd like to do something along these lines

{% highlight "{{ command.lexer }}", lineno='table' %}{{ command.script }}{% endhighlight %}

I have tried:

{% highlight command.lexer, lineno='table' %}
{% highlight 'command.lexer', lineno='table' %}
{% highlight '{{ command.lexer }}', lineno='table' %}

and even

{% set lexer = command.lexer %}
{% highlight 'lexer', lineno='table' %}
{% highlight '{{ lexer }}', lineno='table' %}

I can't seem to figure out the combination of rendering rules between jinja2 and jinja2-highlight / pygments.

I'd really like to not do something like:

{% if command.lexer == 'bash' %}
{% highlight 'bash', lineno='table' %}
{% elif command.lexer == 'perl' %}
{% highlight 'perl', lineno='table' %}
...
{% endif %}

It seems to have to do with the jinja2 parser class, but I'm a bit stuck.. feels like I'm overlooking something trivial.

Various error messages all look like:

jinja2.exceptions.TemplateSyntaxError: expected token 'end of statement block', got ','
mvdwrd
  • 33
  • 6

2 Answers2

0

Unfortunately it seems impossible with the current plugin. There is no recursive jinja syntax, and the way the plugin parses does not seem to handle any variable input well. I have contacted the author, with no reply and after browsing the source code of the plugin it seems possible but not worth my time at this moment to make the necessary changes, so ..

{% if command.lexer == 'bash' %}
{% highlight 'bash', lineno='table' %}
{% elif command.lexer == 'perl' %}
{% highlight 'perl', lineno='table' %}
...
{% endif %}

..it is.

mvdwrd
  • 33
  • 6
0

have you tried with a custom filter see http://jinja.pocoo.org/docs/2.10/api/#custom-filters ? (this proposal does'nt use the jinja2-highlight extension, but only pygments)

in the filters.py file (create it if necessary)

# highlight Filter
from pygments import highlight
from pygments import lexers
from pygments.formatters import HtmlFormatter

lexers_dict = dict()
html_formatter = HtmlFormatter()

def do_highlight(content, language):    
    lexers_dict.setdefault(language,lexers.get_lexer_by_name(language))

    return highlight(content, lexers_dict[language], html_formatter)


def init_app(app):
    """Initialize a Flask application with custom filters."""    
    app.jinja_env.filters['light'] = do_highlight

in the template file (.html)

<div class="content">{{ command.script | light(command.lexer) | safe }}</div>

in the app file (app.py) :

from my_app import filters
filters.init_app(app)