You are browsing a version that has not yet been released. |
Custom Directives
Directives are designed to be an extension mechanism for reStructuredText. It enables you to add custom functionality to reStructuredText without having to add new custom syntaxes.
Predefined Directives
The following directives are predefined and can be used to define a directive with a custom name and template. For more sophisticated directives see section Writing a Custom Directive Implementation.
Ignored Directives
In many projects directives should be ignored for some reason. These directives are often still in the rst files for historic reasons but play no role anymore.
A common example is the .. index::
directive when no index generation is
provided.
You can register ignored directives as follows:
You can register ignored directives by passing objects of the type
Doctrine\RST\Directives\Ignored
to the array in the 2nd argument of the
Doctrine\RST\Kernel
class:
The following directives with all content, data and attributes will now be ignored and cause neither error nor warning nor output:
Data Directives
Data directives pass the data (the part after the double double points) to a template to be processed. The template must take care of escaping the content as is standard in twig.
You can register data directives by passing objects of the type
Doctrine\RST\Directives\Data
to the array in the 2nd argument of the
Doctrine\RST\Kernel
class:
1 use App\RST\Directives\ExampleDirective;
$kernel = new Kernel($configuration, [
new Directives\Data('my-data-directive'), // uses template directives/my-data-directive.html.twig
new Directives\Data('some-directive', 'directives/mytemplate.html.twig'),
]);
$builder = new Builder($kernel);
2
3
4
5
6
7
8
The following directives pass the data to the template. If there are arguments they are ignored. If there is content it is treated as normal node.
Wrapper Directives
Wrapper directives pass the data to a template. The template must contain 3 pipes
|||
once. All content (all indented rst code until the next non-indented
is found) will be parsed, all standard directives, text-roles etc applied.
Arguments will be ignored.
It will then be wrapped by the result of the template, split by |||
.
You can register wrapper directives by passing objects of the type
Doctrine\RST\Directives\Wrapper
to the array in the 2nd argument of the
Doctrine\RST\Kernel
class:
1 use App\RST\Directives\ExampleDirective;
$kernel = new Kernel($configuration, [
new Directives\Wrapper('versionadded'), // uses template directives/versionadded.html.twig
new Directives\Wrapper('another-wrapper', 'directives/some-wrapper-template.html.twig'),
]);
$builder = new Builder($kernel);
2
3
4
5
6
7
8
The template could look like this:
And can be used like this:
Writing a Custom Directive Implementation
You can write your own directives by defining a class that extends the Doctrine\RST\Directives\Directive
class and defines the method getName()
that returns the directive name.
You can then implement one of the following methods:
processAction()
if your directive simply tweak the document without modifying the nodesprocessNode()
if your directive is adding a nodeprocess()
if your directive is tweaking the node that just follows it
See Directive.php for more information.
Example Directive
1 namespace App\RST\Directives;
use Doctrine\RST\Nodes\Node;
use Doctrine\RST\Parser;
use Doctrine\RST\Directives\Directive;
class ExampleDirective extends Directive
{
public function getName() : string
{
return 'example';
}
/**
* @param string[] $options
*/
public function process(
Parser $parser,
?Node $node,
string $variable,
string $data,
array $options
) : void {
// do something to $node
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Now you can register your directive by registering it in a custom directive factory in your Configuration.php:
SubDirective Class
You can also extend the Doctrine\RST\Directives\SubDirective
class and implement the processSub()
method if
you want the sub block to be parsed. Here is an example CautionDirective
:
1 namespace App\RST\Directives;
use Doctrine\RST\Nodes\Node;
use Doctrine\RST\Nodes\WrapperNode;
use Doctrine\RST\Parser;
use Doctrine\RST\Directives\SubDirective;
class CautionDirective extends SubDirective
{
public function getName() : string
{
return 'caution';
}
/**
* @param string[] $options
*/
public function processSub(
Parser $parser,
?Node $document,
string $variable,
string $data,
array $options
) : ?Node {
$divOpen = $parser->renderTemplate('div-open.html.twig', [
'class' => 'caution',
]);
return $parser->getNodeFactory()->createWrapperNode($document, $divOpen, '</div>');
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Now you can use the directive like this and it can contain other reStructuredText syntaxes:
.. caution::
This is some **bold** text!
The above example would output the following HTML:
1 <div class="caution"><p>This is some <strong>bold</strong> text!</p></div>