Server Side Syntax Highlighting with GitDown in Jigsaw

May 8, 2019 • ~ 2 minutes read

code

Several days ago I decided to start a blog using Jigsaw by TightenCo with their starter template.
One of the things I wanted to add, was server-side syntax highlighting, to get rid of JavaScript almost entirely.

So here is how exactly I've done it using GitDown package by @calebporzio.

Installing dependencies

First thing first, you have to install GitDown with Composer

composer require calebporzio/gitdown

Creating custom parser

Under the hood, Jigsaw uses Laravel's container component, and it's excellent because it allows swapping
default parser with the one we need.

After playing with container a bit, I realized that markdown files parser
is bound to TightenCo\Jigsaw\Parsers\MarkdownParser thorough Mni\FrontYAML\Markdown\MarkdownParser interface.

We can override that class, and set new GitDown instance to $parser attribute.
Behind the scenes, Jigsaw will pass each markdown file contents to parse method and store resulting html.

namespace App\Parsers;

use TightenCo\Jigsaw\Parsers\MarkdownParser;
use GitDown\GitDown;

class GitDownParser extends MarkdownParser
{
    /**
     * Settle GitDown as parser
     *
     * @return void
     */
    public function __construct()
    {
        $this->parser = new GitDown(
            getenv('GITHUB_TOKEN'),
            'bozhkos/blog',
            );
    }
}

IMPORTANT NOTE In Jigsaw <1.3.9, parser class was named ParseDownExtraParser.
You have to extend it, instead of TightenCo\Jigsaw\Parsers\MarkdownParser present in the example.

Telling Jigsaw to use a custom parser

Next thing you have to do is adding parser class to autoload.
For that, update your composer.json "autoload" block to following.

"autoload": {
  "psr-4": {
    "App\\Listeners\\": "listeners/",
    "App\\Parsers\\": "Parsers/"
  }

Now, all you have to do is tell Jigsaw to use your class, instead of a built-in one.
For that, add next line at the top of your bootstrap.php file in the project root.

$container->bind(
    Mni\FrontYAML\Markdown\MarkdownParser::class,
    App\Parsers\GitDownParser::class
);

In result, your bootstrap.php file may look like this.

$container->bind(
    Mni\FrontYAML\Markdown\MarkdownParser::class,
    App\Parsers\GitDownParser::class
);
$events->afterBuild(App\Listeners\GenerateSitemap::class);
$events->afterBuild(App\Listeners\GenerateIndex::class);

At this point, if you run ./vendor/bin/jigsaw build command your markdown files is being parsed by GitHub,
which gives you that sweet server-side syntax highlighting.

Setting GitHub token

Without authentication, GitHub limits your API calls to 60 calls/hour. If you use authentication tokens, you can increase this limit to 5000 calls/minute.
You can obtain one here. (You can leave the permissions blank for this token.)

Then, add the following entry to your .env file.

GITHUB_TOKEN=your-token-here

Adding styles

Thankfully GitDown shipped with add the CSS that is required to highlight the code.
You can find more information about styling in repository README.

Done

For this website, changes result in a single 10kb .css file, with no JavaScript, which makes it super light and fast.

The flipside of this approach is builds becoming very slow — not a big deal for me. Now, I comment parser binding when working locally and need builds to go fast.

Once I reach for a better solution - I'll update this post accordingly.

Enjoy!