Last time, we saw how to write about Jekyll tags in Jekyll-based blog posts, using HTML entities or the {% raw %}
block.
These techniques cannot be used in syntax-highlighted code blocks (Jekyll’s {% higlight %}
tag or a Markdown code block), since such blocks are always HTML-escaped. Instead, you can wrap all of the code in the block with a Liquid {% raw %}
tag. Since the Liquid tag is processed before Markdown or syntax highlighting, this works perfectly.
{% raw %}
Liquid uses tags like {% if %} or {% for %}.
It also supports variable interpolation: {{ someVariable }}
{% endraw %}
This approach works wonderfully, until you try to put the {% endraw %}
tag in a code block. You can’t put that in a {% raw %}
block, because it will close the block. You can’t use entities, because text within highlighted code blocks is always HTML-escaped.
One potential option would be to break apart the tag; something like
{% raw %}
This is how you show the termination of the `{% raw %}` tag inside itself:
{% endraw %}
However, due to a bug in Liquid, this doesn’t work correctly. This markup is supposed to mean the following:
- Write the literal text
{%
within the{% raw %}
block - Terminate the
{% raw %}
block with{% endraw %}
- Write the rest of the of the tag (
endraw %}
) - Re-enter the
{% raw %}
block to continue with other markup
What actually happens is that Liquid ignores the actual {% endraw %}
command, and treats the entire line as raw text. In other words, the code you see in the above example is (incorrectly) rendered exactly as written. The literal text {%
before the {% endraw %}
causes Liquid to ignore the tag completely, breaking this technique.
To work around this bug, we need to put the {%
text outside the {% raw %}
block. However, Liquid does not have any way to escape a {
, and we can’t use HTML escaping inside the highlighted code block, so there is no obvious way to write the {%
without breaking the parser.
Variables can help here. We can create a Liquid variable that holds the literal text {%
, then interpolate this variable outside the {% raw %}
block.
For example:
{% assign openTag = '{%' %}
{% raw %}
This is how you show the termination of the `{% raw %}` tag inside itself:
{% endraw %}{{ openTag }} endraw %}{% raw %}
This content is back inside the {% raw %} block
{% endraw %}
This code is parsed like this:
- Terminate the
{% raw %}
block with{% endraw %}
- Write the value of the
openTag
variable ({%
) with{{ openTag }}
- Write the remainder of the
{% endraw %}
tag as literal text withendraw %}
- Re-enter the
{% raw %}
block for additional raw content
This technique can also be used to write tags in inline code: `{{ openTag }} sometag %}`
If these workarounds seem complicated, writing this post itself (also in Liquid Markdown!) was even more complicated.
See the source to see how I did it.
https://blog.slaks.net/2013-06-10/jekyll-endraw-in-code/ https://raw.githubusercontent.com/SLaks/SLaks.Blog/gh-pages/_posts/2013-06-10-jekyll-endraw-in-code.md