Skip to content

Commit eb74281

Browse files
committed
WIP: generate for pdf
1 parent 0df5783 commit eb74281

File tree

9 files changed

+161
-51
lines changed

9 files changed

+161
-51
lines changed

_build/composer.lock

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

_build/conf.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"version": "4.0",
33
"symfony_api_url": "https://api.symfony.com",
4-
"php_doc_url": "https://secure.php.net/manual/en"
4+
"php_doc_url": "https://secure.php.net/manual/en",
5+
"symfony_doc_url": "https://symfony.com/doc/%s"
56
}

_build/src/Command/ParseDoc.php

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
use Doctrine\RST\Event\PostNodeRenderEvent;
77
use Doctrine\RST\Event\PostParseDocumentEvent;
88
use Doctrine\RST\Event\PreBuildRenderEvent;
9-
use Doctrine\RST\Nodes\DocumentNode;
109
use Symfony\Component\Console\Command\Command;
1110
use Symfony\Component\Console\Helper\ProgressBar;
1211
use Symfony\Component\Console\Input\InputInterface;
@@ -15,7 +14,8 @@
1514
use Symfony\Component\Console\Style\SymfonyStyle;
1615
use Symfony\Component\Filesystem\Filesystem;
1716
use Symfony\Component\Finder\Finder;
18-
use SymfonyDocs\JsonGenerator;
17+
use SymfonyDocs\Generator\HtmlForPdfGenerator;
18+
use SymfonyDocs\Generator\JsonGenerator;
1919
use SymfonyDocs\KernelFactory;
2020

2121
/**
@@ -56,22 +56,21 @@ protected function configure()
5656
$this
5757
->addOption('source-dir', null, InputOption::VALUE_REQUIRED, 'RST files Source directory', __DIR__.'/../../..')
5858
->addOption('html-output-dir', null, InputOption::VALUE_REQUIRED, 'HTML files output directory', __DIR__.'/../../html')
59-
->addOption('json-output-dir', null, InputOption::VALUE_REQUIRED, 'JSON files output directory', __DIR__.'/../../json')->addOption('parse-only', null, InputOption::VALUE_OPTIONAL, 'Parse only given directory', null)
60-
// ->addOption('for-pdf', null, InputOption::VALUE_NONE, 'Export for pdf')
61-
;
59+
->addOption('json-output-dir', null, InputOption::VALUE_REQUIRED, 'JSON files output directory', __DIR__.'/../../json')
60+
->addOption('parse-only', null, InputOption::VALUE_OPTIONAL, 'Parse only given directory for PDF (directory relative from source-dir)', null);
6261
}
6362

6463
protected function initialize(InputInterface $input, OutputInterface $output)
6564
{
6665
$this->io = new SymfonyStyle($input, $output);
6766
$this->output = $output;
6867

69-
$this->sourceDir = $this->getRealAbsolutePath($input->getOption('source-dir'));
68+
$this->sourceDir = rtrim($this->getRealAbsolutePath($input->getOption('source-dir')), '/');
7069
if (!$this->filesystem->exists($this->sourceDir)) {
7170
throw new \InvalidArgumentException(sprintf('RST source directory "%s" does not exist', $this->sourceDir));
7271
}
7372

74-
$this->htmlOutputDir = $this->getRealAbsolutePath($input->getOption('html-output-dir'));
73+
$this->htmlOutputDir = rtrim($this->getRealAbsolutePath($input->getOption('html-output-dir')), '/');
7574
if ($this->filesystem->exists($this->htmlOutputDir)) {
7675
$this->filesystem->remove($this->htmlOutputDir);
7776
}
@@ -81,12 +80,19 @@ protected function initialize(InputInterface $input, OutputInterface $output)
8180
$this->filesystem->remove($this->jsonOutputDir);
8281
}
8382

84-
// $this->parseOnly = $this->getRealAbsolutePath($input->getOption('parse-only'));
85-
// if ($this->parseOnly && !$this->filesystem->exists($this->parseOnly)) {
86-
// throw new \InvalidArgumentException(sprintf('Given "parse-only" directory "%s" does not exist', $this->parseOnly));
87-
// }
83+
if ($this->parseOnly = trim($input->getOption('parse-only') ?? '', '/')) {
84+
$absoluteParseOnly = sprintf(
85+
'%s/%s',
86+
$this->sourceDir,
87+
$this->parseOnly
88+
);
8889

89-
$this->builder = new Builder(KernelFactory::createKernel());
90+
if (!$this->filesystem->exists($absoluteParseOnly) || !is_dir($absoluteParseOnly)) {
91+
throw new \InvalidArgumentException(sprintf('Given "parse-only" directory "%s" does not exist', $this->parseOnly));
92+
}
93+
}
94+
95+
$this->builder = new Builder(KernelFactory::createKernel($this->parseOnly));
9096
$eventManager = $this->builder->getConfiguration()->getEventManager();
9197
$eventManager->addEventListener(
9298
[PostParseDocumentEvent::POST_PARSE_DOCUMENT],
@@ -123,12 +129,28 @@ protected function execute(InputInterface $input, OutputInterface $output)
123129
}
124130
}
125131

132+
if (!$this->parseOnly) {
133+
$this->generateJson();
134+
} else {
135+
$this->renderDocForPDF();
136+
}
137+
138+
$this->io->newLine(2);
139+
$this->io->success('Parse process complete');
140+
}
141+
142+
private function generateJson()
143+
{
126144
$this->io->note('Start exporting doc into json files');
127-
$this->progressBar = new ProgressBar($output, $this->finder->count());
145+
$this->progressBar = new ProgressBar($this->output, $this->finder->count());
128146
$jsonGenerator = new JsonGenerator($this->builder->getDocuments()->getAll());
129147
$jsonGenerator->generateJson($this->htmlOutputDir, $this->jsonOutputDir, $this->progressBar);
130-
$this->io->newLine(2);
131-
$this->io->success('Parse process complete');
148+
}
149+
150+
private function renderDocForPDF()
151+
{
152+
$htmlForPdfGenerator = new HtmlForPdfGenerator($this->builder->getDocuments()->getAll());
153+
$htmlForPdfGenerator->generateHtmlForPdf($this->htmlOutputDir, $this->parseOnly);
132154
}
133155

134156
public function handleProgressBar()
@@ -151,7 +173,7 @@ public function postParseDocument(PostParseDocumentEvent $postParseDocumentEvent
151173
{
152174
$file = $postParseDocumentEvent->getDocumentNode()->getEnvironment()->getCurrentFileName();
153175
if (!\in_array($file, $this->parsedFiles)) {
154-
$this->parsedFiles[] = $postParseDocumentEvent->getDocumentNode()->getEnvironment()->getCurrentFileName();
176+
$this->parsedFiles[] = $file;
155177
$this->progressBar->advance();
156178
}
157179
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace SymfonyDocs\Generator;
4+
5+
use Doctrine\RST\Environment;
6+
use Doctrine\RST\Meta\MetaEntry;
7+
8+
trait GeneratorTrait
9+
{
10+
private function getParserFilename(string $filePath, string $inputDir): string
11+
{
12+
return $parserFilename = str_replace([$inputDir.'/', '.html'], ['', ''], $filePath);
13+
}
14+
15+
private function getEnvironment(string $parserFilename): Environment
16+
{
17+
if (!isset($this->environments[$parserFilename])) {
18+
throw new \LogicException(sprintf('Cannot find environment for file "%s"', $parserFilename));
19+
}
20+
21+
return $this->environments[$parserFilename];
22+
}
23+
24+
private function getMeta(string $parserFilename): MetaEntry
25+
{
26+
$environment = $this->getEnvironment($parserFilename);
27+
28+
$allMetas = $environment->getMetas()->getAll();
29+
30+
if (!isset($allMetas[$parserFilename])) {
31+
throw new \LogicException(sprintf('Cannot find metas for file "%s"', $parserFilename));
32+
}
33+
34+
return $allMetas[$parserFilename];
35+
}
36+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace SymfonyDocs\Generator;
4+
5+
use Doctrine\RST\Environment;
6+
use Doctrine\RST\Nodes\DocumentNode;
7+
use Symfony\Component\Filesystem\Filesystem;
8+
use Symfony\Component\Finder\Finder;
9+
10+
/**
11+
* Class HtmlForPdfGenerator
12+
*/
13+
class HtmlForPdfGenerator
14+
{
15+
use GeneratorTrait;
16+
17+
/** @var Environment[] */
18+
private $environments;
19+
20+
public function __construct(array $documents)
21+
{
22+
$this->environments = array_map(
23+
function (DocumentNode $document) {
24+
return $document->getEnvironment();
25+
},
26+
$documents
27+
);
28+
}
29+
30+
public function generateHtmlForPdf(string $htmlDir, string $parseOnly/*, ProgressBar $progressBar*/)
31+
{
32+
$finder = new Finder();
33+
$finder->in($htmlDir)
34+
->depth(0)
35+
->notName($parseOnly);
36+
37+
$fs = new Filesystem();
38+
foreach ($finder as $file) {
39+
$fs->remove($file->getRealPath());
40+
}
41+
42+
$basePath = sprintf('%s/%s', $htmlDir, $parseOnly);
43+
$indexFile = sprintf('%s/%s', $basePath, 'index.html');
44+
if (!$fs->exists($indexFile)) {
45+
throw new \InvalidArgumentException('File "%s" does not exist', $indexFile);
46+
}
47+
48+
$parserFilename = $this->getParserFilename($indexFile, $htmlDir);
49+
$meta = $this->getMeta($parserFilename);
50+
dump(current($meta->getTocs()));
51+
}
52+
}

_build/src/JsonGenerator.php renamed to _build/src/Generator/JsonGenerator.php

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php declare(strict_types=1);
22

3-
namespace SymfonyDocs;
3+
namespace SymfonyDocs\Generator;
44

55
use Doctrine\RST\Environment;
66
use Doctrine\RST\Meta\MetaEntry;
@@ -15,6 +15,8 @@
1515
*/
1616
class JsonGenerator
1717
{
18+
use GeneratorTrait;
19+
1820
/** @var Environment[] */
1921
private $environments;
2022

@@ -68,33 +70,6 @@ public function generateJson(string $inputDir, string $outputDir, ProgressBar $p
6870
$progressBar->finish();
6971
}
7072

71-
private function getParserFilename(string $filePath, string $inputDir): string
72-
{
73-
return $parserFilename = str_replace([$inputDir.'/', '.html'], ['', ''], $filePath);
74-
}
75-
76-
private function getEnvironment(string $parserFilename): Environment
77-
{
78-
if (!isset($this->environments[$parserFilename])) {
79-
throw new \LogicException(sprintf('Cannot find environment for file "%s"', $parserFilename));
80-
}
81-
82-
return $this->environments[$parserFilename];
83-
}
84-
85-
private function getMeta(string $parserFilename): MetaEntry
86-
{
87-
$environment = $this->getEnvironment($parserFilename);
88-
89-
$allMetas = $environment->getMetas()->getAll();
90-
91-
if (!isset($allMetas[$parserFilename])) {
92-
throw new \LogicException(sprintf('Cannot find metas for file "%s"', $parserFilename));
93-
}
94-
95-
return $allMetas[$parserFilename];
96-
}
97-
9873
private function generateToc(MetaEntry $metaEntry, ?array $titles): array
9974
{
10075
if (null === $titles) {

_build/src/KernelFactory.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
*/
1313
final class KernelFactory
1414
{
15-
public static function createKernel(): Kernel
15+
public static function createKernel(?string $parseOnly): Kernel
1616
{
1717
$configuration = new Configuration();
1818
$configuration->setCustomTemplateDirs([__DIR__.'/Templates']);
@@ -24,6 +24,20 @@ public static function createKernel(): Kernel
2424
)
2525
);
2626

27+
if ($parseOnly) {
28+
$configuration->setBaseUrl(
29+
sprintf(
30+
SymfonyDocConfiguration::getSymfonyDocUrl(),
31+
SymfonyDocConfiguration::getVersion()
32+
)
33+
);
34+
$configuration->setBaseUrlEnabledCallable(
35+
static function (string $path) use ($parseOnly) : bool {
36+
return strpos($path, $parseOnly) !== 0;
37+
}
38+
);
39+
}
40+
2741
return new Kernel(
2842
$configuration,
2943
self::getDirectives(),

_build/src/SymfonyDocConfiguration.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,13 @@ public static function getPhpDocUrl(): string
4242

4343
return self::getSymfonyDocConfiguration()['php_doc_url'];
4444
}
45+
46+
public static function getSymfonyDocUrl(): string
47+
{
48+
if (!isset(self::getSymfonyDocConfiguration()['symfony_doc_url'])) {
49+
throw new \RuntimeException('The "symfony_doc_url" must be defined in "/_build/conf.json"');
50+
}
51+
52+
return self::getSymfonyDocConfiguration()['symfony_doc_url'];
53+
}
4554
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<h{{ level }} id="{{ id }}">{{ value|raw }}<a class="headerlink" href="#{{ id }}" title="Permalink to this headline">¶</a></h{{ level }}>
1+
<h{{ titleNode.level }} id="{{ titleNode.id }}">{{ titleNode.value.render()|raw }}<a class="headerlink" href="#{{ titleNode.id }}" title="Permalink to this headline">¶</a></h{{ titleNode.level }}>

0 commit comments

Comments
 (0)