Skip to content

Commit

Permalink
Merge pull request #357 from Roave/support-embedding-src-files
Browse files Browse the repository at this point in the history
Adds support for embedding a file in code blocks
  • Loading branch information
Ocramius authored Jan 3, 2024
2 parents f27d8ed + 724c615 commit 8324c2d
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ Additionally, we have a special Markdown syntax:
* `{{feature:test.feature}}` will render `$(DOCBOOK_TOOL_FEATURES_PATH)/test.feature` as a code block
* Code blocks (triple-backtick) with the `puml` syntax will be converted into a PlantUML diagram. Note your diagram
must start and end with `@startuml` and `@enduml` respectively.
* `{{src-json:test.json}}` will render `$(DOCBOOK_TOOL_FEATURES_PATH)/test.json` as a code block. Only `json` is
supported at the moment.

Example showing all syntax can be seen in `test/fixture/docbook/test.md`.

Expand Down
2 changes: 2 additions & 0 deletions bin/docbook-tool.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Monolog\Logger;
use Roave\DocbookTool\Formatter\AggregatePageFormatter;
use Roave\DocbookTool\Formatter\ExtractFrontMatter;
use Roave\DocbookTool\Formatter\InlineCodeFromFile;
use Roave\DocbookTool\Formatter\InlineExternalImages;
use Roave\DocbookTool\Formatter\InlineFeatureFile;
use Roave\DocbookTool\Formatter\MarkdownToHtml;
Expand Down Expand Up @@ -44,6 +45,7 @@
new InlineExternalImages($logger),
new RenderPlantUmlDiagramInline($logger),
new MarkdownToHtml($logger),
new InlineCodeFromFile($contentPath, $logger),
];

if (is_string($featuresPath)) {
Expand Down
54 changes: 54 additions & 0 deletions src/Formatter/InlineCodeFromFile.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

declare(strict_types=1);

namespace Roave\DocbookTool\Formatter;

use Psr\Log\LoggerInterface;
use Roave\DocbookTool\DocbookPage;
use Safe\Exceptions\SafeExceptionInterface;

use function htmlentities;
use function implode;
use function preg_replace_callback;
use function Safe\file_get_contents;
use function sprintf;

use const ENT_QUOTES;

final class InlineCodeFromFile implements PageFormatter
{
private const ALLOWED_CODE_TYPES = ['json'];

public function __construct(private string $contentPath, private readonly LoggerInterface $logger)
{
}

/** @throws SafeExceptionInterface */
public function __invoke(DocbookPage $page): DocbookPage
{
$this->logger->debug(sprintf('[%s] Checking if source code files can be inlined in %s', self::class, $page->slug()));

return $page->withReplacedContent(
preg_replace_callback(
sprintf(
'/{{src-(%s):([a-zA-Z0-9\/.-]+)}}/',
implode('|', self::ALLOWED_CODE_TYPES),
),
function (array $m) use ($page): string {
/** @var array{1: string, 2: string} $m */
$this->logger->debug(sprintf('[%s] Inlining source code file "%s" of type "%s" in page "%s"', self::class, $m[2], $m[1], $page->slug()));

$sourceCode = file_get_contents($this->contentPath . '/' . $m[2]);

return sprintf(
'<pre><code class="lang-%s">%s</code></pre>',
htmlentities($m[1], ENT_QUOTES),
htmlentities($sourceCode, ENT_QUOTES),
);
},
$page->content(),
),
);
}
}
3 changes: 3 additions & 0 deletions test/fixture/docbook/example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"example": "json"
}
4 changes: 4 additions & 0 deletions test/fixture/docbook/test.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ Links [here](https://www.google.com). **Bold**, _italic_, ~~strikethrough~~, `in

{{feature:test.feature}}

## Inline some JSON

{{src-json:example.json}}

## A diagram

Test with filename:
Expand Down
7 changes: 7 additions & 0 deletions test/fixture/expectations/out.html
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ <h2>Subtitle</h2>
Then I should be overjoyed
</code></pre></p>

<h2>Inline some JSON</h2>

<p><pre><code class="lang-json">{
&quot;example&quot;: &quot;json&quot;
}
</code></pre></p>

<h2>A diagram</h2>

<p>Test with filename:</p>
Expand Down
2 changes: 2 additions & 0 deletions test/integration/DocbookToolGeneratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Psr\Log\NullLogger;
use Roave\DocbookTool\Formatter\AggregatePageFormatter;
use Roave\DocbookTool\Formatter\ExtractFrontMatter;
use Roave\DocbookTool\Formatter\InlineCodeFromFile;
use Roave\DocbookTool\Formatter\InlineExternalImages;
use Roave\DocbookTool\Formatter\InlineFeatureFile;
use Roave\DocbookTool\Formatter\MarkdownToHtml;
Expand Down Expand Up @@ -51,6 +52,7 @@ public function testGeneration(): void
new InlineExternalImages($logger),
new RenderPlantUmlDiagramInline($logger),
new MarkdownToHtml($logger),
new InlineCodeFromFile(self::CONTENT_PATH, $logger),
new InlineFeatureFile(self::FEATURES_PATH, $logger),
]),
'__invoke',
Expand Down
39 changes: 39 additions & 0 deletions test/unit/Formatter/InlineCodeFromFileTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

declare(strict_types=1);

namespace Roave\DocbookToolUnitTest\Formatter;

use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
use Roave\DocbookTool\DocbookPage;
use Roave\DocbookTool\Formatter\InlineCodeFromFile;

/** @covers \Roave\DocbookTool\Formatter\InlineCodeFromFile */
final class InlineCodeFromFileTest extends TestCase
{
public function testExternalSourceCodeIsInlined(): void
{
$markdown = <<<'MD'
Here is some markdown
{{src-json:example.json}}
More markdown
MD;

$page = DocbookPage::fromSlugAndContent('/faked.md', 'slug', $markdown);

$formattedPage = (new InlineCodeFromFile(__DIR__ . '/../../fixture/docbook', new NullLogger()))($page);

self::assertSame(
<<<'MD'
Here is some markdown
<pre><code class="lang-json">{
&quot;example&quot;: &quot;json&quot;
}
</code></pre>
More markdown
MD,
$formattedPage->content(),
);
}
}

0 comments on commit 8324c2d

Please sign in to comment.