Skip to content

Commit c00edbe

Browse files
committed
Allow to build RST content strings
1 parent 5f750ad commit c00edbe

File tree

4 files changed

+131
-1
lines changed

4 files changed

+131
-1
lines changed

src/BuildConfig.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ class BuildConfig
3030
private $subdirectoryToBuild;
3131
private $excludedPaths;
3232
private $fileFinder;
33+
private $isContentAString;
34+
private $disableJsonFileGeneration;
3335

3436
public function __construct()
3537
{
@@ -38,6 +40,8 @@ public function __construct()
3840
$this->symfonyVersion = '4.4';
3941
$this->excludedPaths = [];
4042
$this->imagesPublicPrefix = '';
43+
$this->isContentAString = false;
44+
$this->disableJsonFileGeneration = false;
4145
}
4246

4347
public function createFileFinder(): Finder
@@ -128,6 +132,16 @@ public function getImagesPublicPrefix(): string
128132
return $this->imagesPublicPrefix;
129133
}
130134

135+
public function generateJsonFiles(): bool
136+
{
137+
return !$this->disableJsonFileGeneration;
138+
}
139+
140+
public function isContentAString(): bool
141+
{
142+
return $this->isContentAString;
143+
}
144+
131145
public function setSymfonyVersion(string $version): self
132146
{
133147
$this->symfonyVersion = $version;
@@ -219,4 +233,19 @@ public function setExcludedPaths(array $excludedPaths)
219233

220234
$this->excludedPaths = $excludedPaths;
221235
}
236+
237+
// needed to differentiate between building a dir of contents or just a string of contents
238+
public function setIsContentAString(bool $isString): self
239+
{
240+
$this->isContentAString = true;
241+
242+
return $this;
243+
}
244+
245+
public function disableJsonFileGeneration(): self
246+
{
247+
$this->disableJsonFileGeneration = true;
248+
249+
return $this;
250+
}
222251
}

src/BuildResult.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ class BuildResult
1717
{
1818
private $builder;
1919
private $errors;
20+
// only defined when using build() method
2021
private $jsonResults = [];
22+
// only defined when using buildString() method
23+
private $stringResult = null;
2124

2225
public function __construct(Builder $builder)
2326
{
@@ -45,6 +48,11 @@ public function getErrors(): array
4548
return $this->errors;
4649
}
4750

51+
public function getErrorTrace(): string
52+
{
53+
return implode("\n", $this->errors);
54+
}
55+
4856
public function getMetadata(): Metas
4957
{
5058
return $this->builder->getMetas();
@@ -72,4 +80,18 @@ public function setJsonResults(array $jsonResults): void
7280
{
7381
$this->jsonResults = $jsonResults;
7482
}
83+
84+
/**
85+
* Returns the HTML result of building some string contents
86+
* using the buildString() builder method
87+
*/
88+
public function getStringResult(): ?string
89+
{
90+
return $this->stringResult;
91+
}
92+
93+
public function setStringResult(string $result): void
94+
{
95+
$this->stringResult = $result;
96+
}
7597
}

src/DocBuilder.php

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Doctrine\RST\Builder;
66
use Symfony\Component\Console\Output\NullOutput;
7+
use Symfony\Component\DomCrawler\Crawler;
78
use Symfony\Component\Filesystem\Filesystem;
89
use SymfonyDocsBuilder\CI\MissingFilesChecker;
910
use SymfonyDocsBuilder\Generator\HtmlForPdfGenerator;
@@ -42,11 +43,41 @@ public function build(BuildConfig $config): BuildResult
4243
if ($config->getSubdirectoryToBuild()) {
4344
$htmlForPdfGenerator = new HtmlForPdfGenerator($metas, $config);
4445
$htmlForPdfGenerator->generateHtmlForPdf();
45-
} else {
46+
} elseif ($config->generateJsonFiles()) {
4647
$jsonGenerator = new JsonGenerator($metas, $config);
4748
$buildResult->setJsonResults($jsonGenerator->generateJson($builder->getIndexName()));
49+
} elseif ($config->isContentAString()) {
50+
$htmlFilePath = $config->getOutputDir().'/index.html';
51+
if (is_file($htmlFilePath)) {
52+
// generated HTML contents are a full HTML page, so we need to
53+
// extract the contents of the <body> tag
54+
$crawler = new Crawler(file_get_contents($htmlFilePath));
55+
$buildResult->setStringResult(trim($crawler->filter('body')->html()));
56+
}
4857
}
4958

5059
return $buildResult;
5160
}
61+
62+
public function buildString(string $contents): BuildResult
63+
{
64+
$filesystem = new Filesystem();
65+
$tmpDir = sys_get_temp_dir().'/rst_'.random_int(1, 100000000);
66+
if ($filesystem->exists($tmpDir)) {
67+
$filesystem->remove($tmpDir);
68+
}
69+
$filesystem->mkdir($tmpDir);
70+
71+
$filesystem->dumpFile($tmpDir.'/index.rst', $contents);
72+
73+
$buildConfig = (new BuildConfig())
74+
->setIsContentAString(true)
75+
->setContentDir($tmpDir)
76+
->setOutputDir($tmpDir.'/output')
77+
->disableBuildCache()
78+
->disableJsonFileGeneration()
79+
;
80+
81+
return $this->build($buildConfig);
82+
}
5283
}

tests/IntegrationTest.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,54 @@ public function parserUnitBlockProvider()
261261
];
262262
}
263263

264+
public function testParseString()
265+
{
266+
$rstString = <<<RST
267+
Lorem ipsum dolor sit amet
268+
==========================
269+
270+
Consectetur adipisicing elit, sed do eiusmod
271+
tempor **incididunt ut** labore et dolore magna aliqua.
272+
273+
* Ut enim ad minim veniam
274+
* Quis nostrud exercitation
275+
* Ullamco laboris nisi ut
276+
277+
`Aliquip ex ea commodo <https://symfony.com>`_ consequat.
278+
Duis aute irure dolor in reprehenderit in voluptate `velit esse`_.
279+
280+
Cillum dolore eu fugiat nulla pariatur
281+
--------------------------------------
282+
283+
Excepteur sint occaecat cupidatat non proident, sunt in
284+
culpa qui *officia deserunt* mollit anim id est laborum.
285+
286+
.. _`velit esse`: https://github.com
287+
RST;
288+
289+
$htmlString = <<<HTML
290+
<div class="section">
291+
<h1 id="lorem-ipsum-dolor-sit-amet"><a class="headerlink" href="#lorem-ipsum-dolor-sit-amet" title="Permalink to this headline">Lorem ipsum dolor sit amet</a></h1>
292+
<p>Consectetur adipisicing elit, sed do eiusmod
293+
tempor <strong>incididunt ut</strong> labore et dolore magna aliqua.</p>
294+
<ul>
295+
<li>Ut enim ad minim veniam</li>
296+
<li>Quis nostrud exercitation</li>
297+
<li>Ullamco laboris nisi ut</li>
298+
</ul>
299+
<p><a href="https://symfony.com" class="reference external">Aliquip ex ea commodo</a> consequat.
300+
Duis aute irure dolor in reprehenderit in voluptate <a href="https://github.com" class="reference external" rel="external noopener noreferrer" target="_blank">velit esse</a>.</p>
301+
<div class="section">
302+
<h2 id="cillum-dolore-eu-fugiat-nulla-pariatur"><a class="headerlink" href="#cillum-dolore-eu-fugiat-nulla-pariatur" title="Permalink to this headline">Cillum dolore eu fugiat nulla pariatur</a></h2>
303+
<p>Excepteur sint occaecat cupidatat non proident, sunt in
304+
culpa qui <em>officia deserunt</em> mollit anim id est laborum.</p>
305+
</div>
306+
</div>
307+
HTML;
308+
309+
$this->assertSame($htmlString, (new DocBuilder())->buildString($rstString)->getStringResult());
310+
}
311+
264312
private function createIndenter(): Indenter
265313
{
266314
$indenter = new Indenter();

0 commit comments

Comments
 (0)