Back to Blog

Published: Mar 02, 2021

How to use spatie’s commonmark-highlighter Laravel package

The last couple of weeks I am trying to rebuild my blog in Laravel 8.x. The articles are stored in a MySQL database. I write and store the articles in Markdown. Then when the page is requested, the markdown is converted to html syntax with code highlighting. In this article I will explain how I did this!

Highlight.js

First, I tried to use a package called: GrahamCampbell/Laravel-Markdown. This is a package that convert markdown to html. It is specially made for Laravel and extremely easy to install. First you run the following command: composer require graham-campbell/markdown:^13.1.

Then you can use it in your blade files like this:

For highlighting the code I used highlight.js. The downside of highlight.js is that it renders the color classes after the page is loaded. The screen will load the unstyled code first, and then the colors are being added. The result is a flash of unstyled code blocks. This problem is solved with the commonmark-highlighter package from Spatie.

spatie/commonmark-highlighter

First we will install the package via composer: composer require spatie/commonmark-highlighter.

Then we will add an attribute to our Article model. We can use this attribute in our blade file to show the created html.

<?php  
    namespace App\Models;  
    
    ...
    use App\Services\CommonMark\CommonMark; 
    ...  

    class Article extends Model 
    {  
    ...  
    public function getFormattedTextAttribute()  
    {   
        $body = $this->body;   
        return CommonMark::convertToHtml($body);  
    }  
    ... 
    }

The code above is referencing to a file called: App\Services\CommonMark\CommonMark. So let's create the CommonMark.php file and put it in the App\Services\CommonMark directory. Then add the following code to that file:

<?php

namespace App\Services\CommonMark;

use League\CommonMark\Block\Element\FencedCode;
use League\CommonMark\Block\Element\IndentedCode;
use League\CommonMark\CommonMarkConverter;
use League\CommonMark\Environment;
use League\CommonMark\Extension\GithubFlavoredMarkdownExtension;
use Spatie\CommonMarkHighlighter\FencedCodeRenderer;
use Spatie\CommonMarkHighlighter\IndentedCodeRenderer;

class CommonMark
{

    public static function convertToHtml($markdown)
    {

    $languages = ['html', 'php', 'js', 'yaml', 'bash', 'xml'];

    $environment = Environment::createCommonMarkEnvironment();
    $environment->addExtension(new GithubFlavoredMarkdownExtension());
    $environment->addBlockRenderer(FencedCode::class, new FencedCodeRenderer($languages));
    $environment->addBlockRenderer(IndentedCode::class, new IndentedCodeRenderer($languages));

    $commonMarkConverter = new CommonMarkConverter([], $environment);

    return $commonMarkConverter->convertToHtml($markdown);

    }
}

This code will convert the markdown to html. You can read more about the different options in the CommonMark documentation.

Then we need to call the attribute on the page where we show our article. You can do this by adding the following code in that blade file:

{!! $article->formatted_text !!}

If you load the article page you see that the code is not being highlighted. This is because we don’t have applied css styling. For styling choose a theme from highlight.js. I use the Tomorrow Night Theme.

Now if you load the article page, the code is highlighted.

GitHub

You can see this code live in action in this git repository. If you have any questions, please contact me on Twitter!!

Follow me on twitter to get notified when I post a new blog @larapeakdev

Follow me on twitter to get notified when I post a new blog @larapeakdev