Controlling Whitespace and Empty Lines in Jekyll
Jekyll-generated code can be pretty, too.NOTE: This post will be obsolete soon.
Proper whitespace control was added to Liquid 4. Liquid 4 has now been added to Jekyll, though it’s not part of an official Jekyll release (yet.)
This post applies to Jekyll 3.4.3 and earlier, which use earlier versions of Liquid.
May 29, 2017
The Problem
This blog is powered by the Jekyll static site generator, which internally uses Liquid Markup for templating.
I noticed that Jekyll-generated output contains unwanted empty lines when there are corresponding Liquid template lines in the source code that wouldn’t otherwise produce visible output.
This example from Liquid’s whitespace control documentation illustrates the problem:
Liquid Input
{% assign username = "John G. Chalmers-Smith" %}
{% if username and username.size > 10 %}
Wow, {{ username }}, you have a long name!
{% else %}
Hello there!
{% endif %}
Generated Output
Wow, John G. Chalmers-Smith, you have a long name!
The empty lines are undesirable since they are unnecessary and they make the generated output uglier.
The Solution
Here’s my solution for removing empty lines from Jekyll-generated code.
- Add the following Jekyll plugin by creating a file named
_plugins/regex_filter.rb
with the following contents:
# https://stackoverflow.com/a/25802375/278810
module Jekyll
module RegexFilter
def replace_regex(input, reg_str, repl_str)
re = Regexp.new reg_str
# This will be returned
input.gsub re, repl_str
end
end
end
Liquid::Template.register_filter(Jekyll::RegexFilter)
- Use the following pattern in your Liquid templates:
{% capture output %}
Content starts here
Here are lines with more content
{% if false %}This generates a blank line that will be stripped from the output{% endif %}
Content ends here
{% endcapture %}{{ output | replace_regex: '^\s*$\n', ''}}
- That’s it!
The idea is that a block of template-generated output is captured within the template itself, then fed to a custom Liquid filter (the Jekyll plugin) that removes all empty lines using a regular expression.
The {% raw %}{% endcapture %}{% endraw %}
and {% raw %}{% output %}{% endraw %}
Liquid tags appear on the same line to prevent an empty line from appearing at the top of the generated output.
You can chain multiple invocations of the replace_regex
filter together if you want to perform multiple distinct whitespace transformations.
This is a simple idea, but I think it helps make Jekyll-generated code more pleasant to look at.