Josh Dick portrait Josh Dick

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.

1) 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)

2) 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', ''}}

3) 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 {% endcapture %} and {% output %} 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.