Completed
Push — master ( d1c421...1f5165 )
by Filippo
21s queued 13s
created

BBCodeConverter::removeColor()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.8333
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
/**
4
 * @file BBCodeConverter.php
5
 * @brief This file contains the BBCodeConverter class.
6
 * @details
7
 * @author Filippo F. Fadda
8
 */
9
10
namespace Converter;
11
12
13
/**
14
 * @brief A rudimental converter that takes as input a BBCode formatted text and converts it to Markdown.
15
 */
16
class BBCodeConverter extends Converter
17
{
18
    
19
    
20
    /**
21
     * @brief Removes BBCode size.
22
     */
23
    protected function removeSize()
24
    {
25
        
26
        $this->text = preg_replace_callback('%\[size=\d*\]([\W\D\w\s]*?)\[/size\]%iu',
27
            
28
            function ($matches) {
29
                return $matches[1];
30
            },
31
            
32
            $this->text
33
        );
34
        
35
    }
36
    
37
    
38
    /**
39
     * @brief Removes BBCode center.
40
     */
41
    protected function removeCenter()
42
    {
43
        
44
        $this->text = preg_replace_callback('%\[center\]([\W\D\w\s]*?)\[/center\]%iu',
45
            
46
            function ($matches) {
47
                return $matches[1];
48
            },
49
            
50
            $this->text
51
        );
52
        
53
    }
54
    
55
    
56
    /**
57
     * @brief Removes BBCode center.
58
     */
59
    protected function removeLeft()
60
    {
61
        
62
        $this->text = preg_replace_callback('%\[left\]([\W\D\w\s]*?)\[/left\]%iu',
63
            
64
            function ($matches) {
65
                return $matches[1];
66
            },
67
            
68
            $this->text
69
        );
70
        
71
    }
72
    
73
    /**
74
     * @brief Removes BBCode color.
75
     */
76
    protected function removeColor()
77
    {
78
        
79
        $this->text = preg_replace_callback('%\[color[=?][#?][\w]*\]([\W\D\w\s]*?)\[/color\]%iu',
80
            
81
            function ($matches) {
82
                return $matches[1];
83
            },
84
            
85
            $this->text
86
        );
87
        
88
    }
89
    
90
    
91
    /**
92
     * @brief Replaces BBCode bold.
93
     */
94 View Code Duplication
    protected function replaceBold()
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...
95
    {
96
        
97
        $this->text = preg_replace_callback('%\[b\]([\W\D\w\s]*?)\[/b\]%iu',
98
            
99
            function ($matches) {
100
                return "**" . trim($matches[1], " ") . "**";
101
            },
102
            
103
            $this->text
104
        );
105
        
106
    }
107
    
108
    
109
    /**
110
     * @brief Replaces BBCode italic.
111
     */
112 View Code Duplication
    protected function replaceItalic()
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...
113
    {
114
        
115
        $this->text = preg_replace_callback('%\[i\]([\W\D\w\s]*?)\[/i\]%iu',
116
            
117
            function ($matches) {
118
                return "*" . trim($matches[1], " ") . "*";
119
            },
120
            
121
            $this->text
122
        );
123
        
124
    }
125
    
126
    
127
    /**
128
     * @brief Replaces BBCode underline. Hoedown support underline.
129
     */
130 View Code Duplication
    protected function replaceUnderline()
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...
131
    {
132
        
133
        $this->text = preg_replace_callback('%\[u\]([\W\D\w\s]*?)\[/u\]%iu',
134
            
135
            function ($matches) {
136
                return "_" . trim($matches[1], " ") . "_";
137
            },
138
            
139
            $this->text
140
        );
141
        
142
    }
143
    
144
    
145
    /**
146
     * @brief Replaces BBCode strikethrough.
147
     */
148 View Code Duplication
    protected function replaceStrikethrough()
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...
149
    {
150
        
151
        $this->text = preg_replace_callback('%\[s\]([\W\D\w\s]*?)\[/s\]%iu',
152
            
153
            function ($matches) {
154
                return "~~" . trim($matches[1], " ") . "~~";
155
            },
156
            
157
            $this->text
158
        );
159
        
160
    }
161
    
162
    
163
    /**
164
     * @brief Replaces BBCode lists.
165
     */
166
    protected function replaceLists()
167
    {
168
        
169
        $this->text = preg_replace_callback('%\[list(?P<type>=1)?\](?P<items>[\W\D\w\s]*?)\[/list\]%iu',
170
            
171
            function ($matches) {
172
                $buffer = "";
173
                
174
                $list = preg_replace('/\s*$|^\s*/mu', '', $matches['items']);
175
                if ( is_null($list) )
176
                    throw new \RuntimeException(sprintf("Text identified by '%d' has malformed BBCode lists", $this->id));
177
                
178
                $items = preg_split('/\[\*\]/u', $list);
179
                
180
                $counter = count($items);
181
                
182
                if ( isset($matches['type']) && $matches['type'] == '=1' ) { // ordered list
183
                    // We start from 1 to discard the first string, in fact, it's empty.
184 View Code Duplication
                    for ( $i = 1; $i < $counter; $i++ )
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...
185
                        if ( !empty($items[ $i ]) )
186
                            $buffer .= (string) ( $i ) . '. ' . trim($items[ $i ]) . PHP_EOL;
187
                } else { // unordered list
188
                    // We start from 1 to discard the first string, in fact, it's empty.
189 View Code Duplication
                    for ( $i = 1; $i < $counter; $i++ )
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...
190
                        if ( !empty($items[ $i ]) )
191
                            $buffer .= '- ' . trim($items[ $i ]) . PHP_EOL;
192
                }
193
                
194
                // We need a like break above the list and another one below.
195
                if ( !empty($buffer) )
196
                    $buffer = PHP_EOL . $buffer . PHP_EOL;
197
                
198
                return $buffer;
199
            },
200
            
201
            $this->text
202
        );
203
        
204
    }
205
    
206
    
207
    /**
208
     * @brief Replaces BBCode urls.
209
     */
210 View Code Duplication
    protected function replaceUrls()
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...
211
    {
212
        
213
        $this->text = preg_replace_callback('%\[url\s*=\s*("(?:[^"]*")|\A[^\']*\Z|(?:[^\'">\]\s]+))\s*(?:[^]\s]*)\]([\W\D\w\s]*?)\[/url\]%iu',
214
            
215
            function ($matches) {
216
                if ( isset($matches[1]) && isset($matches[2]) )
217
                    return "[" . $matches[2] . "](" . $matches[1] . ")";
218
                else
219
                    throw new \RuntimeException(sprintf("Text identified by '%d' has malformed BBCode urls", $this->id));
220
            },
221
            
222
            $this->text
223
        );
224
        
225
    }
226
    
227
    
228
    /**
229
     * @brief Replaces BBCode urls without a description.
230
     */
231 View Code Duplication
    protected function replaceUndescribedUrls()
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...
232
    {
233
        $this->text = preg_replace_callback('%\[url\]([\W\D\w\s]*?)\[/url\]%iu',
234
            
235
            function ($matches) {
236
                if ( isset($matches[1]) )
237
                    return "[" . $matches[1] . "](" . $matches[1] . ")";
238
                else
239
                    throw new \RuntimeException(sprintf("Text identified by '%d' has malformed BBCode urls", $this->id));
240
            },
241
            
242
            $this->text
243
        );
244
        
245
    }
246
    
247
    
248
    /**
249
     * @brief Replaces BBCode images.
250
     */
251
    protected function replaceImages()
252
    {
253
        
254
        $this->text = preg_replace_callback('%\[img\s*\]\s*("(?:[^"]*")|\A[^\']*\Z|(?:[^\'">\]\s]+))\s*(?:[^]\s]*)\[/img\]%iu',
255
            
256
            function ($matches) {
257
                if ( isset($matches[1]) )
258
                    return PHP_EOL . "![]" . "(" . $matches[1] . ")" . PHP_EOL;
259
                else
260
                    throw new \RuntimeException(sprintf("Text identified by '%d' have malformed BBCode images", $this->id));
261
            },
262
            
263
            $this->text
264
        );
265
        
266
    }
267
    
268
    
269
    /**
270
     * @brief Replaces BBCode quotes.
271
     * @details Thanks to Casimir et Hippolyte for helping me with this regex.
272
     */
273
    protected function replaceQuotes()
274
    {
275
        // Removes the inner quotes, leaving just one level.
276
        $this->text = preg_replace('~\G(?<!^)(?>(\[quote\b[^]]*](?>[^[]++|\[(?!/?quote)|(?1))*\[/quote])|(?<!\[)(?>[^[]++|\[(?!/?quote))+\K)|\[quote\b[^]]*]\K~', '', $this->text);
277
        
278
        // Replaces all the remaining quotes with '> ' characters.
279
        $this->text = preg_replace_callback('%\[quote\b[^]]*\]((?>[^[]++|\[(?!/?quote))*)\[/quote\]%i',
280
            
281
            function ($matches) {
282
                $quote = preg_replace('/^\s*/mu', '', trim($matches[1]));
283
                return "> " . $quote . PHP_EOL . PHP_EOL;
284
            },
285
            
286
            $this->text
287
        );
288
    }
289
    
290
    
291
    /**
292
     * @brief Replaces BBCode snippets.
293
     */
294
    protected function replaceSnippets()
295
    {
296
        
297
        $this->text = preg_replace_callback('%\[code\s*=?(?P<language>\w*)\](?P<snippet>[\W\D\w\s]*?)\[\/code\]%iu',
298
            
299
            function ($matches) {
300
                if ( isset($matches['snippet']) ) {
301
                    $language = strtolower($matches['language']);
302
                    
303
                    if ( $language == 'html4strict' or $language == 'div' )
304
                        $language = 'html';
305
                    elseif ( $language == 'shell' or $language == 'dos' or $language == 'batch' )
306
                        $language = 'sh';
307
                    elseif ( $language == 'xul' or $language == 'wpf' )
308
                        $language = 'xml';
309
                    elseif ( $language == 'asm' )
310
                        $language = 'nasm';
311
                    elseif ( $language == 'vb' or $language == 'visualbasic' or $language == 'vba' )
312
                        $language = 'vb.net';
313
                    elseif ( $language == 'asp' )
314
                        $language = 'aspx-vb';
315
                    elseif ( $language == 'xaml' )
316
                        $language = 'xml';
317
                    elseif ( $language == 'cplusplus' )
318
                        $language = 'cpp';
319
                    elseif ( $language == 'txt' or $language == 'gettext' )
320
                        $language = 'text';
321
                    elseif ( $language == 'basic' )
322
                        $language = 'cbmbas';
323
                    elseif ( $language == 'lisp' )
324
                        $language = 'clojure';
325
                    elseif ( $language == 'aspnet' )
326
                        $language = 'aspx-vb';
327
                    
328
                    return PHP_EOL . "```" . $language . PHP_EOL . trim($matches['snippet']) . PHP_EOL . "```" . PHP_EOL;
329
                } else
330
                    throw new \RuntimeException(sprintf("Text identified by '%d' has malformed BBCode snippet.", $this->id));
331
            },
332
            
333
            $this->text
334
        );
335
        
336
    }
337
    
338
    
339
    /**
340
     * @brief Converts the provided BBCode text to an equivalent Markdown text.
341
     */
342
    public function toMarkdown()
343
    {
344
        $this->removeCenter();
345
        $this->removeLeft();
346
        $this->removeColor();
347
        $this->removeSize();
348
        $this->replaceBold();
349
        $this->replaceItalic();
350
        $this->replaceUnderline();
351
        $this->replaceStrikethrough();
352
        $this->replaceLists();
353
        $this->replaceUrls();
354
        $this->replaceUndescribedUrls();
355
        $this->replaceImages();
356
        $this->replaceQuotes();
357
        $this->replaceSnippets();
358
        
359
        return trim($this->text);
360
    }
361
    
362
}