Skip to content

Commit

Permalink
Add Mermaid diagrams converter
Browse files Browse the repository at this point in the history
  • Loading branch information
pronskiy committed Mar 21, 2024
1 parent 4aa3217 commit 9e5a7f6
Show file tree
Hide file tree
Showing 11 changed files with 1,278 additions and 16 deletions.
6 changes: 4 additions & 2 deletions app/SculpinKernel.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

use App\Bundles\AtomFeedGeneratorBundle\SculpinAtomFeedGeneratorBundle;
use App\Bundles\MermaidBundle\SculpinMermaidBundle;
use App\Bundles\SharingImageGeneratorBundle\SculpinSharingImageGeneratorBundle;
use Sculpin\Bundle\SculpinBundle\HttpKernel\AbstractKernel;

Expand All @@ -10,7 +11,8 @@ protected function getAdditionalSculpinBundles(): array
{
return [
SculpinAtomFeedGeneratorBundle::class,
SculpinSharingImageGeneratorBundle::class
SculpinSharingImageGeneratorBundle::class,
SculpinMermaidBundle::class,
];
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace App\Bundles\MermaidBundle\DependencyInjection;

use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;

class Configuration implements ConfigurationInterface
{
public function getConfigTreeBuilder(): TreeBuilder
{
return new TreeBuilder('sculpin_mermaid_converter');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace App\Bundles\MermaidBundle\DependencyInjection;

use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;

class SculpinMermaidExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container): void
{
$loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.xml');
}
}
81 changes: 81 additions & 0 deletions app/src/Bundles/MermaidBundle/MermaidConverter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

namespace App\Bundles\MermaidBundle;

use Dflydev\DotAccessConfiguration\Configuration;
use Sculpin\Core\Event\ConvertEvent;
use Sculpin\Core\Sculpin;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Process\Process;

class MermaidConverter implements EventSubscriberInterface
{
private Configuration $configuration;

public function __construct(Configuration $configuration)
{
$this->configuration = $configuration;
}

public static function getSubscribedEvents(): array
{
return [
Sculpin::EVENT_BEFORE_CONVERT => 'beforeConvert',
];
}

public function beforeConvert(ConvertEvent $event): void
{
$env = $this->configuration->get('env') ?? 'dev';

$source = $event->source();
$original_file = file_get_contents($source->file()->getRealPath());
$original_content = $source->content();
if (is_null($original_content) || !str_contains($original_content, '```mermaid')) {
return;
}

$year = date('Y', $source->data()->get('date'));
$slug = basename($source->data()->get('url'));
$filesystem = new Filesystem();
$assets_path = "/assets/post-images/{$year}/{$slug}/";
$image_path = "output_$env{$assets_path}";
if (!$filesystem->exists($image_path)) {
$filesystem->mkdir($image_path);
}

$process = new Process([
'npx', '-p', '@mermaid-js/mermaid-cli',
'mmdc', '-i', $source->file()->getRealPath(),
// '-o', $source->file()->getRealPath(),
]);
echo "\n";
$process->run(function($type, $buffer) { echo($buffer); });

$finder = new Finder();
$finder->files()->in(dirname($source->file()->getRealPath()))->name('*.svg');

$mermaid_block_regex = '/```mermaid([^\S\n]*\r?\n([\s\S]*?))```/';

$diagrams = [];
foreach ($finder as $file) {
$filesystem->copy($file->getRealPath(), $image_path . $file->getFilename());
$diagrams[] = $assets_path . $file->getFilename();
$filesystem->remove($file->getRealPath());
}

$new_content = $original_content;
$i = 0;
$new_content = preg_replace_callback(
$mermaid_block_regex,
function ($matches) use ($diagrams, &$i) {
return sprintf("![Diagram %d](%s)", $i, $diagrams[$i++]);
},
$new_content
);

$source->setContent($new_content);
}
}
15 changes: 15 additions & 0 deletions app/src/Bundles/MermaidBundle/Resources/config/services.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

<services>
<service id="sculpin_mermaid.converter"
class="App\Bundles\MermaidBundle\MermaidConverter">
<argument type="service" id="sculpin.site_configuration"/>

<tag name="kernel.event_subscriber"/>
</service>
</services>

</container>
9 changes: 9 additions & 0 deletions app/src/Bundles/MermaidBundle/SculpinMermaidBundle.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace App\Bundles\MermaidBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;

class SculpinMermaidBundle extends Bundle
{
}
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"php": "^8.3",
"ext-gd": "*",
"ext-dom": "*",
"sculpin/sculpin": "3.3.0-alpha"
"sculpin/sculpin": "3.3.0-alpha",
"symfony/process": "^6.4|^7.0"
},
"require-dev": {
"roave/security-advisories": "dev-latest"
Expand Down
63 changes: 62 additions & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 9e5a7f6

Please sign in to comment.