From 66b8eecf6e56525cf4bedef58baebd712614f54f Mon Sep 17 00:00:00 2001 From: "lina.wolf" Date: Wed, 2 Oct 2024 21:13:57 +0200 Subject: [PATCH] [FEATURE] Make index file configurable The index file will also be used in automatic menu building. As oposed to setting "input-file" not only the one file mentioned will be rendererd but all files from the directory. However the name of the input file can be changed. Some markdown projects like to change the name of the index file. For example powermail is using Readme.md as index file in every directory: https://github.com/in2code-de/powermail/tree/master/Documentation References #1108 (cherry picked from commit 34b41fed3583ba897f1f559d8c52acf59f9d1159) --- .../guides-cli/resources/schema/guides.xsd | 1 + .../Directives/MenuDirective.php | 17 ++++++++++--- .../Directives/ToctreeDirective.php | 10 +++++++- .../DependencyInjection/GuidesExtension.php | 5 ++++ .../src/Handlers/ParseDirectoryHandler.php | 25 +++++++++++++------ .../guides/src/Settings/ProjectSettings.php | 13 ++++++++++ .../index-name-md/expected/anotherPage.html | 8 ++++++ .../index-name-md/expected/readme.html | 8 ++++++ .../expected/yetAnotherPage.html | 8 ++++++ .../index-name-md/input/anotherPage.md | 3 +++ .../markdown/index-name-md/input/guides.xml | 8 ++++++ .../markdown/index-name-md/input/readme.md | 3 +++ .../index-name-md/input/yetAnotherPage.md | 3 +++ 13 files changed, 100 insertions(+), 12 deletions(-) create mode 100644 tests/Integration/tests/markdown/index-name-md/expected/anotherPage.html create mode 100644 tests/Integration/tests/markdown/index-name-md/expected/readme.html create mode 100644 tests/Integration/tests/markdown/index-name-md/expected/yetAnotherPage.html create mode 100644 tests/Integration/tests/markdown/index-name-md/input/anotherPage.md create mode 100644 tests/Integration/tests/markdown/index-name-md/input/guides.xml create mode 100644 tests/Integration/tests/markdown/index-name-md/input/readme.md create mode 100644 tests/Integration/tests/markdown/index-name-md/input/yetAnotherPage.md diff --git a/packages/guides-cli/resources/schema/guides.xsd b/packages/guides-cli/resources/schema/guides.xsd index bd326a1b8..c25cc6f6a 100644 --- a/packages/guides-cli/resources/schema/guides.xsd +++ b/packages/guides-cli/resources/schema/guides.xsd @@ -21,6 +21,7 @@ + diff --git a/packages/guides-restructured-text/src/RestructuredText/Directives/MenuDirective.php b/packages/guides-restructured-text/src/RestructuredText/Directives/MenuDirective.php index 66d164129..2d0074580 100644 --- a/packages/guides-restructured-text/src/RestructuredText/Directives/MenuDirective.php +++ b/packages/guides-restructured-text/src/RestructuredText/Directives/MenuDirective.php @@ -20,6 +20,8 @@ use phpDocumentor\Guides\RestructuredText\Parser\Directive; use phpDocumentor\Guides\RestructuredText\Parser\DirectiveOption; use phpDocumentor\Guides\RestructuredText\Toc\ToctreeBuilder; +use phpDocumentor\Guides\Settings\ProjectSettings; +use phpDocumentor\Guides\Settings\SettingsManager; use function count; @@ -28,12 +30,18 @@ * is for display only. It does not change the position of document in the document tree and can therefore be included * all pages as navigation. * - * By default it displays a menu of the pages on level 1 up to level 2. + * By default, it displays a menu of the pages on level 1 up to level 2. */ final class MenuDirective extends BaseDirective { - public function __construct(private readonly ToctreeBuilder $toctreeBuilder) - { + private SettingsManager $settingsManager; + + public function __construct( + private readonly ToctreeBuilder $toctreeBuilder, + SettingsManager|null $settingsManager = null, + ) { + // if for backward compatibility reasons no settings manager was passed, use the defaults + $this->settingsManager = $settingsManager ?? new SettingsManager(new ProjectSettings()); } public function getName(): string @@ -49,7 +57,8 @@ public function process( $parserContext = $blockContext->getDocumentParserContext()->getParser()->getParserContext(); $options = $directive->getOptions(); $options['glob'] = new DirectiveOption('glob', true); - $options['globExclude'] ??= new DirectiveOption('globExclude', 'index,Index'); + $indexName = $this->settingsManager->getProjectSettings()->getIndexName(); + $options['globExclude'] ??= new DirectiveOption('globExclude', $indexName); $toctreeFiles = $this->toctreeBuilder->buildToctreeEntries( $parserContext, diff --git a/packages/guides-restructured-text/src/RestructuredText/Directives/ToctreeDirective.php b/packages/guides-restructured-text/src/RestructuredText/Directives/ToctreeDirective.php index 9afe04800..9b1e17784 100644 --- a/packages/guides-restructured-text/src/RestructuredText/Directives/ToctreeDirective.php +++ b/packages/guides-restructured-text/src/RestructuredText/Directives/ToctreeDirective.php @@ -21,6 +21,8 @@ use phpDocumentor\Guides\RestructuredText\Parser\DirectiveOption; use phpDocumentor\Guides\RestructuredText\Parser\Productions\Rule; use phpDocumentor\Guides\RestructuredText\Toc\ToctreeBuilder; +use phpDocumentor\Guides\Settings\ProjectSettings; +use phpDocumentor\Guides\Settings\SettingsManager; /** * Sphinx based Toctree directive. @@ -33,11 +35,16 @@ */ final class ToctreeDirective extends BaseDirective { + private SettingsManager $settingsManager; + /** @param Rule $startingRule */ public function __construct( private readonly ToctreeBuilder $toctreeBuilder, private readonly Rule $startingRule, + SettingsManager|null $settingsManager = null, ) { + // if for backward compatibility reasons no settings manager was passed, use the defaults + $this->settingsManager = $settingsManager ?? new SettingsManager(new ProjectSettings()); } public function getName(): string @@ -52,7 +59,8 @@ public function process( ): Node|null { $parserContext = $blockContext->getDocumentParserContext()->getParser()->getParserContext(); $options = $directive->getOptions(); - $options['globExclude'] ??= new DirectiveOption('globExclude', 'index,Index'); + $indexName = $this->settingsManager->getProjectSettings()->getIndexName(); + $options['globExclude'] ??= new DirectiveOption('globExclude', $indexName); $toctreeFiles = $this->toctreeBuilder->buildToctreeEntries( $parserContext, diff --git a/packages/guides/src/DependencyInjection/GuidesExtension.php b/packages/guides/src/DependencyInjection/GuidesExtension.php index 6db4af678..10d37c716 100644 --- a/packages/guides/src/DependencyInjection/GuidesExtension.php +++ b/packages/guides/src/DependencyInjection/GuidesExtension.php @@ -114,6 +114,7 @@ static function ($value) { ->scalarNode('theme')->end() ->scalarNode('input')->end() ->scalarNode('input_file')->end() + ->scalarNode('index_name')->end() ->scalarNode('output')->end() ->scalarNode('input_format')->end() ->arrayNode('output_format') @@ -237,6 +238,10 @@ public function load(array $configs, ContainerBuilder $container): void } } + if (isset($config['index_name']) && $config['index_name'] !== '') { + $projectSettings->setIndexName((string) $config['index_name']); + } + if (isset($config['output'])) { $projectSettings->setOutput((string) $config['output']); } diff --git a/packages/guides/src/Handlers/ParseDirectoryHandler.php b/packages/guides/src/Handlers/ParseDirectoryHandler.php index 4c7075899..8851e4b80 100644 --- a/packages/guides/src/Handlers/ParseDirectoryHandler.php +++ b/packages/guides/src/Handlers/ParseDirectoryHandler.php @@ -21,20 +21,28 @@ use phpDocumentor\Guides\Event\PreParseProcess; use phpDocumentor\Guides\FileCollector; use phpDocumentor\Guides\Nodes\DocumentNode; +use phpDocumentor\Guides\Settings\ProjectSettings; +use phpDocumentor\Guides\Settings\SettingsManager; use Psr\EventDispatcher\EventDispatcherInterface; +use function array_map; use function assert; +use function explode; +use function implode; use function sprintf; final class ParseDirectoryHandler { - private const INDEX_FILE_NAMES = ['index', 'Index']; + private SettingsManager $settingsManager; public function __construct( private readonly FileCollector $fileCollector, private readonly CommandBus $commandBus, private readonly EventDispatcherInterface $eventDispatcher, + SettingsManager|null $settingsManager = null, ) { + // if for backward compatibility reasons no settings manager was passed, use the defaults + $this->settingsManager = $settingsManager ?? new SettingsManager(new ProjectSettings()); } /** @return DocumentNode[] */ @@ -98,17 +106,20 @@ private function getDirectoryIndexFile( $hashedContentFromFilesystem[$itemFromFilesystem['basename']] = true; } - foreach (self::INDEX_FILE_NAMES as $indexName) { - $indexFilename = sprintf('%s.%s', $indexName, $extension); - if (isset($hashedContentFromFilesystem[$indexFilename])) { + $indexFileNames = array_map('trim', explode(',', $this->settingsManager->getProjectSettings()->getIndexName())); + + $indexNamesNotFound = []; + foreach ($indexFileNames as $indexName) { + $fullIndexFilename = sprintf('%s.%s', $indexName, $extension); + if (isset($hashedContentFromFilesystem[$fullIndexFilename])) { return $indexName; } - } - $indexFilename = sprintf('%s.%s', self::INDEX_FILE_NAMES[0], $extension); + $indexNamesNotFound[] = $fullIndexFilename; + } throw new InvalidArgumentException( - sprintf('Could not find index file "%s" in "%s"', $indexFilename, $directory), + sprintf('Could not find an index file "%s", expected file names: %s', $directory, implode(', ', $indexNamesNotFound)), ); } } diff --git a/packages/guides/src/Settings/ProjectSettings.php b/packages/guides/src/Settings/ProjectSettings.php index 84b5272a5..1256ac701 100644 --- a/packages/guides/src/Settings/ProjectSettings.php +++ b/packages/guides/src/Settings/ProjectSettings.php @@ -24,6 +24,7 @@ final class ProjectSettings private string $theme = 'default'; private string $input = 'docs'; private string $inputFile = ''; + private string $indexName = 'index,Index'; private string $output = 'output'; private string $inputFormat = 'rst'; /** @var string[] */ @@ -230,4 +231,16 @@ public function setIgnoredDomains(array $ignoredDomains): void { $this->ignoredDomains = $ignoredDomains; } + + public function getIndexName(): string + { + return $this->indexName; + } + + public function setIndexName(string $indexName): ProjectSettings + { + $this->indexName = $indexName; + + return $this; + } } diff --git a/tests/Integration/tests/markdown/index-name-md/expected/anotherPage.html b/tests/Integration/tests/markdown/index-name-md/expected/anotherPage.html new file mode 100644 index 000000000..49c0fd5c5 --- /dev/null +++ b/tests/Integration/tests/markdown/index-name-md/expected/anotherPage.html @@ -0,0 +1,8 @@ + +
+

Another Page

+ +

Lorem Ipsum Dolor.

+ +
+ diff --git a/tests/Integration/tests/markdown/index-name-md/expected/readme.html b/tests/Integration/tests/markdown/index-name-md/expected/readme.html new file mode 100644 index 000000000..96305e73d --- /dev/null +++ b/tests/Integration/tests/markdown/index-name-md/expected/readme.html @@ -0,0 +1,8 @@ + +
+

Sample Markdown Document

+ +

Lorem Ipsum

+ +
+ diff --git a/tests/Integration/tests/markdown/index-name-md/expected/yetAnotherPage.html b/tests/Integration/tests/markdown/index-name-md/expected/yetAnotherPage.html new file mode 100644 index 000000000..3507b6a5f --- /dev/null +++ b/tests/Integration/tests/markdown/index-name-md/expected/yetAnotherPage.html @@ -0,0 +1,8 @@ + +
+

Yet Another Page

+ +

Lorem Ipsum Dolor.

+ +
+ diff --git a/tests/Integration/tests/markdown/index-name-md/input/anotherPage.md b/tests/Integration/tests/markdown/index-name-md/input/anotherPage.md new file mode 100644 index 000000000..02e0321a5 --- /dev/null +++ b/tests/Integration/tests/markdown/index-name-md/input/anotherPage.md @@ -0,0 +1,3 @@ +# Another Page + +Lorem Ipsum Dolor. diff --git a/tests/Integration/tests/markdown/index-name-md/input/guides.xml b/tests/Integration/tests/markdown/index-name-md/input/guides.xml new file mode 100644 index 000000000..d5cab2bc1 --- /dev/null +++ b/tests/Integration/tests/markdown/index-name-md/input/guides.xml @@ -0,0 +1,8 @@ + + + diff --git a/tests/Integration/tests/markdown/index-name-md/input/readme.md b/tests/Integration/tests/markdown/index-name-md/input/readme.md new file mode 100644 index 000000000..de6e617b5 --- /dev/null +++ b/tests/Integration/tests/markdown/index-name-md/input/readme.md @@ -0,0 +1,3 @@ +# Sample Markdown Document + +Lorem Ipsum diff --git a/tests/Integration/tests/markdown/index-name-md/input/yetAnotherPage.md b/tests/Integration/tests/markdown/index-name-md/input/yetAnotherPage.md new file mode 100644 index 000000000..fd7c625a3 --- /dev/null +++ b/tests/Integration/tests/markdown/index-name-md/input/yetAnotherPage.md @@ -0,0 +1,3 @@ +# Yet Another Page + +Lorem Ipsum Dolor.