Skip to content

Commit 6a8dcae

Browse files
authored
Merge pull request #603 from phpDocumentor/feat/plantuml-rendering
Feat: Add plantuml server rendering
2 parents dd41f65 + 4857cfe commit 6a8dcae

File tree

12 files changed

+217
-10
lines changed

12 files changed

+217
-10
lines changed

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"ext-json": "*",
2929
"ext-mbstring": "*",
3030
"doctrine/lexer": "^3.0",
31+
"jawira/plantuml-encoding": "^1.1",
3132
"league/commonmark": "^2.4",
3233
"league/flysystem": "^1.0.5",
3334
"league/tactician": "^1.1",

composer.lock

Lines changed: 56 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/guides-cli/src/DependencyInjection/ContainerFactory.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public function __construct(array $defaultExtensions = [])
4343
$this->configLoader = new XmlFileLoader(new FileLocator());
4444

4545
foreach ([new GuidesExtension(), new ReStructuredTextExtension(), ...$defaultExtensions] as $extension) {
46-
$this->registerExtension($extension);
46+
$this->registerExtension($extension, []);
4747
}
4848
}
4949

@@ -54,7 +54,7 @@ public function loadExtensionConfig(string $extension, array $config): void
5454

5555
$extensionAlias = $this->registeredExtensions[$extensionFqcn] ?? false;
5656
if (!$extensionAlias) {
57-
$this->registerExtension(new $extensionFqcn());
57+
$this->registerExtension(new $extensionFqcn(), $config);
5858

5959
return;
6060
}
@@ -79,10 +79,11 @@ public function create(string $vendorDir): Container
7979
return $this->container;
8080
}
8181

82-
private function registerExtension(ExtensionInterface $extension): void
82+
/** @param array<mixed> $config */
83+
private function registerExtension(ExtensionInterface $extension, array $config): void
8384
{
8485
$this->container->registerExtension($extension);
85-
$this->container->loadFromExtension($extension->getAlias());
86+
$this->container->loadFromExtension($extension->getAlias(), $config);
8687

8788
$this->registeredExtensions[$extension::class] = $extension->getAlias();
8889
}

packages/guides-graphs/composer.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,11 @@
2424
"php": "^8.1",
2525
"phpdocumentor/guides": "self.version",
2626
"phpdocumentor/guides-restructured-text": "self.version",
27+
"jawira/plantuml-encoding": "^1.0",
2728
"symfony/process": "^5.4 || ^6.3",
2829
"twig/twig": "~2.0 || ^3.0"
30+
},
31+
"suggest": {
32+
"jawira/plantuml": "To render graphs locally using plant uml"
2933
}
3034
}

packages/guides-graphs/resources/config/guides-graphs.php

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,37 @@
33
declare(strict_types=1);
44

55
use phpDocumentor\Guides\Graphs\Directives\UmlDirective;
6-
use phpDocumentor\Guides\RestructuredText\Directives\BaseDirective;
6+
use phpDocumentor\Guides\Graphs\Nodes\UmlNode;
7+
use phpDocumentor\Guides\Graphs\Renderer\DiagramRenderer;
8+
use phpDocumentor\Guides\Graphs\Renderer\PlantumlRenderer;
9+
use phpDocumentor\Guides\Graphs\Renderer\PlantumlServerRenderer;
10+
use phpDocumentor\Guides\Graphs\Twig\UmlExtension;
11+
use phpDocumentor\Guides\NodeRenderers\TemplateNodeRenderer;
712
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
813

914
return static function (ContainerConfigurator $container): void {
1015
$container->services()
1116
->defaults()
1217
->autowire()
1318
->autoconfigure()
14-
->instanceof(BaseDirective::class)
19+
->set(UmlDirective::class)
1520
->tag('phpdoc.guides.directive')
16-
->set(UmlDirective::class);
21+
22+
->set('phpdoc.guides.', TemplateNodeRenderer::class)
23+
->tag('phpdoc.guides.noderenderer.html')
24+
->arg('$template', 'body/uml.html.twig')
25+
->arg('$nodeClass', UmlNode::class)
26+
27+
->set(PlantumlRenderer::class)
28+
->arg('$plantUmlBinaryPath', '%guides.graphs.plantuml_binary%')
29+
30+
->set(PlantumlServerRenderer::class)
31+
->arg(
32+
'$plantumlServerUrl',
33+
'%guides.graphs.plantuml_server%',
34+
)
35+
->alias(DiagramRenderer::class, PlantumlServerRenderer::class)
36+
37+
->set(UmlExtension::class)
38+
->tag('twig.extension');
1739
};
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace phpDocumentor\Guides\Graphs\DependencyInjection;
6+
7+
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
8+
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
9+
use Symfony\Component\Config\Definition\ConfigurationInterface;
10+
11+
use function assert;
12+
13+
class Configuration implements ConfigurationInterface
14+
{
15+
public function getConfigTreeBuilder(): TreeBuilder
16+
{
17+
$treeBuilder = new TreeBuilder('Graphs');
18+
$rootNode = $treeBuilder->getRootNode();
19+
assert($rootNode instanceof ArrayNodeDefinition);
20+
21+
$rootNode->children()
22+
->scalarNode('renderer')
23+
->defaultValue('plantuml-server')
24+
->info('Render engine to use for generating graphs')
25+
->end()
26+
->scalarNode('plantuml_server')
27+
->defaultValue('https://www.plantuml.com/plantuml')
28+
->info('URL of the PlantUML server to use')
29+
->end()
30+
->scalarNode('plantuml_binary')
31+
->defaultValue('plantuml')
32+
->info('Path to your local PlantUML binary')
33+
->end();
34+
35+
return $treeBuilder;
36+
}
37+
}

packages/guides-graphs/src/Graphs/DependencyInjection/GraphsExtension.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,37 @@
77
use Symfony\Component\Config\FileLocator;
88
use Symfony\Component\DependencyInjection\ContainerBuilder;
99
use Symfony\Component\DependencyInjection\Extension\Extension;
10+
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
1011
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
1112

1213
use function dirname;
1314

14-
class GraphsExtension extends Extension
15+
class GraphsExtension extends Extension implements PrependExtensionInterface
1516
{
1617
/** @param mixed[] $configs */
1718
public function load(array $configs, ContainerBuilder $container): void
1819
{
20+
$config = $this->processConfiguration(
21+
$this->getConfiguration($configs, $container),
22+
$configs,
23+
);
24+
25+
$container->setParameter('guides.graphs.renderer', $config['renderer']);
26+
$container->setParameter('guides.graphs.plantuml_binary', $config['plantuml_binary']);
27+
$container->setParameter('guides.graphs.plantuml_server', $config['plantuml_server']);
28+
1929
$loader = new PhpFileLoader(
2030
$container,
2131
new FileLocator(dirname(__DIR__, 3) . '/resources/config'),
2232
);
2333

2434
$loader->load('guides-graphs.php');
2535
}
36+
37+
public function prepend(ContainerBuilder $container): void
38+
{
39+
$container->prependExtensionConfig('guides', [
40+
'base_template_paths' => [dirname(__DIR__, 3) . '/resources/template/html'],
41+
]);
42+
}
2643
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace phpDocumentor\Guides\Graphs\Renderer;
6+
7+
use Psr\Log\LoggerInterface;
8+
use Symfony\Contracts\HttpClient\HttpClientInterface;
9+
10+
use function Jawira\PlantUml\encodep;
11+
12+
final class PlantumlServerRenderer implements DiagramRenderer
13+
{
14+
public function __construct(
15+
private readonly HttpClientInterface $httpClient,
16+
private readonly string $plantumlServerUrl,
17+
private readonly LoggerInterface $logger,
18+
) {
19+
}
20+
21+
public function render(string $diagram): string|null
22+
{
23+
$encodedDiagram = encodep($diagram);
24+
25+
$response = $this->httpClient->request(
26+
'GET',
27+
$this->plantumlServerUrl . '/svg/' . $encodedDiagram,
28+
);
29+
30+
if ($response->getStatusCode() !== 200) {
31+
$this->logger->error('Failed to render diagram using server:' . $this->plantumlServerUrl);
32+
33+
return null;
34+
}
35+
36+
return $response->getContent();
37+
}
38+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<title>Uml Directive</title>
5+
6+
</head>
7+
<body>
8+
<div class="section" id="uml-directive">
9+
<h1>Uml Directive</h1>
10+
11+
<figure
12+
class="uml-diagram"
13+
><?xml version="1.0" encoding="us-ascii" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="120px" preserveAspectRatio="none" style="width:163px;height:120px;background:#FFFFFF;" version="1.1" viewBox="0 0 163 120" width="163px" zoomAndPan="magnify"><defs/><g><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="29" x2="29" y1="36.2969" y2="85.4297"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="112" x2="112" y1="36.2969" y2="85.4297"/><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="48" x="5" y="5"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="34" x="12" y="24.9951">class</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="48" x="5" y="84.4297"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="34" x="12" y="104.4248">class</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="90" x="67" y="5"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="76" x="74" y="24.9951">otherClass</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="90" x="67" y="84.4297"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="76" x="74" y="104.4248">otherClass</text><polygon fill="#181818" points="100,63.4297,110,67.4297,100,71.4297,104,67.4297" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="29" x2="106" y1="67.4297" y2="67.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="59" x="36" y="62.3638">message</text><!--SRC=[Iyv9B2vMqBLJo2_9I2ro1lEi579JYuiJqrC1]--></g></svg></figure>
14+
</div>
15+
16+
</body>
17+
</html>

0 commit comments

Comments
 (0)