Allow code in-lining instead of everything

Create snip content parser
This commit is contained in:
Tim
2023-04-06 22:50:54 +02:00
parent f20608082a
commit bf63b7a274
7 changed files with 134 additions and 5 deletions

View File

@ -0,0 +1,21 @@
<?php
namespace App\Service\SnipParser;
use App\Service\SnipParser\Stages\HtmlEscapeStage;
use App\Service\SnipParser\Stages\ReplaceBlocksStage;
use League\Pipeline\PipelineBuilder;
class Pipeline
{
public function parse(string $payload): string
{
$builder = new PipelineBuilder();
$pipeline = $builder
->add(new HtmlEscapeStage())
->add(new ReplaceBlocksStage('<pre><code>', '</code></pre>', '```'))
->build();
return $pipeline->process($payload);
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace App\Service\SnipParser\Stages;
use League\Pipeline\StageInterface;
class HtmlEscapeStage implements StageInterface
{
public function __invoke(mixed $payload): string
{
return htmlspecialchars($payload, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace App\Service\SnipParser\Stages;
use InvalidArgumentException;
use League\Pipeline\StageInterface;
class ReplaceBlocksStage implements StageInterface
{
public function __construct(
public readonly string $openTag = '<pre><code>',
public readonly string $closeTag = '</code></pre>',
public readonly string $delimiter = '```'
) {}
public function __invoke(mixed $payload): string
{
if (!is_string($payload)) {
throw new InvalidArgumentException('The payload must be a string.');
}
return $this->replaceCodeBlocks($payload);
}
private function replaceCodeBlocks(string $text): string
{
$pattern = sprintf('/%s(.+?)%s/s', preg_quote($this->delimiter), preg_quote($this->delimiter));
return preg_replace_callback($pattern, function ($matches) {
return $this->openTag . trim($matches[1]) . $this->closeTag;
}, $text);
}
}