Skip to content

Commit

Permalink
Commonmark
Browse files Browse the repository at this point in the history
  • Loading branch information
brendt committed Mar 15, 2024
1 parent 9f919c0 commit b21323e
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 2 deletions.
31 changes: 31 additions & 0 deletions HighlightCodeBlockRendererTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Tempest\Highlight\CommonMark;

use League\CommonMark\Environment\Environment;
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
use League\CommonMark\Extension\CommonMark\Node\Block\FencedCode;
use League\CommonMark\Extension\FrontMatter\FrontMatterExtension;
use League\CommonMark\MarkdownConverter;
use PHPUnit\Framework\TestCase;

class HighlightCodeBlockRendererTest extends TestCase
{
public function test_commonmark(): void
{
$environment = new Environment();

$environment
->addExtension(new CommonMarkCoreExtension())
->addExtension(new FrontMatterExtension())
->addRenderer(FencedCode::class, new \Tempest\Highlight\CommonMark\HighlightCodeBlockRenderer());

$markdown = new MarkdownConverter($environment);

$parsed = $markdown->convert("```php
class Foo {}
```");

$this->assertStringContainsString('hl-keyword', $parsed->getContent());
}
}
28 changes: 27 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,30 @@ Or you can build your own with just a couple of classes:
}
```

You should style your any pre tags yourself.
You should style your any pre tags yourself.

## CommonMark integration

If you're using `league/commonmark`, you can add highlight support to codeblocks like so:

```php
use League\CommonMark\Environment\Environment;
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
use League\CommonMark\Extension\CommonMark\Node\Block\FencedCode;
use League\CommonMark\MarkdownConverter;
use Tempest\Highlight\CommonMark\HighlightCodeBlockRenderer;

$environment = new Environment();

$environment
->addExtension(new CommonMarkCoreExtension())
->addRenderer(FencedCode::class, new HighlightCodeBlockRenderer());

$markdown = new MarkdownConverter($environment);
```

Keep in mind that you need to manually install `league/commonmark`:

```php
composer require league/commonmark;
```
4 changes: 3 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
"require-dev": {
"phpunit/phpunit": "^11.0",
"phpstan/phpstan": "^1.10.0",
"friendsofphp/php-cs-fixer": "^3.21"
"friendsofphp/php-cs-fixer": "^3.21",
"league/commonmark": "^2.4",
"larapack/dd": "^1.1"
},
"scripts": {
"phpunit": "vendor/bin/phpunit --display-warnings --display-skipped --display-deprecations --display-errors --display-notices",
Expand Down
39 changes: 39 additions & 0 deletions src/CommonMark/HighlightCodeBlockRenderer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace Tempest\Highlight\CommonMark;

use InvalidArgumentException;
use League\CommonMark\Extension\CommonMark\Node\Block\FencedCode;
use League\CommonMark\Extension\CommonMark\Renderer\Block\FencedCodeRenderer as BaseFencedCodeRenderer;
use League\CommonMark\Node\Node;
use League\CommonMark\Renderer\ChildNodeRendererInterface;
use League\CommonMark\Renderer\NodeRendererInterface;
use Tempest\Highlight\Highlighter;

class HighlightCodeBlockRenderer implements NodeRendererInterface
{
public function render(Node $node, ChildNodeRendererInterface $childRenderer)
{
if (! $node instanceof FencedCode) {
throw new InvalidArgumentException('Block must be instance of ' . FencedCode::class);
}

$renderer = new BaseFencedCodeRenderer();

$language = $node->getInfoWords()[0] ?? 'txt';

$highlight = new Highlighter();

/** @var \League\CommonMark\Util\HtmlElement $codeBlock */
$codeBlock = $renderer->render($node, $childRenderer);

/** @var string $codeText */
$codeText = $codeBlock->getContents(false)->getContents();

$codeBlock->setContents($highlight->parse($codeText, $language));

$codeBlock->setContents($codeBlock->getContents());

return $codeBlock;
}
}

0 comments on commit b21323e

Please sign in to comment.