Skip to content

Commit b3f922f

Browse files
jaapiolinawolf
authored andcommitted
Add more docs about directives
1 parent ad31e46 commit b3f922f

File tree

8 files changed

+213
-5
lines changed

8 files changed

+213
-5
lines changed

docs/components/compiler.rst

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,47 @@
11
.. include:: /include.rst.txt
22

3+
.. _compiler-component:
4+
35
========
46
Compiler
57
========
68

79
This library uses a simplified compiler design. This basically means that our pipeline contains less steps
810
than a regular compiler. But its following the same semantics.
911

12+
stages
13+
======
14+
1015
Lexing and Parsing
11-
==================
16+
------------------
1217

1318
A typical compiler will have separate lexing, syntax analysis. However the parser
1419
was designed to do part of the lexing because of all context-dependent logic of most Markup languages.
1520
We call this the parsing phase. This will result into an AST that is mostly close to the original source. It
1621
might contain some optimizations for later use.
1722

1823
Semantic analysis and Intermediate code generation
19-
==================================================
24+
--------------------------------------------------
2025

2126
The semantic analysis phase of this library is performing a number of steps to collect information of the parsed markup
2227
language. A good example is the collection of the table of contents and the metadata of the parsed documents.
2328
This is the moment where document node traversers are executed.
2429

2530
Code optimization
26-
=================
31+
-----------------
2732

2833
Do some pre-rendering stuff, like buiding the TOC content and other rendering preparations before the real rendering starts.
2934

3035
Code generation
31-
===============
36+
---------------
37+
38+
Code generation a.k.a. rendering. This is the phase where the AST is transformed into the final output format.
39+
40+
Extending
41+
=========
42+
43+
The compiler is designed to be extended. This allows you to remove or add nodes to the AST or mutate the AST in any way
44+
you like. Compiler extension is mostly done when you want want to do dynamic calulations based on the AST. The mutations
45+
will not have direct impact on the rendering process. Style changes should be done in the rendering phase.
3246

33-
Code generation a.k.a. rendering. We do deliver a headless
47+
To read more about extending the compiler, see :ref:`extending_compiler`.

docs/developers/compiler.rst

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
.. _extending_compiler:
2+
3+
=========
4+
Compiler
5+
=========
6+
7+
To extend the compiler you need a custom extension. This guide assumes you have a basic understanding of the compiler
8+
and have read the :ref:`compiler-component` description. If you haven't read that yet, please do so before continuing.
9+
Also, this guide assumes you have an :ref:`extension <developer-extension>` set up.
10+
11+
If you want to extend the compiler to support new features there are two options:
12+
13+
- Implement a :php:class:`phpDocumentor\Guides\Compiler\NodeTransformer`
14+
- Implement a :php:class:`phpDocumentor\Guides\Compiler\CompilerPass`
15+
16+
NodeTransformer
17+
===============
18+
19+
Node transformers are used to transform specific types of nodes in the AST. This is usefull when you want to remove
20+
a node type or manipulate nodes of a specific type. Your new node transformer should implement the :php:class:`phpDocumentor\Guides\Compiler\NodeTransformer`
21+
interface and you should register it in the dependency injection container.
22+
23+
.. code-block:: php
24+
:caption: your-extension.php
25+
26+
<?php
27+
28+
return static function (ContainerConfigurator $container): void {
29+
$container->services()
30+
->set(YourNodeTransformer::class)
31+
->tag('phpdoc.guides.compiler.nodeTransformers');
32+
33+
.. note::
34+
35+
The tag `phpdoc.guides.compiler.nodeTransformers` is used to register the node transformer in the compiler. The higher
36+
the priority of the node transformer, the earlier it will be executed. Where higest priority is `PHP_INT_MAX`, lower
37+
number is lower priority.
38+
39+
CompilerPass
40+
============
41+
42+
If you want to do more complex transformations for example transformations that require multiple nodes to be transformed
43+
you should implement a :php:class:`phpDocumentor\Guides\Compiler\CompilerPass`. A compiler pass needs to be registered
44+
just like a node transformer.
45+
46+
.. code-block:: php
47+
:caption: your-extension.php
48+
49+
<?php
50+
51+
return static function (ContainerConfigurator $container): void {
52+
$container->services()
53+
->set(YourCompilerPass::class)
54+
->tag('phpdoc.guides.compiler.passes');
55+
56+
.. note::
57+
58+
The tag `phpdoc.guides.compiler.passes` is used to register the node transformer in the compiler. The higher
59+
the priority of the node transformer, the earlier it will be executed. Where higest priority is `PHP_INT_MAX`, lower
60+
number is lower priority.

docs/developers/directive.rst

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
=========
2+
Directive
3+
=========
4+
5+
Directives are the extension points of ReStructuredText. They are used to add custom nodes to the document tree.
6+
The parser will do the basic parsing of a directive. Then it will hand over the directive to a directive handler, which
7+
will do the actual processing of the directive.
8+
9+
.. hint::
10+
11+
This project contains a lot of directives. You can find them in the :php:namespace:`\phpDocumentor\Guides\RestructuredText\Directives` namespace.
12+
Including the way how to use them.
13+
14+
To implement a directive you need to create a class that extends :php:class:`\phpDocumentor\Guides\RestructuredText\Directives\BaseDirective`.
15+
And register it with the parser using a :ref:`custom extension <developer-extension>`.
16+
17+
.. code-block:: php
18+
:caption: your-extension.php
19+
20+
<?php
21+
22+
return static function (ContainerConfigurator $container): void {
23+
$container->services()
24+
->set(YourDirective::class)
25+
->tag('phpdoc.guides.directive');
26+
27+
By design this library distinguishes between three types of directives:
28+
29+
- :php:class:`phpDocumentor\Guides\RestructuredText\Directives\SubDirective`
30+
This is the most common directive type. It is used to add a new node type to the document tree that allows you to do
31+
custom rendering. See :ref:`directive-reference` for examples.
32+
33+
- :php:class:`phpDocumentor\Guides\RestructuredText\Directives\ActionDirective`
34+
Action directives are not producing nodes in the document tree. They can be used to perform actions on the document.
35+
For example set the default language for code blocks or configure other settings.
36+
37+
- :php:class:`phpDocumentor\Guides\RestructuredText\Directives\ActionDirective`,
38+
more or less a basic directive handler.
39+
This is the most advanced directive type. You are on your own here. You need to do everything yourself.
40+
41+
Implement a sub directive
42+
========================
43+
44+
A sub directivehandler is a node with child nodes. The parser will take care of the parsing of the directive content.
45+
All you need to do is create a node and add the content.
46+
47+
.. literalinclude:: directive/subdirective.php
48+
:language: php
49+
:caption: your-extension/Directive/ExampleDirective.php
50+
:lineos:
51+
52+
53+
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
namespace YourExtension\Directives;
4+
5+
use phpDocumentor\Guides\RestructuredText\Nodes\Node;
6+
use phpDocumentor\Guides\RestructuredText\Nodes\SubDirectiveNode;
7+
use phpDocumentor\Guides\RestructuredText\Parser\SubDirectiveParser;
8+
use phpDocumentor\Guides\RestructuredText\Parser\SubDirectiveParserFactory;
9+
10+
class ExampleSubDirective extends SubDirective
11+
{
12+
public function getName(): string
13+
{
14+
return 'example';
15+
}
16+
17+
final protected function processSub(
18+
BlockContext $blockContext,
19+
CollectionNode $collectionNode,
20+
Directive $directive,
21+
): Node|null {
22+
return new ExampleNode(
23+
$this->name,
24+
$directive->getDataNode(),
25+
$this->text,
26+
$collectionNode->getChildren(),
27+
);
28+
}
29+
}

docs/developers/extensions/index.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
.. include:: /include.rst.txt
22

3+
.. _developer-extension:
4+
35
==========
46
Extensions
57
==========

docs/developers/index.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,5 @@ it in some other way that is not possible with the ``guides`` command line tool.
1212
:titlesonly:
1313

1414
extensions/index
15+
compiler
16+
directive

docs/reference/restructuredtext/admonitions.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
.. include:: /include.rst.txt
22

3+
.. _directive-reference:
4+
35
===========
46
Admonitions
57
===========

phpdoc.dist.xml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<phpdocumentor
3+
configVersion="3"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xmlns="https://www.phpdoc.org"
6+
xsi:noNamespaceSchemaLocation="data/xsd/phpdoc.xsd"
7+
>
8+
<title>Guides</title>
9+
<paths>
10+
<output>build/docs</output>
11+
</paths>
12+
<version number="0.2.0">
13+
<folder>latest</folder>
14+
<api>
15+
<source dsn="packages">
16+
<path>**/src/</path>
17+
</source>
18+
<output>api</output>
19+
<ignore hidden="true" symlinks="true">
20+
<path>tests/**/*</path>
21+
<path>build/**/*</path>
22+
<path>var/**/*</path>
23+
<path>vendor/**/*</path>
24+
</ignore>
25+
<extensions>
26+
<extension>php</extension>
27+
</extensions>
28+
<ignore-tags>
29+
<ignore-tag>template</ignore-tag>
30+
<ignore-tag>template-extends</ignore-tag>
31+
<ignore-tag>template-implements</ignore-tag>
32+
<ignore-tag>extends</ignore-tag>
33+
<ignore-tag>implements</ignore-tag>
34+
</ignore-tags>
35+
<default-package-name>phpDocumentor</default-package-name>
36+
</api>
37+
<guide>
38+
<source dsn=".">
39+
<path>docs</path>
40+
</source>
41+
<output>guides</output>
42+
</guide>
43+
</version>
44+
<setting name="guides.enabled" value="true"/>
45+
<template name="default" />
46+
</phpdocumentor>

0 commit comments

Comments
 (0)