Commit Redux

A software development blog in commit-sized retrospectives

Colorizing Terminal Output

Friday May 23 2025 • 12:00 PM

Jekyll has support for drafts in the form of a dedicated _drafts directory. The files in this directory won’t have a date in the filename, and to see these drafts when running a local server, the Jekyll process has to be launched with the drafts flag.

$ jekyll serve --drafts

I’ve gotten into the habit of “drafting” by adding a published: false property directly in a post’s front matter. This saves time by not having to rename files or move them between directories.

I modified my Rakefile to output the status of each post.

Rakefile output

Most of the update is contained within a new method called get_post_status(file) which looks like this:

def get_post_status(file)
    content = File.read(file)

    if content =~ /\A---\s*\n(.*?)\n---\s*\n/m
      front_matter = YAML.safe_load($1, permitted_classes: [Time])
      status_text = front_matter["published"] == false ? "unpublished" : "published"
      padded = status_text.ljust(11)

      return status_text == "published" ? "\e[0;32m#{padded}\e[0m" : "\e[0;33m#{padded}\e[0m"
    else
      "unknown".ljust(11)
    end
  end

RegEx

\A---\s*\n(.*?)\n---\s*\n
A RegEx for capturing Jekyll Front Matter

The RegEx above (courtesy of an LLM) is designed to match the formatting of a Jekyll front matter block.

The \A anchors the match to the very start of the string. The first ---\s*\n matches the opening YAML delimiter (---) possibly followed by spaces and a newline. The core of the expression, (.*?)\n, is a non-greedy match that captures everything up to the first newline before the closing delimiter, allowing it to extract the contents of the front matter. The final part, ---\s*\n, matches the closing YAML delimiter (again allowing optional spaces) followed by a newline. The m modifier at the end enables multiline mode so that . in (.*?) can match newline characters as well.

ANSI Color Codes

I found this GitHub Gist with ANSI Color Codes. Adding these to the published / unpublished strings changed the space padding around the post status, so I refactored the method to pad the string prior to adding the color code.

Output Ruby String Format

For the final output, I added another item to the format string.

POST_FILES.each_with_index do |file, index|
  post_status = get_post_status(file) # published, unpublished
  puts "%02d. | %s | %s" % [index + 1, post_status, file]
end