Passed
Push — 2.0 ( 989696...a89474 )
by Colin
06:29 queued 03:39
created

AdjacentTextMerger   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 80
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 23
eloc 37
dl 0
loc 80
ccs 44
cts 44
cp 1
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A mergeTextNodesBetweenExclusive() 0 9 5
A mergeChildNodes() 0 9 4
A mergeTextNodesInclusive() 0 27 5
A mergeIfNeeded() 0 19 6
A mergeWithDirectlyAdjacentNodes() 0 6 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 2697
    public static function mergeChildNodes(Node $node): void
27
    {
28
        // No children or just one child node, no need for merging
29 2697
        if ($node->firstChild() === $node->lastChild() || $node->firstChild() === null || $node->lastChild() === null) {
30 1569
            return;
31
        }
32
33
        /** @psalm-suppress PossiblyNullArgument */
34 1479
        self::mergeTextNodesInclusive($node->firstChild(), $node->lastChild());
35 1479
    }
36
37 528
    public static function mergeTextNodesBetweenExclusive(Node $fromNode, Node $toNode): void
38
    {
39
        // No nodes between them
40 528
        if ($fromNode === $toNode || $fromNode->next() === $toNode || $fromNode->next() === null || $toNode->previous() === null) {
41 3
            return;
42
        }
43
44
        /** @psalm-suppress PossiblyNullArgument */
45 528
        self::mergeTextNodesInclusive($fromNode->next(), $toNode->previous());
46 528
    }
47
48 51
    public static function mergeWithDirectlyAdjacentNodes(Text $node): void
49
    {
50 51
        $start = ($previous = $node->previous()) instanceof Text ? $previous : $node;
51 51
        $end   = ($next = $node->next()) instanceof Text ? $next : $node;
52
53 51
        self::mergeIfNeeded($start, $end);
54 51
    }
55
56 1695
    private static function mergeTextNodesInclusive(Node $fromNode, Node $toNode): void
57
    {
58 1695
        $first = null;
59 1695
        $last  = null;
60
61 1695
        $node = $fromNode;
62 1695
        while ($node !== null) {
63 1695
            if ($node instanceof Text) {
64 1668
                if ($first === null) {
65 1668
                    $first = $node;
66
                }
67
68 1668
                $last = $node;
69
            } else {
70 1293
                self::mergeIfNeeded($first, $last);
71 1293
                $first = null;
72 1293
                $last  = null;
73
            }
74
75 1695
            if ($node === $toNode) {
76 1695
                break;
77
            }
78
79 1605
            $node = $node->next();
80
        }
81
82 1695
        self::mergeIfNeeded($first, $last);
83 1695
    }
84
85 1713
    private static function mergeIfNeeded(?Text $first, ?Text $last): void
86
    {
87 1713
        if ($first === null || $last === null || $first === $last) {
88
            // No merging needed
89 1359
            return;
90
        }
91
92 573
        $s = $first->getLiteral();
93
94 573
        $node = $first->next();
95 573
        $stop = $last->next();
96 573
        while ($node !== $stop && $node instanceof Text) {
97 573
            $s     .= $node->getLiteral();
98 573
            $unlink = $node;
99 573
            $node   = $node->next();
100 573
            $unlink->detach();
101
        }
102
103 573
        $first->setLiteral($s);
104 573
    }
105
}
106