Ticket #5543: FCKeditorParser.body.php

File FCKeditorParser.body.php, 22.5 KB (added by fdujardi, 15 years ago)
Line 
1<?php
2
3class FCKeditorParser extends FCKeditorParserWrapper
4{
5        public static $fkc_mw_makeImage_options;
6        protected $fck_mw_strtr_span;
7        protected $fck_mw_strtr_span_counter=1;
8        protected $fck_mw_taghook;
9        protected $fck_internal_parse_text;
10        protected $fck_matches = array();
11
12        private $FCKeditorMagicWords = array(
13        '__NOTOC__',
14        '__FORCETOC__',
15        '__NOEDITSECTION__',
16        '__START__',
17        '__NOTITLECONVERT__',
18        '__NOCONTENTCONVERT__',
19        '__END__',
20        '__TOC__',
21        '__NOTC__',
22        '__NOCC__',
23        "__FORCETOC__",
24        "__NEWSECTIONLINK__",
25        "__NOGALLERY__",
26        );
27
28        /**
29         * Add special string (that would be changed by Parser) to array and return simple unique string
30         * that will remain unchanged during whole parsing operation.
31         * At the end we'll replace all this unique strings with original content
32         *
33         * @param string $text
34         * @return string
35         */
36        private function fck_addToStrtr($text, $replaceLineBreaks = true) {
37                $key = 'Fckmw'.$this->fck_mw_strtr_span_counter.'fckmw';
38                $this->fck_mw_strtr_span_counter++;
39                if ($replaceLineBreaks) {
40                        $this->fck_mw_strtr_span[$key] = str_replace(array("\r\n", "\n", "\r"),"fckLR",$text);
41                }
42                else {
43                        $this->fck_mw_strtr_span[$key] = $text;
44                }
45                return $key;
46        }
47
48        /**
49         * Handle link to subpage if necessary
50         * @param string $target the source of the link
51         * @param string &$text the link text, modified as necessary
52         * @return string the full name of the link
53         * @private
54         */
55        function maybeDoSubpageLink($target, &$text) {
56                return $target;
57        }
58
59        /**
60         * DO NOT Replace special strings like "ISBN xxx" and "RFC xxx" with
61         * magic external links.
62         *
63         * DML
64         * @private
65         */
66        function doMagicLinks( $text ) {
67                return $text;
68        }
69
70        /**
71        * Callback function for custom tags: feed, ref, references etc.
72        *
73        * @param string $str Input
74        * @param array $argv Arguments
75        * @return string
76        */
77        function fck_genericTagHook( $str, $argv, $parser ) {
78                if (in_array($this->fck_mw_taghook, array("ref", "math", "references", "source"))) {
79                        $class = $this->fck_mw_taghook;
80                }
81                else {
82                        $class = "special";
83                }
84
85                if (empty($argv)) {
86                        $ret = "<span class=\"fck_mw_".$class."\" _fck_mw_customtag=\"true\" _fck_mw_tagname=\"".$this->fck_mw_taghook."\">";
87                }
88                else {
89                        $ret = "<span class=\"fck_mw_".$class."\" _fck_mw_customtag=\"true\" _fck_mw_tagname=\"".$this->fck_mw_taghook."\"";
90                        foreach ($argv as $key=>$value) {
91                                $ret .= " ".$key."=\"".$value."\"";
92                        }
93                        $ret .=">";
94                }
95                if (is_null($str)) {
96                        $ret = substr($ret, 0, -1) . " />";
97                }
98                else {
99                        $ret .= htmlspecialchars($str);
100                        $ret .= "</span>";
101                }
102
103                $replacement = $this->fck_addToStrtr($ret);
104                return $replacement;
105        }
106
107        /**
108        * Callback function for wiki tags: nowiki, includeonly, noinclude
109        *
110        * @param string $tagName tag name, eg. nowiki, math
111        * @param string $str Input
112        * @param array $argv Arguments
113        * @return string
114        */
115        function fck_wikiTag( $tagName, $str, $argv = array()) {
116                if (empty($argv)) {
117                        $ret = "<span class=\"fck_mw_".$tagName."\" _fck_mw_customtag=\"true\" _fck_mw_tagname=\"".$tagName."\">";
118                }
119                else {
120                        $ret = "<span class=\"fck_mw_".$tagName."\" _fck_mw_customtag=\"true\" _fck_mw_tagname=\"".$tagName."\"";
121                        foreach ($argv as $key=>$value) {
122                                $ret .= " ".$key."=\"".$value."\"";
123                        }
124                        $ret .=">";
125                }
126                if (is_null($str)) {
127                        $ret = substr($ret, 0, -1) . " />";
128                }
129                else {
130                        $ret .= htmlspecialchars($str);
131                        $ret .= "</span>";
132                }
133
134                $replacement = $this->fck_addToStrtr($ret);
135
136                return $replacement;
137        }
138
139        /**
140         * Strips and renders nowiki, pre, math, hiero
141         * If $render is set, performs necessary rendering operations on plugins
142         * Returns the text, and fills an array with data needed in unstrip()
143         *
144         * @param StripState $state
145         *
146         * @param bool $stripcomments when set, HTML comments <!-- like this -->
147         *  will be stripped in addition to other tags. This is important
148         *  for section editing, where these comments cause confusion when
149         *  counting the sections in the wikisource
150         *
151         * @param array dontstrip contains tags which should not be stripped;
152         *  used to prevent stipping of <gallery> when saving (fixes bug 2700)
153         *
154         * @private
155         */
156        function strip( $text, $state, $stripcomments = false , $dontstrip = array () ) {
157                global $wgContLang, $wgUseTeX, $wgScriptPath, $wgVersion, $wgHooks, $wgExtensionFunctions;
158
159                wfProfileIn( __METHOD__ );
160                $render = ($this->mOutputType == OT_HTML);
161
162                $uniq_prefix = $this->mUniqPrefix;
163                $commentState = new ReplacementArray;
164                $nowikiItems = array();
165                $generalItems = array();
166
167                $elements = array_merge( array( 'nowiki', 'gallery', 'math' ), array_keys( $this->mTagHooks ) );
168                if ( (isset($wgHooks['ParserFirstCallInit']) && in_array('efSyntaxHighlight_GeSHiSetup', $wgHooks['ParserFirstCallInit']))
169                        || (isset($wgExtensionFunctions) && in_array('efSyntaxHighlight_GeSHiSetup', $wgExtensionFunctions)) ) {
170                        $elements = array_merge( $elements, array( 'source' ) );
171                }
172                if ( (isset($wgHooks['ParserFirstCallInit']) && in_array('wfCite', $wgHooks['ParserFirstCallInit']))
173                        || (isset($wgExtensionFunctions) && in_array('wfCite', $wgExtensionFunctions)) ) {
174                        $elements = array_merge( $elements, array( 'ref', 'references' ) );
175                }
176                global $wgRawHtml;
177                if( $wgRawHtml ) {
178                        $elements[] = 'html';
179                }
180
181                # Removing $dontstrip tags from $elements list (currently only 'gallery', fixing bug 2700)
182                foreach ( $elements AS $k => $v ) {
183                        if ( !in_array ( $v , $dontstrip ) ) continue;
184                        unset ( $elements[$k] );
185                }
186
187                $elements = array_unique($elements);
188                $matches = array();
189                if (version_compare("1.12", $wgVersion, ">")) {
190                        $text = Parser::extractTagsAndParams( $elements, $text, $matches, $uniq_prefix );
191                }
192                else {
193                        $text = self::extractTagsAndParams( $elements, $text, $matches, $uniq_prefix );
194                }
195
196                foreach( $matches as $marker => $data ) {
197                        list( $element, $content, $params, $tag ) = $data;
198                        if( $render ) {
199                                $tagName = strtolower( $element );
200                                wfProfileIn( __METHOD__."-render-$tagName" );
201                                switch( $tagName ) {
202                                        case '!--':
203                                                // Comment
204                                                if( substr( $tag, -3 ) == '-->' ) {
205                                                        $output = $tag;
206                                                } else {
207                                                        // Unclosed comment in input.
208                                                        // Close it so later stripping can remove it
209                                                        $output = "$tag-->";
210                                                }
211                                                break;
212                                        case 'references':
213                                                $output = $this->fck_wikiTag('references', $content, $params);
214                                                break;
215                                        case 'ref':
216                                                $output = $this->fck_wikiTag('ref', $content, $params);
217                                                break;
218                                        case 'syntaxhighlight':
219                                        case 'source':
220                                                $output = $this->fck_wikiTag('source', $content, $params);
221                                                break;
222                                        case 'html':
223                                                if( $wgRawHtml ) {
224                                                        $output = $this->fck_wikiTag('html', $content, $params);
225                                                }
226                                                break;
227                                        case 'nowiki':
228                                                $output = $this->fck_wikiTag('nowiki', $content, $params); //required by FCKeditor
229                                                break;
230                                        case 'math':
231                                                if($wgUseTeX){          //normal render
232                                                        $output = $wgContLang->armourMath( MathRenderer::renderMath( $content ) );
233                                                }else                           //show fakeimage
234                                                        $output = '<img _fckfakelement="true" class="FCK__MWMath" _fck_mw_math="'.$content.'" src="'.$wgScriptPath.'/skins/common/images/button_math.png" />';
235                                                break;
236                                        case 'gallery':
237                                                $output = $this->fck_wikiTag('gallery', $content, $params); //required by FCKeditor
238                                                //$output = $this->renderImageGallery( $content, $params );
239                                                break;
240                                        default:
241                                                if( isset( $this->mTagHooks[$tagName] ) ) {
242                                                        $this->fck_mw_taghook = $tagName; //required by FCKeditor
243                                                        $output = call_user_func_array( $this->mTagHooks[$tagName],
244                                                        array( $content, $params, $this ) );
245                                                } else {
246                                                        throw new MWException( "Invalid call hook $element" );
247                                                }
248                                }
249                                wfProfileOut( __METHOD__."-render-$tagName" );
250                        } else {
251                                // Just stripping tags; keep the source
252                                $output = $tag;
253                        }
254
255                        // Unstrip the output, to support recursive strip() calls
256                        $output = $state->unstripBoth( $output );
257
258                        if( !$stripcomments && $element == '!--' ) {
259                                $commentState->setPair( $marker, $output );
260                        } elseif ( $element == 'html' || $element == 'nowiki' ) {
261                                $nowikiItems[$marker] = $output;
262                        } else {
263                                $generalItems[$marker] = $output;
264                        }
265                }
266                # Add the new items to the state
267                # We do this after the loop instead of during it to avoid slowing
268                # down the recursive unstrip
269                $state->nowiki->mergeArray( $nowikiItems );
270                $state->general->mergeArray( $generalItems );
271
272                # Unstrip comments unless explicitly told otherwise.
273                # (The comments are always stripped prior to this point, so as to
274                # not invoke any extension tags / parser hooks contained within
275                # a comment.)
276                if ( !$stripcomments ) {
277                        // Put them all back and forget them
278                        $text = $commentState->replace( $text );
279                }
280
281                $this->fck_matches = $matches;
282                wfProfileOut( __METHOD__ );
283                return $text;
284        }
285
286        /** Replace HTML comments with unique text using fck_addToStrtr function
287         *
288         * @private
289         * @param string $text
290         * @return string
291         */
292        private function fck_replaceHTMLcomments( $text ) {
293                wfProfileIn( __METHOD__ );
294                while (($start = strpos($text, '<!--')) !== false) {
295                        $end = strpos($text, '-->', $start + 4);
296                        if ($end === false) {
297                                # Unterminated comment; bail out
298                                break;
299                        }
300
301                        $end += 3;
302
303                        # Trim space and newline if the comment is both
304                        # preceded and followed by a newline
305                        $spaceStart = max($start - 1, 0);
306                        $spaceLen = $end - $spaceStart;
307                        while (substr($text, $spaceStart, 1) === ' ' && $spaceStart > 0) {
308                                $spaceStart--;
309                                $spaceLen++;
310                        }
311                        while (substr($text, $spaceStart + $spaceLen, 1) === ' ')
312                        $spaceLen++;
313                        if (substr($text, $spaceStart, 1) === "\n" and substr($text, $spaceStart + $spaceLen, 1) === "\n") {
314                                # Remove the comment, leading and trailing
315                                # spaces, and leave only one newline.
316                                $replacement = $this->fck_addToStrtr(substr($text, $spaceStart, $spaceLen+1), false);
317                                $text = substr_replace($text, $replacement."\n", $spaceStart, $spaceLen + 1);
318                        }
319                        else {
320                                # Remove just the comment.
321                                $replacement = $this->fck_addToStrtr(substr($text, $start, $end - $start), false);
322                                $text = substr_replace($text, $replacement, $start, $end - $start);
323                        }
324                }
325                wfProfileOut( __METHOD__ );
326
327                return $text;
328        }
329
330        function replaceInternalLinks( $text ) {
331                $text = preg_replace("/\[\[([^|\[\]]*?)\]\]/", "[[$1|RTENOTITLE]]", $text);     //#2223: [[()]] =>      [[%1|RTENOTITLE]]
332                $text = preg_replace("/\[\[:(.*?)\]\]/", "[[RTECOLON$1]]", $text);      //change ':' => 'RTECOLON' in links
333                $text = parent::replaceInternalLinks($text);
334                $text = preg_replace("/\|RTENOTITLE\]\]/", "]]", $text);                                // remove unused RTENOTITLE
335
336                return $text;
337        }
338
339        function makeImage( $nt, $options ) {
340                FCKeditorParser::$fkc_mw_makeImage_options = $options;
341                return parent::makeImage( $nt, $options );
342        }
343
344        /**
345         * Replace templates with unique text to preserve them from parsing
346         *
347         * @todo if {{template}} is inside string that also must be returned unparsed,
348         * e.g. <noinclude>{{template}}</noinclude>
349         * {{template}} replaced with Fckmw[n]fckmw which is wrong...
350         *
351         * @param string $text
352         * @return string
353         */
354        private function fck_replaceTemplates( $text ) {
355
356                $callback = array('{' =>
357                array(
358                'end'=>'}',
359                'cb' => array(
360                2=>array('FCKeditorParser', 'fck_leaveTemplatesAlone'),
361                3=>array('FCKeditorParser', 'fck_leaveTemplatesAlone'),
362                ),
363                'min' =>2,
364                'max' =>3,
365                )
366                );
367
368                $text = $this->replace_callback($text, $callback);
369
370                $tags = array();
371                $offset=0;
372                $textTmp = $text;
373                while (false !== ($pos = strpos($textTmp, "<!--FCK_SKIP_START-->")))
374                {
375                        $tags[abs($pos + $offset)] = 1;
376                        $textTmp = substr($textTmp, $pos+21);
377                        $offset += $pos + 21;
378                }
379
380                $offset=0;
381                $textTmp = $text;
382                while (false !== ($pos = strpos($textTmp, "<!--FCK_SKIP_END-->")))
383                {
384                        $tags[abs($pos + $offset)] = -1;
385                        $textTmp = substr($textTmp, $pos+19);
386                        $offset += $pos + 19;
387                }
388
389                if (!empty($tags)) {
390                        ksort($tags);
391
392                        $strtr = array("<!--FCK_SKIP_START-->" => "", "<!--FCK_SKIP_END-->" => "");
393
394                        $sum=0;
395                        $lastSum=0;
396                        $finalString = "";
397                        $stringToParse = "";
398                        $startingPos = 0;
399                        $inner = "";
400                        $strtr_span = array();
401                        foreach ($tags as $pos=>$type) {
402                                $sum += $type;
403                                if (!$pos) {
404                                        $opened = 0;
405                                        $closed = 0;
406                                }
407                                else {
408                                        $opened = substr_count($text, '[', 0, $pos);                    //count [
409                                        $closed = substr_count($text, ']', 0, $pos);                    //count ]
410                                }
411                                if ($sum == 1 && $lastSum == 0) {
412                                        $stringToParse .= strtr(substr($text, $startingPos, $pos - $startingPos), $strtr);
413                                        $startingPos = $pos;
414                                }
415                                else if ($sum == 0) {
416                                        $stringToParse .= 'Fckmw'.$this->fck_mw_strtr_span_counter.'fckmw';
417                                        $inner = htmlspecialchars(strtr(substr($text, $startingPos, $pos - $startingPos + 19), $strtr));
418                                        $this->fck_mw_strtr_span['href="Fckmw'.$this->fck_mw_strtr_span_counter.'fckmw"'] = 'href="'.$inner.'"';
419                                        if($opened <= $closed) {                                                // {{template}} is NOT in [] or [[]]
420                                                $this->fck_mw_strtr_span['Fckmw'.$this->fck_mw_strtr_span_counter.'fckmw'] = '<span class="fck_mw_template">'.str_replace(array("\r\n", "\n", "\r"),"fckLR",$inner).'</span>';
421                                        }else{
422                                                $this->fck_mw_strtr_span['Fckmw'.$this->fck_mw_strtr_span_counter.'fckmw'] = str_replace(array("\r\n", "\n", "\r"),"fckLR",$inner);
423                                        }
424                                        $startingPos = $pos + 19;
425                                        $this->fck_mw_strtr_span_counter++;
426                                }
427                                $lastSum = $sum;
428                        }
429                        $stringToParse .= substr($text, $startingPos);
430                        $text = &$stringToParse;
431                }
432
433                return $text;
434        }
435
436        function internalParse ( $text ) {
437
438                $this->fck_internal_parse_text =& $text;
439
440                //these three tags should remain unchanged
441                $text = StringUtils::delimiterReplaceCallback( '<includeonly>', '</includeonly>', array($this, 'fck_includeonly'), $text );
442                $text = StringUtils::delimiterReplaceCallback( '<noinclude>', '</noinclude>', array($this, 'fck_noinclude'), $text );
443                $text = StringUtils::delimiterReplaceCallback( '<onlyinclude>', '</onlyinclude>', array($this, 'fck_onlyinclude'), $text );
444
445                //html comments shouldn't be stripped
446                $text = $this->fck_replaceHTMLcomments( $text );
447                //as well as templates
448                $text = $this->fck_replaceTemplates( $text );
449
450                $finalString = parent::internalParse($text);
451
452                return $finalString;
453        }
454        function fck_includeonly( $matches ) {
455                return $this->fck_wikiTag('includeonly', $matches[1]);
456        }
457        function fck_noinclude( $matches ) {
458                return $this->fck_wikiTag('noinclude', $matches[1]);
459        }
460        function fck_onlyinclude( $matches ) {
461                return $this->fck_wikiTag('onlyinclude', $matches[1]);
462        }
463        function fck_leaveTemplatesAlone( $matches ) {
464                return "<!--FCK_SKIP_START-->".$matches['text']."<!--FCK_SKIP_END-->";
465        }
466        function formatHeadings( $text, $isMain=true ) {
467                return $text;
468        }
469        function replaceFreeExternalLinks( $text ) { return $text; }
470        function stripNoGallery(&$text) {}
471        function stripToc( $text ) {
472                //$prefix = '<span class="fck_mw_magic">';
473                //$suffix = '</span>';
474                $prefix = '';
475                $suffix = '';
476
477                $strtr = array();
478                foreach ($this->FCKeditorMagicWords as $word) {
479                        $strtr[$word] = $prefix . $word . $suffix;
480                }
481
482                return strtr( $text, $strtr );
483        }
484
485        function doDoubleUnderscore( $text ) {
486                return $text;
487        }
488
489        function parse( $text, &$title, $options, $linestart = true, $clearState = true, $revid = null ) {
490                $text = preg_replace("/^#REDIRECT/", "<!--FCK_REDIRECT-->", $text);
491                $parserOutput = parent::parse($text, $title, $options, $linestart , $clearState , $revid );
492
493                $categories = $parserOutput->getCategories();
494                if ($categories) {
495                        $appendString = "";
496                        foreach ($categories as $cat=>$val) {
497                                $args = '';
498                                if( $val == 'RTENOTITLE' ){
499                                                $args .= '_fcknotitle="true" ';
500                                        $val = $cat;
501                                }
502                                if ($val != $title->mTextform) {
503                                        $appendString .= "<a ".$args."href=\"Category:" . $cat ."\">" . $val ."</a> ";
504                                }
505                                else {
506                                        $appendString .= "<a ".$args."href=\"Category:" . $cat ."\">Category:" . $cat ."</a> ";
507                                }
508                        }
509                        $parserOutput->setText($parserOutput->getText() . $appendString);
510                }
511
512                if (!empty($this->fck_mw_strtr_span)) {
513                        global $leaveRawTemplates;
514                        if (!empty($leaveRawTemplates)) {
515                                foreach ($leaveRawTemplates as $l) {
516                                        $this->fck_mw_strtr_span[$l] = substr($this->fck_mw_strtr_span[$l], 30, -7);
517                                }
518                        }
519                        $text = strtr($parserOutput->getText(), $this->fck_mw_strtr_span);
520                        $parserOutput->setText(strtr($text, $this->fck_mw_strtr_span));
521                }
522                if (!empty($this->fck_matches)) {
523                        $text = $parserOutput->getText() ;
524                        foreach ($this->fck_matches as $key => $m) {
525                                $text = str_replace( $key, $m[3], $text);
526                        }
527                        $parserOutput->setText($text);
528                }
529
530                if (!empty($parserOutput->mLanguageLinks)) {
531                        foreach ($parserOutput->mLanguageLinks as $l) {
532                                $parserOutput->setText($parserOutput->getText() . "\n" . "<a href=\"".$l."\">".$l."</a>") ;
533                        }
534                }
535
536                $parserOutput->setText(str_replace("<!--FCK_REDIRECT-->", "#REDIRECT", $parserOutput->getText()));
537
538                return $parserOutput;
539        }
540
541        /**
542         * Make lists from lines starting with ':', '*', '#', etc.
543         *
544         * @private
545         * @return string the lists rendered as HTML
546         */
547        function doBlockLevels( $text, $linestart ) {
548                $fname = 'Parser::doBlockLevels';
549                wfProfileIn( $fname );
550
551                # Parsing through the text line by line.  The main thing
552                # happening here is handling of block-level elements p, pre,
553                # and making lists from lines starting with * # : etc.
554                #
555                $textLines = explode( "\n", $text );
556
557                $lastPrefix = $output = '';
558                $this->mDTopen = $inBlockElem = false;
559                $prefixLength = 0;
560                $paragraphStack = false;
561
562                if ( !$linestart ) {
563                        $output .= array_shift( $textLines );
564                }
565                foreach ( $textLines as $oLine ) {
566                        $lastPrefixLength = strlen( $lastPrefix );
567                        $preCloseMatch = preg_match('/<\\/pre/i', $oLine );
568                        $preOpenMatch = preg_match('/<pre/i', $oLine );
569                        if ( !$this->mInPre ) {
570                                # Multiple prefixes may abut each other for nested lists.
571                                $prefixLength = strspn( $oLine, '*#:;' );
572                                $pref = substr( $oLine, 0, $prefixLength );
573
574                                # eh?
575                                $pref2 = str_replace( ';', ':', $pref );
576                                $t = substr( $oLine, $prefixLength );
577                                $this->mInPre = !empty($preOpenMatch);
578                        } else {
579                                # Don't interpret any other prefixes in preformatted text
580                                $prefixLength = 0;
581                                $pref = $pref2 = '';
582                                $t = $oLine;
583                        }
584
585                        # List generation
586                        if( $prefixLength && 0 == strcmp( $lastPrefix, $pref2 ) ) {
587                                # Same as the last item, so no need to deal with nesting or opening stuff
588                                $output .= $this->nextItem( substr( $pref, -1 ) );
589                                $paragraphStack = false;
590
591                                if ( substr( $pref, -1 ) == ';') {
592                                        # The one nasty exception: definition lists work like this:
593                                        # ; title : definition text
594                                        # So we check for : in the remainder text to split up the
595                                        # title and definition, without b0rking links.
596                                        $term = $t2 = '';
597                                        if ($this->findColonNoLinks($t, $term, $t2) !== false) {
598                                                $t = $t2;
599                                                $output .= $term . $this->nextItem( ':' );
600                                        }
601                                }
602                        } elseif( $prefixLength || $lastPrefixLength ) {
603                                # Either open or close a level...
604                                $commonPrefixLength = $this->getCommon( $pref, $lastPrefix );
605                                $paragraphStack = false;
606
607                                while( $commonPrefixLength < $lastPrefixLength ) {
608                                        $output .= $this->closeList( $lastPrefix{$lastPrefixLength-1} );
609                                        --$lastPrefixLength;
610                                }
611                                if ( $prefixLength <= $commonPrefixLength && $commonPrefixLength > 0 ) {
612                                        $output .= $this->nextItem( $pref{$commonPrefixLength-1} );
613                                }
614                                while ( $prefixLength > $commonPrefixLength ) {
615                                        $char = substr( $pref, $commonPrefixLength, 1 );
616                                        $output .= $this->openList( $char );
617
618                                        if ( ';' == $char ) {
619                                                # FIXME: This is dupe of code above
620                                                if ($this->findColonNoLinks($t, $term, $t2) !== false) {
621                                                        $t = $t2;
622                                                        $output .= $term . $this->nextItem( ':' );
623                                                }
624                                        }
625                                        ++$commonPrefixLength;
626                                }
627                                $lastPrefix = $pref2;
628                        }
629                        if( 0 == $prefixLength ) {
630                                wfProfileIn( "$fname-paragraph" );
631                                # No prefix (not in list)--go to paragraph mode
632                                // XXX: use a stack for nestable elements like span, table and div
633                                $openmatch = preg_match('/(?:<table|<blockquote|<h1|<h2|<h3|<h4|<h5|<h6|<pre|<tr|<p|<ul|<ol|<li|<\\/tr|<\\/td|<\\/th)/iS', $t );
634                                $closematch = preg_match(
635                                '/(?:<\\/table|<\\/blockquote|<\\/h1|<\\/h2|<\\/h3|<\\/h4|<\\/h5|<\\/h6|'.
636                                '<td|<th|<\\/?div|<hr|<\\/pre|<\\/p|'.$this->mUniqPrefix.'-pre|<\\/li|<\\/ul|<\\/ol|<\\/?center)/iS', $t );
637                                if ( $openmatch or $closematch ) {
638                                        $paragraphStack = false;
639                                        # TODO bug 5718: paragraph closed
640                                        $output .= $this->closeParagraph();
641                                        if ( $preOpenMatch and !$preCloseMatch ) {
642                                                $this->mInPre = true;
643                                        }
644                                        if ( $closematch ) {
645                                                $inBlockElem = false;
646                                        } else {
647                                                $inBlockElem = true;
648                                        }
649                                } else if ( !$inBlockElem && !$this->mInPre ) {
650                                        if ( ' ' == $t{0} and ( $this->mLastSection == 'pre' or trim($t) != '' ) ) {
651                                                // pre
652                                                if ($this->mLastSection != 'pre') {
653                                                        $paragraphStack = false;
654                                                        $output .= $this->closeParagraph().'<pre class="_fck_mw_lspace">';
655                                                        $this->mLastSection = 'pre';
656                                                }
657                                                $t = substr( $t, 1 );
658                                        } else {
659                                                // paragraph
660                                                if ( '' == trim($t) ) {
661                                                        if ( $paragraphStack ) {
662                                                                $output .= $paragraphStack.'<br />';
663                                                                $paragraphStack = false;
664                                                                $this->mLastSection = 'p';
665                                                        } else {
666                                                                if ($this->mLastSection != 'p' ) {
667                                                                        $output .= $this->closeParagraph();
668                                                                        $this->mLastSection = '';
669                                                                        $paragraphStack = '<p>';
670                                                                } else {
671                                                                        $paragraphStack = '</p><p>';
672                                                                }
673                                                        }
674                                                } else {
675                                                        if ( $paragraphStack ) {
676                                                                $output .= $paragraphStack;
677                                                                $paragraphStack = false;
678                                                                $this->mLastSection = 'p';
679                                                        } else if ($this->mLastSection != 'p') {
680                                                                $output .= $this->closeParagraph().'<p>';
681                                                                $this->mLastSection = 'p';
682                                                        }
683                                                }
684                                        }
685                                }
686                                wfProfileOut( "$fname-paragraph" );
687                        }
688                        // somewhere above we forget to get out of pre block (bug 785)
689                        if($preCloseMatch && $this->mInPre) {
690                                $this->mInPre = false;
691                        }
692                        if ($paragraphStack === false) {
693                                $output .= $t."\n";
694                        }
695                }
696                while ( $prefixLength ) {
697                        $output .= $this->closeList( $pref2{$prefixLength-1} );
698                        --$prefixLength;
699                }
700                if ( '' != $this->mLastSection ) {
701                        $output .= '</' . $this->mLastSection . '>';
702                        $this->mLastSection = '';
703                }
704
705                wfProfileOut( $fname );
706                return $output;
707        }
708}
© 2003 – 2022, CKSource sp. z o.o. sp.k. All rights reserved. | Terms of use | Privacy policy