Skip to content

Commit 8236aed

Browse files
committed
Create json files associated
1 parent f522f00 commit 8236aed

File tree

6 files changed

+363
-6
lines changed

6 files changed

+363
-6
lines changed

_build/.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
/vendor/
2-
/tests/_output
2+
/tests/_output
3+
/tests/_outputJson

_build/composer.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@
99
}
1010
},
1111
"require": {
12+
"ext-json": "*",
1213
"doctrine/rst-parser": "dev-sf-docs-tweaks",
1314
"scrivo/highlight.php": "v9.12.0.5",
1415
"symfony/phpunit-bridge": "^4.1",
15-
"symfony/filesystem": "^4.1"
16+
"symfony/filesystem": "^4.1",
17+
"symfony/dom-crawler": "^4.1",
18+
"symfony/css-selector": "^4.1"
1619
},
1720
"repositories": [
1821
{

_build/composer.lock

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

_build/notes.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,5 @@ Notes
1818
- /!\ tip / caution / node / etc... with nested reference
1919
- no more `colgroup` in tables ??
2020
- add `&nbsp` instead of simple space to lines in code blocks
21+
- test if there is only one <h1> in each page
22+
- we're assuming there is only one toctree per page...

_build/src/JsonGenerator.php

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace SymfonyDocs;
4+
5+
use Doctrine\RST\HTML\Document;
6+
use Doctrine\RST\HTML\Environment;
7+
use Doctrine\RST\MetaEntry;
8+
use Symfony\Component\DomCrawler\Crawler;
9+
use Symfony\Component\Filesystem\Filesystem;
10+
use Symfony\Component\Finder\Finder;
11+
12+
/**
13+
* Class JsonGenerator
14+
*/
15+
class JsonGenerator
16+
{
17+
/** @var Environment[] */
18+
private $environments;
19+
20+
public function __construct(array $documents)
21+
{
22+
$this->environments = array_map(
23+
function (Document $document) {
24+
return $document->getEnvironment();
25+
},
26+
$documents
27+
);
28+
}
29+
30+
public function generateJson(string $inputDir, string $outputDir)
31+
{
32+
$finder = new Finder();
33+
$finder->in($inputDir)
34+
->name('*.html')
35+
->files();
36+
37+
$fs = new Filesystem();
38+
$fs->remove($outputDir);
39+
40+
foreach ($finder as $file) {
41+
$crawler = new Crawler($file->getContents());
42+
43+
$parserFilename = $this->getParserFilename($file->getRealPath(), $inputDir);
44+
$meta = $this->getMeta($parserFilename);
45+
46+
$data = [
47+
'body' => $crawler->filter('body')->html(),
48+
'title' => $meta->getTitle(),
49+
'current_page_name' => $parserFilename,
50+
'toc' => $this->generateToc($meta, current($meta->getTitles())[1]),
51+
'next' => $this->guessNext($parserFilename),
52+
'prev' => $this->guessPrev($parserFilename),
53+
'rellinks' => [
54+
$this->guessNext($parserFilename),
55+
$this->guessPrev($parserFilename),
56+
],
57+
];
58+
59+
$fs->dumpFile(
60+
str_replace([$inputDir, '.html'], [$outputDir, '.json'], $file->getRealPath()),
61+
json_encode($data, JSON_PRETTY_PRINT)
62+
);
63+
}
64+
}
65+
66+
private function getParserFilename(string $filePath, string $inputDir): string
67+
{
68+
return $parserFilename = str_replace([$inputDir.'/', '.html'], ['', ''], $filePath);
69+
}
70+
71+
private function getEnvironment(string $parserFilename): Environment
72+
{
73+
if (!isset($this->environments[$parserFilename])) {
74+
throw new \LogicException(sprintf('Cannot guess file name in parser "%s"', $parserFilename));
75+
}
76+
77+
return $this->environments[$parserFilename];
78+
}
79+
80+
private function getMeta(string $parserFilename): MetaEntry
81+
{
82+
$environment = $this->getEnvironment($parserFilename);
83+
84+
$allMetas = $environment->getMetas()->getAll();
85+
86+
if (!isset($allMetas[$parserFilename])) {
87+
throw new \LogicException(sprintf('Cannot find metas for file "%s"', $parserFilename));
88+
}
89+
90+
return $allMetas[$parserFilename];
91+
}
92+
93+
private function generateToc(MetaEntry $metaEntry, array $titles): array
94+
{
95+
$tocTree = [];
96+
97+
foreach ($titles as $title) {
98+
$tocTree[] = [
99+
'url' => sprintf('%s#%s', $metaEntry->getUrl(), Environment::slugify($title[0])),
100+
'title' => $title[0],
101+
'children' => $this->generateToc($metaEntry, $title[1]),
102+
];
103+
}
104+
105+
return $tocTree;
106+
}
107+
108+
private function guessNext(string $parserFilename): ?array
109+
{
110+
list($toc, $indexCurrentFile) = $this->getNextPrevInformation($parserFilename);
111+
112+
if (!isset($toc[$indexCurrentFile + 1])) {
113+
return null;
114+
}
115+
116+
return [
117+
'title' => $this->getMeta($toc[$indexCurrentFile + 1])->getTitle(),
118+
'link' => $this->getMeta($toc[$indexCurrentFile + 1])->getUrl(),
119+
];
120+
}
121+
122+
private function guessPrev(string $parserFilename): ?array
123+
{
124+
list($toc, $indexCurrentFile) = $this->getNextPrevInformation($parserFilename);
125+
126+
if (!isset($toc[$indexCurrentFile - 1])) {
127+
return null;
128+
}
129+
130+
return [
131+
'title' => $this->getMeta($toc[$indexCurrentFile - 1])->getTitle(),
132+
'link' => $this->getMeta($toc[$indexCurrentFile - 1])->getUrl(),
133+
];
134+
}
135+
136+
private function getNextPrevInformation(string $parserFilename): ?array
137+
{
138+
$meta = $this->getMeta($parserFilename);
139+
$parentFile = $meta->getParent();
140+
141+
if (!$parentFile) {
142+
return [null, null];
143+
}
144+
145+
$metaParent = $this->getMeta($parentFile);
146+
147+
if (!$metaParent->getTocs() || \count($metaParent->getTocs()) !== 1) {
148+
return [null, null];
149+
}
150+
151+
$toc = current($metaParent->getTocs());
152+
153+
if (\count($toc) < 2 || !isset(array_flip($toc)[$parserFilename])) {
154+
return [null, null];
155+
}
156+
157+
$indexCurrentFile = array_flip($toc)[$parserFilename];
158+
159+
return [$toc, $indexCurrentFile];
160+
}
161+
}

0 commit comments

Comments
 (0)