Completed
Pull Request — master (#178)
by
unknown
13:35
created

FooterTrait::consumeFootnoteList()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 25
rs 9.2088
c 0
b 0
f 0
cc 5
nc 5
nop 2
1
<?php
2
/**
3
 * Created by Andrew Solovov.
4
 * User: Andrey
5
 * Date: 15.01.2021
6
 * Time: 18:36
7
 *
8
 * Project name: markdown
9
 *
10
 * @author     Andrew Solovov <[email protected]>
11
 * @copyright  1997-2021 Pan Russian solovov.ru
12
 */
13
14
namespace cebe\markdown\block;
15
16
17
trait FooterTrait
18
{
19
20
    protected $footnotes = [];
21
    protected $footnoteNum = 1;
22
23
    /**
24
     * @param $text
25
     * @return string
26
     */
27
    public function parse($text)
28
    {
29
        $absy = $this->parseBlocks(explode("\n", $text));
0 ignored issues
show
Bug introduced by
It seems like parseBlocks() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
30
31
        foreach ($absy as $block) {
32
            if ($block[0] == 'footnote') {
33
                $block['num'] = $this->footnoteNum;
34
                $this->footnotes[] = $block;
35
                $this->footnoteNum++;
36
            }
37
        }
38
        $markup = parent::parse($text);
39
        $markup = $this->applyFooter($markup, $this->footnotes);
40
41
        return $markup;
42
    }
43
44
    /**
45
     * @param $content
46
     * @param $blocks
47
     * @return string
48
     */
49
    protected function applyFooter($content, $blocks)
50
    {
51
        foreach ($blocks as $block) {
52
            $number = $block['num'] . ". ";
53
            $link = '<a href="#fnref:' . $block['id'] . '" class="footnote-backref">↑</a>';
54
            $text = $this->renderAbsy($block['content']);
0 ignored issues
show
Bug introduced by
It seems like renderAbsy() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
55
            $text = $this->renderAbsy($this->parseInline($text));
0 ignored issues
show
Bug introduced by
It seems like parseInline() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
Bug introduced by
It seems like renderAbsy() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
56
            $text = substr_replace($text, $number, 3, 0);
57
            $text = substr_replace($text, $link, -5, 0);
58
59
            $content .= '<footnotes id="fn:' . $block['id'] . '">' . $text . "</footnotes>\n";
60
        }
61
        return $content;
62
    }
63
64
    /**
65
     * Parses a footnote link indicated by `[^`.
66
     * @marker [^
67
     * @param $text
68
     * @return array
69
     */
70 View Code Duplication
    protected function parseFootnoteLink($text)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
71
    {
72
        if (preg_match('/^\[\^(.+?)\]/', $text, $matches)) {
73
            return [
74
                ['footnoteLink', $matches[1]],
75
                strlen($matches[0])
76
            ];
77
        }
78
        return [['text', $text[0]], 1];
79
    }
80
81
    /**
82
     * @param $block
83
     * @return string
84
     */
85
    protected function renderFootnoteLink($block)
86
    {
87
        $footnoteId = $block[1];
88
        $num = 0;
89
        $found = false;
90
        foreach ($this->footnotes as $footnote) {
91
            $num ++;
92
            if ($footnote['id']==$footnoteId) {
93
                $found = true;
94
                break;
95
            }
96
        }
97
        if (!$found)
98
            $num = '?';
99
100
        $text = htmlspecialchars($block[1], ENT_NOQUOTES | ENT_SUBSTITUTE, 'UTF-8');
101
        return '<sup id="fnref:' . $text . '"><a href="#fn:' . $text . '" class="footnote-ref" rel="footnote">[' . $num . ']</a></sup>';
102
    }
103
104
    /**
105
     * identify a line as the beginning of a footnote block
106
     *
107
     * @param $line
108
     * @return false|int
109
     */
110
    protected function identifyFootnoteList($line)
111
    {
112
        return preg_match('/^\[\^(.+?)\]:/', $line);
113
    }
114
115
    /**
116
     * Consume lines for a footnote
117
     */
118
    protected function consumeFootnoteList($lines, $current)
119
    {
120
        $id = '';
121
        $content = [];
122
        $count = count($lines);
123
        for ($i = $current; $i < $count; $i++) {
124
            $line = $lines[$i];
125
126
            if ($id == '') {
127
                if (preg_match('/^\[\^(.+?)\]:[ \t]+/', $line, $matches)) {
128
                    $id = $matches[1];
129
                    $str = substr($line, strlen($matches[0]));
130
                    $content[] = $str;
131
                }
132
            } else if (strlen(trim($line)) == 0) {
133
                break;
134
            } else {
135
                $content[] = ltrim($line);
136
            }
137
        }
138
139
        $block = ['footnote', 'id' => $id, 'content' => $this->parseBlocks($content)];
0 ignored issues
show
Bug introduced by
It seems like parseBlocks() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
140
141
        return [$block, $i];
142
    }
143
144
    /**
145
     * @param $block
146
     * @return string
147
     */
148
    protected function renderFootnote($block)
0 ignored issues
show
Unused Code introduced by
The parameter $block is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
149
    {
150
        return '';
151
    }
152
153
154
}