Skip to content

Implement JSON builder #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/sphinx/out/crud.fjson
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"parents": [], "prev": {"link": "../dashboards/", "title": "Dashboards"}, "next": {"link": "../design/", "title": "Design"}, "title": "CRUD", "meta": null, "body": "<section id=\"crud\">\n<h1>CRUD<a class=\"headerlink\" href=\"#crud\" title=\"Permalink to this heading\">\u00b6</a></h1>\n<p>CRUD stands for: \u201ccreate, read, update, delete\u201d.</p>\n<p>Or it might be: \u201cCrazy runner\u2019s utter delight\u201d (which would\nbe, of course, a warm spring morning).</p>\n</section>\n", "metatags": "<meta name=\"generator\" content=\"Docutils 0.19: https://docutils.sourceforge.io/\" />\n", "rellinks": [["genindex", "General Index", "I", "index"], ["design", "Design", "N", "next"], ["dashboards", "Dashboards", "P", "previous"]], "sourcename": "crud.rst.txt", "toc": "<ul>\n<li><a class=\"reference internal\" href=\"#\">CRUD</a></li>\n</ul>\n", "display_toc": false, "page_source_suffix": ".rst", "current_page_name": "crud", "sidebars": ["about.html", "navigation.html", "relations.html", "searchbox.html", "donate.html"], "customsidebar": null, "alabaster_version": "0.7.13"}
1 change: 1 addition & 0 deletions lib/sphinx/out/dashboards.fjson
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"parents": [], "prev": {"link": "../", "title": "JSON Generation Test"}, "next": {"link": "../crud/", "title": "CRUD"}, "title": "Dashboards", "meta": null, "body": "<section id=\"dashboards\">\n<h1>Dashboards<a class=\"headerlink\" href=\"#dashboards\" title=\"Permalink to this heading\">\u00b6</a></h1>\n<p>A file about dashboards\u2026 probably the one in an admin area\u2026 but\nmaybe also the ones found in a car!</p>\n</section>\n", "metatags": "<meta name=\"generator\" content=\"Docutils 0.19: https://docutils.sourceforge.io/\" />\n", "rellinks": [["genindex", "General Index", "I", "index"], ["crud", "CRUD", "N", "next"], ["index", "JSON Generation Test", "P", "previous"]], "sourcename": "dashboards.rst.txt", "toc": "<ul>\n<li><a class=\"reference internal\" href=\"#\">Dashboards</a></li>\n</ul>\n", "display_toc": false, "page_source_suffix": ".rst", "current_page_name": "dashboards", "sidebars": ["about.html", "navigation.html", "relations.html", "searchbox.html", "donate.html"], "customsidebar": null, "alabaster_version": "0.7.13"}
1 change: 1 addition & 0 deletions lib/sphinx/out/design.fjson
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"parents": [], "prev": {"link": "../crud/", "title": "CRUD"}, "next": {"link": "sub-page/", "title": "Design Sub-Page"}, "title": "Design", "meta": null, "body": "<section id=\"design\">\n<h1>Design<a class=\"headerlink\" href=\"#design\" title=\"Permalink to this heading\">\u00b6</a></h1>\n<p>Something that should not be left to most programmers\nto try to do.</p>\n<section id=\"section-1\">\n<h2>Section 1<a class=\"headerlink\" href=\"#section-1\" title=\"Permalink to this heading\">\u00b6</a></h2>\n<p>The toctree below should affects the next/prev. The\nfirst entry is effectively ignored, as it was already\nincluded by the toctree in index.rst (which is parsed first).</p>\n<section id=\"some-subsection\">\n<h3>Some subsection<a class=\"headerlink\" href=\"#some-subsection\" title=\"Permalink to this heading\">\u00b6</a></h3>\n<p>This is a subsection of the first section. That\u2019s all.</p>\n</section>\n<section id=\"id1\">\n<h3>Some subsection<a class=\"headerlink\" href=\"#id1\" title=\"Permalink to this heading\">\u00b6</a></h3>\n<p>This sub-section uses the same title as before to test that the tool\nnever generated two or more headings with the same ID.</p>\n</section>\n</section>\n<section id=\"section-2\">\n<h2>Section 2<a class=\"headerlink\" href=\"#section-2\" title=\"Permalink to this heading\">\u00b6</a></h2>\n<p>However, crud (which is ALSO included in the toctree in index.rst),\nWILL be read here, as the \u201ccrud\u201d in index.rst has not been read\nyet (design comes first). Also, design/sub-page WILL be considered.</p>\n<section id=\"id2\">\n<h3>Some subsection<a class=\"headerlink\" href=\"#id2\" title=\"Permalink to this heading\">\u00b6</a></h3>\n<p>This sub-section also uses the same title as in the previous section\nto test that the tool never generated two or more headings with the same ID.</p>\n<div class=\"toctree-wrapper compound\">\n<ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../dashboards/\">Dashboards</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"../crud/\">CRUD</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"sub-page/\">Design Sub-Page</a></li>\n</ul>\n</div>\n</section>\n</section>\n</section>\n", "metatags": "<meta name=\"generator\" content=\"Docutils 0.19: https://docutils.sourceforge.io/\" />\n", "rellinks": [["genindex", "General Index", "I", "index"], ["design/sub-page", "Design Sub-Page", "N", "next"], ["crud", "CRUD", "P", "previous"]], "sourcename": "design.rst.txt", "toc": "<ul>\n<li><a class=\"reference internal\" href=\"#\">Design</a><ul>\n<li><a class=\"reference internal\" href=\"#section-1\">Section 1</a><ul>\n<li><a class=\"reference internal\" href=\"#some-subsection\">Some subsection</a></li>\n<li><a class=\"reference internal\" href=\"#id1\">Some subsection</a></li>\n</ul>\n</li>\n<li><a class=\"reference internal\" href=\"#section-2\">Section 2</a><ul>\n<li><a class=\"reference internal\" href=\"#id2\">Some subsection</a></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n", "display_toc": true, "page_source_suffix": ".rst", "current_page_name": "design", "sidebars": ["about.html", "navigation.html", "relations.html", "searchbox.html", "donate.html"], "customsidebar": null, "alabaster_version": "0.7.13"}
1 change: 1 addition & 0 deletions lib/sphinx/out/design/sub-page.fjson
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"parents": [{"link": "../", "title": "Design"}], "prev": {"link": "../", "title": "Design"}, "next": {"link": "../../fields/", "title": "Fields"}, "title": "Design Sub-Page", "meta": {}, "body": "<section id=\"design-sub-page\">\n<h1>Design Sub-Page<a class=\"headerlink\" href=\"#design-sub-page\" title=\"Permalink to this heading\">\u00b6</a></h1>\n<p>Hi! I\u2019m a design sub-page, to determine if the next/previous\nfunctionality works correctly. Have a designy day!</p>\n</section>\n", "metatags": "<meta name=\"generator\" content=\"Docutils 0.19: https://docutils.sourceforge.io/\" />\n", "rellinks": [["genindex", "General Index", "I", "index"], ["fields", "Fields", "N", "next"], ["design", "Design", "P", "previous"]], "sourcename": "design/sub-page.rst.txt", "toc": "<ul>\n<li><a class=\"reference internal\" href=\"#\">Design Sub-Page</a></li>\n</ul>\n", "display_toc": false, "page_source_suffix": ".rst", "current_page_name": "design/sub-page", "sidebars": ["about.html", "navigation.html", "relations.html", "searchbox.html", "donate.html"], "customsidebar": null, "alabaster_version": "0.7.13"}
1 change: 1 addition & 0 deletions lib/sphinx/out/fields.fjson
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"parents": [], "prev": {"link": "../design/sub-page/", "title": "Design Sub-Page"}, "next": null, "title": "Fields", "meta": null, "body": "<section id=\"fields\">\n<h1>Fields<a class=\"headerlink\" href=\"#fields\" title=\"Permalink to this heading\">\u00b6</a></h1>\n<p>I love fields: big open prairies, grass fields, corn fields\u2026 really,\nany type of field, I\u2019m a fan.</p>\n</section>\n", "metatags": "<meta name=\"generator\" content=\"Docutils 0.19: https://docutils.sourceforge.io/\" />\n", "rellinks": [["genindex", "General Index", "I", "index"], ["design/sub-page", "Design Sub-Page", "P", "previous"]], "sourcename": "fields.rst.txt", "toc": "<ul>\n<li><a class=\"reference internal\" href=\"#\">Fields</a></li>\n</ul>\n", "display_toc": false, "page_source_suffix": ".rst", "current_page_name": "fields", "sidebars": ["about.html", "navigation.html", "relations.html", "searchbox.html", "donate.html"], "customsidebar": null, "alabaster_version": "0.7.13"}
1 change: 1 addition & 0 deletions lib/sphinx/out/index.fjson
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"parents": [], "prev": null, "next": {"link": "dashboards/", "title": "Dashboards"}, "title": "JSON Generation Test", "meta": null, "body": "<section id=\"json-generation-test\">\n<h1>JSON Generation Test<a class=\"headerlink\" href=\"#json-generation-test\" title=\"Permalink to this heading\">\u00b6</a></h1>\n<p>In the toctree below, \u201cdesign\u201d also has a toctree, which affects\nhow these will be parsed.</p>\n<div class=\"toctree-wrapper compound\">\n<ul>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"dashboards/\">Dashboards</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"crud/\">CRUD</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"design/\">Design</a></li>\n<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"fields/\">Fields</a></li>\n</ul>\n</div>\n</section>\n", "metatags": "<meta name=\"generator\" content=\"Docutils 0.19: https://docutils.sourceforge.io/\" />\n", "rellinks": [["genindex", "General Index", "I", "index"], ["dashboards", "Dashboards", "N", "next"]], "sourcename": "index.rst.txt", "toc": "<ul>\n<li><a class=\"reference internal\" href=\"#\">JSON Generation Test</a></li>\n</ul>\n", "display_toc": false, "page_source_suffix": ".rst", "current_page_name": "index", "sidebars": ["about.html", "navigation.html", "relations.html", "searchbox.html", "donate.html"], "customsidebar": null, "alabaster_version": "0.7.13"}
26 changes: 26 additions & 0 deletions lib/sphinx/out/orphan.fjson
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"parents": [],
"prev": null,
"next": null,
"title": "Orphan",
"meta": {},
"body": "<section id=\"orphan\">\n<h1>Orphan<a class=\"headerlink\" href=\"#orphan\" title=\"Permalink to this heading\">\u00b6</a></h1>\n<p>I\u2019m a little lonely, because nobody has included me in their toctree!</p>\n</section>\n",
"metatags": "<meta name=\"generator\" content=\"Docutils 0.19: https://docutils.sourceforge.io/\" />\n",
"rellinks": [
["genindex", "General Index", "I", "index"]
],
"sourcename": "orphan.rst.txt",
"toc": "<ul>\n<li><a class=\"reference internal\" href=\"#\">Orphan</a></li>\n</ul>\n",
"display_toc": false,
"page_source_suffix": ".rst",
"current_page_name": "orphan",
"sidebars": [
"about.html",
"navigation.html",
"relations.html",
"searchbox.html",
"donate.html"
],
"customsidebar": null,
"alabaster_version": "0.7.13"
}
5 changes: 5 additions & 0 deletions lib/symfony-extension/config/renderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use SymfonyTools\GuidesExtension\NodeRenderer\CodeNodeRenderer;
use SymfonyTools\GuidesExtension\NodeRenderer\MenuEntryRenderer;
use SymfonyTools\GuidesExtension\Node\ExternalLinkNode;
use SymfonyTools\GuidesExtension\Renderer\JsonRenderer;
use SymfonyTools\GuidesExtension\Twig\CodeExtension;
use SymfonyTools\GuidesExtension\Twig\UrlExtension;
use Twig\Extension\ExtensionInterface;
Expand Down Expand Up @@ -42,5 +43,9 @@

->set(SymfonyHighlighter::class)
->decorate(Highlighter::class)

->set(JsonRenderer::class)
->arg('$nodeRendererFactory', service('phpdoc.guides.noderenderer.factory.json'))
->tag('phpdoc.renderer.typerenderer', ['format' => 'json', 'noderender_tag' => 'phpdoc.guides.noderenderer.html'])
;
};
2 changes: 1 addition & 1 deletion lib/symfony-extension/config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

->set(EventDispatcherInterface::class, EventDispatcher::class)

->set(BuildConfig::class)
->set(BuildConfig::class)->public()

->set(DocBuilder::class)->public()
;
Expand Down
12 changes: 11 additions & 1 deletion lib/symfony-extension/src/Build/BuildConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,21 @@ public function getSymfonyRepositoryUrl(): string
return str_replace('{symfonyVersion}', $this->getSymfonyVersion(), self::SYMFONY_REPOSITORY_URL);
}

public function getFormat(): string
public function setOutputFormat(string $format): void
{
$this->format = $format;
}

public function getOutputFormat(): string
{
return $this->format;
}

public function getFormat(): string
{
return 'fjson' === $this->format ? 'html' : $this->format;
}

public function createProjectNode(): ProjectNode
{
return new ProjectNode('Symfony', $this->symfonyVersion);
Expand Down
26 changes: 12 additions & 14 deletions lib/symfony-extension/src/DocBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@
use phpDocumentor\Guides\Compiler\CompilerContext;
use phpDocumentor\Guides\Handlers\CompileDocumentsCommand;
use phpDocumentor\Guides\Handlers\ParseDirectoryCommand;
use phpDocumentor\Guides\Handlers\RenderCommand;
use phpDocumentor\Guides\Handlers\RenderDocumentCommand;
use phpDocumentor\Guides\Nodes\DocumentNode;
use phpDocumentor\Guides\RenderContext;
use phpDocumentor\Guides\Renderer\TypeRendererFactory;
use phpDocumentor\Guides\Twig\Theme\ThemeManager;
use SymfonyTools\GuidesExtension\Build\BuildConfig;
use SymfonyTools\GuidesExtension\Build\BuildEnvironment;
Expand All @@ -27,6 +29,7 @@ final class DocBuilder
{
public function __construct(
private CommandBus $commandBus,
private TypeRendererFactory $rendererFactory,
private ThemeManager $themeManager,
private BuildConfig $buildConfig,
) {
Expand All @@ -43,20 +46,15 @@ public function build(BuildEnvironment $buildEnvironment): void

$documents = $this->commandBus->handle(new CompileDocumentsCommand($documents, new CompilerContext($projectNode)));

foreach ($documents as $document) {
$this->commandBus->handle(new RenderDocumentCommand(
$document,
RenderContext::forDocument(
$document,
$documents,
$buildEnvironment->getSourceFilesystem(),
$buildEnvironment->getOutputFilesystem(),
'/',
'html',
$projectNode
)
));
}
$this->rendererFactory->getRenderSet($this->buildConfig->getOutputFormat())->render(
new RenderCommand(
$this->buildConfig->getFormat(),
$documents,
$buildEnvironment->getSourceFilesystem(),
$buildEnvironment->getOutputFilesystem(),
$projectNode
)
);
}

public function buildString(string $contents): string
Expand Down
67 changes: 67 additions & 0 deletions lib/symfony-extension/src/Renderer/JsonRenderer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

/*
* This file is part of the Guides SymfonyExtension package.
*
* (c) Wouter de Jong
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace SymfonyTools\GuidesExtension\Renderer;

use phpDocumentor\Guides\Handlers\RenderCommand;
use phpDocumentor\Guides\NodeRenderers\NodeRendererFactory;
use phpDocumentor\Guides\Nodes\Node;
use phpDocumentor\Guides\RenderContext;
use phpDocumentor\Guides\Renderer\TypeRenderer;
use phpDocumentor\Guides\Renderer\UrlGenerator\UrlGeneratorInterface;

class JsonRenderer implements TypeRenderer
{
public function __construct(
private NodeRendererFactory $nodeRendererFactory,
private UrlGeneratorInterface $urlGenerator,
) {
}

public function render(RenderCommand $renderCommand): void
{
$projectRenderContext = RenderContext::forProject(
$renderCommand->getProjectNode(),
$renderCommand->getDocumentArray(),
$renderCommand->getOrigin(),
$renderCommand->getDestination(),
$renderCommand->getDestinationPath(),
$renderCommand->getOutputFormat(),
)->withIterator($renderCommand->getDocumentIterator());

foreach ($projectRenderContext->getIterator() as $documentNode) {
$context = $projectRenderContext->withDocument($documentNode);
$html = implode(
"\n",
array_map(fn (Node $node): string => $this->nodeRendererFactory->get($node)->render($node, $context), $documentNode->getChildren())
);

$prevDocument = $context->getIterator()->previousNode();
$nextDocument = $context->getIterator()->nextNode();
$context->getDestination()->put(
$context->getDestinationPath().'/'.$context->getCurrentFileName().'.fjson',
json_encode([
'parents' => [],
'prev' => $prevDocument ? [
'title' => $prevDocument->getTitle()?->toString() ?? '',
'link' => substr($this->urlGenerator->createFileUrl($context, $prevDocument->getFilePath()), 0, -4).'html',
] : null,
'next' => $nextDocument ? [
'title' => $nextDocument->getTitle()?->toString() ?? '',
'link' => substr($this->urlGenerator->createFileUrl($context, $nextDocument->getFilePath()), 0, -4).'html',
] : null,
'title' => $documentNode->getTitle()?->toString() ?? '',
'body' => $html,
], \JSON_PRETTY_PRINT)
);
}
}
}
Loading