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; |
15
|
|
|
|
16
|
|
|
use InvalidArgumentException; |
17
|
|
|
use phpDocumentor\Guides\Environment; |
18
|
|
|
use phpDocumentor\Guides\Nodes\ListNode; |
19
|
|
|
use phpDocumentor\Guides\Nodes\Node; |
20
|
|
|
use phpDocumentor\Guides\Nodes\SpanNode; |
21
|
|
|
use function array_pop; |
22
|
|
|
use function count; |
23
|
|
|
use function get_class; |
24
|
|
|
|
25
|
|
|
class ListNodeRenderer implements NodeRenderer |
26
|
|
|
{ |
27
|
|
|
/** @var FormatListRenderer */ |
28
|
|
|
private $formatListRenderer; |
29
|
|
|
|
30
|
|
|
/** @var Environment */ |
31
|
|
|
private $environment; |
32
|
|
|
|
33
|
|
|
public function __construct(FormatListRenderer $formatListRenderer, Environment $environment) |
34
|
|
|
{ |
35
|
|
|
$this->formatListRenderer = $formatListRenderer; |
36
|
|
|
$this->environment = $environment; |
37
|
|
|
} |
38
|
|
|
|
39
|
|
|
public function render(Node $node) : string |
40
|
|
|
{ |
41
|
|
|
if ($node instanceof ListNode === false) { |
42
|
|
|
throw new InvalidArgumentException('Invalid node presented'); |
43
|
|
|
} |
44
|
|
|
|
45
|
|
|
$depth = -1; |
46
|
|
|
$value = ''; |
47
|
|
|
$stack = []; |
48
|
|
|
|
49
|
|
|
foreach ($node->getLines() as $line) { |
50
|
|
|
/** @var SpanNode $text */ |
51
|
|
|
$text = $line['text']; |
52
|
|
|
|
53
|
|
|
$prefix = $line['prefix']; |
54
|
|
|
$ordered = $line['ordered']; |
55
|
|
|
$newDepth = $line['depth']; |
56
|
|
|
|
57
|
|
|
if ($depth < $newDepth) { |
58
|
|
|
$tags = $this->formatListRenderer->createList($node, $ordered); |
59
|
|
|
$value .= $tags[0]; |
60
|
|
|
$stack[] = [$newDepth, $tags[1] . "\n"]; |
61
|
|
|
$depth = $newDepth; |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
while ($depth > $newDepth) { |
65
|
|
|
$top = $stack[count($stack) - 1]; |
66
|
|
|
|
67
|
|
|
if ($top[0] <= $newDepth) { |
68
|
|
|
continue; |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
$value .= $top[1]; |
72
|
|
|
array_pop($stack); |
73
|
|
|
$top = $stack[count($stack) - 1]; |
74
|
|
|
$depth = $top[0]; |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
$renderedText = $this->environment->getNodeRendererFactory()->get(get_class($text))->render($text); |
78
|
|
|
$value .= $this->formatListRenderer->createElement($node, $renderedText, $prefix) . "\n"; |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
while ($stack) { |
|
|
|
|
82
|
|
|
[, $closing] = array_pop($stack); |
|
|
|
|
83
|
|
|
$value .= $closing; |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
return $value; |
87
|
|
|
} |
88
|
|
|
} |
89
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.