Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Bogey's avatar
Level 1

Using Laravel's markdown parser

I need to modify the way laravel's markdown parser converts certain markdown to HTML. Specifically I need to change the HTML the markdown converts to.

The code blocks convert (for the most part) correctly, but I would like to add some classes to the <pre> tag to add some features offered by the javascript syntax highlighting plug-in I'm using. I don't want to resort to DOM manipulation neither by JavaScript nor by the PHP DOM class. I was hoping there's a more elegant solution to this. I don't necessarily want to download any additional packages unless I absolutely have to.

Thank you

0 likes
3 replies
kiwi0134's avatar
kiwi0134
Best Answer
Level 8

Hello,

I can think of two ways of solving this:

  1. Use child selectors for CSS
  2. Implement a CommonMark extension.

My answer focuses on the second approach.

this is quite a common question. Laravel uses the CommonMark library for this: https://github.com/laravel/framework/blob/443ec4438c48923c9caa9c2b409a12b84a10033f/src/Illuminate/Support/Str.php#L619-L624

The CommonMark library can be extended. In the following, you'll find a link to an issue with code on how to add the class attribute to specific elements. Unfortunately, as far as I know, you cannot register CommonMark extensions globally. So if you want to use Str#markdown-Method, you're out of luck. But you can compose your own CommonMark environment in, for example, a custom helper method. It's fairly easy to do. Here is the example for such a class: https://github.com/GrahamCampbell/Laravel-Markdown/issues/155

This is the class Laravel uses: https://github.com/thephpleague/commonmark/blob/e11438aa1ed14505ee84c0e736378b5d6781b3c7/src/GithubFlavoredMarkdownConverter.php#L23

Here's some documentation about extensions: https://commonmark.thephpleague.com/2.4/customization/extensions/

1 like
Bogey's avatar
Level 1

@kiwi0134 Not necessarily the answer I used but your reply directed me into this direction.

I found The Docs to league/markdown package from one of those links you posted. I created a folder 'Traits' in folder app ('app/Traits') and made a file titled MarkdownEnvironment.php.

The following is how I filled it (right now used the example config, but every use case is different).

<?php

namespace App\Traits;

use League\CommonMark\Environment\Environment;
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
use League\CommonMark\Extension\CommonMark\Node\Block\Heading;
use League\CommonMark\Extension\CommonMark\Node\Inline\Link;
use League\CommonMark\Extension\DefaultAttributes\DefaultAttributesExtension;
use League\CommonMark\Extension\Table\Table;
use League\CommonMark\MarkdownConverter;
use League\CommonMark\Node\Block\Paragraph;

trait MarkdownEnvironment {

    public function setEnvironment($environment)
    {
        $config = call_user_func([$this, $environment]);

        $environment = new Environment($config);
        $environment->addExtension(new CommonMarkCoreExtension());

        // Add the extension
        $environment->addExtension(new DefaultAttributesExtension());

        // Instantiate the converter engine and start converting some Markdown!
        return new MarkdownConverter($environment);
    }

    protected function post()
    {
        return [
            'default_attributes' => [
                Heading::class => [
                    'class' => static function (Heading $node) {
                        if ($node->getLevel() === 1) {
                            return 'title-main';
                        } else {
                            return null;
                        }
                    },
                ],
                Table::class => [
                    'class' => 'table',
                ],
                Paragraph::class => [
                    'class' => ['text-center', 'font-comic-sans'],
                ],
                Link::class => [
                    'class' => 'btn btn-link',
                    'target' => '_blank',
                ],
            ],
        ];
    }
}

In my PostController

use App\Traits\MarkdownEnvironment;

class PostController extends Controller
{
    use MarkdownEnvironment;

and the use-case would be

$markdown = $this->setEnvironment('post');

$parsedBody = $markdown->convert($post['body']);

And now you can use the trait in every controller that uses markdown (comments, post...) and have different set of configurations for each environment.

Now I have to find a way to target the tag somehow. Apparently they don't have the pre::class available like they have those classes in their example.

1 like

Please or to participate in this conversation.