twigphp / Twig

Twig, the flexible, fast, and secure template language for PHP
https://twig.symfony.com/
BSD 3-Clause "New" or "Revised" License
8.17k stars 1.25k forks source link

[twig-extra-bundle] markdown_to_html: Passing configuration to League\CommonMark\CommonMarkConverter #3725

Open Dasug opened 2 years ago

Dasug commented 2 years ago

I'm using the twig extra bundle's markdown_to_html filter on Symfony 6.1 with League/CommonMark as the markdown parser library.

The library has a few configuration options that can be passed to the CommonMarkConverter constructor and cannot be adjusted after the CommonMarkConverter object has been constructed. See https://commonmark.thephpleague.com/2.3/configuration/

Currently however, the LeagueCommonMarkConverterFactory class seems to call the CommonMarkConverter without any parameters: https://github.com/twigphp/Twig/blob/3cefebac2bdc754031578a50732dd7ffdd09bfec/extra/twig-extra-bundle/LeagueCommonMarkConverterFactory.php#L34

Is there therefore currently no simple way to pass configuration to the library or have I missed something obvious?

I have been able to bypass the factory class by manually declaring the CommonMarkConverter constructor arguments in the services.yaml file as such:

League\CommonMark\CommonMarkConverter:
    arguments:
        $config: {allow_unsafe_links: false}

twig.markdown.league_common_mark_converter:
    alias: League\CommonMark\CommonMarkConverter

However as this bypasses the Factory class I then lose the capability of including any CommonMark extensions.

gitrequests commented 1 year ago

Same problem. How to pass configuration to Converter or Environment? Extensions work with configuration from Environment too. We currently cannot set up CommonMark and Extensions at all.

lmeyer commented 1 year ago

I've found a way to pass configuration to CommonMark Environment. I'm not sure if it's completely ok, but seems to work for me (configuration, extensions, extensions configuration).

Basically you need to override LeagueCommonMarkConverterFactory.

Put the following in services.yml :

services:
    twig.markdown.league_common_mark_converter_factory:
        class: App\Twig\LeagueCommonMarkConverterFactory
        arguments:
            - !tagged_iterator twig.markdown.league_extension

Then grab vendor/twig/extra-bundle/LeagueCommonMarkConverterFactory.php, copy and paste it to src/Twig/LeagueCommonMarkConverterFactory.php.

You can now add your own configuration like this :

<?php

namespace App\Twig;

use League\CommonMark\CommonMarkConverter;
use League\CommonMark\Extension\ExtensionInterface;

/**
 * @internal
 */
final class LeagueCommonMarkConverterFactory
{
    private $extensions;

    /**
     * @param ExtensionInterface[] $extensions
     */
    public function __construct(iterable $extensions)
    {
        $this->extensions = $extensions;
    }

    public function __invoke(): CommonMarkConverter
    {
        $config = [
            'renderer' => [
                'allow_unsafe_links' => false,
            ],
            'table' => [
                'wrap' => [
                    'enabled' => true,
                    'tag' => 'div',
                    'attributes' => ['class' => 'table-responsive'],
                ],
            ],
        ];

        $converter = new CommonMarkConverter($config);

        foreach ($this->extensions as $extension) {
            $converter->getEnvironment()->addExtension($extension);
        }

        return $converter;
    }
}
Dasug commented 1 year ago

Looks like in the meantime (actually quite some time ago), someone opened a pull request that tries to address the same issue: #3737 Just mentioning it here so that there's a link between this issue and the pull request.