-style tags. This should not be anything we # may want to use in wikisyntax define( 'STRIP_COMMENTS', 'HTMLCommentStrip' ); # prefix for escaping, used in two functions at least define( 'UNIQ_PREFIX', 'NaodW29'); # Constants needed for external link processing define( 'URL_PROTOCOLS', 'http|https|ftp|irc|gopher|news|mailto' ); define( 'HTTP_PROTOCOLS', 'http|https' ); # Everything except bracket, space, or control characters define( 'EXT_LINK_URL_CLASS', '[^]<>"\\x00-\\x20\\x7F]' ); # Including space define( 'EXT_LINK_TEXT_CLASS', '[^\]\\x00-\\x1F\\x7F]' ); define( 'EXT_IMAGE_FNAME_CLASS', '[A-Za-z0-9_.,~%\\-+&;#*?!=()@\\x80-\\xFF]' ); define( 'EXT_IMAGE_EXTENSIONS', 'gif|png|jpg|jpeg' ); define( 'EXT_LINK_BRACKETED', '/\[(('.URL_PROTOCOLS.'):'.EXT_LINK_URL_CLASS.'+) *('.EXT_LINK_TEXT_CLASS.'*?)\]/S' ); define( 'EXT_IMAGE_REGEX', '/^('.HTTP_PROTOCOLS.':)'. # Protocol '('.EXT_LINK_URL_CLASS.'+)\\/'. # Hostname and path '('.EXT_IMAGE_FNAME_CLASS.'+)\\.((?i)'.EXT_IMAGE_EXTENSIONS.')$/S' # Filename ); /** * PHP Parser * * Processes wiki markup * *
* There are three main entry points into the Parser class: * parse() * produces HTML output * preSaveTransform(). * produces altered wiki markup. * transformMsg() * performs brace substitution on MediaWiki messages * * Globals used: * objects: $wgLang, $wgDateFormatter, $wgLinkCache * * NOT $wgArticle, $wgUser or $wgTitle. Keep them away! * * settings: * $wgUseTex*, $wgUseDynamicDates*, $wgInterwikiMagic*, * $wgNamespacesWithSubpages, $wgAllowExternalImages*, * $wgLocaltimezone * * * only within ParserOptions ** * @package MediaWiki */ class Parser { /**#@+ * @access private */ # Persistent: var $mTagHooks; # Cleared with clearState(): var $mOutput, $mAutonumber, $mDTopen, $mStripState = array(); var $mVariables, $mIncludeCount, $mArgStack, $mLastSection, $mInPre; # Temporary: var $mOptions, $mTitle, $mOutputType, $mTemplates, // cache of already loaded templates, avoids // multiple SQL queries for the same string $mTemplatePath; // stores an unsorted hash of all the templates already loaded // in this path. Used for loop detection. /**#@-*/ /** * Constructor * * @access public */ function Parser() { $this->mTemplates = array(); $this->mTemplatePath = array(); $this->mTagHooks = array(); $this->clearState(); } /** * Clear Parser state * * @access private */ function clearState() { $this->mOutput = new ParserOutput; $this->mAutonumber = 0; $this->mLastSection = ""; $this->mDTopen = false; $this->mVariables = false; $this->mIncludeCount = array(); $this->mStripState = array(); $this->mArgStack = array(); $this->mInPre = false; } /** * First pass--just handle
' . wfEscapeHTMLTagsOnly( $content ) . ''; } else { $pre_content[$marker] = '
'.$content.''; } } # gallery $text = Parser::extractTags('gallery', $text, $gallery_content, $uniq_prefix); foreach( $gallery_content as $marker => $content ) { require_once( 'ImageGallery.php' ); if ( $render ) { $gallery_content[$marker] = Parser::renderImageGallery( $content ); } else { $gallery_content[$marker] = '
mInPre ) { # Multiple prefixes may abut each other for nested lists. $prefixLength = strspn( $oLine, '*#:;' ); $pref = substr( $oLine, 0, $prefixLength ); # eh? $pref2 = str_replace( ';', ':', $pref ); $t = substr( $oLine, $prefixLength ); $this->mInPre = !empty($preOpenMatch); } else { # Don't interpret any other prefixes in preformatted text $prefixLength = 0; $pref = $pref2 = ''; $t = $oLine; } # List generation if( $prefixLength && 0 == strcmp( $lastPrefix, $pref2 ) ) { # Same as the last item, so no need to deal with nesting or opening stuff $output .= $this->nextItem( substr( $pref, -1 ) ); $paragraphStack = false; if ( substr( $pref, -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. if ($this->findColonNoLinks($t, $term, $t2) !== false) { $t = $t2; $output .= $term . $this->nextItem( ':' ); } } } elseif( $prefixLength || $lastPrefixLength ) { # Either open or close a level... $commonPrefixLength = $this->getCommon( $pref, $lastPrefix ); $paragraphStack = false; while( $commonPrefixLength < $lastPrefixLength ) { $output .= $this->closeList( $lastPrefix{$lastPrefixLength-1} ); --$lastPrefixLength; } if ( $prefixLength <= $commonPrefixLength && $commonPrefixLength > 0 ) { $output .= $this->nextItem( $pref{$commonPrefixLength-1} ); } while ( $prefixLength > $commonPrefixLength ) { $char = substr( $pref, $commonPrefixLength, 1 ); $output .= $this->openList( $char ); if ( ';' == $char ) { # FIXME: This is dupe of code above if ($this->findColonNoLinks($t, $term, $t2) !== false) { $t = $t2; $output .= $term . $this->nextItem( ':' ); } } ++$commonPrefixLength; } $lastPrefix = $pref2; } if( 0 == $prefixLength ) { wfProfileIn( "$fname-paragraph" ); # No prefix (not in list)--go to paragraph mode $uniq_prefix = UNIQ_PREFIX; // XXX: use a stack for nestable elements like span, table and div $openmatch = preg_match('/(