Example #1
0
 public static function convertDataToAttributes($data)
 {
     // get ID of current CK instance
     $instance = RTE::getInstanceId();
     // properly encode JSON
     $encoded = RTEReverseParser::encodeRTEData($data);
     $encoded = Sanitizer::encodeAttribute($encoded);
     return " data-rte-meta=\"{$encoded}\" data-rte-instance=\"{$instance}\" ";
 }
Example #2
0
 /**
  * Make lists from lines starting with ':', '*', '#', etc. (DBL)
  *
  * @param $text String
  * @param $linestart Boolean: whether or not this is at the start of a line.
  * @private
  * @return string the lists rendered as HTML
  */
 function doBlockLevels($text, $linestart)
 {
     wfProfileIn(__METHOD__);
     # Parsing through the text line by line.  The main thing
     # happening here is handling of block-level elements p, pre,
     # and making lists from lines starting with * # : etc.
     #
     $textLines = StringUtils::explode("\n", $text);
     $lastPrefix = $output = '';
     $this->mDTopen = $inBlockElem = false;
     $prefixLength = 0;
     $paragraphStack = false;
     $comment = $prefixType = false;
     # wikia change
     foreach ($textLines as $oLine) {
         # Fix up $linestart
         if (!$linestart) {
             $output .= $oLine;
             $linestart = true;
             continue;
         }
         # * = ul
         # # = ol
         # ; = dt
         # : = dd
         # RTE (Rich Text Editor) - begin
         # @author: Macbre
         $this->doBlockLevelsLineStart($oLine, $output);
         # RTE - end
         $lastPrefixLength = strlen($lastPrefix);
         $preCloseMatch = preg_match('/<\\/pre/i', $oLine);
         $preOpenMatch = preg_match('/<pre/i', $oLine);
         # If not in a <pre> element, scan for and figure out what prefixes are there.
         if (!$this->mInPre) {
             # Multiple prefixes may abut each other for nested lists.
             $prefixLength = strspn($oLine, '*#:;');
             $prefix = substr($oLine, 0, $prefixLength);
             # eh?
             # ; and : are both from definition-lists, so they're equivalent
             #  for the purposes of determining whether or not we need to open/close
             #  elements.
             $prefix2 = str_replace(';', ':', $prefix);
             $t = substr($oLine, $prefixLength);
             $this->mInPre = (bool) $preOpenMatch;
         } else {
             # Don't interpret any other prefixes in preformatted text
             $prefixLength = 0;
             $prefix = $prefix2 = '';
             $t = $oLine;
         }
         # RTE (Rich Text Editor) - begin
         # @author: Macbre
         $this->mCurrentPrefix = $prefix;
         # RTE - end
         # List generation
         if ($prefixLength && $lastPrefix === $prefix2) {
             # Same as the last item, so no need to deal with nesting or opening stuff
             $output .= $this->nextItem(substr($prefix, -1));
             $paragraphStack = false;
             if (substr($prefix, -1) === ';') {
                 # The one nasty exception: definition lists work like this:
                 # ; title : definition text
                 # So we check for : in the remainder text to split up the
                 # title and definition, without b0rking links.
                 $term = $t2 = '';
                 if ($this->findColonNoLinks($t, $term, $t2) !== false) {
                     $t = $t2;
                     $output .= $term . $this->nextItem(':');
                 }
             }
         } elseif ($prefixLength || $lastPrefixLength) {
             # We need to open or close prefixes, or both.
             # Either open or close a level...
             $commonPrefixLength = $this->getCommon($prefix, $lastPrefix);
             $paragraphStack = false;
             # Close all the prefixes which aren't shared.
             while ($commonPrefixLength < $lastPrefixLength) {
                 $output .= $this->closeList($lastPrefix[$lastPrefixLength - 1]);
                 --$lastPrefixLength;
             }
             # Continue the current prefix if appropriate.
             if ($prefixLength <= $commonPrefixLength && $commonPrefixLength > 0) {
                 $output .= $this->nextItem($prefix[$commonPrefixLength - 1]);
             }
             # Open prefixes where appropriate.
             while ($prefixLength > $commonPrefixLength) {
                 $char = substr($prefix, $commonPrefixLength, 1);
                 /* Wikia change begin - @author: Macbre */
                 $this->mLastCommonPrefix = $prefixLength == $commonPrefixLength + 1;
                 /* Wikia change end */
                 $output .= $this->openList($char);
                 if (';' === $char) {
                     # @todo FIXME: This is dupe of code above
                     if ($this->findColonNoLinks($t, $term, $t2) !== false) {
                         $t = $t2;
                         $output .= $term . $this->nextItem(':');
                     }
                 }
                 ++$commonPrefixLength;
             }
             $lastPrefix = $prefix2;
         }
         # If we have no prefixes, go to paragraph mode.
         if (0 == $prefixLength) {
             wfProfileIn(__METHOD__ . "-paragraph");
             # No prefix (not in list)--go to paragraph mode
             # XXX: use a stack for nestable elements like span, table and div
             $openmatch = preg_match('/(?:<aside|<table|<h1|<h2|<h3|<h4|<h5|<h6|<pre|<tr|<p|<ul|<ol|<li|<\\/tr|<\\/td|<\\/th)/iS', $t);
             /**
              * Wikia change start
              * @author Federico "Lox" Lucignano
              *
              * Stop the parser from wrapping figure tags in paragraphs
              */
             $closematch = preg_match('/(?:<\\/?aside|<\\/table|<\\/h1|<\\/h2|<\\/h3|<\\/h4|<\\/h5|<\\/h6|' . '<td|<th|<\\/?div|<\\/?figure|<hr|<\\/pre|<\\/p|' . $this->mUniqPrefix . '-pre|' . $this->mUniqPrefix . '-bloglist|' . $this->mUniqPrefix . '-infobox|<\\/li|<\\/ul|<\\/ol|<\\/?center)/iS', $t);
             /**
              * Wikia change end
              */
             # RTE (Rich Text Editor) - begin
             # @author: Macbre
             $this->doOpenCloseMatch($t, $openmatch, $closematch);
             # RTE - end
             if ($openmatch or $closematch) {
                 $paragraphStack = false;
                 # TODO bug 5718: paragraph closed
                 $output .= $this->closeParagraph();
                 if ($preOpenMatch and !$preCloseMatch) {
                     $this->mInPre = true;
                 }
                 $inBlockElem = !$closematch;
             } elseif (!$inBlockElem && !$this->mInPre) {
                 if (' ' == substr($t, 0, 1) and $this->mLastSection === 'pre' || trim($t) != '') {
                     # pre
                     if ($this->mLastSection !== 'pre') {
                         $paragraphStack = false;
                         $output .= $this->closeParagraph() . '<pre>';
                         $this->mLastSection = 'pre';
                     }
                     $t = substr($t, 1);
                 } else {
                     # paragraph
                     if (trim($t) === '') {
                         if ($paragraphStack) {
                             $output .= $paragraphStack . '<br />';
                             $paragraphStack = false;
                             $this->mLastSection = 'p';
                         } else {
                             if ($this->mLastSection !== 'p') {
                                 $output .= $this->closeParagraph();
                                 $this->mLastSection = '';
                                 $paragraphStack = '<p>';
                             } else {
                                 $paragraphStack = '</p><p>';
                             }
                         }
                     } else {
                         if ($paragraphStack) {
                             $output .= $paragraphStack;
                             $paragraphStack = false;
                             $this->mLastSection = 'p';
                         } elseif ($this->mLastSection !== 'p') {
                             $output .= $this->closeParagraph() . '<p>';
                             $this->mLastSection = 'p';
                         } else {
                             # RTE (Rich Text Editor) - begin
                             # @author: Macbre
                             global $wgRTEParserEnabled;
                             if (!empty($wgRTEParserEnabled)) {
                                 // count trailing spaces
                                 $text = ltrim(strrev($output), "\n");
                                 $spaces = strspn($text, ' ');
                                 $output .= RTEReverseParser::buildComment('LINE_BREAK', array('spaces' => $spaces));
                             }
                             # RTE - end
                         }
                     }
                 }
             }
             wfProfileOut(__METHOD__ . "-paragraph");
         }
         # somewhere above we forget to get out of pre block (bug 785)
         if ($preCloseMatch && $this->mInPre) {
             $this->mInPre = false;
         }
         if ($paragraphStack === false) {
             $output .= $t . "\n";
         }
         # RTE (Rich Text Editor) - begin
         # @author: Macbre
         $this->doBlockLevelsLineEnd($oLine, $output);
         # RTE - end
     }
     while ($prefixLength) {
         $output .= $this->closeList($prefix2[$prefixLength - 1]);
         --$prefixLength;
     }
     if ($this->mLastSection != '') {
         $output .= '</' . $this->mLastSection . '>';
         $this->mLastSection = '';
     }
     wfProfileOut(__METHOD__);
     return $output;
 }
Example #3
0
 /**
  * Convert wikitext to HTML and add extra HTML attributes for RTE
  *
  * @param $text String: text we want to parse
  * @param $title A title object
  * @param $options ParserOptions
  * @param $linestart boolean
  * @param $clearState boolean
  * @param $revid Int: number to pass in {{REVISIONID}}
  * @return ParserOutput a ParserOutput
  */
 public function parse($text, Title $title, ParserOptions $options, $linestart = true, $clearState = true, $revid = null)
 {
     wfProfileIn(__METHOD__);
     // get rid of all \r in wikitext
     $text = str_replace("\r\n", "\n", $text);
     // count newlines at the beginning of the wikitext
     $emptyLinesAtStart = strspn($text, "\n");
     if ($emptyLinesAtStart > 0) {
         // don't double count empty lines at the beginning of wikitext
         $this->emptyLinesBefore = $emptyLinesAtStart * -1;
     }
     // mark HTML entities from wikitext (&amp; &#58; &#x5f;)
     $text = self::markEntities($text);
     // set flag indicating parsing for CK
     global $wgRTEParserEnabled;
     $wgRTEParserEnabled = true;
     // don't use XML cache in preprocessor
     global $wgPreprocessorCacheThreshold;
     $wgPreprocessorCacheThreshold = 1000000;
     //RTE::log(__METHOD__ . '::beforeParse', $text);
     // parse to HTML
     $output = parent::parse($text, $title, $options, $linestart, $clearState, $revid);
     $wgRTEParserEnabled = false;
     // add extra RTE attributes to HTML elements (for correct handling of spaces and newlines when parsing back to wikitext)
     $html = $output->getText();
     // add RTE_EMPTY_LINES_BEFORE comment
     if ($emptyLinesAtStart > 0) {
         $html = RTEReverseParser::addEmptyLinesBeforeComment($emptyLinesAtStart) . $html;
     }
     //RTE::log(__METHOD__ . '::beforeReplace', $html);
     // wrap HTML entities inside span "placeholders" (&amp; &#58; &#x5f;)
     $html = self::wrapEntities($html);
     wfProfileIn(__METHOD__ . '::regexp');
     // remove EMPTY_LINES_BEFORE comments which are before closing tags - refs RT#38889
     // <!-- RTE_EMPTY_LINES_BEFORE_1 --></td></tr></table>  <= remove this one
     // <!-- RTE_EMPTY_LINES_BEFORE_1 --><p>
     $html = preg_replace('%<!-- RTE_EMPTY_LINES_BEFORE_(\\d+) -->(</[^>]+></)%s', '\\2', $html);
     // move empty lines counter data from comment to next opening tag attribute (thx to Marooned)
     $html = preg_replace('%<!-- RTE_EMPTY_LINES_BEFORE_(\\d+) -->(?!<!)(.*?)(<[^/][^>]*)>%s', '\\2\\3 data-rte-empty-lines-before="\\1">', $html);
     // remove not replaced EMPTY_LINES_BEFORE comments
     // <!-- RTE_EMPTY_LINES_BEFORE_1 -- data-rte-empty-lines-before="1">
     $html = preg_replace('%<!-- RTE_EMPTY_LINES_BEFORE_(\\d+) [^>]+>%s', '', $html);
     // add data-rte-spaces-before for list items and table cells
     $html = preg_replace_callback("/<(li|dd|dt|td|th)([^>]*)>( +)/", 'RTEParser::spacesBeforeCallback', $html);
     // replace placeholder markers with placeholders
     $html = preg_replace_callback("/-01-(\\d{4})/", 'RTE::replacePlaceholder', $html);
     // replace dataidx attribute with data-rte-meta attribute storing JSON encoded meta data
     $html = preg_replace_callback('/ _rte_dataidx="(\\d{4})" /', 'RTEData::replaceIdxByData', $html);
     $html = preg_replace("/-(?:" . RTEMarker::INTERNAL_WIKITEXT . "|" . RTEMarker::EXTERNAL_WIKITEXT . ")-\\d{4}/", '', $html);
     // RT#40786: add empty paragraphs between headings (</h3>\n<h3 ...)
     $html = preg_replace("%(</h\\d>\\s)(<h\\d)%s", '$1<p data-rte-filler="true"></p>$2', $html);
     wfProfileOut(__METHOD__ . '::regexp');
     // add extra attribute for p tags coming from parser
     $html = strtr($html, array('<p>' => '<p data-rte-fromparser="true">', '<p ' => '<p data-rte-fromparser="true" '));
     // add empty paragraph for new / empty pages
     if ($html == '') {
         $html = Xml::element('p');
     }
     // update parser output
     RTE::log(__METHOD__, $html);
     $output->setText($html);
     wfProfileOut(__METHOD__);
     return $output;
 }
 function parseInternal()
 {
     $parser = new RTEReverseParser();
     return $parser->parse($this->mText);
 }
Example #5
0
 /**
  * Parse given HTML from CK back to wikitext
  */
 public static function HtmlToWikitext($html)
 {
     wfProfileIn(__METHOD__);
     $RTEReverseParser = new RTEReverseParser();
     $wikitext = $RTEReverseParser->parse($html);
     wfProfileOut(__METHOD__);
     return $wikitext;
 }