Passed
Push — main ( 989696...2152d5 )
by Colin
05:14 queued 02:09
created

mergeWithDirectlyAdjacentNodes()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 6
ccs 4
cts 4
cp 1
rs 10
c 0
b 0
f 0
cc 3
nc 4
nop 1
crap 3
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the league/commonmark package.
7
 *
8
 * (c) Colin O'Dell <[email protected]>
9
 *
10
 * Additional emphasis processing code based on commonmark-java (https://github.com/atlassian/commonmark-java)
11
 *  - (c) Atlassian Pty Ltd
12
 *
13
 * For the full copyright and license information, please view the LICENSE
14
 * file that was distributed with this source code.
15
 */
16
17
namespace League\CommonMark\Node\Inline;
18
19
use League\CommonMark\Node\Node;
20
21
/**
22
 * @internal
23
 */
24
final class AdjacentTextMerger
25
{
26 2769
    public static function mergeChildNodes(Node $node): void
27
    {
28
        // No children or just one child node, no need for merging
29 2769
        if ($node->firstChild() === $node->lastChild() || $node->firstChild() === null || $node->lastChild() === null) {
30 1611
            return;
31
        }
32
33
        /** @psalm-suppress PossiblyNullArgument */
34 1539
        self::mergeTextNodesInclusive($node->firstChild(), $node->lastChild());
35 1539
    }
36
37 546
    public static function mergeTextNodesBetweenExclusive(Node $fromNode, Node $toNode): void
38
    {
39
        // No nodes between them
40 546
        if ($fromNode === $toNode || $fromNode->next() === $toNode || $fromNode->next() === null || $toNode->previous() === null) {
41 3
            return;
42
        }
43
44
        /** @psalm-suppress PossiblyNullArgument */
45 546
        self::mergeTextNodesInclusive($fromNode->next(), $toNode->previous());
46 546
    }
47
48 54
    public static function mergeWithDirectlyAdjacentNodes(Text $node): void
49
    {
50 54
        $start = ($previous = $node->previous()) instanceof Text ? $previous : $node;
51 54
        $end   = ($next = $node->next()) instanceof Text ? $next : $node;
52
53 54
        self::mergeIfNeeded($start, $end);
54 54
    }
55
56 1758
    private static function mergeTextNodesInclusive(Node $fromNode, Node $toNode): void
57
    {
58 1758
        $first = null;
59 1758
        $last  = null;
60
61 1758
        $node = $fromNode;
62 1758
        while ($node !== null) {
63 1758
            if ($node instanceof Text) {
64 1731
                if ($first === null) {
65 1731
                    $first = $node;
66
                }
67
68 1731
                $last = $node;
69
            } else {
70 1359
                self::mergeIfNeeded($first, $last);
71 1359
                $first = null;
72 1359
                $last  = null;
73
            }
74
75 1758
            if ($node === $toNode) {
76 1758
                break;
77
            }
78
79 1668
            $node = $node->next();
80
        }
81
82 1758
        self::mergeIfNeeded($first, $last);
83 1758
    }
84
85 1776
    private static function mergeIfNeeded(?Text $first, ?Text $last): void
86
    {
87 1776
        if ($first === null || $last === null || $first === $last) {
88
            // No merging needed
89 1425
            return;
90
        }
91
92 576
        $s = $first->getLiteral();
93
94 576
        $node = $first->next();
95 576
        $stop = $last->next();
96 576
        while ($node !== $stop && $node instanceof Text) {
97 576
            $s     .= $node->getLiteral();
98 576
            $unlink = $node;
99 576
            $node   = $node->next();
100 576
            $unlink->detach();
101
        }
102
103 576
        $first->setLiteral($s);
104 576
    }
105
}
106