Skip to content

addRenderer and addExtension inconsistency #1023

Open
@Arcesilas

Description

Version(s) affected

2.4.2

Description

When adding an additional custom renderer, it is not executed if no priority is set when added via an extension.

Renderer added with: $environment->addRenderer($class, $renderer) will be actually run on the appropriate node class, whereas renderer added via the register method of an extension will not be run at all.

Dump of $environment->getRenderersForClass($class) shows that the order of the renderers for the class if not the same when added via addRenderer() or via an extension.

When renderer is added via an extension, if it is added with a priority > 0, it will take precedence on the default renderer and be executed. It's ok, but adding a renderer via both methods should produce the same result, especially as renderer is added with the same priority in both cases by default.

If this behavior is not bogus, then maybe it should be explained in the documentation: I've spent about 2 hours trying to figure out why my extension was not working while in my previous tests with addRenderer the renderer was working fine...

How to reproduce

Create a custom renderer. For example:

class YamlCodeRenderer implements NodeRendererInterface
{
    public function render(Node $node, ChildNodeRendererInterface $childRenderer)
    {
        if (str_starts_with($node->getInfo(), 'yaml')) {
            return "We should do something with YAML code block";
        }
    }
}

Register the renderer:

$cmark = new \League\CommonMark\CommonMarkConverter();
$cmark->getEnvironment()->addRenderer(FencedCode::class, new YamlCodeRenderer());
echo $cmark->convert("```yaml\ntest\n```");

Output:

We should do something with YAML code block

Now, register the renderer via an extension:

class MyExtension implements ExtensionInterface
{
    public function register(EnvironmentBuilderInterface $environment): void
    {
        $environment->addRenderer(
            FencedCode::class,
            new YamlCodeRenderer()
        );
    }
}

and:

$cmark = new \League\CommonMark\CommonMarkConverter();
$cmark->getEnvironment()->addExtension(new MyExtension());
echo $cmark->convert("```yaml\ntest\n```");

Output:

test

Possible solution

No response

Additional context

Dump of $environment->getRenderersForClass() when added via $environment->addRenderer():

class League\CommonMark\Util\PrioritizedList#40 (2) {
  private array $list =>
  array(1) {
    [0] =>
    array(2) {
      [0] =>
      class YamlCodeRenderer#39 (0) {
      }
      [1] =>
      class League\CommonMark\Extension\CommonMark\Renderer\Block\FencedCodeRenderer#70 (0) {
      }
    }
  }
  private ?Traversable $optimized =>
  class ArrayIterator#116 (1) {
    private $storage =>
    array(2) {
      [0] =>
      class YamlCodeRenderer#39 (0) {
      }
      [1] =>
      class League\CommonMark\Extension\CommonMark\Renderer\Block\FencedCodeRenderer#70 (0) {
      }
    }
  }
}

Dump of $environment->getRenderersForClass() when added via extension:

class League\CommonMark\Util\PrioritizedList#70 (2) {
  private array $list =>
  array(1) {
    [0] =>
    array(2) {
      [0] =>
      class League\CommonMark\Extension\CommonMark\Renderer\Block\FencedCodeRenderer#69 (0) {
      }
      [1] =>
      class YamlCodeRenderer#102 (0) {
      }
    }
  }
  private ?Traversable $optimized =>
  class ArrayIterator#117 (1) {
    private $storage =>
    array(2) {
      [0] =>
      class League\CommonMark\Extension\CommonMark\Renderer\Block\FencedCodeRenderer#69 (0) {
      }
      [1] =>
      class YamlCodeRenderer#102 (0) {
      }
    }
  }
}

Did this project help you today? Did it make you happy in any way?

Thanks a lot for this great package. It's incredibly powerful and customizable: it helps make everything become possible.

Metadata

Assignees

Labels

do not closeIssue which won't close due to inactivitydocumentationDocumentation issues or updatesenhancementNew functionality or behavior

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions