Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New page linker #58

Merged
merged 4 commits into from
Oct 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,9 @@

{{ "Page linking example" | textToHeading('H1') }}

1) <a>InvalidArgumentException</a> - create a reference by short class name

2) <a>Doctrine\Common\Annotations\AnnotationException</a> - creating a reference by full class name

3) <a>Class map</a> - create a link to another page

4) <a>/demo/demo1/docs/sectionWithSubsections/classListExample/index.md</a> - creating a link by file path

5) <a>/demo/demo1/docs/sectionWithSubsections/classListExample/index2.md</a> - non-exists link case
1) [a]InvalidArgumentException[/a] - create a reference by short class name
2) [a]Doctrine\Common\Annotations\AnnotationException[/a] - creating a reference by full class name
3) [a x-title='Custom title']Doctrine\Common\Annotations\AnnotationException[/a] - creating a reference by full class name with custom title
4) [a]Class map[/a] - create a link to another page
5) [a]/demo/demo1/docs/sectionWithSubsections/classListExample/index.md[/a] - creating a link by file path
6) [a]/demo/demo1/docs/sectionWithSubsections/classListExample/index2.md[/a] - non-exists link case
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@ public function __invoke(RootEntityCollection $rootEntityCollection, string $con
preg_match("/({$name}:)([^#]+)(#)(( ?\([^\\)]+\\))?)(.*)/", $configContent, $matches);
if (is_array($defaultValue)) {
if (is_associative_array($defaultValue)) {
$tmpDefaultValue = "<a>{$defaultValue['class']}|short_form</a>";
$shortName = array_reverse(explode('\\', $defaultValue['class']))[0];
$tmpDefaultValue = "[a x-title='{$shortName}']{$defaultValue['class']}[/a]";
} else {
$tmpDefaultValue = "\n\n";
foreach ($defaultValue as $v) {
$tmpDefaultValue .= "- <a>{$v['class']}|short_form</a>\n\n";
$shortName = array_reverse(explode('\\', $v['class']))[0];
$tmpDefaultValue .= "- [a x-title='{$shortName}']{$v['class']}[/a]\n\n";
}
}
$defaultValue = $tmpDefaultValue;
Expand Down
12 changes: 6 additions & 6 deletions selfdoc/templates/README.md.twig
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ Add the BumbleDocGen to the `composer.json` file of your project using the follo

{{ "Detailed technical description" | textToHeading('H2') }}

💡 Please refer to the <a x-title="Description of the technical part of the project">Technical description of the project</a> for a detailed explanation of all the classes and methods used.
💡 Please refer to the [a x-title="Description of the technical part of the project"]Technical description of the project[/a] for a detailed explanation of all the classes and methods used.

{{ "Core Features" | textToHeading('H2') }}

- 🔍 <b><a x-title="Parsing">Parser</a>:</b>
- 🔍 <b>[a x-title="Parsing"]Parser[/a]:</b>
BumbleDocGen scans your project by parsing PHP files, extracting comments, and providing detailed models of your code.

- ✍️ <b><a x-title="Rendering">Renderer</a>:</b>
- ✍️ <b>[a x-title="Rendering"]Renderer[/a]:</b>
BumbleDocGen generates markdown content using templates and fills them with data obtained from parsing your code.

- 🧠 <b>AI tools for documentation generation:</b>
Expand All @@ -30,17 +30,17 @@ Add the BumbleDocGen to the `composer.json` file of your project using the follo

{{ "Entry points" | textToHeading('H3') }}

BumbleDocGen's interface consists of mainly two classes: <a>DocGenerator</a> and <a>DocGeneratorFactory</a>.
BumbleDocGen's interface consists of mainly two classes: [a]DocGenerator[/a] and [a]DocGeneratorFactory[/a].

- <a>DocGenerator</a> provides main operations for generating the documents.
- [a]DocGenerator[/a] provides main operations for generating the documents.

- `addMissingDocBlocks()`: This method creates missing docBlocks in your code.
- `fillInReadmeMdTemplate()`: This method prepares the `README.md` file using a predefined template.
- `generate()`: This method produces all necessary documentation.
- `generateProjectTemplatesStructure()`: This method creates a structure for project templates.
- `parseAndGetRootEntityCollectionsGroup()`: This method parses your project's files and collects information for the documentation.

- <a>DocGeneratorFactory</a> provides a method for creating `DocGenerator` instance.
- [a]DocGeneratorFactory[/a] provides a method for creating `DocGenerator` instance.

- `create(configurationFiles: string)`: This method creates a `DocGenerator` instance using provided configuration files.
- `setCustomConfigurationParameters(customConfigurationParameters: array)`: This method sets custom configuration parameters for the `DocGenerator` creation.
Expand Down
2 changes: 1 addition & 1 deletion selfdoc/templates/tech/1.configuration/readme.md.twig
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ They can be in different formats: <a href='https://yaml.org/'>yaml</a>, <a href=

But it is not necessary to use files to store the configuration; you can also initialize the documentation generator instance by passing there an array of configuration parameters (see <a href='https://github.com/bumble-tech/bumble-doc-gen/tree/master/demo'>demo-5</a>)

During the instance creation process, configuration data is loaded into <a>Configuration</a> class, and the code works directly with it.
During the instance creation process, configuration data is loaded into [a]Configuration[/a] class, and the code works directly with it.

{{ "Configuration file example" | textToHeading('H2') }}

Expand Down
4 changes: 2 additions & 2 deletions selfdoc/templates/tech/2.parser/entity.md.twig
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Entities are always handled through collections. Collections are the result of t

To further facilitate the handling of these entities, we utilize entity collections.
These collections not only group relevant entities together but also provide convenient methods for filtering and manipulating these entities.
The root collections (<a>RootEntityCollection</a>), which are directly accessible in your templates, are as follows:
The root collections ([a]RootEntityCollection[/a]), which are directly accessible in your templates, are as follows:

<table>
<tr>
Expand All @@ -66,7 +66,7 @@ The root collections (<a>RootEntityCollection</a>), which are directly accessibl

{{ "Available entities" | textToHeading('H2') }}

Following is the list of available entities that are consistent with <a>EntityInterface</a> and can be created.
Following is the list of available entities that are consistent with [a]EntityInterface[/a] and can be created.
These classes are a convenient wrapper for accessing data in templates:

<table>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ These rules facilitate a strategic extraction of elements, such as classes, meth
By implementing these filters, users are endowed with the capability to customize the documentation output, ensuring that it precisely aligns with their requirements and expectations.
This level of granularity not only streamlines the documentation process but also guarantees that the resultant documents are devoid of superfluous details, focusing solely on pertinent information.

All filter conditions implement the <a>ConditionInterface</a> interface.
All filter conditions implement the [a]ConditionInterface[/a] interface.

{{ "Mechanism for adding entities to the collection" | textToHeading('H2') }}

Expand Down
2 changes: 1 addition & 1 deletion selfdoc/templates/tech/2.parser/readme.md.twig
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

{{ "Documentation parser" | textToHeading('H1') }}

Most often, we need <a>ProjectParser</a> in order to get a list of entities for documentation.
Most often, we need [a]ProjectParser[/a] in order to get a list of entities for documentation.
But this is not the only use of this tool. The result of the parser's work (a collection of entities) can be used to programmatically analyze the project and perform any operations based on this analysis.
For example, in our documentation generator, we also use the result of the parser in the tasks of generating documentation using AI tools.
You can also use the parser for your own purposes other than generating documentation.
Expand Down
2 changes: 1 addition & 1 deletion selfdoc/templates/tech/2.parser/sourceLocator.md.twig
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Source locators are set in the configuration:
- "%project_root%/src"
- "%project_root%/selfdoc"' | textToCodeBlock('yaml') }}

You can create your own source locators or use any existing ones. All source locators must implement the <a>SourceLocatorInterface</a> interface.
You can create your own source locators or use any existing ones. All source locators must implement the [a]SourceLocatorInterface[/a] interface.

{{ "Built-in source locators" | textToHeading('H2') }}

Expand Down
4 changes: 2 additions & 2 deletions selfdoc/templates/tech/3.renderer/02_breadcrumbs.md.twig
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

{{ "Documentation structure and breadcrumbs" | textToHeading('H1') }}

To work with breadcrumbs and get the structure of the documentation, we use the inner class <a>BreadcrumbsHelper</a>.
To work with breadcrumbs and get the structure of the documentation, we use the inner class [a]BreadcrumbsHelper[/a].
To build the documentation structure, twig templates from the `templates_dir` configuration are used.

{{ "Project structure definitions" | textToHeading('H2') }}
Expand All @@ -25,7 +25,7 @@ In this way, complex documentation structures can be created with less file nest

{{ "Displaying breadcrumbs in documents" | textToHeading('H2') }}

There is a built-in function to generate breadcrumbs in templates <a>GeneratePageBreadcrumbs</a>.
There is a built-in function to generate breadcrumbs in templates [a]GeneratePageBreadcrumbs[/a].
Here is how it is used in twig templates:

{{ '{{ generatePageBreadcrumbs(title, _self) }\}' | textToCodeBlock('twig') }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ twig_filters:
```

It is important to remember that when a template is inherited, custom filters are not overridden and augmented.
This information is detailed on page <a>Configuration files</a>.
This information is detailed on page [a]Configuration files[/a].

{{ "Defautl template filters" | textToHeading('H2') }}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Functions available during page generation are defined in <a href='{{ getDocumen
We use the twig template engine, you can get more information about working with functions here: https://twig.symfony.com/doc/1.x/advanced.html#functions

You can also create your own functions and use them for any purpose, such as loading some additional information into a template, filtering data, or formatting the output of any information.
Each function must implement the <a>CustomFunctionInterface</a> interface, implement the `__invoke` magic method, and be added to the configuration.
Each function must implement the [a]CustomFunctionInterface[/a] interface, implement the `__invoke` magic method, and be added to the configuration.

{{ "How to use a function in a template" | textToHeading('H2') }}

Expand All @@ -28,7 +28,7 @@ twig_functions:
```

It is important to remember that when a template is inherited, custom functions are not overridden and augmented.
This information is detailed on page <a>Configuration files</a>.
This information is detailed on page [a]Configuration files[/a].

{{ "Defautl template functions" | textToHeading('H2') }}

Expand Down
4 changes: 2 additions & 2 deletions selfdoc/templates/tech/3.renderer/templatesLinking.md.twig
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ We have several options for this, such as using special functions or using a spe

{{ "Completing blank links" | textToHeading('H2') }}

Plugin <a>PageHtmlLinkerPlugin</a> have been added to the basic configuration,
Plugin [a]PageHtmlLinkerPlugin[/a] have been added to the basic configuration,
which process the text of the filled template before its result is written to a file, and fill in all empty links.

For example, an empty link:
Expand All @@ -24,5 +24,5 @@ will be replaced with this link:

The second way to relink templates is to generate links through functions.

There are a number of functions that allow you to get a link to an entity, for example <a>GetDocumentedEntityUrl</a>, and there are also functions for getting a link to other documents, for example <a>GetDocumentationPageUrl</a>.
There are a number of functions that allow you to get a link to an entity, for example [a]GetDocumentedEntityUrl[/a], and there are also functions for getting a link to other documents, for example [a]GetDocumentationPageUrl[/a].
You can also implement your own functions for relinking if necessary.
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ There are several variables available in each processed template.

1) Firstly, these are built-in twig variables, for example `_self`, which returns the path to the processed template.

2) Secondly, variables with collections of processed programming languages are available in the template (see <a>LanguageHandlerInterface</a>). For example, when processing a PHP project collection, a collection <a>ClassEntityCollection</a> will be available in the template under the name <b>phpClassEntityCollection</b>
2) Secondly, variables with collections of processed programming languages are available in the template (see [a]LanguageHandlerInterface[/a]). For example, when processing a PHP project collection, a collection [a]ClassEntityCollection[/a] will be available in the template under the name <b>phpClassEntityCollection</b>
4 changes: 2 additions & 2 deletions selfdoc/templates/tech/4.pluginSystem/readme.md.twig
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

The documentation generator includes the ability to expand the functionality using plugins that allow you to add the necessary functionality to the system without changing its core.

The system is built on the basis of an event model, each plugin class must implement <a>PluginInterface</a>.
The system is built on the basis of an event model, each plugin class must implement [a]PluginInterface[/a].

{{ "Configuration example" | textToHeading('H2') }}

Expand Down Expand Up @@ -45,7 +45,7 @@ Plugins for any programming languages work regardless of which language handler
<td>
<ul>
{% for key in pluginEntity.getMethodEntity('getSubscribedEvents').getFirstReturnValue() | eval | keys %}
<li><a>{{ key }}|short_form</a></li>
<li>[a]{{ key }}|short_form[/a]</li>
{% endfor %}
</ul>
</td>
Expand Down
1 change: 1 addition & 0 deletions src/Core/Configuration/defaultConfiguration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@ twig_filters: # (array<CustomFilterInterface>) Filters that
- class: \BumbleDocGen\Core\Renderer\Twig\Filter\PregMatch
plugins: # (array<PluginInterface>|null) List of plugins
- class: \BumbleDocGen\Core\Plugin\CorePlugin\PageLinker\PageHtmlLinkerPlugin
- class: \BumbleDocGen\Core\Plugin\CorePlugin\PageLinker\PageLinkerPlugin
- class: \BumbleDocGen\Core\Plugin\CorePlugin\LastPageCommitter\LastPageCommitter
additional_console_commands: # (array<Command>) Additional console commands
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
* <a>Existent page name</a> => <a href="/docs/some/page/targetPage.html">Existent page name</a>
*
* @example
* <a x-title="Custom title">\Namespace\ClassName</a> => <a href="/docs/some/page/ClassName.md">Custom title</a>
* <a x-title="Custom title">\Namespace\ClassName</a> => <a href="/docs/some/page/ClassName.md">Custom title</a>
*
* @example
* <a>\Namespace\ClassName</a> => <a href="/docs/some/page/ClassName.md">\Namespace\ClassName</a>
* <a>\Namespace\ClassName</a> => <a href="/docs/some/page/ClassName.md">\Namespace\ClassName</a>
*
* @example
* <a>Non-existent page name</a> => Non-existent page name
Expand Down
52 changes: 52 additions & 0 deletions src/Core/Plugin/CorePlugin/PageLinker/PageLinkerPlugin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

declare(strict_types=1);

namespace BumbleDocGen\Core\Plugin\CorePlugin\PageLinker;

/**
* Adds URLs to empty links in HTML format;
* Links may contain:
* 1) Short entity name
* 2) Full entity name
* 3) Relative link to the entity file from the root directory of the project
* 4) Page title ( title )
* 5) Template key ( BreadcrumbsHelper::getTemplateLinkKey() )
* 6) Relative reference to the entity document from the root directory of the documentation
*
* @example
* [a]Existent page name[/a] => <a href="/docs/some/page/targetPage.html">Existent page name</a>
*
* @example
* [a x-title="Custom title"]\Namespace\ClassName[/a] => <a href="/docs/some/page/ClassName.md">Custom title</a>
*
* @example
* [a]\Namespace\ClassName[/a] => <a href="/docs/some/page/ClassName.md">\Namespace\ClassName</a>
*
* @example
* [a]Non-existent page name[/a] => Non-existent page name
*/
final class PageLinkerPlugin extends BasePageLinker
{
protected function getLinkRegEx(): string
{
return '/(\\[a(?![^>]*\bhref\b)[^\\]]*\\])(.*?)(\\[\/a\\])/m';
}

protected function getUrlFromMatch(string $match): string
{
preg_match($this->getLinkRegEx(), $match, $m);
return $m[2] ?? '#';
}

protected function getCustomTitleFromMatch(string $match): string
{
preg_match('/(x-title=("|\')(.*?)("|\'))/', $match, $m);
return $m[3] ?? '';
}

protected function getOutputTemplate(): string
{
return '<a href="%url%">%title%</a>';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
<tr><th>Name</th><th>Namespace</th></tr>
<tr><td colspan='2'><b>Abstract classes</b></td></tr>
{% for abstractClassEntity in phpClassEntityCollection.getOnlyAbstractClasses() %}
<tr><td><a>{{ abstractClassEntity.getName() }}|short_form</a><td>{{ abstractClassEntity.getNamespaceName() }}</td></tr>
<tr><td>[a x-title='{{ classEntity.getShortName() }}']{{ abstractClassEntity.getName() }}[/a]<td>{{ abstractClassEntity.getNamespaceName() }}</td></tr>
{% endfor %}
<tr><td colspan='2'><b>Classes</b></td></tr>
{% for classEntity in phpClassEntityCollection.getOnlyInstantiable() %}
<tr><td><a>{{ classEntity.getName() }}|short_form</a><td>{{ classEntity.getNamespaceName() }}</td></tr>
<tr><td>[a x-title='{{ classEntity.getShortName() }}']{{ classEntity.getName() }}[/a]<td>{{ classEntity.getNamespaceName() }}</td></tr>
{% endfor %}
</table>
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
<table>
<tr><th>Name</th><th>Namespace</th></tr>
{% for interfaceEntity in phpClassEntityCollection.getOnlyInterfaces() %}
<tr><td><a>{{ interfaceEntity.getName() }}|short_form</a><td>{{ interfaceEntity.getNamespaceName() }}</td></tr>
<tr><td>[a x-title='{{ interfaceEntity.getShortName() }}']{{ interfaceEntity.getName() }}[/a]<td>{{ interfaceEntity.getNamespaceName() }}</td></tr>
{% endfor %}
</table>
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
<table>
<tr><th>Name</th><th>Namespace</th></tr>
{% for traitEntity in phpClassEntityCollection.getOnlyTraits() %}
<tr><td><a>{{ traitEntity.getName() }}|short_form</a><td>{{ traitEntity.getNamespaceName() }}</td></tr>
<tr><td>[a x-title='{{ traitEntity.getShortName() }}']{{ traitEntity.getName() }}[/a]<td>{{ traitEntity.getNamespaceName() }}</td></tr>
{% endfor %}
</table>