Completed
Push — master ( 2ad12b...ca8b05 )
by Sebastian
02:50
created

Text::renderVariable()   C

Complexity

Conditions 8
Paths 6

Size

Total Lines 30
Code Lines 20

Duplication

Lines 9
Ratio 30 %

Importance

Changes 0
Metric Value
cc 8
eloc 20
c 0
b 0
f 0
nc 6
nop 2
dl 9
loc 30
rs 5.3846
1
<?php
2
/*
3
 * citeproc-php
4
 *
5
 * @link        http://github.com/seboettg/citeproc-php for the source repository
6
 * @copyright   Copyright (c) 2016 Sebastian Böttger.
7
 * @license     https://opensource.org/licenses/MIT
8
 */
9
10
namespace Seboettg\CiteProc\Rendering;
11
12
use Seboettg\CiteProc\CiteProc;
13
use Seboettg\CiteProc\Context;
14
use Seboettg\CiteProc\Exception\CiteProcException;
15
use Seboettg\CiteProc\RenderingState;
16
use Seboettg\CiteProc\Styles\AffixesTrait;
17
use Seboettg\CiteProc\Styles\ConsecutivePunctuationCharacterTrait;
18
use Seboettg\CiteProc\Styles\DisplayTrait;
19
use Seboettg\CiteProc\Styles\FormattingTrait;
20
use Seboettg\CiteProc\Styles\QuotesTrait;
21
use Seboettg\CiteProc\Styles\TextCaseTrait;
22
use Seboettg\CiteProc\Util\CiteProcHelper;
23
use Seboettg\CiteProc\Util\NumberHelper;
24
use Seboettg\CiteProc\Util\PageHelper;
25
use Seboettg\CiteProc\Util\StringHelper;
26
27
28
/**
29
 * Class Term
30
 * @package Seboettg\CiteProc\Node\Style
31
 *
32
 * @author Sebastian Böttger <[email protected]>
33
 */
34
class Text implements Rendering
35
{
36
    use FormattingTrait,
37
        AffixesTrait,
38
        TextCaseTrait,
39
        DisplayTrait,
40
        ConsecutivePunctuationCharacterTrait,
41
        QuotesTrait;
42
43
    /**
44
     * @var string
45
     */
46
    private $toRenderType;
47
48
    /**
49
     * @var string
50
     */
51
    private $toRenderTypeValue;
52
53
    /**
54
     * @var string
55
     */
56
    private $form = "long";
57
58
    /**
59
     * Text constructor.
60
     * @param \SimpleXMLElement $node
61
     */
62
    public function __construct(\SimpleXMLElement $node)
63
    {
64
        foreach ($node->attributes() as $attribute) {
65
            $name = $attribute->getName();
66
            if (in_array($name, ['value', 'variable', 'macro', 'term'])) {
67
                $this->toRenderType = $name;
68
                $this->toRenderTypeValue = (string) $attribute;
69
            }
70
            if ($name === "form") {
71
                $this->form = (string) $attribute;
72
            }
73
        }
74
        $this->initFormattingAttributes($node);
75
        $this->initDisplayAttributes($node);
76
        $this->initTextCaseAttributes($node);
77
        $this->initAffixesAttributes($node);
78
        $this->initQuotesAttributes($node);
79
    }
80
81
    /**
82
     * @param \stdClass $data
83
     * @param int|null $citationNumber
84
     * @return string
85
     */
86
    public function render($data, $citationNumber = null)
87
    {
88
        $lang = (isset($data->language) && $data->language != 'en') ? $data->language : 'en';
89
90
        $renderedText = "";
91
        switch ($this->toRenderType) {
92
            case 'value':
93
                $renderedText = $this->applyTextCase($this->toRenderTypeValue, $lang);
94
                break;
95
            case 'variable':
96
                if ($this->toRenderTypeValue === "citation-number") {
97
                    $renderedText = $this->renderCitationNumber($data, $citationNumber);
98
                    break;
99
                } else if ($this->toRenderTypeValue === "page") {
100
                    $renderedText = $this->renderPage($data);
101
                    // for test sort_BibliographyCitationNumberDescending.json
102
                } else {
103
                    $renderedText = $this->renderVariable($data, $lang);
104
                }
105
                if (CiteProc::getContext()->getRenderingState()->getValue() === RenderingState::SUBSTITUTION) {
106
                    unset($data->{$this->toRenderTypeValue});
107
                }
108
                $renderedText = $this->applyAdditionalMarkupFunction($data, $renderedText);
109
                break;
110
            case 'macro':
111
                $renderedText = $this->renderMacro($data);
112
                break;
113
            case 'term':
114
                $term = CiteProc::getContext()->getLocale()->filter("terms", $this->toRenderTypeValue, $this->form)->single;
115
                $renderedText = !empty($term) ? $this->applyTextCase($term, $lang) : "";
116
        }
117
        if (!empty($renderedText)) {
118
            $renderedText = $this->formatRenderedText($renderedText);
119
        }
120
        return $renderedText;
121
    }
122
123
    /**
124
     * @return string
125
     */
126
    public function getSource()
127
    {
128
        return $this->toRenderType;
129
    }
130
131
    /**
132
     * @return string
133
     */
134
    public function getVariable()
135
    {
136
        return $this->toRenderTypeValue;
137
    }
138
139
    private function renderPage($data)
140
    {
141
        if (empty($data->page)) {
142
            return "";
143
        }
144
145
        if (preg_match(NumberHelper::PATTERN_COMMA_AMPERSAND_RANGE, $data->page)) {
146
            $data->page = $this->normalizeDateRange($data->page);
147
            $ranges = preg_split("/[-–]/", trim($data->page));
148
            if (count($ranges) > 1) {
149
                if (!empty(CiteProc::getContext()->getGlobalOptions()) && !empty(CiteProc::getContext()->getGlobalOptions()->getPageRangeFormat())) {
150
                    return PageHelper::processPageRangeFormats($ranges, CiteProc::getContext()->getGlobalOptions()->getPageRangeFormat());
151
                }
152
                list($from, $to) = $ranges;
153
                return "$from-$to";
154
            }
155
        }
156
        return $data->page;
157
    }
158
159
    private function normalizeDateRange($page)
160
    {
161
        if (preg_match("/^(\d+)--(\d+)$/", trim($page), $matches)) {
162
            return $matches[1]."-".$matches[2];
163
        }
164
        return $page;
165
    }
166
167
    /**
168
     * @param $data
169
     * @param $renderedText
170
     * @return mixed
171
     */
172
    private function applyAdditionalMarkupFunction($data, $renderedText)
173
    {
174
        return CiteProcHelper::applyAdditionMarkupFunction($data, $this->toRenderTypeValue, $renderedText);
175
    }
176
177
    /**
178
     * @param $data
179
     * @param $lang
180
     * @return string
181
     */
182
    private function renderVariable($data, $lang)
183
    {
184
        // check if there is an attribute with prefix short or long e.g. shortTitle or longAbstract
185
        // test case group_ShortOutputOnly.json
186
        $renderedText = "";
187
        if (in_array($this->form, ["short", "long"])) {
188
            $attrWithPrefix = $this->form . ucfirst($this->toRenderTypeValue);
189
            $attrWithSuffix = $this->toRenderTypeValue . "-" . $this->form;
190
            if (isset($data->{$attrWithPrefix}) && !empty($data->{$attrWithPrefix})) {
191
                $renderedText = $this->applyTextCase(StringHelper::clearApostrophes($data->{$attrWithPrefix}), $lang);
192
            } else {
193
                if (isset($data->{$attrWithSuffix}) && !empty($data->{$attrWithSuffix})) {
194
                    $renderedText = $this->applyTextCase(StringHelper::clearApostrophes($data->{$attrWithSuffix}),
195
                        $lang);
196 View Code Duplication
                } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
197
                    if (isset($data->{$this->toRenderTypeValue})) {
198
                        $renderedText = $this->applyTextCase(StringHelper::clearApostrophes($data->{$this->toRenderTypeValue}),
199
                            $lang);
200
                    }
201
202
                }
203
            }
204 View Code Duplication
        } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
205
            if (!empty($data->{$this->toRenderTypeValue})) {
206
                $renderedText = $this->applyTextCase(StringHelper::clearApostrophes($data->{$this->toRenderTypeValue}),
207
                    $lang);
208
            }
209
        }
210
        return $renderedText;
211
    }
212
213
    /**
214
     * @param $renderedText
215
     * @return string
216
     */
217
    private function formatRenderedText($renderedText)
218
    {
219
        $text = $this->format($renderedText);
220
        $res = $this->addAffixes($text);
221
        if (!empty($res)) {
222
            $res = $this->removeConsecutiveChars($res);
223
        }
224
        $res = $this->addSurroundingQuotes($res);
225
        return $this->wrapDisplayBlock($res);
226
    }
227
228
    /**
229
     * @param $data
230
     * @param $citationNumber
231
     * @return int|mixed
232
     */
233
    private function renderCitationNumber($data, $citationNumber)
234
    {
235
        $renderedText = $citationNumber + 1;
236
        $renderedText = $this->applyAdditionalMarkupFunction($data, $renderedText);
237
        return $renderedText;
238
    }
239
240
    /**
241
     * @param $data
242
     * @return string
243
     */
244
    private function renderMacro($data)
245
    {
246
        $macro = CiteProc::getContext()->getMacro($this->toRenderTypeValue);
247
        if (is_null($macro)) {
248
            try {
249
                throw new CiteProcException("Macro \"" . $this->toRenderTypeValue . "\" does not exist.");
250
            } catch (CiteProcException $e) {
251
                $renderedText = "";
252
            }
253
        } else {
254
            $renderedText = $macro->render($data);
255
        }
256
        return $renderedText;
257
    }
258
}
0 ignored issues
show
Coding Style introduced by
As per coding style, files should not end with a newline character.

This check marks files that end in a newline character, i.e. an empy line.

Loading history...
259