Skip to content

Commit 8409e2e

Browse files
authored
Merge pull request #1144 from phpDocumentor/backport/1.x/pr-1131
[1.x] Merge pull request #1131 from phpDocumentor/feature/md-admonitions
2 parents 98245d2 + 9990496 commit 8409e2e

File tree

18 files changed

+256
-104
lines changed

18 files changed

+256
-104
lines changed

packages/guides-markdown/src/Markdown/Parsers/BlockQuoteParser.php

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,21 @@
1818
use League\CommonMark\Node\NodeWalker;
1919
use League\CommonMark\Node\NodeWalkerEvent;
2020
use phpDocumentor\Guides\MarkupLanguageParser;
21+
use phpDocumentor\Guides\Nodes\AdmonitionNode;
22+
use phpDocumentor\Guides\Nodes\Inline\PlainTextInlineNode;
23+
use phpDocumentor\Guides\Nodes\InlineCompoundNode;
2124
use phpDocumentor\Guides\Nodes\Node;
25+
use phpDocumentor\Guides\Nodes\ParagraphNode;
2226
use phpDocumentor\Guides\Nodes\QuoteNode;
2327
use Psr\Log\LoggerInterface;
2428
use RuntimeException;
2529

30+
use function array_shift;
31+
use function count;
2632
use function sprintf;
33+
use function trim;
2734

28-
/** @extends AbstractBlockParser<QuoteNode> */
35+
/** @extends AbstractBlockParser<Node> */
2936
final class BlockQuoteParser extends AbstractBlockParser
3037
{
3138
/** @param iterable<AbstractBlockParser<Node>> $subParsers */
@@ -35,7 +42,7 @@ public function __construct(
3542
) {
3643
}
3744

38-
public function parse(MarkupLanguageParser $parser, NodeWalker $walker, CommonMarkNode $current): QuoteNode
45+
public function parse(MarkupLanguageParser $parser, NodeWalker $walker, CommonMarkNode $current): Node
3946
{
4047
$content = [];
4148

@@ -55,6 +62,58 @@ public function parse(MarkupLanguageParser $parser, NodeWalker $walker, CommonMa
5562

5663
// leaving the heading node
5764
if ($commonMarkNode instanceof BlockQuote) {
65+
if (count($content) > 0 && $content[0] instanceof ParagraphNode && ($content[0]->getValue()[0]) instanceof InlineCompoundNode) {
66+
$paragraphContent = $content[0]->getValue()[0]->getValue();
67+
if (count($paragraphContent) > 0 && $paragraphContent[0] instanceof PlainTextInlineNode) {
68+
$text = trim($paragraphContent[0]->getValue());
69+
$newParagraphContent = $paragraphContent;
70+
array_shift($newParagraphContent);
71+
switch ($text) {
72+
case '[!NOTE]':
73+
return new AdmonitionNode(
74+
'note',
75+
new InlineCompoundNode([new PlainTextInlineNode('Note')]),
76+
'Note',
77+
$newParagraphContent,
78+
);
79+
80+
case '[!TIP]':
81+
return new AdmonitionNode(
82+
'tip',
83+
new InlineCompoundNode([new PlainTextInlineNode('Tip')]),
84+
'Tip',
85+
$newParagraphContent,
86+
);
87+
88+
case '[!IMPORTANT]':
89+
return new AdmonitionNode(
90+
'important',
91+
new InlineCompoundNode([new PlainTextInlineNode('Important')]),
92+
'Important',
93+
$newParagraphContent,
94+
);
95+
96+
case '[!WARNING]':
97+
return new AdmonitionNode(
98+
'warning',
99+
new InlineCompoundNode([new PlainTextInlineNode('Warning')]),
100+
'Warning',
101+
$newParagraphContent,
102+
);
103+
104+
case '[!CAUTION]':
105+
return new AdmonitionNode(
106+
'caution',
107+
new InlineCompoundNode([new PlainTextInlineNode('Caution')]),
108+
'Caution',
109+
$newParagraphContent,
110+
);
111+
}
112+
}
113+
114+
$content[0] = new ParagraphNode([new InlineCompoundNode($paragraphContent)]);
115+
}
116+
58117
return new QuoteNode($content);
59118
}
60119

packages/guides-restructured-text/src/RestructuredText/Directives/AbstractAdmonitionDirective.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313

1414
namespace phpDocumentor\Guides\RestructuredText\Directives;
1515

16+
use phpDocumentor\Guides\Nodes\AdmonitionNode;
1617
use phpDocumentor\Guides\Nodes\CollectionNode;
1718
use phpDocumentor\Guides\Nodes\Node;
18-
use phpDocumentor\Guides\RestructuredText\Nodes\AdmonitionNode;
1919
use phpDocumentor\Guides\RestructuredText\Parser\BlockContext;
2020
use phpDocumentor\Guides\RestructuredText\Parser\Directive;
2121
use phpDocumentor\Guides\RestructuredText\Parser\Productions\Rule;

packages/guides-restructured-text/src/RestructuredText/Directives/AdmonitionDirective.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313

1414
namespace phpDocumentor\Guides\RestructuredText\Directives;
1515

16+
use phpDocumentor\Guides\Nodes\AdmonitionNode;
1617
use phpDocumentor\Guides\Nodes\CollectionNode;
1718
use phpDocumentor\Guides\Nodes\Node;
18-
use phpDocumentor\Guides\RestructuredText\Nodes\AdmonitionNode;
1919
use phpDocumentor\Guides\RestructuredText\Parser\BlockContext;
2020
use phpDocumentor\Guides\RestructuredText\Parser\Directive;
2121

packages/guides-restructured-text/src/RestructuredText/NodeRenderers/Html/AdmonitionNodeRenderer.php

Lines changed: 1 addition & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -13,47 +13,6 @@
1313

1414
namespace phpDocumentor\Guides\RestructuredText\NodeRenderers\Html;
1515

16-
use InvalidArgumentException;
17-
use phpDocumentor\Guides\NodeRenderers\NodeRenderer;
18-
use phpDocumentor\Guides\Nodes\Node;
19-
use phpDocumentor\Guides\RenderContext;
20-
use phpDocumentor\Guides\RestructuredText\Nodes\AdmonitionNode;
21-
use phpDocumentor\Guides\TemplateRenderer;
22-
23-
use function implode;
24-
use function is_a;
25-
26-
/** @implements NodeRenderer<AdmonitionNode> */
27-
final class AdmonitionNodeRenderer implements NodeRenderer
16+
final class AdmonitionNodeRenderer extends \phpDocumentor\Guides\NodeRenderers\Html\AdmonitionNodeRenderer
2817
{
29-
public function __construct(private readonly TemplateRenderer $renderer)
30-
{
31-
}
32-
33-
public function supports(string $nodeFqcn): bool
34-
{
35-
return $nodeFqcn === AdmonitionNode::class || is_a($nodeFqcn, AdmonitionNode::class, true);
36-
}
37-
38-
public function render(Node $node, RenderContext $renderContext): string
39-
{
40-
if ($node instanceof AdmonitionNode === false) {
41-
throw new InvalidArgumentException('Node must be an instance of ' . AdmonitionNode::class);
42-
}
43-
44-
$classes = $node->getClasses();
45-
46-
return $this->renderer->renderTemplate(
47-
$renderContext,
48-
'body/admonition.html.twig',
49-
[
50-
'name' => $node->getName(),
51-
'text' => $node->getText(),
52-
'title' => $node->getTitle(),
53-
'isTitled' => $node->isTitled(),
54-
'class' => implode(' ', $classes),
55-
'node' => $node->getValue(),
56-
],
57-
);
58-
}
5918
}

packages/guides-restructured-text/src/RestructuredText/Nodes/AdmonitionNode.php

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -13,36 +13,6 @@
1313

1414
namespace phpDocumentor\Guides\RestructuredText\Nodes;
1515

16-
use phpDocumentor\Guides\Nodes\CompoundNode;
17-
use phpDocumentor\Guides\Nodes\InlineCompoundNode;
18-
use phpDocumentor\Guides\Nodes\Node;
19-
20-
/** @extends CompoundNode<Node> */
21-
final class AdmonitionNode extends CompoundNode
16+
class AdmonitionNode extends \phpDocumentor\Guides\Nodes\AdmonitionNode
2217
{
23-
/** @param Node[] $value */
24-
public function __construct(private readonly string $name, private readonly InlineCompoundNode|null $title, private readonly string $text, array $value, private readonly bool $isTitled = false)
25-
{
26-
parent::__construct($value);
27-
}
28-
29-
public function getName(): string
30-
{
31-
return $this->name;
32-
}
33-
34-
public function getTitle(): InlineCompoundNode|null
35-
{
36-
return $this->title;
37-
}
38-
39-
public function getText(): string
40-
{
41-
return $this->text;
42-
}
43-
44-
public function isTitled(): bool
45-
{
46-
return $this->isTitled;
47-
}
4818
}

packages/guides-theme-bootstrap/resources/template/body/admonition.html.twig

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
1+
{% if name == 'caution' %}
2+
{% include "body/admonitions/caution.html.twig" %}
3+
{% endif %}
24
{% if name == 'important' %}
35
{% include "body/admonitions/important.html.twig" %}
46
{% endif %}
57
{% if name == 'note' %}
68
{% include "body/admonitions/note.html.twig" %}
79
{% endif %}
8-
{% if name == 'warning' or name == 'caution' %}
10+
{% if name == 'warning' %}
911
{% include "body/admonitions/warning.html.twig" %}
1012
{% endif %}
1113
{% if name == 'tip' or name == 'hint' %}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<div class="alert alert-danger {{ class ? (' '~class) }}{% if node.classes %} {{ node.classesString }}{% endif %}" role="alert">
2+
<h4 class="alert-heading">Caution</h4>
3+
{{ renderNode(node) }}
4+
</div>
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<div class="alert alert-danger {{ class ? (' '~class) }}{% if node.classes %} {{ node.classesString }}{% endif %}" role="alert">
2-
<h4 class="alert-heading">Tip</h4>
1+
<div class="alert alert-warning {{ class ? (' '~class) }}{% if node.classes %} {{ node.classesString }}{% endif %}" role="alert">
2+
<h4 class="alert-heading">Imortant</h4>
33
{{ renderNode(node) }}
44
</div>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
<div class="alert alert-danger {{ class ? (' '~class) }}{% if node.classes %} {{ node.classesString }}{% endif %}" role="alert">
2-
<h4 class="alert-heading">Tip</h4>
2+
<h4 class="alert-heading">Warning</h4>
33
{{ renderNode(node) }}
44
</div>
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* This file is part of phpDocumentor.
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*
11+
* @link https://phpdoc.org
12+
*/
13+
14+
namespace phpDocumentor\Guides\NodeRenderers\Html;
15+
16+
use InvalidArgumentException;
17+
use phpDocumentor\Guides\NodeRenderers\NodeRenderer;
18+
use phpDocumentor\Guides\Nodes\AdmonitionNode;
19+
use phpDocumentor\Guides\Nodes\Node;
20+
use phpDocumentor\Guides\RenderContext;
21+
use phpDocumentor\Guides\TemplateRenderer;
22+
23+
use function implode;
24+
use function is_a;
25+
26+
/** @implements NodeRenderer<AdmonitionNode> */
27+
class AdmonitionNodeRenderer implements NodeRenderer
28+
{
29+
public function __construct(private readonly TemplateRenderer $renderer)
30+
{
31+
}
32+
33+
public function supports(string $nodeFqcn): bool
34+
{
35+
return $nodeFqcn === AdmonitionNode::class || is_a($nodeFqcn, AdmonitionNode::class, true);
36+
}
37+
38+
public function render(Node $node, RenderContext $renderContext): string
39+
{
40+
if ($node instanceof AdmonitionNode === false) {
41+
throw new InvalidArgumentException('Node must be an instance of ' . AdmonitionNode::class);
42+
}
43+
44+
$classes = $node->getClasses();
45+
46+
return $this->renderer->renderTemplate(
47+
$renderContext,
48+
'body/admonition.html.twig',
49+
[
50+
'name' => $node->getName(),
51+
'text' => $node->getText(),
52+
'title' => $node->getTitle(),
53+
'isTitled' => $node->isTitled(),
54+
'class' => implode(' ', $classes),
55+
'node' => $node->getValue(),
56+
],
57+
);
58+
}
59+
}

0 commit comments

Comments
 (0)