TextNode::getPostfixSyntax()   B
last analyzed

Complexity

Conditions 7
Paths 8

Size

Total Lines 30
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 18
c 1
b 0
f 0
nc 8
nop 0
dl 0
loc 30
rs 8.8333
1
<?php
2
3
namespace dokuwiki\plugin\prosemirror\parser;
4
5
class TextNode extends Node implements InlineNodeInterface
6
{
7
    /** @var  TextNode */
8
    public $previous;
9
10
    /** @var  Node */
11
    protected $parent;
12
13
    /** @var Mark[] */
14
    protected $marks = [];
15
16
    protected $text = '';
17
18
    public function __construct($data, Node $parent, Node $previous = null)
19
    {
20
        $this->parent = &$parent;
21
        if ($previous !== false) {
0 ignored issues
show
introduced by
The condition $previous !== false is always true.
Loading history...
22
            $this->previous = &$previous;
23
        }
24
25
        $this->text = $data['text'] ?? '';
26
        if (isset($data['marks'])) {
27
            $this->setMarks($data['marks']);
28
        }
29
    }
30
31
    public function getPrefixSyntax()
32
    {
33
        $doc = '';
34
35
        /** @var Mark[] $openingMarks */
36
        $openingMarks = [];
37
        foreach ($this->marks as $mark) {
38
            if ($mark->isOpeningMark()) {
39
                $previousOpeningMark = end($openingMarks);
40
                if ($previousOpeningMark) {
41
                    $mark->setPrevious($previousOpeningMark);
42
                    $previousOpeningMark->setNext($mark);
43
                }
44
                $openingMarks[] = $mark;
45
            }
46
        }
47
48
        if (!empty($openingMarks)) {
49
            $mark = $openingMarks[0]->getFirst();
50
            $doc .= $mark->getOpeningSyntax();
51
            while ($mark = $mark->getNext()) {
52
                $doc .= $mark->getOpeningSyntax();
53
            }
54
55
            foreach ($openingMarks as $mark) {
56
                $mark->setNext(null);
57
                $mark->setPrevious(null);
58
            }
59
        }
60
        return $doc;
61
    }
62
63
    public function getPostfixSyntax()
64
    {
65
        $doc = '';
66
        /** @var Mark[] $closingMarks */
67
        $closingMarks = [];
68
        foreach ($this->marks as $mark) {
69
            if ($mark->isClosingMark()) {
70
                $previousClosingMark = end($closingMarks);
71
                if ($previousClosingMark) {
72
                    $mark->setPrevious($previousClosingMark);
73
                    $previousClosingMark->setNext($mark);
74
                }
75
                $closingMarks[] = $mark;
76
            }
77
        }
78
79
        if (!empty($closingMarks)) {
80
            $mark = $closingMarks[0]->getLast();
81
            $doc .= $mark->getClosingSyntax();
82
            while ($mark = $mark->getPrevious()) {
83
                $doc .= $mark->getClosingSyntax();
84
            }
85
86
            foreach ($closingMarks as $mark) {
87
                $mark->setNext(null);
88
                $mark->setPrevious(null);
89
            }
90
        }
91
92
        return $doc;
93
    }
94
95
    public function getInnerSyntax()
96
    {
97
        return $this->text;
98
    }
99
100
101
    public function toSyntax()
102
    {
103
        $prefix = $this->getPrefixSyntax();
104
        $inner = $this->getInnerSyntax();
105
        $postfix = $this->getPostfixSyntax();
106
        return $prefix . $inner . $postfix;
107
    }
108
109
    /**
110
     * @param array $marks
111
     *
112
     * @return $this
113
     * @throws \Exception
114
     */
115
    protected function setMarks(array $marks)
116
    {
117
        foreach ($marks as $markData) {
118
            $currentMark = new Mark($markData, $this);
119
            $type = $currentMark->getType();
120
            $this->marks[$type] = $currentMark;
121
            if ($this->previous !== null) {
122
                $this->previous->increaseMark($type);
123
            }
124
        }
125
        return $this;
126
    }
127
128
    /**
129
     * @param string $markType
130
     */
131
    public function increaseMark($markType)
132
    {
133
        if (!isset($this->marks[$markType])) {
134
            return;
135
        }
136
137
        $this->marks[$markType]->incrementTail();
138
        if ($this->previous !== null) {
139
            $this->previous->increaseMark($markType);
140
        }
141
    }
142
143
    public function getStartingNodeMarkScore($markType)
144
    {
145
        if ($this === $this->previous) {
146
            throw new \Exception('circular reference: ' . $this->text);
147
        }
148
        if (!isset($this->marks[$markType])) {
149
            // we don't have that mark
150
            return null;
151
        }
152
        if ($this->previous === null) {
153
            // we are the first node
154
            return $this->marks[$markType]->getTailLength();
155
        }
156
157
        $earlierMarkScore = $this->previous->getStartingNodeMarkScore($markType);
158
        if ($earlierMarkScore === null) {
159
            // the mark begins with us
160
            return $this->marks[$markType]->getTailLength();
161
        }
162
        return $earlierMarkScore;
163
    }
164
}
165