Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 1
<?php
2
 
3
namespace Sabberworm\CSS;
4
 
5
use Sabberworm\CSS\Comment\Commentable;
6
use Sabberworm\CSS\Parsing\OutputException;
7
 
8
class OutputFormatter
9
{
10
    /**
11
     * @var OutputFormat
12
     */
13
    private $oFormat;
14
 
15
    public function __construct(OutputFormat $oFormat)
16
    {
17
        $this->oFormat = $oFormat;
18
    }
19
 
20
    /**
21
     * @param string $sName
22
     * @param string|null $sType
23
     *
24
     * @return string
25
     */
26
    public function space($sName, $sType = null)
27
    {
28
        $sSpaceString = $this->oFormat->get("Space$sName");
29
        // If $sSpaceString is an array, we have multiple values configured
30
        // depending on the type of object the space applies to
31
        if (is_array($sSpaceString)) {
32
            if ($sType !== null && isset($sSpaceString[$sType])) {
33
                $sSpaceString = $sSpaceString[$sType];
34
            } else {
35
                $sSpaceString = reset($sSpaceString);
36
            }
37
        }
38
        return $this->prepareSpace($sSpaceString);
39
    }
40
 
41
    /**
42
     * @return string
43
     */
44
    public function spaceAfterRuleName()
45
    {
46
        return $this->space('AfterRuleName');
47
    }
48
 
49
    /**
50
     * @return string
51
     */
52
    public function spaceBeforeRules()
53
    {
54
        return $this->space('BeforeRules');
55
    }
56
 
57
    /**
58
     * @return string
59
     */
60
    public function spaceAfterRules()
61
    {
62
        return $this->space('AfterRules');
63
    }
64
 
65
    /**
66
     * @return string
67
     */
68
    public function spaceBetweenRules()
69
    {
70
        return $this->space('BetweenRules');
71
    }
72
 
73
    /**
74
     * @return string
75
     */
76
    public function spaceBeforeBlocks()
77
    {
78
        return $this->space('BeforeBlocks');
79
    }
80
 
81
    /**
82
     * @return string
83
     */
84
    public function spaceAfterBlocks()
85
    {
86
        return $this->space('AfterBlocks');
87
    }
88
 
89
    /**
90
     * @return string
91
     */
92
    public function spaceBetweenBlocks()
93
    {
94
        return $this->space('BetweenBlocks');
95
    }
96
 
97
    /**
98
     * @return string
99
     */
100
    public function spaceBeforeSelectorSeparator()
101
    {
102
        return $this->space('BeforeSelectorSeparator');
103
    }
104
 
105
    /**
106
     * @return string
107
     */
108
    public function spaceAfterSelectorSeparator()
109
    {
110
        return $this->space('AfterSelectorSeparator');
111
    }
112
 
113
    /**
114
     * @param string $sSeparator
115
     *
116
     * @return string
117
     */
118
    public function spaceBeforeListArgumentSeparator($sSeparator)
119
    {
120
        return $this->space('BeforeListArgumentSeparator', $sSeparator);
121
    }
122
 
123
    /**
124
     * @param string $sSeparator
125
     *
126
     * @return string
127
     */
128
    public function spaceAfterListArgumentSeparator($sSeparator)
129
    {
130
        return $this->space('AfterListArgumentSeparator', $sSeparator);
131
    }
132
 
133
    /**
134
     * @return string
135
     */
136
    public function spaceBeforeOpeningBrace()
137
    {
138
        return $this->space('BeforeOpeningBrace');
139
    }
140
 
141
    /**
142
     * Runs the given code, either swallowing or passing exceptions, depending on the `bIgnoreExceptions` setting.
143
     *
144
     * @param string $cCode the name of the function to call
145
     *
146
     * @return string|null
147
     */
148
    public function safely($cCode)
149
    {
150
        if ($this->oFormat->get('IgnoreExceptions')) {
151
            // If output exceptions are ignored, run the code with exception guards
152
            try {
153
                return $cCode();
154
            } catch (OutputException $e) {
155
                return null;
156
            } // Do nothing
157
        } else {
158
            // Run the code as-is
159
            return $cCode();
160
        }
161
    }
162
 
163
    /**
164
     * Clone of the `implode` function, but calls `render` with the current output format instead of `__toString()`.
165
     *
166
     * @param string $sSeparator
167
     * @param array<array-key, Renderable|string> $aValues
168
     * @param bool $bIncreaseLevel
169
     *
170
     * @return string
171
     */
172
    public function implode($sSeparator, array $aValues, $bIncreaseLevel = false)
173
    {
174
        $sResult = '';
175
        $oFormat = $this->oFormat;
176
        if ($bIncreaseLevel) {
177
            $oFormat = $oFormat->nextLevel();
178
        }
179
        $bIsFirst = true;
180
        foreach ($aValues as $mValue) {
181
            if ($bIsFirst) {
182
                $bIsFirst = false;
183
            } else {
184
                $sResult .= $sSeparator;
185
            }
186
            if ($mValue instanceof Renderable) {
187
                $sResult .= $mValue->render($oFormat);
188
            } else {
189
                $sResult .= $mValue;
190
            }
191
        }
192
        return $sResult;
193
    }
194
 
195
    /**
196
     * @param string $sString
197
     *
198
     * @return string
199
     */
200
    public function removeLastSemicolon($sString)
201
    {
202
        if ($this->oFormat->get('SemicolonAfterLastRule')) {
203
            return $sString;
204
        }
205
        $sString = explode(';', $sString);
206
        if (count($sString) < 2) {
207
            return $sString[0];
208
        }
209
        $sLast = array_pop($sString);
210
        $sNextToLast = array_pop($sString);
211
        array_push($sString, $sNextToLast . $sLast);
212
        return implode(';', $sString);
213
    }
214
 
215
    /**
216
     *
217
     * @param array<Commentable> $aComments
218
     *
219
     * @return string
220
     */
221
    public function comments(Commentable $oCommentable)
222
    {
223
        if (!$this->oFormat->bRenderComments) {
224
            return '';
225
        }
226
 
227
        $sResult = '';
228
        $aComments = $oCommentable->getComments();
229
        $iLastCommentIndex = count($aComments) - 1;
230
 
231
        foreach ($aComments as $i => $oComment) {
232
            $sResult .= $oComment->render($this->oFormat);
233
            $sResult .= $i === $iLastCommentIndex ? $this->spaceAfterBlocks() : $this->spaceBetweenBlocks();
234
        }
235
        return $sResult;
236
    }
237
 
238
    /**
239
     * @param string $sSpaceString
240
     *
241
     * @return string
242
     */
243
    private function prepareSpace($sSpaceString)
244
    {
245
        return str_replace("\n", "\n" . $this->indent(), $sSpaceString);
246
    }
247
 
248
    /**
249
     * @return string
250
     */
251
    private function indent()
252
    {
253
        return str_repeat($this->oFormat->sIndentation, $this->oFormat->level());
254
    }
255
}