diff --git a/src/BuildConfig.php b/src/BuildConfig.php index 07320b1..7817faf 100644 --- a/src/BuildConfig.php +++ b/src/BuildConfig.php @@ -30,6 +30,10 @@ class BuildConfig private $subdirectoryToBuild; private $excludedPaths; private $fileFinder; + // needed to know if we're building an entire directory of RST contents or just a single RST string + private $contentIsString; + // these are the *.fjson files generated by Sphinx and maintained for compatibility reasons + private $generateJsonFiles; public function __construct() { @@ -38,6 +42,8 @@ public function __construct() $this->symfonyVersion = '4.4'; $this->excludedPaths = []; $this->imagesPublicPrefix = ''; + $this->contentIsString = false; + $this->generateJsonFiles = true; } public function createFileFinder(): Finder @@ -128,6 +134,16 @@ public function getImagesPublicPrefix(): string return $this->imagesPublicPrefix; } + public function generateJsonFiles(): bool + { + return $this->generateJsonFiles; + } + + public function isContentAString(): bool + { + return $this->contentIsString; + } + public function setSymfonyVersion(string $version): self { $this->symfonyVersion = $version; @@ -219,4 +235,23 @@ public function setExcludedPaths(array $excludedPaths) $this->excludedPaths = $excludedPaths; } + + /* + * Call this method when you're building a string of RST contents (e.g. the + * contents of a single file) instead of the common case of building an + * entire directory of RST files. + */ + public function setContentIsString(): self + { + $this->contentIsString = true; + + return $this; + } + + public function disableJsonFileGeneration(): self + { + $this->generateJsonFiles = false; + + return $this; + } } diff --git a/src/BuildResult.php b/src/BuildResult.php index a31a71a..840914e 100644 --- a/src/BuildResult.php +++ b/src/BuildResult.php @@ -17,7 +17,10 @@ class BuildResult { private $builder; private $errors; + // only defined when using build() method private $jsonResults = []; + // only defined when using buildString() method + private $stringResult = null; public function __construct(Builder $builder) { @@ -45,6 +48,11 @@ public function getErrors(): array return $this->errors; } + public function getErrorTrace(): string + { + return implode("\n", $this->errors); + } + public function getMetadata(): Metas { return $this->builder->getMetas(); @@ -72,4 +80,18 @@ public function setJsonResults(array $jsonResults): void { $this->jsonResults = $jsonResults; } + + /** + * Returns the HTML result of building some string contents + * using the buildString() builder method + */ + public function getStringResult(): ?string + { + return $this->stringResult; + } + + public function setStringResult(string $result): void + { + $this->stringResult = $result; + } } diff --git a/src/DocBuilder.php b/src/DocBuilder.php index 1f1b079..46ce806 100644 --- a/src/DocBuilder.php +++ b/src/DocBuilder.php @@ -4,6 +4,7 @@ use Doctrine\RST\Builder; use Symfony\Component\Console\Output\NullOutput; +use Symfony\Component\DomCrawler\Crawler; use Symfony\Component\Filesystem\Filesystem; use SymfonyDocsBuilder\CI\MissingFilesChecker; use SymfonyDocsBuilder\Generator\HtmlForPdfGenerator; @@ -38,15 +39,49 @@ public function build(BuildConfig $config): BuildResult $filesystem->dumpFile($config->getOutputDir().'/build_errors.txt', implode("\n", $buildResult->getErrors())); } - $metas = $buildResult->getMetadata(); - if ($config->getSubdirectoryToBuild()) { + if ($config->isContentAString()) { + $htmlFilePath = $config->getOutputDir().'/index.html'; + if (is_file($htmlFilePath)) { + // generated HTML contents are a full HTML page, so we need to + // extract the contents of the
tag + $crawler = new Crawler(file_get_contents($htmlFilePath)); + $buildResult->setStringResult(trim($crawler->filter('body')->html())); + } + } elseif ($config->getSubdirectoryToBuild()) { + $metas = $buildResult->getMetadata(); $htmlForPdfGenerator = new HtmlForPdfGenerator($metas, $config); $htmlForPdfGenerator->generateHtmlForPdf(); - } else { + } elseif ($config->generateJsonFiles()) { + $metas = $buildResult->getMetadata(); $jsonGenerator = new JsonGenerator($metas, $config); $buildResult->setJsonResults($jsonGenerator->generateJson($builder->getIndexName())); } return $buildResult; } + + public function buildString(string $contents): BuildResult + { + $filesystem = new Filesystem(); + $tmpDir = sys_get_temp_dir().'/doc_builder_build_string_'.random_int(1, 100000000); + if ($filesystem->exists($tmpDir)) { + $filesystem->remove($tmpDir); + } + $filesystem->mkdir($tmpDir); + + $filesystem->dumpFile($tmpDir.'/index.rst', $contents); + + $buildConfig = (new BuildConfig()) + ->setContentIsString() + ->setContentDir($tmpDir) + ->setOutputDir($tmpDir.'/output') + ->disableBuildCache() + ->disableJsonFileGeneration() + ; + + $buildResult = $this->build($buildConfig); + $filesystem->remove($tmpDir); + + return $buildResult; + } } diff --git a/tests/IntegrationTest.php b/tests/IntegrationTest.php index 31fe408..7bf7737 100644 --- a/tests/IntegrationTest.php +++ b/tests/IntegrationTest.php @@ -261,6 +261,54 @@ public function parserUnitBlockProvider() ]; } + public function testParseString() + { + $rstString = <<Consectetur adipisicing elit, sed do eiusmod +tempor incididunt ut labore et dolore magna aliqua.
+Aliquip ex ea commodo consequat. +Duis aute irure dolor in reprehenderit in voluptate velit esse.
+Excepteur sint occaecat cupidatat non proident, sunt in +culpa qui officia deserunt mollit anim id est laborum.
+