Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

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