--- /dev/null
+ DO NOT WANT\r
+ NOT WANT @defgroup Parser Parser\r
+ NOT WANT \r
+ NOT WANT @file\r
+ NOT WANT @ingroup Parser\r
+ NOT WANT File for Parser and related classes\r
+ WANT\r
+\r
+\r
+ DO NOT WANT\r
+ NOT WANT PHP Parser - Processes wiki markup (which uses a more user-friendly\r
+ NOT WANT syntax, such as "[[link]]" for making links), and provides a one-way\r
+ NOT WANT transformation of that wiki markup it into XHTML output / markup\r
+ NOT WANT (which in turn the browser understands, and can display).\r
+ NOT WANT \r
+ NOT WANT <pre>\r
+ NOT WANT There are five main entry points into the Parser class:\r
+ NOT WANT parse()\r
+ NOT WANT produces HTML output\r
+ NOT WANT preSaveTransform().\r
+ NOT WANT produces altered wiki markup.\r
+ NOT WANT preprocess()\r
+ NOT WANT removes HTML comments and expands templates\r
+ NOT WANT cleanSig()\r
+ NOT WANT Cleans a signature before saving it to preferences\r
+ NOT WANT extractSections()\r
+ NOT WANT Extracts sections from an article for section editing\r
+ NOT WANT getPreloadText()\r
+ NOT WANT Removes <noinclude> sections, and <includeonly> tags.\r
+ NOT WANT \r
+ NOT WANT Globals used:\r
+ NOT WANT objects: $wgLang, $wgContLang\r
+ NOT WANT \r
+ NOT WANT NOT $wgArticle, $wgUser or $wgTitle. Keep them away!\r
+ NOT WANT \r
+ NOT WANT settings:\r
+ NOT WANT $wgUseTex*, $wgUseDynamicDates*, $wgInterwikiMagic*,\r
+ NOT WANT $wgNamespacesWithSubpages, $wgAllowExternalImages*,\r
+ NOT WANT $wgLocaltimezone, $wgAllowSpecialInclusion*,\r
+ NOT WANT $wgMaxArticleSize*\r
+ NOT WANT \r
+ NOT WANT * only within ParserOptions\r
+ NOT WANT </pre>\r
+ NOT WANT \r
+ NOT WANT @ingroup Parser\r
+ WANT\r
+ IM IN UR SPECIAL Parser\r
+ DO NOT WANT\r
+ NOT WANT Update this version number when the ParserOutput format\r
+ NOT WANT changes in an incompatible way, so the parser cache\r
+ NOT WANT can automatically discard old data.\r
+ WANT\r
+ I ALWAYZ HAS VERSION IZ '1.6.4';\r
+\r
+ BTW Flags for Parser::setFunctionHook\r
+ BTW Also available as global constants from Defines.php\r
+ I ALWAYZ HAS SFH_NO_HASH IZ 1;\r
+ I ALWAYZ HAS SFH_OBJECT_ARGS IZ 2;\r
+\r
+ BTW Constants needed for external link processing\r
+ BTW Everything except bracket, space, or control characters\r
+ I ALWAYZ HAS EXT_LINK_URL_CLASS IZ '[^][<>"\\x00-\\x20\\x7F]';\r
+ I ALWAYZ HAS EXT_IMAGE_REGEX IZ '/^(http:\/\/|https:\/\/)([^][<>"\\x00-\\x20\\x7F]+)\r
+ \\/([A-Za-z0-9_.,~%\\-+&;#*?!=()@\\x80-\\xFF]+)\\.((?i)gif|png|jpg|jpeg)$/Sx';\r
+\r
+ BTW State constants for the definition list colon extraction\r
+ I ALWAYZ HAS COLON_STATE_TEXT IZ 0;\r
+ I ALWAYZ HAS COLON_STATE_TAG IZ 1;\r
+ I ALWAYZ HAS COLON_STATE_TAGSTART IZ 2;\r
+ I ALWAYZ HAS COLON_STATE_CLOSETAG IZ 3;\r
+ I ALWAYZ HAS COLON_STATE_TAGSLASH IZ 4;\r
+ I ALWAYZ HAS COLON_STATE_COMMENT IZ 5;\r
+ I ALWAYZ HAS COLON_STATE_COMMENTDASH IZ 6;\r
+ I ALWAYZ HAS COLON_STATE_COMMENTDASHDASH IZ 7;\r
+\r
+ BTW Flags for preprocessToDom\r
+ I ALWAYZ HAS PTD_FOR_INCLUSION IZ 1;\r
+\r
+ BTW Allowed values for $this->mOutputType\r
+ BTW Parameter to startExternalParse().\r
+ I ALWAYZ HAS OT_HTML IZ 1; # like parse()\r
+ I ALWAYZ HAS OT_WIKI IZ 2; # like preSaveTransform()\r
+ I ALWAYZ HAS OT_PREPROCESS IZ 3; # like preprocess()\r
+ I ALWAYZ HAS OT_MSG IZ 3;\r
+ I ALWAYZ HAS OT_PLAIN IZ 4; # like extractSections() - portions of the original are returned unchanged.\r
+\r
+ BTW Marker Suffix needs to be accessible staticly.\r
+ I ALWAYZ HAS MARKER_SUFFIX IZ "-QINU\x7f";\r
+\r
+ BTW Persistent:\r
+ I HAS UR $mTagHooks, $mTransparentTagHooks, $mFunctionHooks, $mFunctionSynonyms, $mVariables\r
+ I HAS UR $mSubstWords, $mImageParams, $mImageParamsMagicArray, $mStripList, $mMarkerIndex\r
+ I HAS UR $mPreprocessor, $mExtLinkBracketedRegex, $mUrlProtocols, $mDefaultStripList\r
+ I HAS UR $mVarCache, $mConf, $mFunctionTagHooks\r
+\r
+\r
+ BTW Cleared with clearState():\r
+ I HAS UR $mOutput, $mAutonumber, $mDTopen, $mStripState\r
+ I HAS UR $mIncludeCount, $mArgStack, $mLastSection, $mInPre\r
+ I HAS UR $mLinkHolders, $mLinkID\r
+ I HAS UR $mIncludeSizes, $mPPNodeCount, $mDefaultSort\r
+ I HAS UR $mTplExpandCache # empty-frame expansion cache\r
+ I HAS UR $mTplRedirCache, $mTplDomCache, $mHeadings, $mDoubleUnderscores\r
+ I HAS UR $mExpensiveFunctionCount # number of expensive parser function calls\r
+\r
+ BTW Temporary\r
+ BTW These are variables reset at least once per parse regardless of $clearState\r
+ I HAS UR $mOptions # ParserOptions object\r
+ I HAS UR $mTitle # Title context, used for self-link rendering and similar things\r
+ I HAS UR $mOutputType # Output type, one of the OT_xxx constants\r
+ I HAS UR $ot # Shortcut alias, see setOutputType()\r
+ I HAS UR $mRevisionId # ID to display in {{REVISIONID}} tags\r
+ I HAS UR $mRevisionTimestamp # The timestamp of the specified revision ID\r
+ I HAS UR $mRevIdForTs # The revision ID which was used to fetch the timestamp\r
+\r
+ DO NOT WANT\r
+ NOT WANT Constructor\r
+ NOT WANT \r
+ NOT WANT @public\r
+ WANT\r
+ SO IM LIKE __construct WITH UR $conf = array()\r
+ UR SPECIAL mConf IZ $conf;\r
+ UR SPECIAL mTagHooks IZ EMPTY;\r
+ UR SPECIAL mTransparentTagHooks IZ EMPTY;\r
+ UR SPECIAL mFunctionHooks IZ EMPTY;\r
+ UR SPECIAL mFunctionTagHooks IZ EMPTY;\r
+ UR SPECIAL mFunctionSynonyms IZ BUCKET 0 => array(), 1 => array() );\r
+ UR SPECIAL mDefaultStripList IZ $this->mStripList = array();\r
+ UR SPECIAL mUrlProtocols IZ wfUrlProtocols();\r
+ UR SPECIAL mExtLinkBracketedRegex IZ '/\[(\b(' . wfUrlProtocols() . ')'.\r
+ '[^][<>"\\x00-\\x20\\x7F]+) *([^\]\\x0a\\x0d]*?)\]/S';\r
+ UR SPECIAL mVarCache IZ EMPTY;\r
+ IZ isset( $conf['preprocessorClass'] )\r
+ UR SPECIAL mPreprocessorClass IZ $conf['preprocessorClass'];\r
+ ORLY extension_loaded( 'domxml' )\r
+ BTW PECL extension that conflicts with the core DOM extension (bug 13770)\r
+ IM ON UR wfDebug DOING "Warning: you have the obsolete domxml extension for PHP. Please remove it!\n"\r
+ UR SPECIAL mPreprocessorClass IZ 'Preprocessor_Hash';\r
+ ORLY extension_loaded( 'dom' )\r
+ UR SPECIAL mPreprocessorClass IZ 'Preprocessor_DOM';\r
+ NOWAI\r
+ UR SPECIAL mPreprocessorClass IZ 'Preprocessor_Hash';\r
+ KTHX\r
+ UR SPECIAL mMarkerIndex IZ 0;\r
+ UR SPECIAL mFirstCall IZ true;\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Reduce memory usage to reduce the impact of circular references\r
+ WANT\r
+ SO IM LIKE __destruct\r
+ IZ isset( $this->mLinkHolders )\r
+ IM ON UR SPECIAL mLinkHolders->__destruct\r
+ KTHX\r
+ IM IN UR this ITZA name => $value\r
+ IM ON UR unset DOING $this->$name\r
+ KTHX\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Do various kinds of initialisation on the first call of the parser\r
+ WANT\r
+ SO IM LIKE firstCallInit\r
+ IZ !$this->mFirstCall\r
+ return;\r
+ KTHX\r
+ UR SPECIAL mFirstCall IZ false;\r
+\r
+ IM ON UR wfProfileIn DOING __METHOD__\r
+\r
+ CoreParserFunctions::register( $this );\r
+ CoreTagHooks::register( $this );\r
+ IM ON UR SPECIAL initialiseVariables\r
+\r
+ IM ON UR wfRunHooks DOING 'ParserFirstCallInit', array( &$this )\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Clear Parser state\r
+ NOT WANT \r
+ NOT WANT @private\r
+ WANT\r
+ SO IM LIKE clearState\r
+ IM ON UR wfProfileIn DOING __METHOD__\r
+ IZ $this->mFirstCall\r
+ IM ON UR SPECIAL firstCallInit\r
+ KTHX\r
+ UR SPECIAL mOutput IZ new ParserOutput;\r
+ UR SPECIAL mAutonumber IZ 0;\r
+ UR SPECIAL mLastSection IZ '';\r
+ UR SPECIAL mDTopen IZ false;\r
+ UR SPECIAL mIncludeCount IZ EMPTY;\r
+ UR SPECIAL mStripState IZ new StripState;\r
+ UR SPECIAL mArgStack IZ false;\r
+ UR SPECIAL mInPre IZ false;\r
+ UR SPECIAL mLinkHolders IZ new LinkHolderArray( $this );\r
+ UR SPECIAL mLinkID IZ 0;\r
+ UR SPECIAL mRevisionTimestamp IZ $this->mRevisionId = null;\r
+ UR SPECIAL mVarCache IZ EMPTY;\r
+\r
+ DO NOT WANT\r
+ NOT WANT Prefix for temporary replacement strings for the multipass parser.\r
+ NOT WANT \x07 should never appear in input as it's disallowed in XML.\r
+ NOT WANT Using it at the front also gives us a little extra robustness\r
+ NOT WANT since it shouldn't match when butted up against identifier-like\r
+ NOT WANT string constructs.\r
+ NOT WANT \r
+ NOT WANT Must not consist of all title characters, or else it will change\r
+ NOT WANT the behaviour of <nowiki> in a link.\r
+ WANT\r
+ BTW $this->mUniqPrefix = "\x07UNIQ" . Parser::getRandomString();\r
+ BTW Changed to \x7f to allow XML double-parsing -- TS\r
+ UR SPECIAL mUniqPrefix IZ "\x7fUNIQ" . self::getRandomString();\r
+\r
+\r
+ BTW Clear these on every parse, bug 4549\r
+ UR SPECIAL mTplExpandCache IZ $this->mTplRedirCache = $this->mTplDomCache = array();\r
+\r
+ UR SPECIAL mShowToc IZ true;\r
+ UR SPECIAL mForceTocPosition IZ false;\r
+ UR SPECIAL mIncludeSizes IZ BUCKET\r
+ 'post-expand' => 0,\r
+ 'arg' => 0,\r
+ BUCKET\r
+ UR SPECIAL mPPNodeCount IZ 0;\r
+ UR SPECIAL mDefaultSort IZ false;\r
+ UR SPECIAL mHeadings IZ EMPTY;\r
+ UR SPECIAL mDoubleUnderscores IZ EMPTY;\r
+ UR SPECIAL mExpensiveFunctionCount IZ 0;\r
+\r
+ BTW Fix cloning\r
+ IZ isset( $this->mPreprocessor ) && $this->mPreprocessor->parser !== $this\r
+ UR SPECIAL mPreprocessor IZ null;\r
+ KTHX\r
+\r
+ IM ON UR wfRunHooks DOING 'ParserClearState', array( &$this )\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ KTHX\r
+\r
+ SO IM LIKE setOutputType WITH UR $ot\r
+ UR SPECIAL mOutputType IZ $ot;\r
+ BTW Shortcut alias\r
+ UR SPECIAL ot IZ BUCKET\r
+ 'html' => $ot == self::OT_HTML,\r
+ 'wiki' => $ot == self::OT_WIKI,\r
+ 'pre' => $ot == self::OT_PREPROCESS,\r
+ 'plain' => $ot == self::OT_PLAIN,\r
+ BUCKET\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Set the context title\r
+ WANT\r
+ SO IM LIKE setTitle WITH UR $t\r
+ IZ !$t || $t instanceof FakeTitle\r
+ I HAS t IZ Title::newFromText( 'NO TITLE' )\r
+ KTHX\r
+\r
+ IZ strval( $t->getFragment() ) !== ''\r
+ BTW Strip the fragment to avoid various odd effects\r
+ UR SPECIAL mTitle IZ clone $t;\r
+ IM ON UR SPECIAL mTitle->setFragment DOING ''\r
+ NOWAI\r
+ UR SPECIAL mTitle IZ $t;\r
+ KTHX\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Accessor for mUniqPrefix.\r
+ NOT WANT \r
+ NOT WANT @public\r
+ WANT\r
+ SO IM LIKE uniqPrefix\r
+ IZ !isset( $this->mUniqPrefix )\r
+ BTW @todo Fixme: this is probably *horribly wrong*\r
+ BTW LanguageConverter seems to want $wgParser's uniqPrefix, however\r
+ BTW if this is called for a parser cache hit, the parser may not\r
+ BTW have ever been initialized in the first place.\r
+ BTW Not really sure what the heck is supposed to be going on here.\r
+ I FOUND MAH ''\r
+ BTW throw new MWException( "Accessing uninitialized mUniqPrefix" );\r
+ KTHX\r
+ I FOUND MAH $this->mUniqPrefix\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Convert wikitext to HTML\r
+ NOT WANT Do not call this function recursively.\r
+ NOT WANT \r
+ NOT WANT @param $text String: text we want to parse\r
+ NOT WANT @param $title A title object\r
+ NOT WANT @param $options ParserOptions\r
+ NOT WANT @param $linestart boolean\r
+ NOT WANT @param $clearState boolean\r
+ NOT WANT @param $revid Int: number to pass in {{REVISIONID}}\r
+ NOT WANT @return ParserOutput a ParserOutput\r
+ WANT\r
+ SO IM LIKE parse WITH UR $text, Title $title, ParserOptions $options, $linestart = true, $clearState = true, $revid = null\r
+ DO NOT WANT\r
+ NOT WANT First pass--just handle <nowiki> sections, pass the rest off\r
+ NOT WANT to internalParse() which does all the real work.\r
+ WANT\r
+\r
+ I HAS UR $wgUseTidy, $wgAlwaysUseTidy, $wgContLang, $wgDisableLangConversion ON UR INTERNETS\r
+ I HAS fname IZ __METHOD__.'-' . wfGetCaller()\r
+ IM ON UR wfProfileIn DOING __METHOD__\r
+ IM ON UR wfProfileIn DOING $fname\r
+\r
+ IZ $clearState\r
+ IM ON UR SPECIAL clearState\r
+ KTHX\r
+\r
+ UR SPECIAL mOptions IZ $options;\r
+ IM ON UR SPECIAL setTitle DOING $title # Page title has to be set for the pre-processor\r
+\r
+ I HAS oldRevisionId IZ $this->mRevisionId\r
+ I HAS oldRevisionTimestamp IZ $this->mRevisionTimestamp\r
+ IZ $revid !== null\r
+ UR SPECIAL mRevisionId IZ $revid;\r
+ UR SPECIAL mRevisionTimestamp IZ null;\r
+ KTHX\r
+ IM ON UR SPECIAL setOutputType DOING self::OT_HTML\r
+ IM ON UR wfRunHooks DOING 'ParserBeforeStrip', array( &$this, &$text, &$this->mStripState )\r
+ BTW No more strip!\r
+ IM ON UR wfRunHooks DOING 'ParserAfterStrip', array( &$this, &$text, &$this->mStripState )\r
+ I HAS text IZ $this->internalParse( $text )\r
+\r
+ I HAS text IZ $this->mStripState->unstripGeneral( $text )\r
+\r
+ BTW Clean up special characters, only run once, next-to-last before doBlockLevels\r
+ I HAS fixtags IZ BUCKET\r
+ BTW french spaces, last one Guillemet-left\r
+ BTW only if there is something before the space\r
+ '/(.) (?=\\?|:|;|!|%|\\302\\273)/' => '\\1 \\2',\r
+ BTW french spaces, Guillemet-right\r
+ '/(\\302\\253) /' => '\\1 ',\r
+ '/ (!\s*important)/' => ' \\1', # Beware of CSS magic word !important, bug #11874.\r
+ BUCKET\r
+ I HAS text IZ preg_replace( array_keys( $fixtags ), array_values( $fixtags ), $text )\r
+\r
+ I HAS text IZ $this->doBlockLevels( $text, $linestart )\r
+\r
+ IM ON UR SPECIAL replaceLinkHolders DOING $text\r
+\r
+ BTW The position of the convert() call should not be changed. it\r
+ BTW assumes that the links are all replaced and the only thing left\r
+ BTW is the <nowiki> mark.\r
+ if ( !( $wgDisableLangConversion\r
+ || isset( $this->mDoubleUnderscores['nocontentconvert'] )\r
+ || $this->mTitle->isTalkPage()\r
+ || $this->mTitle->isConversionTable() ) ) {\r
+ I HAS text IZ $wgContLang->convert( $text )\r
+ KTHX\r
+\r
+ BTW A title may have been set in a conversion rule.\r
+ BTW Note that if a user tries to set a title in a conversion\r
+ BTW rule but content conversion was not done, then the parser\r
+ BTW won't pick it up. This is probably expected behavior.\r
+ IZ $wgContLang->getConvRuleTitle()\r
+ IM ON UR SPECIAL mOutput->setTitleText DOING $wgContLang->getConvRuleTitle()\r
+ KTHX\r
+\r
+ I HAS text IZ $this->mStripState->unstripNoWiki( $text )\r
+\r
+ IM ON UR wfRunHooks DOING 'ParserBeforeTidy', array( &$this, &$text )\r
+\r
+//!JF Move to its own function\r
+\r
+ I HAS uniq_prefix IZ $this->mUniqPrefix\r
+ I HAS matches IZ EMPTY\r
+ I HAS elements IZ array_keys( $this->mTransparentTagHooks )\r
+ I HAS text IZ self::extractTagsAndParams( $elements, $text, $matches, $uniq_prefix )\r
+\r
+ IM IN UR matches ITZA marker => $data\r
+ list( $element, $content, $params, $tag ) = $data;\r
+ I HAS tagName IZ strtolower( $element )\r
+ IZ isset( $this->mTransparentTagHooks[$tagName] )\r
+ I HAS output IZ call_user_func_array( $this->mTransparentTagHooks[$tagName], array( $content, $params, $this ) )\r
+ NOWAI\r
+ I HAS output IZ $tag\r
+ KTHX\r
+ IM ON UR SPECIAL mStripState->general->setPair DOING $marker, $output\r
+ KTHX\r
+ I HAS text IZ $this->mStripState->unstripGeneral( $text )\r
+\r
+ I HAS text IZ Sanitizer::normalizeCharReferences( $text )\r
+\r
+ IZ ( $wgUseTidy && $this->mOptions->mTidy ) || $wgAlwaysUseTidy\r
+ I HAS text IZ MWTidy::tidy( $text )\r
+ NOWAI\r
+ BTW attempt to sanitize at least some nesting problems\r
+ BTW (bug #2702 and quite a few others)\r
+ I HAS tidyregs IZ BUCKET\r
+ BTW ''Something [http://www.cool.com cool''] -->\r
+ BTW <i>Something</i><a href="http://www.cool.com"..><i>cool></i></a>\r
+ '/(<([bi])>)(<([bi])>)?([^<]*)(<\/?a[^<]*>)([^<]*)(<\/\\4>)?(<\/\\2>)/' =>\r
+ '\\1\\3\\5\\8\\9\\6\\1\\3\\7\\8\\9',\r
+ BTW fix up an anchor inside another anchor, only\r
+ BTW at least for a single single nested link (bug 3695)\r
+ '/(<a[^>]+>)([^<]*)(<a[^>]+>[^<]*)<\/a>(.*)<\/a>/' =>\r
+ '\\1\\2</a>\\3</a>\\1\\4</a>',\r
+ BTW fix div inside inline elements- doBlockLevels won't wrap a line which\r
+ BTW contains a div, so fix it up here; replace\r
+ BTW div with escaped text\r
+ '/(<([aib]) [^>]+>)([^<]*)(<div([^>]*)>)(.*)(<\/div>)([^<]*)(<\/\\2>)/' =>\r
+ '\\1\\3<div\\5>\\6</div>\\8\\9',\r
+ BTW remove empty italic or bold tag pairs, some\r
+ BTW introduced by rules above\r
+ '/<([bi])><\/\\1>/' => '',\r
+ BUCKET\r
+\r
+ text IZ preg_replace(\r
+ array_keys( $tidyregs ),\r
+ array_values( $tidyregs ),\r
+ $text );\r
+ KTHX\r
+ I HAS UR $wgExpensiveParserFunctionLimit ON UR INTERNETS\r
+ IZ $this->mExpensiveFunctionCount > $wgExpensiveParserFunctionLimit\r
+ IM ON UR SPECIAL limitationWarn DOING 'expensive-parserfunction', $this->mExpensiveFunctionCount, $wgExpensiveParserFunctionLimit\r
+ KTHX\r
+\r
+ IM ON UR wfRunHooks DOING 'ParserAfterTidy', array( &$this, &$text )\r
+\r
+ BTW Information on include size limits, for the benefit of users who try to skirt them\r
+ IZ $this->mOptions->getEnableLimitReport()\r
+ I HAS max IZ $this->mOptions->getMaxIncludeSize()\r
+ I HAS PFreport IZ "Expensive parser function count: {$this->mExpensiveFunctionCount}/$wgExpensiveParserFunctionLimit\n"\r
+ $limitReport =\r
+ "NewPP limit report\n" .\r
+ "Preprocessor node count: {$this->mPPNodeCount}/{$this->mOptions->mMaxPPNodeCount}\n" .\r
+ "Post-expand include size: {$this->mIncludeSizes['post-expand']}/$max bytes\n" .\r
+ "Template argument size: {$this->mIncludeSizes['arg']}/$max bytes\n".\r
+ I HAS PFreport\r
+ IM ON UR wfRunHooks DOING 'ParserLimitReport', array( $this, &$limitReport )\r
+ text HAS MOAR "\n<!-- \n$limitReport-->\n";\r
+ KTHX\r
+ IM ON UR SPECIAL mOutput->setText DOING $text\r
+\r
+ UR SPECIAL mRevisionId IZ $oldRevisionId;\r
+ UR SPECIAL mRevisionTimestamp IZ $oldRevisionTimestamp;\r
+ IM ON UR wfProfileOut DOING $fname\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+\r
+ I FOUND MAH $this->mOutput\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Recursive parser entry point that can be called from an extension tag\r
+ NOT WANT hook.\r
+ NOT WANT \r
+ NOT WANT If $frame is not provided, then template variables (e.g., {{{1}}}) within $text are not expanded\r
+ NOT WANT \r
+ NOT WANT @param $text String: text extension wants to have parsed\r
+ NOT WANT @param PPFrame $frame: The frame to use for expanding any template variables\r
+ WANT\r
+ SO IM LIKE recursiveTagParse WITH UR $text, $frame=false\r
+ IM ON UR wfProfileIn DOING __METHOD__\r
+ IM ON UR wfRunHooks DOING 'ParserBeforeStrip', array( &$this, &$text, &$this->mStripState )\r
+ IM ON UR wfRunHooks DOING 'ParserAfterStrip', array( &$this, &$text, &$this->mStripState )\r
+ I HAS text IZ $this->internalParse( $text, false, $frame )\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ I FOUND MAH $text\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Expand templates and variables in the text, producing valid, static wikitext.\r
+ NOT WANT Also removes comments.\r
+ WANT\r
+ SO IM LIKE preprocess WITH UR $text, $title, $options, $revid = null\r
+ IM ON UR wfProfileIn DOING __METHOD__\r
+ IM ON UR SPECIAL clearState\r
+ IM ON UR SPECIAL setOutputType DOING self::OT_PREPROCESS\r
+ UR SPECIAL mOptions IZ $options;\r
+ IM ON UR SPECIAL setTitle DOING $title\r
+ IZ $revid !== null\r
+ UR SPECIAL mRevisionId IZ $revid;\r
+ KTHX\r
+ IM ON UR wfRunHooks DOING 'ParserBeforeStrip', array( &$this, &$text, &$this->mStripState )\r
+ IM ON UR wfRunHooks DOING 'ParserAfterStrip', array( &$this, &$text, &$this->mStripState )\r
+ I HAS text IZ $this->replaceVariables( $text )\r
+ I HAS text IZ $this->mStripState->unstripBoth( $text )\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ I FOUND MAH $text\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Process the wikitext for the ?preload= feature. (bug 5210)\r
+ NOT WANT \r
+ NOT WANT <noinclude>, <includeonly> etc. are parsed as for template transclusion, \r
+ NOT WANT comments, templates, arguments, tags hooks and parser functions are untouched.\r
+ WANT\r
+ SO IM LIKE getPreloadText WITH UR $text, $title, $options\r
+ BTW Parser (re)initialisation\r
+ IM ON UR SPECIAL clearState\r
+ IM ON UR SPECIAL setOutputType DOING self::OT_PLAIN\r
+ UR SPECIAL mOptions IZ $options;\r
+ IM ON UR SPECIAL setTitle DOING $title \r
+\r
+ I HAS flags IZ PPFrame::NO_ARGS | PPFrame::NO_TEMPLATES\r
+ I HAS dom IZ $this->preprocessToDom( $text, self::PTD_FOR_INCLUSION )\r
+ I FOUND MAH $this->getPreprocessor()->newFrame()->expand( $dom, $flags )\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Get a random string\r
+ NOT WANT \r
+ NOT WANT @private\r
+ NOT WANT @static\r
+ WANT\r
+ SO IM LIKE getRandomString\r
+ I FOUND MAH dechex( mt_rand( 0, 0x7fffffff ) ) . dechex( mt_rand( 0, 0x7fffffff ) )\r
+ KTHX\r
+\r
+ function &getTitle() { return $this->mTitle; }\r
+ SO IM LIKE getOptions TESTING UR return $this->mOptions;\r
+ SO IM LIKE getRevisionId TESTING UR return $this->mRevisionId;\r
+ SO IM LIKE getOutput TESTING UR return $this->mOutput;\r
+ SO IM LIKE nextLinkID TESTING UR return $this->mLinkID++;\r
+\r
+ SO IM LIKE getFunctionLang\r
+ I HAS UR $wgLang, $wgContLang ON UR INTERNETS\r
+\r
+ I HAS target IZ $this->mOptions->getTargetLanguage()\r
+ IZ $target !== null\r
+ I FOUND MAH $target\r
+ NOWAI\r
+ I FOUND MAH $this->mOptions->getInterfaceMessage() ? $wgLang : $wgContLang\r
+ KTHX\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Get a preprocessor object\r
+ WANT\r
+ SO IM LIKE getPreprocessor\r
+ IZ !isset( $this->mPreprocessor )\r
+ I HAS class IZ $this->mPreprocessorClass\r
+ UR SPECIAL mPreprocessor IZ new $class( $this );\r
+ KTHX\r
+ I FOUND MAH $this->mPreprocessor\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Replaces all occurrences of HTML-style comments and the given tags\r
+ NOT WANT in the text with a random marker and returns the next text. The output\r
+ NOT WANT parameter $matches will be an associative array filled with data in\r
+ NOT WANT the form:\r
+ NOT WANT 'UNIQ-xxxxx' => array(\r
+ NOT WANT 'element',\r
+ NOT WANT 'tag content',\r
+ NOT WANT array( 'param' => 'x' ),\r
+ NOT WANT '<element param="x">tag content</element>' ) )\r
+ NOT WANT \r
+ NOT WANT @param $elements list of element names. Comments are always extracted.\r
+ NOT WANT @param $text Source text string.\r
+ NOT WANT @param $uniq_prefix\r
+ NOT WANT \r
+ NOT WANT @public\r
+ NOT WANT @static\r
+ WANT\r
+ SO IM LIKE extractTagsAndParams WITH UR $elements, $text, &$matches, $uniq_prefix = ''\r
+ static $n = 1;\r
+ I HAS stripped IZ ''\r
+ I HAS matches IZ EMPTY\r
+\r
+ I HAS taglist IZ implode( '|', $elements )\r
+ I HAS start IZ "/<($taglist)(\\s+[^>]*?|\\s*?)(\/?" . ">)|<(!--)/i"\r
+\r
+ STEALIN UR $text != ''\r
+ I HAS p IZ preg_split( $start, $text, 2, PREG_SPLIT_DELIM_CAPTURE )\r
+ stripped HAS MOAR $p[0];\r
+ IZ count( $p ) < 5\r
+ break;\r
+ KTHX\r
+ IZ count( $p ) > 5\r
+ BTW comment\r
+ I HAS element IZ $p[4]\r
+ I HAS attributes IZ ''\r
+ I HAS close IZ ''\r
+ I HAS inside IZ $p[5]\r
+ NOWAI\r
+ BTW tag\r
+ I HAS element IZ $p[1]\r
+ I HAS attributes IZ $p[2]\r
+ I HAS close IZ $p[3]\r
+ I HAS inside IZ $p[4]\r
+ KTHX\r
+\r
+ I HAS marker IZ "$uniq_prefix-$element-" . sprintf( '%08X', $n++ ) . self::MARKER_SUFFIX\r
+ stripped HAS MOAR $marker;\r
+\r
+ IZ $close === '/>'\r
+ BTW Empty element tag, <tag />\r
+ I HAS content\r
+ I HAS text IZ $inside\r
+ I HAS tail\r
+ NOWAI\r
+ IZ $element === '!--'\r
+ I HAS end IZ '/(-->)/'\r
+ NOWAI\r
+ I HAS end IZ "/(<\\/$element\\s*>)/i"\r
+ KTHX\r
+ I HAS q IZ preg_split( $end, $inside, 2, PREG_SPLIT_DELIM_CAPTURE )\r
+ I HAS content IZ $q[0]\r
+ IZ count( $q ) < 3\r
+ BTW No end tag -- let it run out to the end of the text.\r
+ I HAS tail IZ ''\r
+ I HAS text IZ ''\r
+ NOWAI\r
+ I HAS tail IZ $q[1]\r
+ I HAS text IZ $q[2]\r
+ KTHX\r
+ KTHX\r
+\r
+ $matches[$marker] = array( $element,\r
+ $content,\r
+ Sanitizer::decodeTagAttributes( $attributes ),\r
+ "<$element$attributes$close$content$tail" );\r
+ KTHX\r
+ I FOUND MAH $stripped\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Get a list of strippable XML-like elements\r
+ WANT\r
+ SO IM LIKE getStripList\r
+ I FOUND MAH $this->mStripList\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT @deprecated use replaceVariables\r
+ WANT\r
+ SO IM LIKE strip WITH UR $text, $state, $stripcomments = false , $dontstrip = array()\r
+ I FOUND MAH $text\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Restores pre, math, and other extensions removed by strip()\r
+ NOT WANT \r
+ NOT WANT always call unstripNoWiki() after this one\r
+ NOT WANT @private\r
+ NOT WANT @deprecated use $this->mStripState->unstrip()\r
+ WANT\r
+ SO IM LIKE unstrip WITH UR $text, $state\r
+ I FOUND MAH $state->unstripGeneral( $text )\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Always call this after unstrip() to preserve the order\r
+ NOT WANT \r
+ NOT WANT @private\r
+ NOT WANT @deprecated use $this->mStripState->unstrip()\r
+ WANT\r
+ SO IM LIKE unstripNoWiki WITH UR $text, $state\r
+ I FOUND MAH $state->unstripNoWiki( $text )\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT @deprecated use $this->mStripState->unstripBoth()\r
+ WANT\r
+ SO IM LIKE unstripForHTML WITH UR $text\r
+ I FOUND MAH $this->mStripState->unstripBoth( $text )\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Add an item to the strip state\r
+ NOT WANT Returns the unique tag which must be inserted into the stripped text\r
+ NOT WANT The tag will be replaced with the original text in unstrip()\r
+ NOT WANT \r
+ NOT WANT @private\r
+ WANT\r
+ SO IM LIKE insertStripItem WITH UR $text\r
+ I HAS rnd IZ "{$this->mUniqPrefix}-item-{$this->mMarkerIndex}-" . self::MARKER_SUFFIX\r
+ $this->mMarkerIndex++;\r
+ IM ON UR SPECIAL mStripState->general->setPair DOING $rnd, $text\r
+ I FOUND MAH $rnd\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Interface with html tidy\r
+ NOT WANT @deprecated Use MWTidy::tidy()\r
+ WANT\r
+ SO IM ALWAYS LIKE tidy WITH UR $text\r
+ IM ON UR wfDeprecated DOING __METHOD__\r
+ I FOUND MAH MWTidy::tidy( $text )\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT parse the wiki syntax used to render tables\r
+ NOT WANT \r
+ NOT WANT @private\r
+ WANT\r
+ SO IM LIKE doTableStuff WITH UR $text\r
+ IM ON UR wfProfileIn DOING __METHOD__\r
+\r
+ I HAS lines IZ StringUtils::explode( "\n", $text )\r
+ I HAS out IZ ''\r
+ I HAS td_history IZ EMPTY # Is currently a td tag open?\r
+ I HAS last_tag_history IZ EMPTY # Save history of last lag activated (td, th or caption)\r
+ I HAS tr_history IZ EMPTY # Is currently a tr tag open?\r
+ I HAS tr_attributes IZ EMPTY # history of tr attributes\r
+ I HAS has_opened_tr IZ EMPTY # Did this table open a <tr> element?\r
+ I HAS indent_level IZ 0 # indent level of the table\r
+\r
+ IM IN UR lines ITZA outLine\r
+ I HAS line IZ trim( $outLine )\r
+\r
+ IZ $line == '' # empty line, go to next line\r
+ out HAS MOAR $outLine."\n";\r
+ continue;\r
+ KTHX\r
+ I HAS first_character IZ $line[0]\r
+ I HAS matches IZ EMPTY\r
+\r
+ IZ preg_match( '/^(:*)\{\|(.*)$/', $line , $matches )\r
+ BTW First check if we are starting a new table\r
+ I HAS indent_level IZ strlen( $matches[1] )\r
+\r
+ I HAS attributes IZ $this->mStripState->unstripBoth( $matches[2] )\r
+ I HAS attributes IZ Sanitizer::fixTagAttributes( $attributes , 'table' )\r
+\r
+ I HAS outLine IZ str_repeat( '<dl><dd>' , $indent_level ) . "<table{$attributes}>"\r
+ IM ON UR array_push DOING $td_history , false\r
+ IM ON UR array_push DOING $last_tag_history , ''\r
+ IM ON UR array_push DOING $tr_history , false\r
+ IM ON UR array_push DOING $tr_attributes , ''\r
+ IM ON UR array_push DOING $has_opened_tr , false\r
+ ORLY count( $td_history ) == 0\r
+ BTW Don't do any of the following\r
+ out HAS MOAR $outLine."\n";\r
+ continue;\r
+ ORLY substr( $line , 0 , 2 ) === '|}'\r
+ BTW We are ending a table\r
+ I HAS line IZ '</table>' . substr( $line , 2 )\r
+ I HAS last_tag IZ array_pop( $last_tag_history )\r
+\r
+ IZ !array_pop( $has_opened_tr )\r
+ I HAS line IZ "<tr><td></td></tr>{$line}"\r
+ KTHX\r
+\r
+ IZ array_pop( $tr_history )\r
+ I HAS line IZ "</tr>{$line}"\r
+ KTHX\r
+\r
+ IZ array_pop( $td_history )\r
+ I HAS line IZ "</{$last_tag}>{$line}"\r
+ KTHX\r
+ IM ON UR array_pop DOING $tr_attributes\r
+ I HAS outLine IZ $line . str_repeat( '</dd></dl>' , $indent_level )\r
+ ORLY substr( $line , 0 , 2 ) === '|-'\r
+ BTW Now we have a table row\r
+ I HAS line IZ preg_replace( '#^\|-+#', '', $line )\r
+\r
+ BTW Whats after the tag is now only attributes\r
+ I HAS attributes IZ $this->mStripState->unstripBoth( $line )\r
+ I HAS attributes IZ Sanitizer::fixTagAttributes( $attributes, 'tr' )\r
+ IM ON UR array_pop DOING $tr_attributes\r
+ IM ON UR array_push DOING $tr_attributes, $attributes\r
+\r
+ I HAS line IZ ''\r
+ I HAS last_tag IZ array_pop( $last_tag_history )\r
+ IM ON UR array_pop DOING $has_opened_tr\r
+ IM ON UR array_push DOING $has_opened_tr , true\r
+\r
+ IZ array_pop( $tr_history )\r
+ I HAS line IZ '</tr>'\r
+ KTHX\r
+\r
+ IZ array_pop( $td_history )\r
+ I HAS line IZ "</{$last_tag}>{$line}"\r
+ KTHX\r
+\r
+ I HAS outLine IZ $line\r
+ IM ON UR array_push DOING $tr_history , false\r
+ IM ON UR array_push DOING $td_history , false\r
+ IM ON UR array_push DOING $last_tag_history , ''\r
+ ORLY $first_character === '|' || $first_character === '!' || substr( $line , 0 , 2 ) === '|+'\r
+ BTW This might be cell elements, td, th or captions\r
+ IZ substr( $line , 0 , 2 ) === '|+'\r
+ I HAS first_character IZ '+'\r
+ I HAS line IZ substr( $line , 1 )\r
+ KTHX\r
+\r
+ I HAS line IZ substr( $line , 1 )\r
+\r
+ IZ $first_character === '!'\r
+ I HAS line IZ str_replace( '!!' , '||' , $line )\r
+ KTHX\r
+\r
+ BTW Split up multiple cells on the same line.\r
+ BTW FIXME : This can result in improper nesting of tags processed\r
+ BTW by earlier parser steps, but should avoid splitting up eg\r
+ BTW attribute values containing literal "||".\r
+ I HAS cells IZ StringUtils::explodeMarkup( '||' , $line )\r
+\r
+ I HAS outLine IZ ''\r
+\r
+ BTW Loop through each table cell\r
+ IM IN UR cells ITZA cell\r
+ I HAS previous IZ ''\r
+ IZ $first_character !== '+'\r
+ I HAS tr_after IZ array_pop( $tr_attributes )\r
+ IZ !array_pop( $tr_history )\r
+ I HAS previous IZ "<tr{$tr_after}>\n"\r
+ KTHX\r
+ IM ON UR array_push DOING $tr_history , true\r
+ IM ON UR array_push DOING $tr_attributes , ''\r
+ IM ON UR array_pop DOING $has_opened_tr\r
+ IM ON UR array_push DOING $has_opened_tr , true\r
+ KTHX\r
+\r
+ I HAS last_tag IZ array_pop( $last_tag_history )\r
+\r
+ IZ array_pop( $td_history )\r
+ I HAS previous IZ "</{$last_tag}>{$previous}"\r
+ KTHX\r
+\r
+ IZ $first_character === '|'\r
+ I HAS last_tag IZ 'td'\r
+ ORLY $first_character === '!'\r
+ I HAS last_tag IZ 'th'\r
+ ORLY $first_character === '+'\r
+ I HAS last_tag IZ 'caption'\r
+ NOWAI\r
+ I HAS last_tag IZ ''\r
+ KTHX\r
+\r
+ IM ON UR array_push DOING $last_tag_history , $last_tag\r
+\r
+ BTW A cell could contain both parameters and data\r
+ I HAS cell_data IZ explode( '|' , $cell , 2 )\r
+\r
+ BTW Bug 553: Note that a '|' inside an invalid link should not\r
+ BTW be mistaken as delimiting cell parameters\r
+ IZ strpos( $cell_data[0], '[[' ) !== false\r
+ I HAS cell IZ "{$previous}<{$last_tag}>{$cell}"\r
+ ORLY count( $cell_data ) == 1\r
+ I HAS cell IZ "{$previous}<{$last_tag}>{$cell_data[0]}"\r
+ NOWAI\r
+ I HAS attributes IZ $this->mStripState->unstripBoth( $cell_data[0] )\r
+ I HAS attributes IZ Sanitizer::fixTagAttributes( $attributes , $last_tag )\r
+ I HAS cell IZ "{$previous}<{$last_tag}{$attributes}>{$cell_data[1]}"\r
+ KTHX\r
+\r
+ outLine HAS MOAR $cell;\r
+ IM ON UR array_push DOING $td_history , true\r
+ KTHX\r
+ KTHX\r
+ out HAS MOAR $outLine . "\n";\r
+ KTHX\r
+\r
+ BTW Closing open td, tr && table\r
+ STEALIN UR count( $td_history ) > 0\r
+ IZ array_pop( $td_history )\r
+ out HAS MOAR "</td>\n";\r
+ KTHX\r
+ IZ array_pop( $tr_history )\r
+ out HAS MOAR "</tr>\n";\r
+ KTHX\r
+ IZ !array_pop( $has_opened_tr )\r
+ out HAS MOAR "<tr><td></td></tr>\n" ;\r
+ KTHX\r
+\r
+ out HAS MOAR "</table>\n";\r
+ KTHX\r
+\r
+ BTW Remove trailing line-ending (b/c)\r
+ IZ substr( $out, -1 ) === "\n"\r
+ I HAS out IZ substr( $out, 0, -1 )\r
+ KTHX\r
+\r
+ BTW special case: don't return empty table\r
+ IZ $out === "<table>\n<tr><td></td></tr>\n</table>"\r
+ I HAS out IZ ''\r
+ KTHX\r
+\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+\r
+ I FOUND MAH $out\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Helper function for parse() that transforms wiki markup into\r
+ NOT WANT HTML. Only called for $mOutputType == self::OT_HTML.\r
+ NOT WANT \r
+ NOT WANT @private\r
+ WANT\r
+ SO IM LIKE internalParse WITH UR $text, $isMain = true, $frame=false\r
+ IM ON UR wfProfileIn DOING __METHOD__\r
+\r
+ I HAS origText IZ $text\r
+\r
+ BTW Hook to suspend the parser in this state\r
+ IZ !wfRunHooks( 'ParserBeforeInternalParse', array( &$this, &$text, &$this->mStripState ) )\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ I FOUND MAH $text \r
+ KTHX\r
+\r
+ BTW if $frame is provided, then use $frame for replacing any variables\r
+ IZ $frame\r
+ BTW use frame depth to infer how include/noinclude tags should be handled\r
+ BTW depth=0 means this is the top-level document; otherwise it's an included document\r
+ IZ !$frame->depth\r
+ I HAS flag IZ 0\r
+ NOWAI\r
+ I HAS flag IZ Parser::PTD_FOR_INCLUSION\r
+ I HAS dom IZ $this->preprocessToDom( $text, $flag )\r
+ I HAS text IZ $frame->expand( $dom )\r
+ KTHX\r
+ NOWAI\r
+ BTW if $frame is not provided, then use old-style replaceVariables\r
+ I HAS text IZ $this->replaceVariables( $text )\r
+ KTHX\r
+\r
+ I HAS text IZ Sanitizer::removeHTMLtags( $text, array( &$this, 'attributeStripCallback' ), false, array_keys( $this->mTransparentTagHooks ) )\r
+ IM ON UR wfRunHooks DOING 'InternalParseBeforeLinks', array( &$this, &$text, &$this->mStripState )\r
+\r
+ BTW Tables need to come after variable replacement for things to work\r
+ BTW properly; putting them before other transformations should keep\r
+ BTW exciting things like link expansions from showing up in surprising\r
+ BTW places.\r
+ I HAS text IZ $this->doTableStuff( $text )\r
+\r
+ I HAS text IZ preg_replace( '/(^|\n)-----*/', '\\1<hr />', $text )\r
+\r
+ I HAS text IZ $this->doDoubleUnderscore( $text )\r
+\r
+ I HAS text IZ $this->doHeadings( $text )\r
+ IZ $this->mOptions->getUseDynamicDates()\r
+ I HAS df IZ DateFormatter::getInstance()\r
+ I HAS text IZ $df->reformat( $this->mOptions->getDateFormat(), $text )\r
+ KTHX\r
+ I HAS text IZ $this->doAllQuotes( $text )\r
+ I HAS text IZ $this->replaceInternalLinks( $text )\r
+ I HAS text IZ $this->replaceExternalLinks( $text )\r
+\r
+ BTW replaceInternalLinks may sometimes leave behind\r
+ BTW absolute URLs, which have to be masked to hide them from replaceExternalLinks\r
+ I HAS text IZ str_replace( $this->mUniqPrefix.'NOPARSE', '', $text )\r
+\r
+ I HAS text IZ $this->doMagicLinks( $text )\r
+ I HAS text IZ $this->formatHeadings( $text, $origText, $isMain )\r
+\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ I FOUND MAH $text\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Replace special strings like "ISBN xxx" and "RFC xxx" with\r
+ NOT WANT magic external links.\r
+ NOT WANT \r
+ NOT WANT DML\r
+ NOT WANT @private\r
+ WANT\r
+ SO IM LIKE doMagicLinks WITH UR $text\r
+ IM ON UR wfProfileIn DOING __METHOD__\r
+ I HAS prots IZ $this->mUrlProtocols\r
+ I HAS urlChar IZ self::EXT_LINK_URL_CLASS\r
+ text IZ preg_replace_callback(\r
+ '!(?: # Start cases\r
+ (<a[ \t\r\n>].*?</a>) | # m[1]: Skip link text\r
+ (<.*?>) | # m[2]: Skip stuff inside HTML elements' . "\r
+ (\\b(?:$prots)$urlChar+) | # m[3]: Free external links" . '\r
+ (?:RFC|PMID)\s+([0-9]+) | # m[4]: RFC or PMID, capture number\r
+ ISBN\s+(\b # m[5]: ISBN, capture number\r
+ (?: 97[89] [\ \-]? )? # optional 13-digit ISBN prefix\r
+ (?: [0-9] [\ \-]? ){9} # 9 digits with opt. delimiters\r
+ [0-9Xx] # check digit\r
+ \b)\r
+ )!x', array( &$this, 'magicLinkCallback' ), $text );\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ I FOUND MAH $text\r
+ KTHX\r
+\r
+ SO IM LIKE magicLinkCallback WITH UR $m\r
+ IZ isset( $m[1] ) && $m[1] !== ''\r
+ BTW Skip anchor\r
+ I FOUND MAH $m[0]\r
+ ORLY isset( $m[2] ) && $m[2] !== ''\r
+ BTW Skip HTML element\r
+ I FOUND MAH $m[0]\r
+ ORLY isset( $m[3] ) && $m[3] !== ''\r
+ BTW Free external link\r
+ I FOUND MAH $this->makeFreeExternalLink( $m[0] )\r
+ ORLY isset( $m[4] ) && $m[4] !== ''\r
+ BTW RFC or PMID\r
+ I HAS CssClass IZ ''\r
+ IZ substr( $m[0], 0, 3 ) === 'RFC'\r
+ I HAS keyword IZ 'RFC'\r
+ I HAS urlmsg IZ 'rfcurl'\r
+ I HAS CssClass IZ 'mw-magiclink-rfc'\r
+ I HAS id IZ $m[4]\r
+ ORLY substr( $m[0], 0, 4 ) === 'PMID'\r
+ I HAS keyword IZ 'PMID'\r
+ I HAS urlmsg IZ 'pubmedurl'\r
+ I HAS CssClass IZ 'mw-magiclink-pmid'\r
+ I HAS id IZ $m[4]\r
+ NOWAI\r
+ throw new MWException( __METHOD__.': unrecognised match type "' .\r
+ IM ON UR substr DOING $m[0], 0, 20 ) . '"'\r
+ KTHX\r
+ I HAS url IZ wfMsg( $urlmsg, $id)\r
+ I HAS sk IZ $this->mOptions->getSkin()\r
+ I HAS la IZ $sk->getExternalLinkAttributes( "external $CssClass" )\r
+ I FOUND MAH "<a href=\"{$url}\"{$la}>{$keyword} {$id}</a>"\r
+ ORLY isset( $m[5] ) && $m[5] !== ''\r
+ BTW ISBN\r
+ I HAS isbn IZ $m[5]\r
+ num IZ strtr( $isbn, array(\r
+ '-' => '',\r
+ ' ' => '',\r
+ 'x' => 'X',\r
+ ));\r
+ I HAS titleObj IZ SpecialPage::getTitleFor( 'Booksources', $num )\r
+ return'<a href="' .\r
+ $titleObj->escapeLocalUrl() .\r
+ "\" class=\"internal mw-magiclink-isbn\">ISBN $isbn</a>";\r
+ NOWAI\r
+ I FOUND MAH $m[0]\r
+ KTHX\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Make a free external link, given a user-supplied URL\r
+ NOT WANT @return HTML\r
+ NOT WANT @private\r
+ WANT\r
+ SO IM LIKE makeFreeExternalLink WITH UR $url\r
+ I HAS UR $wgContLang ON UR INTERNETS\r
+ IM ON UR wfProfileIn DOING __METHOD__\r
+\r
+ I HAS sk IZ $this->mOptions->getSkin()\r
+ I HAS trail IZ ''\r
+\r
+ BTW The characters '<' and '>' (which were escaped by\r
+ BTW removeHTMLtags()) should not be included in\r
+ BTW URLs, per RFC 2396.\r
+ I HAS m2 IZ EMPTY\r
+ IZ preg_match( '/&(lt|gt);/', $url, $m2, PREG_OFFSET_CAPTURE )\r
+ I HAS trail IZ substr( $url, $m2[0][1] ) . $trail\r
+ I HAS url IZ substr( $url, 0, $m2[0][1] )\r
+ KTHX\r
+\r
+ BTW Move trailing punctuation to $trail\r
+ I HAS sep IZ ',;\.:!?'\r
+ BTW If there is no left bracket, then consider right brackets fair game too\r
+ IZ strpos( $url, '(' ) === false\r
+ sep HAS MOAR ')';\r
+ KTHX\r
+\r
+ I HAS numSepChars IZ strspn( strrev( $url ), $sep )\r
+ IZ $numSepChars\r
+ I HAS trail IZ substr( $url, -$numSepChars ) . $trail\r
+ I HAS url IZ substr( $url, 0, -$numSepChars )\r
+ KTHX\r
+\r
+ I HAS url IZ Sanitizer::cleanUrl( $url )\r
+\r
+ BTW Is this an external image?\r
+ I HAS text IZ $this->maybeMakeExternalImage( $url )\r
+ IZ $text === false\r
+ BTW Not an image, make a link\r
+ text IZ $sk->makeExternalLink( $url, $wgContLang->markNoConversion($url), true, 'free',\r
+ IM ON UR SPECIAL getExternalLinkAttribs DOING $url )\r
+ BTW Register it in the output object...\r
+ BTW Replace unnecessary URL escape codes with their equivalent characters\r
+ I HAS pasteurized IZ self::replaceUnusualEscapes( $url )\r
+ IM ON UR SPECIAL mOutput->addExternalLink DOING $pasteurized\r
+ KTHX\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ I FOUND MAH $text . $trail\r
+ KTHX\r
+\r
+\r
+ DO NOT WANT\r
+ NOT WANT Parse headers and return html\r
+ NOT WANT \r
+ NOT WANT @private\r
+ WANT\r
+ SO IM LIKE doHeadings WITH UR $text\r
+ IM ON UR wfProfileIn DOING __METHOD__\r
+ for ( $i = 6; $i >= 1; --$i ) {\r
+ I HAS h IZ str_repeat( '=', $i )\r
+ text IZ preg_replace( "/^$h(.+)$h\\s*$/m",\r
+ "<h$i>\\1</h$i>", $text );\r
+ KTHX\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ I FOUND MAH $text\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Replace single quotes with HTML markup\r
+ NOT WANT @private\r
+ NOT WANT @return string the altered text\r
+ WANT\r
+ SO IM LIKE doAllQuotes WITH UR $text\r
+ IM ON UR wfProfileIn DOING __METHOD__\r
+ I HAS outtext IZ ''\r
+ I HAS lines IZ StringUtils::explode( "\n", $text )\r
+ IM IN UR lines ITZA line\r
+ outtext HAS MOAR $this->doQuotes( $line ) . "\n";\r
+ KTHX\r
+ I HAS outtext IZ substr( $outtext, 0,-1 )\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ I FOUND MAH $outtext\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Helper function for doAllQuotes()\r
+ WANT\r
+ SO IM LIKE doQuotes WITH UR $text\r
+ I HAS arr IZ preg_split( "/(''+)/", $text, -1, PREG_SPLIT_DELIM_CAPTURE )\r
+ IZ count( $arr ) == 1\r
+ I FOUND MAH $text\r
+ NOWAI\r
+ BTW First, do some preliminary work. This may shift some apostrophes from\r
+ BTW being mark-up to being text. It also counts the number of occurrences\r
+ BTW of bold and italics mark-ups.\r
+ I HAS i IZ 0\r
+ I HAS numbold IZ 0\r
+ I HAS numitalics IZ 0\r
+ IM IN UR arr ITZA r\r
+ IZ ( $i % 2 ) == 1\r
+ BTW If there are ever four apostrophes, assume the first is supposed to\r
+ BTW be text, and the remaining three constitute mark-up for bold text.\r
+ IZ strlen( $arr[$i] ) == 4\r
+ $arr[$i-1] .= "'";\r
+ $arr[$i] = "'''";\r
+ ORLY strlen( $arr[$i] ) > 5\r
+ BTW If there are more than 5 apostrophes in a row, assume they're all\r
+ BTW text except for the last 5.\r
+ $arr[$i-1] .= str_repeat( "'", strlen( $arr[$i] ) - 5 );\r
+ $arr[$i] = "'''''";\r
+ KTHX\r
+ BTW Count the number of occurrences of bold and italics mark-ups.\r
+ BTW We are not counting sequences of five apostrophes.\r
+ IZ strlen( $arr[$i] ) == 2 \r
+ $numitalics++;\r
+ ORLY strlen( $arr[$i] ) == 3 \r
+ $numbold++;\r
+ ORLY strlen( $arr[$i] ) == 5 \r
+ $numitalics++; \r
+ $numbold++;\r
+ KTHX\r
+ KTHX\r
+ $i++;\r
+ KTHX\r
+\r
+ BTW If there is an odd number of both bold and italics, it is likely\r
+ BTW that one of the bold ones was meant to be an apostrophe followed\r
+ BTW by italics. Which one we cannot know for certain, but it is more\r
+ BTW likely to be one that has a single-letter word before it.\r
+ IZ ( $numbold % 2 == 1 ) && ( $numitalics % 2 == 1 )\r
+ I HAS i IZ 0\r
+ I HAS firstsingleletterword IZ -1\r
+ I HAS firstmultiletterword IZ -1\r
+ I HAS firstspace IZ -1\r
+ IM IN UR arr ITZA r\r
+ IZ ( $i % 2 == 1 ) and ( strlen( $r ) == 3 )\r
+ I HAS x1 IZ substr( $arr[$i-1], -1 )\r
+ I HAS x2 IZ substr( $arr[$i-1], -2, 1 )\r
+ IZ $x1 === ' '\r
+ IZ $firstspace == -1\r
+ I HAS firstspace IZ $i\r
+ KTHX\r
+ KTHX elseif ( $x2 === ' ') {\r
+ IZ $firstsingleletterword == -1 \r
+ I HAS firstsingleletterword IZ $i\r
+ KTHX\r
+ NOWAI\r
+ IZ $firstmultiletterword == -1\r
+ I HAS firstmultiletterword IZ $i\r
+ KTHX\r
+ KTHX\r
+ KTHX\r
+ $i++;\r
+ KTHX\r
+\r
+ BTW If there is a single-letter word, use it!\r
+ IZ $firstsingleletterword > -1\r
+ $arr[$firstsingleletterword] = "''";\r
+ $arr[$firstsingleletterword-1] .= "'";\r
+ ORLY $firstmultiletterword > -1\r
+ BTW If not, but there's a multi-letter word, use that one.\r
+ $arr[$firstmultiletterword] = "''";\r
+ $arr[$firstmultiletterword-1] .= "'";\r
+ ORLY $firstspace > -1\r
+ BTW ... otherwise use the first one that has neither.\r
+ BTW (notice that it is possible for all three to be -1 if, for example,\r
+ BTW there is only one pentuple-apostrophe in the line)\r
+ $arr[$firstspace] = "''";\r
+ $arr[$firstspace-1] .= "'";\r
+ KTHX\r
+ KTHX\r
+\r
+ BTW Now let's actually convert our apostrophic mush to HTML!\r
+ I HAS output IZ ''\r
+ I HAS buffer IZ ''\r
+ I HAS state IZ ''\r
+ I HAS i IZ 0\r
+ IM IN UR arr ITZA r\r
+ IZ ( $i % 2 ) == 0\r
+ IZ $state === 'both'\r
+ buffer HAS MOAR $r;\r
+ NOWAI\r
+ output HAS MOAR $r;\r
+ KTHX\r
+ NOWAI\r
+ IZ strlen( $r ) == 2\r
+ IZ $state === 'i'\r
+ output HAS MOAR '</i>'; $state = '';\r
+ ORLY $state === 'bi'\r
+ output HAS MOAR '</i>'; $state = 'b';\r
+ ORLY $state === 'ib'\r
+ output HAS MOAR '</b></i><b>'; $state = 'b';\r
+ ORLY $state === 'both'\r
+ output HAS MOAR '<b><i>'.$buffer.'</i>'; $state = 'b';\r
+ NOWAI # $state can be 'b' or ''\r
+ output HAS MOAR '<i>'; $state .= 'i';\r
+ KTHX\r
+ ORLY strlen( $r ) == 3\r
+ IZ $state === 'b'\r
+ output HAS MOAR '</b>'; $state = '';\r
+ ORLY $state === 'bi'\r
+ output HAS MOAR '</i></b><i>'; $state = 'i';\r
+ ORLY $state === 'ib'\r
+ output HAS MOAR '</b>'; $state = 'i';\r
+ ORLY $state === 'both'\r
+ output HAS MOAR '<i><b>'.$buffer.'</b>'; $state = 'i';\r
+ NOWAI # $state can be 'i' or ''\r
+ output HAS MOAR '<b>'; $state .= 'b';\r
+ KTHX\r
+ ORLY strlen( $r ) == 5\r
+ IZ $state === 'b'\r
+ output HAS MOAR '</b><i>'; $state = 'i';\r
+ ORLY $state === 'i'\r
+ output HAS MOAR '</i><b>'; $state = 'b';\r
+ ORLY $state === 'bi'\r
+ output HAS MOAR '</i></b>'; $state = '';\r
+ ORLY $state === 'ib'\r
+ output HAS MOAR '</b></i>'; $state = '';\r
+ ORLY $state === 'both'\r
+ output HAS MOAR '<i><b>'.$buffer.'</b></i>'; $state = '';\r
+ NOWAI # ($state == '')\r
+ I HAS buffer IZ ''; $state = 'both'\r
+ KTHX\r
+ KTHX\r
+ KTHX\r
+ $i++;\r
+ KTHX\r
+ BTW Now close all remaining tags. Notice that the order is important.\r
+ IZ $state === 'b' || $state === 'ib'\r
+ output HAS MOAR '</b>';\r
+ KTHX\r
+ IZ $state === 'i' || $state === 'bi' || $state === 'ib'\r
+ output HAS MOAR '</i>';\r
+ KTHX\r
+ IZ $state === 'bi'\r
+ output HAS MOAR '</b>';\r
+ KTHX\r
+ BTW There might be lonely ''''', so make sure we have a buffer\r
+ IZ $state === 'both' && $buffer\r
+ output HAS MOAR '<b><i>'.$buffer.'</i></b>';\r
+ KTHX\r
+ I FOUND MAH $output\r
+ KTHX\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Replace external links (REL)\r
+ NOT WANT \r
+ NOT WANT Note: this is all very hackish and the order of execution matters a lot.\r
+ NOT WANT Make sure to run maintenance/parserTests.php if you change this code.\r
+ NOT WANT \r
+ NOT WANT @private\r
+ WANT\r
+ SO IM LIKE replaceExternalLinks WITH UR $text\r
+ I HAS UR $wgContLang ON UR INTERNETS\r
+ IM ON UR wfProfileIn DOING __METHOD__\r
+\r
+ I HAS sk IZ $this->mOptions->getSkin()\r
+\r
+ I HAS bits IZ preg_split( $this->mExtLinkBracketedRegex, $text, -1, PREG_SPLIT_DELIM_CAPTURE )\r
+ I HAS s IZ array_shift( $bits )\r
+\r
+ I HAS i IZ 0\r
+ STEALIN UR $i<count( $bits )\r
+ I HAS url IZ $bits[$i++]\r
+ I HAS protocol IZ $bits[$i++]\r
+ I HAS text IZ $bits[$i++]\r
+ I HAS trail IZ $bits[$i++]\r
+\r
+ BTW The characters '<' and '>' (which were escaped by\r
+ BTW removeHTMLtags()) should not be included in\r
+ BTW URLs, per RFC 2396.\r
+ I HAS m2 IZ EMPTY\r
+ IZ preg_match( '/&(lt|gt);/', $url, $m2, PREG_OFFSET_CAPTURE )\r
+ I HAS text IZ substr( $url, $m2[0][1] ) . ' ' . $text\r
+ I HAS url IZ substr( $url, 0, $m2[0][1] )\r
+ KTHX\r
+\r
+ BTW If the link text is an image URL, replace it with an <img> tag\r
+ BTW This happened by accident in the original parser, but some people used it extensively\r
+ I HAS img IZ $this->maybeMakeExternalImage( $text )\r
+ IZ $img !== false\r
+ I HAS text IZ $img\r
+ KTHX\r
+\r
+ I HAS dtrail IZ ''\r
+\r
+ BTW Set linktype for CSS - if URL==text, link is essentially free\r
+ I HAS linktype IZ ( $text === $url ) ? 'free' : 'text'\r
+\r
+ BTW No link text, e.g. [http://domain.tld/some.link]\r
+ IZ $text == ''\r
+ BTW Autonumber if allowed. See bug #5918\r
+ IZ strpos( wfUrlProtocols(), substr( $protocol, 0, strpos( $protocol, ':' ) ) ) !== false\r
+ I HAS langObj IZ $this->getFunctionLang()\r
+ I HAS text IZ '[' . $langObj->formatNum( ++$this->mAutonumber ) . ']'\r
+ I HAS linktype IZ 'autonumber'\r
+ NOWAI\r
+ BTW Otherwise just use the URL\r
+ I HAS text IZ htmlspecialchars( $url )\r
+ I HAS linktype IZ 'free'\r
+ KTHX\r
+ NOWAI\r
+ BTW Have link text, e.g. [http://domain.tld/some.link text]s\r
+ BTW Check for trail\r
+ IM ON UR list DOING $dtrail, $trail ) = Linker::splitTrail( $trail\r
+ KTHX\r
+\r
+ I HAS text IZ $wgContLang->markNoConversion( $text )\r
+\r
+ I HAS url IZ Sanitizer::cleanUrl( $url )\r
+\r
+ BTW Use the encoded URL\r
+ BTW This means that users can paste URLs directly into the text\r
+ BTW Funny characters like ö aren't valid in URLs anyway\r
+ BTW This was changed in August 2004\r
+ s HAS MOAR $sk->makeExternalLink( $url, $text, false, $linktype,\r
+ $this->getExternalLinkAttribs( $url ) ) . $dtrail . $trail;\r
+\r
+ BTW Register link in the output object.\r
+ BTW Replace unnecessary URL escape codes with the referenced character\r
+ BTW This prevents spammers from hiding links from the filters\r
+ I HAS pasteurized IZ self::replaceUnusualEscapes( $url )\r
+ IM ON UR SPECIAL mOutput->addExternalLink DOING $pasteurized\r
+ KTHX\r
+\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ I FOUND MAH $s\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Get an associative array of additional HTML attributes appropriate for a\r
+ NOT WANT particular external link. This currently may include rel => nofollow\r
+ NOT WANT (depending on configuration, namespace, and the URL's domain) and/or a\r
+ NOT WANT target attribute (depending on configuration).\r
+ NOT WANT \r
+ NOT WANT @param string $url Optional URL, to extract the domain from for rel =>\r
+ NOT WANT nofollow if appropriate\r
+ NOT WANT @return array Associative array of HTML attributes\r
+ WANT\r
+ SO IM LIKE getExternalLinkAttribs WITH UR $url = false\r
+ I HAS attribs IZ EMPTY\r
+ I HAS UR $wgNoFollowLinks, $wgNoFollowNsExceptions ON UR INTERNETS\r
+ I HAS ns IZ $this->mTitle->getNamespace()\r
+ IZ $wgNoFollowLinks && !in_array( $ns, $wgNoFollowNsExceptions )\r
+ $attribs['rel'] = 'nofollow';\r
+\r
+ I HAS UR $wgNoFollowDomainExceptions ON UR INTERNETS\r
+ IZ $wgNoFollowDomainExceptions\r
+ I HAS bits IZ wfParseUrl( $url )\r
+ IZ is_array( $bits ) && isset( $bits['host'] )\r
+ IM IN UR wgNoFollowDomainExceptions ITZA domain\r
+ IZ substr( $bits['host'], -strlen( $domain ) ) == $domain\r
+ IM ON UR unset DOING $attribs['rel']\r
+ break;\r
+ KTHX\r
+ KTHX\r
+ KTHX\r
+ KTHX\r
+ KTHX\r
+ IZ $this->mOptions->getExternalLinkTarget()\r
+ $attribs['target'] = $this->mOptions->getExternalLinkTarget();\r
+ KTHX\r
+ I FOUND MAH $attribs\r
+ KTHX\r
+\r
+\r
+ DO NOT WANT\r
+ NOT WANT Replace unusual URL escape codes with their equivalent characters\r
+ NOT WANT @param string\r
+ NOT WANT @return string\r
+ NOT WANT @static\r
+ NOT WANT @todo This can merge genuinely required bits in the path or query string,\r
+ NOT WANT breaking legit URLs. A proper fix would treat the various parts of\r
+ NOT WANT the URL differently; as a workaround, just use the output for\r
+ NOT WANT statistical records, not for actual linking/output.\r
+ WANT\r
+ SO IM ALWAYS LIKE replaceUnusualEscapes WITH UR $url\r
+ return preg_replace_callback( '/%[0-9A-Fa-f]{2}/',\r
+ IM ON UR array DOING __CLASS__, 'replaceUnusualEscapesCallback' ), $url\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Callback function used in replaceUnusualEscapes().\r
+ NOT WANT Replaces unusual URL escape codes with their equivalent character\r
+ NOT WANT @static\r
+ NOT WANT @private\r
+ WANT\r
+ SO IM ALWAYS LIKE replaceUnusualEscapesCallback WITH UR $matches\r
+ I HAS char IZ urldecode( $matches[0] )\r
+ I HAS ord IZ ord( $char )\r
+ BTW Is it an unsafe or HTTP reserved character according to RFC 1738?\r
+ IZ $ord > 32 && $ord < 127 && strpos( '<>"#{}|\^~[]`;/?', $char ) === false\r
+ BTW No, shouldn't be escaped\r
+ I FOUND MAH $char\r
+ NOWAI\r
+ BTW Yes, leave it escaped\r
+ I FOUND MAH $matches[0]\r
+ KTHX\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT make an image if it's allowed, either through the global\r
+ NOT WANT option, through the exception, or through the on-wiki whitelist\r
+ NOT WANT @private\r
+ WANT\r
+ SO IM LIKE maybeMakeExternalImage WITH UR $url\r
+ I HAS sk IZ $this->mOptions->getSkin()\r
+ I HAS imagesfrom IZ $this->mOptions->getAllowExternalImagesFrom()\r
+ I HAS imagesexception IZ !empty( $imagesfrom )\r
+ I HAS text IZ false\r
+ BTW $imagesfrom could be either a single string or an array of strings, parse out the latter\r
+ IZ $imagesexception && is_array( $imagesfrom )\r
+ I HAS imagematch IZ false\r
+ IM IN UR imagesfrom ITZA match\r
+ IZ strpos( $url, $match ) === 0\r
+ I HAS imagematch IZ true\r
+ break;\r
+ KTHX\r
+ KTHX\r
+ ORLY $imagesexception\r
+ I HAS imagematch IZ ( strpos( $url, $imagesfrom ) === 0 )\r
+ NOWAI\r
+ I HAS imagematch IZ false\r
+ KTHX\r
+ if ( $this->mOptions->getAllowExternalImages()\r
+ || ( $imagesexception && $imagematch ) ) {\r
+ IZ preg_match( self::EXT_IMAGE_REGEX, $url )\r
+ BTW Image found\r
+ I HAS text IZ $sk->makeExternalImage( $url )\r
+ KTHX\r
+ KTHX\r
+ if ( !$text && $this->mOptions->getEnableImageWhitelist()\r
+ && preg_match( self::EXT_IMAGE_REGEX, $url ) ) {\r
+ I HAS whitelist IZ explode( "\n", wfMsgForContent( 'external_image_whitelist' ) )\r
+ IM IN UR whitelist ITZA entry\r
+ BTW Sanitize the regex fragment, make it case-insensitive, ignore blank entries/comments\r
+ IZ strpos( $entry, '#' ) === 0 || $entry === ''\r
+ continue;\r
+ KTHX\r
+ IZ preg_match( '/' . str_replace( '/', '\\/', $entry ) . '/i', $url )\r
+ BTW Image matches a whitelist entry\r
+ I HAS text IZ $sk->makeExternalImage( $url )\r
+ break;\r
+ KTHX\r
+ KTHX\r
+ KTHX\r
+ I FOUND MAH $text\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Process [[ ]] wikilinks\r
+ NOT WANT @return processed text\r
+ NOT WANT \r
+ NOT WANT @private\r
+ WANT\r
+ SO IM LIKE replaceInternalLinks WITH UR $s\r
+ IM ON UR SPECIAL mLinkHolders->merge DOING $this->replaceInternalLinks2( $s )\r
+ I FOUND MAH $s\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Process [[ ]] wikilinks (RIL)\r
+ NOT WANT @return LinkHolderArray\r
+ NOT WANT \r
+ NOT WANT @private\r
+ WANT\r
+ SO IM LIKE replaceInternalLinks2 WITH UR &$s\r
+ I HAS UR $wgContLang ON UR INTERNETS\r
+\r
+ IM ON UR wfProfileIn DOING __METHOD__\r
+\r
+ IM ON UR wfProfileIn DOING __METHOD__.'-setup'\r
+ static $tc = FALSE, $e1, $e1_img;\r
+ BTW the % is needed to support urlencoded titles as well\r
+ IZ !$tc\r
+ I HAS tc IZ Title::legalChars() . '#%'\r
+ BTW Match a link having the form [[namespace:link|alternate]]trail\r
+ I HAS e1 IZ "/^([{$tc}]+)(?:\\|(.+?))?]](.*)\$/sD"\r
+ BTW Match cases where there is no "]]", which might still be images\r
+ I HAS e1_img IZ "/^([{$tc}]+)\\|(.*)\$/sD"\r
+ KTHX\r
+\r
+ I HAS sk IZ $this->mOptions->getSkin()\r
+ I HAS holders IZ new LinkHolderArray( $this )\r
+\r
+ BTW split the entire text string on occurences of [[\r
+ I HAS a IZ StringUtils::explode( '[[', ' ' . $s )\r
+ BTW get the first element (all text up to first [[), and remove the space we added\r
+ I HAS s IZ $a->current()\r
+ $a->next();\r
+ I HAS line IZ $a->current() # Workaround for broken ArrayIterator::next() that returns "void"\r
+ I HAS s IZ substr( $s, 1 )\r
+\r
+ I HAS useLinkPrefixExtension IZ $wgContLang->linkPrefixExtension()\r
+ I HAS e2\r
+ IZ $useLinkPrefixExtension\r
+ BTW Match the end of a line for a word that's not followed by whitespace,\r
+ BTW e.g. in the case of 'The Arab al[[Razi]]', 'al' will be matched\r
+ I HAS e2 IZ wfMsgForContent( 'linkprefix' )\r
+ KTHX\r
+\r
+ IZ is_null( $this->mTitle )\r
+ IM ON UR wfProfileOut DOING __METHOD__.'-setup'\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ throw new MWException( __METHOD__.": \$this->mTitle is null\n" );\r
+ KTHX\r
+ I HAS nottalk IZ !$this->mTitle->isTalkPage()\r
+\r
+ IZ $useLinkPrefixExtension\r
+ I HAS m IZ EMPTY\r
+ IZ preg_match( $e2, $s, $m )\r
+ I HAS first_prefix IZ $m[2]\r
+ NOWAI\r
+ I HAS first_prefix IZ false\r
+ KTHX\r
+ NOWAI\r
+ I HAS prefix IZ ''\r
+ KTHX\r
+\r
+ IZ $wgContLang->hasVariants()\r
+ I HAS selflink IZ $wgContLang->convertLinkToAllVariants( $this->mTitle->getPrefixedText() )\r
+ NOWAI\r
+ I HAS selflink IZ BUCKET $this->mTitle->getPrefixedText() );\r
+ KTHX\r
+ I HAS useSubpages IZ $this->areSubpagesAllowed()\r
+ IM ON UR wfProfileOut DOING __METHOD__.'-setup'\r
+\r
+ BTW Loop for each link\r
+ for ( ; $line !== false && $line !== null ; $a->next(), $line = $a->current() ) {\r
+ BTW Check for excessive memory usage\r
+ IZ $holders->isBig()\r
+ BTW Too big\r
+ BTW Do the existence check, replace the link holders and clear the array\r
+ $holders->replace( $s );\r
+ $holders->clear();\r
+ KTHX\r
+\r
+ IZ $useLinkPrefixExtension\r
+ IM ON UR wfProfileIn DOING __METHOD__.'-prefixhandling'\r
+ IZ preg_match( $e2, $s, $m )\r
+ I HAS prefix IZ $m[2]\r
+ I HAS s IZ $m[1]\r
+ NOWAI\r
+ $prefix='';\r
+ KTHX\r
+ BTW first link\r
+ IZ $first_prefix\r
+ I HAS prefix IZ $first_prefix\r
+ I HAS first_prefix IZ false\r
+ KTHX\r
+ IM ON UR wfProfileOut DOING __METHOD__.'-prefixhandling'\r
+ KTHX\r
+\r
+ I HAS might_be_img IZ false\r
+\r
+ IM ON UR wfProfileIn DOING __METHOD__."-e1"\r
+ IZ preg_match( $e1, $line, $m ) # page with normal text or alt\r
+ I HAS text IZ $m[2]\r
+ BTW If we get a ] at the beginning of $m[3] that means we have a link that's something like:\r
+ BTW [[Image:Foo.jpg|[http://example.com desc]]] <- having three ] in a row fucks up,\r
+ BTW the real problem is with the $e1 regex\r
+ BTW See bug 1300.\r
+ BTW \r
+ BTW Still some problems for cases where the ] is meant to be outside punctuation,\r
+ BTW and no image is in sight. See bug 2095.\r
+ BTW \r
+ if ( $text !== '' &&\r
+ substr( $m[3], 0, 1 ) === ']' &&\r
+ strpos( $text, '[' ) !== false\r
+ )\r
+ {\r
+ text HAS MOAR ']'; # so that replaceExternalLinks($text) works later\r
+ $m[3] = substr( $m[3], 1 );\r
+ KTHX\r
+ BTW fix up urlencoded title texts\r
+ IZ strpos( $m[1], '%' ) !== false\r
+ BTW Should anchors '#' also be rejected?\r
+ $m[1] = str_replace( array('<', '>'), array('<', '>'), urldecode( $m[1] ) );\r
+ KTHX\r
+ I HAS trail IZ $m[3]\r
+ ORLY preg_match( $e1_img, $line, $m ) # Invalid, but might be an image with a link in its caption\r
+ I HAS might_be_img IZ true\r
+ I HAS text IZ $m[2]\r
+ IZ strpos( $m[1], '%' ) !== false\r
+ $m[1] = urldecode( $m[1] );\r
+ KTHX\r
+ I HAS trail IZ ""\r
+ NOWAI # Invalid form; output directly\r
+ s HAS MOAR $prefix . '[[' . $line ;\r
+ IM ON UR wfProfileOut DOING __METHOD__."-e1"\r
+ continue;\r
+ KTHX\r
+ IM ON UR wfProfileOut DOING __METHOD__."-e1"\r
+ IM ON UR wfProfileIn DOING __METHOD__."-misc"\r
+\r
+ BTW Don't allow internal links to pages containing\r
+ BTW PROTO: where PROTO is a valid URL protocol; these\r
+ BTW should be external links.\r
+ IZ preg_match( '/^\b(?:' . wfUrlProtocols() . ')/', $m[1] )\r
+ s HAS MOAR $prefix . '[[' . $line ;\r
+ IM ON UR wfProfileOut DOING __METHOD__."-misc"\r
+ continue;\r
+ KTHX\r
+\r
+ BTW Make subpage if necessary\r
+ IZ $useSubpages\r
+ I HAS link IZ $this->maybeDoSubpageLink( $m[1], $text )\r
+ NOWAI\r
+ I HAS link IZ $m[1]\r
+ KTHX\r
+\r
+ I HAS noforce IZ ( substr( $m[1], 0, 1 ) !== ':' )\r
+ IZ !$noforce\r
+ BTW Strip off leading ':'\r
+ I HAS link IZ substr( $link, 1 )\r
+ KTHX\r
+\r
+ IM ON UR wfProfileOut DOING __METHOD__."-misc"\r
+ IM ON UR wfProfileIn DOING __METHOD__."-title"\r
+ I HAS nt IZ Title::newFromText( $this->mStripState->unstripNoWiki( $link ) )\r
+ IZ $nt === null\r
+ s HAS MOAR $prefix . '[[' . $line;\r
+ IM ON UR wfProfileOut DOING __METHOD__."-title"\r
+ continue;\r
+ KTHX\r
+\r
+ I HAS ns IZ $nt->getNamespace()\r
+ I HAS iw IZ $nt->getInterWiki()\r
+ IM ON UR wfProfileOut DOING __METHOD__."-title"\r
+\r
+ IZ $might_be_img # if this is actually an invalid link\r
+ IM ON UR wfProfileIn DOING __METHOD__."-might_be_img"\r
+ IZ $ns == NS_FILE && $noforce # but might be an image\r
+ I HAS found IZ false\r
+ STEALIN UR true\r
+ BTW look at the next 'line' to see if we can close it there\r
+ $a->next();\r
+ I HAS next_line IZ $a->current()\r
+ IZ $next_line === false || $next_line === null\r
+ break;\r
+ KTHX\r
+ I HAS m IZ explode( ']]', $next_line, 3 )\r
+ IZ count( $m ) == 3\r
+ BTW the first ]] closes the inner link, the second the image\r
+ I HAS found IZ true\r
+ text HAS MOAR "[[{$m[0]}]]{$m[1]}";\r
+ I HAS trail IZ $m[2]\r
+ break;\r
+ ORLY count( $m ) == 2\r
+ BTW if there's exactly one ]] that's fine, we'll keep looking\r
+ text HAS MOAR "[[{$m[0]}]]{$m[1]}";\r
+ NOWAI\r
+ BTW if $next_line is invalid too, we need look no further\r
+ text HAS MOAR '[[' . $next_line;\r
+ break;\r
+ KTHX\r
+ KTHX\r
+ IZ !$found\r
+ BTW we couldn't find the end of this imageLink, so output it raw\r
+ BTW but don't ignore what might be perfectly normal links in the text we've examined\r
+ $holders->merge( $this->replaceInternalLinks2( $text ) );\r
+ s HAS MOAR "{$prefix}[[$link|$text";\r
+ BTW note: no $trail, because without an end, there *is* no trail\r
+ IM ON UR wfProfileOut DOING __METHOD__."-might_be_img"\r
+ continue;\r
+ KTHX\r
+ NOWAI # it's not an image, so output it raw\r
+ s HAS MOAR "{$prefix}[[$link|$text";\r
+ BTW note: no $trail, because without an end, there *is* no trail\r
+ IM ON UR wfProfileOut DOING __METHOD__."-might_be_img"\r
+ continue;\r
+ KTHX\r
+ IM ON UR wfProfileOut DOING __METHOD__."-might_be_img"\r
+ KTHX\r
+\r
+ I HAS wasblank IZ ( $text == '' )\r
+ IZ $wasblank\r
+ I HAS text IZ $link\r
+ KTHX\r
+\r
+ BTW Link not escaped by : , create the various objects\r
+ IZ $noforce\r
+\r
+ BTW Interwikis\r
+ IM ON UR wfProfileIn DOING __METHOD__."-interwiki"\r
+ IZ $iw && $this->mOptions->getInterwikiMagic() && $nottalk && $wgContLang->getLanguageName( $iw )\r
+ IM ON UR SPECIAL mOutput->addLanguageLink DOING $nt->getFullText()\r
+ I HAS s IZ rtrim( $s . $prefix )\r
+ s HAS MOAR trim( $trail, "\n" ) == '' ? '': $prefix . $trail;\r
+ IM ON UR wfProfileOut DOING __METHOD__."-interwiki"\r
+ continue;\r
+ KTHX\r
+ IM ON UR wfProfileOut DOING __METHOD__."-interwiki"\r
+\r
+ IZ $ns == NS_FILE\r
+ IM ON UR wfProfileIn DOING __METHOD__."-image"\r
+ IZ !wfIsBadImage( $nt->getDBkey(), $this->mTitle )\r
+ IZ $wasblank\r
+ BTW if no parameters were passed, $text\r
+ BTW becomes something like "File:Foo.png",\r
+ BTW which we don't want to pass on to the\r
+ BTW image generator\r
+ I HAS text IZ ''\r
+ NOWAI\r
+ BTW recursively parse links inside the image caption\r
+ BTW actually, this will parse them in any other parameters, too,\r
+ BTW but it might be hard to fix that, and it doesn't matter ATM\r
+ I HAS text IZ $this->replaceExternalLinks( $text )\r
+ $holders->merge( $this->replaceInternalLinks2( $text ) );\r
+ KTHX\r
+ BTW cloak any absolute URLs inside the image markup, so replaceExternalLinks() won't touch them\r
+ s HAS MOAR $prefix . $this->armorLinks( $this->makeImage( $nt, $text, $holders ) ) . $trail;\r
+ NOWAI\r
+ s HAS MOAR $prefix . $trail;\r
+ KTHX\r
+ IM ON UR SPECIAL mOutput->addImage DOING $nt->getDBkey()\r
+ IM ON UR wfProfileOut DOING __METHOD__."-image"\r
+ continue;\r
+\r
+ KTHX\r
+\r
+ IZ $ns == NS_CATEGORY\r
+ IM ON UR wfProfileIn DOING __METHOD__."-category"\r
+ I HAS s IZ rtrim( $s . "\n" ) # bug 87\r
+\r
+ IZ $wasblank\r
+ I HAS sortkey IZ $this->getDefaultSort()\r
+ NOWAI\r
+ I HAS sortkey IZ $text\r
+ KTHX\r
+ I HAS sortkey IZ Sanitizer::decodeCharReferences( $sortkey )\r
+ I HAS sortkey IZ str_replace( "\n", '', $sortkey )\r
+ I HAS sortkey IZ $wgContLang->convertCategoryKey( $sortkey )\r
+ IM ON UR SPECIAL mOutput->addCategory DOING $nt->getDBkey(), $sortkey\r
+\r
+ DO NOT WANT\r
+ NOT WANT Strip the whitespace Category links produce, see bug 87\r
+ NOT WANT @todo We might want to use trim($tmp, "\n") here.\r
+ WANT\r
+ s HAS MOAR trim( $prefix . $trail, "\n" ) == '' ? '': $prefix . $trail;\r
+\r
+ IM ON UR wfProfileOut DOING __METHOD__."-category"\r
+ continue;\r
+ KTHX\r
+ KTHX\r
+\r
+ BTW Self-link checking\r
+ IZ $nt->getFragment() === '' && $ns != NS_SPECIAL\r
+ IZ in_array( $nt->getPrefixedText(), $selflink, true )\r
+ s HAS MOAR $prefix . $sk->makeSelfLinkObj( $nt, $text, '', $trail );\r
+ continue;\r
+ KTHX\r
+ KTHX\r
+\r
+ BTW NS_MEDIA is a pseudo-namespace for linking directly to a file\r
+ BTW FIXME: Should do batch file existence checks, see comment below\r
+ IZ $ns == NS_MEDIA\r
+ IM ON UR wfProfileIn DOING __METHOD__."-media"\r
+ BTW Give extensions a chance to select the file revision for us\r
+ I HAS skip IZ $time = false\r
+ IM ON UR wfRunHooks DOING 'BeforeParserMakeImageLinkObj', array( &$this, &$nt, &$skip, &$time )\r
+ IZ $skip\r
+ I HAS link IZ $sk->link( $nt )\r
+ NOWAI\r
+ I HAS link IZ $sk->makeMediaLinkObj( $nt, $text, $time )\r
+ KTHX\r
+ BTW Cloak with NOPARSE to avoid replacement in replaceExternalLinks\r
+ s HAS MOAR $prefix . $this->armorLinks( $link ) . $trail;\r
+ IM ON UR SPECIAL mOutput->addImage DOING $nt->getDBkey()\r
+ IM ON UR wfProfileOut DOING __METHOD__."-media"\r
+ continue;\r
+ KTHX\r
+\r
+ IM ON UR wfProfileIn DOING __METHOD__."-always_known"\r
+ BTW Some titles, such as valid special pages or files in foreign repos, should\r
+ BTW be shown as bluelinks even though they're not included in the page table\r
+ BTW \r
+ BTW FIXME: isAlwaysKnown() can be expensive for file links; we should really do\r
+ BTW batch file existence checks for NS_FILE and NS_MEDIA\r
+ IZ $iw == '' && $nt->isAlwaysKnown()\r
+ IM ON UR SPECIAL mOutput->addLink DOING $nt\r
+ s HAS MOAR $this->makeKnownLinkHolder( $nt, $text, '', $trail, $prefix );\r
+ NOWAI\r
+ BTW Links will be added to the output link list after checking\r
+ s HAS MOAR $holders->makeHolder( $nt, $text, '', $trail, $prefix );\r
+ KTHX\r
+ IM ON UR wfProfileOut DOING __METHOD__."-always_known"\r
+ KTHX\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ I FOUND MAH $holders\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Make a link placeholder. The text returned can be later resolved to a real link with\r
+ NOT WANT replaceLinkHolders(). This is done for two reasons: firstly to avoid further\r
+ NOT WANT parsing of interwiki links, and secondly to allow all existence checks and\r
+ NOT WANT article length checks (for stub links) to be bundled into a single query.\r
+ NOT WANT \r
+ NOT WANT @deprecated\r
+ WANT\r
+ SO IM LIKE makeLinkHolder WITH UR &$nt, $text = '', $query = '', $trail = '', $prefix = ''\r
+ I FOUND MAH $this->mLinkHolders->makeHolder( $nt, $text, $query, $trail, $prefix )\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Render a forced-blue link inline; protect against double expansion of\r
+ NOT WANT URLs if we're in a mode that prepends full URL prefixes to internal links.\r
+ NOT WANT Since this little disaster has to split off the trail text to avoid\r
+ NOT WANT breaking URLs in the following text without breaking trails on the\r
+ NOT WANT wiki links, it's been made into a horrible function.\r
+ NOT WANT \r
+ NOT WANT @param Title $nt\r
+ NOT WANT @param string $text\r
+ NOT WANT @param string $query\r
+ NOT WANT @param string $trail\r
+ NOT WANT @param string $prefix\r
+ NOT WANT @return string HTML-wikitext mix oh yuck\r
+ WANT\r
+ SO IM LIKE makeKnownLinkHolder WITH UR $nt, $text = '', $query = '', $trail = '', $prefix = ''\r
+ IM ON UR list DOING $inside, $trail ) = Linker::splitTrail( $trail\r
+ I HAS sk IZ $this->mOptions->getSkin()\r
+ BTW FIXME: use link() instead of deprecated makeKnownLinkObj()\r
+ I HAS link IZ $sk->makeKnownLinkObj( $nt, $text, $query, $inside, $prefix )\r
+ I FOUND MAH $this->armorLinks( $link ) . $trail\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Insert a NOPARSE hacky thing into any inline links in a chunk that's\r
+ NOT WANT going to go through further parsing steps before inline URL expansion.\r
+ NOT WANT \r
+ NOT WANT Not needed quite as much as it used to be since free links are a bit\r
+ NOT WANT more sensible these days. But bracketed links are still an issue.\r
+ NOT WANT \r
+ NOT WANT @param string more-or-less HTML\r
+ NOT WANT @return string less-or-more HTML with NOPARSE bits\r
+ WANT\r
+ SO IM LIKE armorLinks WITH UR $text\r
+ return preg_replace( '/\b(' . wfUrlProtocols() . ')/',\r
+ "{$this->mUniqPrefix}NOPARSE$1", $text );\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Return true if subpage links should be expanded on this page.\r
+ NOT WANT @return bool\r
+ WANT\r
+ SO IM LIKE areSubpagesAllowed\r
+ BTW Some namespaces don't allow subpages\r
+ I FOUND MAH MWNamespace::hasSubpages( $this->mTitle->getNamespace() )\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Handle link to subpage if necessary\r
+ NOT WANT @param string $target the source of the link\r
+ NOT WANT @param string &$text the link text, modified as necessary\r
+ NOT WANT @return string the full name of the link\r
+ NOT WANT @private\r
+ WANT\r
+ SO IM LIKE maybeDoSubpageLink WITH UR $target, &$text\r
+ I FOUND MAH Linker::normalizeSubpageLink( $this->mTitle, $target, $text )\r
+ KTHX\r
+\r
+ DO NOT WANT#@+\r
+ NOT WANT Used by doBlockLevels()\r
+ NOT WANT @private\r
+ WANT\r
+ SO IM LIKE closeParagraph\r
+ I HAS result IZ ''\r
+ IZ $this->mLastSection != ''\r
+ I HAS result IZ '</' . $this->mLastSection . ">\n"\r
+ KTHX\r
+ UR SPECIAL mInPre IZ false;\r
+ UR SPECIAL mLastSection IZ '';\r
+ I FOUND MAH $result\r
+ KTHX\r
+ DO NOT WANT\r
+ NOT WANT getCommon() returns the length of the longest common substring\r
+ NOT WANT of both arguments, starting at the beginning of both.\r
+ NOT WANT @private \r
+ WANT \r
+ SO IM LIKE getCommon WITH UR $st1, $st2\r
+ I HAS fl IZ strlen( $st1 )\r
+ I HAS shorter IZ strlen( $st2 )\r
+ IZ $fl < $shorter \r
+ I HAS shorter IZ $fl \r
+ KTHX\r
+\r
+ for ( $i = 0; $i < $shorter; ++$i ) {\r
+ IZ $st1{$i} != $st2{$i} \r
+ break; \r
+ KTHX\r
+ KTHX\r
+ I FOUND MAH $i\r
+ KTHX\r
+ DO NOT WANT\r
+ NOT WANT These next three functions open, continue, and close the list\r
+ NOT WANT element appropriate to the prefix character passed into them.\r
+ NOT WANT @private \r
+ WANT\r
+ SO IM LIKE openList WITH UR $char\r
+ I HAS result IZ $this->closeParagraph()\r
+\r
+ IZ '*' === $char \r
+ result HAS MOAR '<ul><li>'; \r
+ ORLY '#' === $char \r
+ result HAS MOAR '<ol><li>'; \r
+ ORLY ':' === $char \r
+ result HAS MOAR '<dl><dd>'; \r
+ ORLY ';' === $char\r
+ result HAS MOAR '<dl><dt>';\r
+ UR SPECIAL mDTopen IZ true;\r
+ NOWAI \r
+ I HAS result IZ '<!-- ERR 1 -->' \r
+ KTHX\r
+\r
+ I FOUND MAH $result\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT TODO: document\r
+ NOT WANT @param $char String\r
+ NOT WANT @private\r
+ WANT\r
+ SO IM LIKE nextItem WITH UR $char\r
+ IZ '*' === $char || '#' === $char \r
+ I FOUND MAH '</li><li>' \r
+ ORLY ':' === $char || ';' === $char\r
+ I HAS close IZ '</dd>'\r
+ IZ $this->mDTopen \r
+ I HAS close IZ '</dt>' \r
+ KTHX\r
+ IZ ';' === $char\r
+ UR SPECIAL mDTopen IZ true;\r
+ I FOUND MAH $close . '<dt>'\r
+ NOWAI\r
+ UR SPECIAL mDTopen IZ false;\r
+ I FOUND MAH $close . '<dd>'\r
+ KTHX\r
+ KTHX\r
+ I FOUND MAH '<!-- ERR 2 -->'\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT TODO: document\r
+ NOT WANT @param $char String\r
+ NOT WANT @private\r
+ WANT\r
+ SO IM LIKE closeList WITH UR $char\r
+ IZ '*' === $char \r
+ I HAS text IZ '</li></ul>' \r
+ ORLY '#' === $char \r
+ I HAS text IZ '</li></ol>' \r
+ ORLY ':' === $char\r
+ IZ $this->mDTopen\r
+ UR SPECIAL mDTopen IZ false;\r
+ I HAS text IZ '</dt></dl>'\r
+ NOWAI\r
+ I HAS text IZ '</dd></dl>'\r
+ KTHX\r
+ NOWAI \r
+ I FOUND MAH '<!-- ERR 3 -->' \r
+ KTHX\r
+ I FOUND MAH $text."\n"\r
+ KTHX\r
+ DO NOT WANT#@-*/\r
+\r
+ DO NOT WANT\r
+ NOT WANT Make lists from lines starting with ':', '*', '#', etc. (DBL)\r
+ NOT WANT \r
+ NOT WANT @param $linestart bool whether or not this is at the start of a line.\r
+ NOT WANT @private\r
+ NOT WANT @return string the lists rendered as HTML\r
+ WANT\r
+ SO IM LIKE doBlockLevels WITH UR $text, $linestart\r
+ IM ON UR wfProfileIn DOING __METHOD__\r
+\r
+ BTW Parsing through the text line by line. The main thing\r
+ BTW happening here is handling of block-level elements p, pre,\r
+ BTW and making lists from lines starting with * # : etc.\r
+ BTW \r
+ I HAS textLines IZ StringUtils::explode( "\n", $text )\r
+\r
+ I HAS lastPrefix IZ $output = ''\r
+ UR SPECIAL mDTopen IZ $inBlockElem = false;\r
+ I HAS prefixLength IZ 0\r
+ I HAS paragraphStack IZ false\r
+\r
+ IM IN UR textLines ITZA oLine\r
+ BTW Fix up $linestart\r
+ IZ !$linestart\r
+ output HAS MOAR $oLine;\r
+ I HAS linestart IZ true\r
+ continue;\r
+ KTHX\r
+ BTW * = ul\r
+ BTW # = ol\r
+ BTW ; = dt\r
+ BTW : = dd\r
+\r
+ I HAS lastPrefixLength IZ strlen( $lastPrefix )\r
+ I HAS preCloseMatch IZ preg_match( '/<\\/pre/i', $oLine )\r
+ I HAS preOpenMatch IZ preg_match( '/<pre/i', $oLine )\r
+ BTW If not in a <pre> element, scan for and figure out what prefixes are there.\r
+ IZ !$this->mInPre\r
+ BTW Multiple prefixes may abut each other for nested lists.\r
+ I HAS prefixLength IZ strspn( $oLine, '*#:;' )\r
+ I HAS prefix IZ substr( $oLine, 0, $prefixLength )\r
+\r
+ BTW eh?\r
+ BTW ; and : are both from definition-lists, so they're equivalent\r
+ BTW for the purposes of determining whether or not we need to open/close\r
+ BTW elements.\r
+ I HAS prefix2 IZ str_replace( ';', ':', $prefix )\r
+ I HAS t IZ substr( $oLine, $prefixLength )\r
+ UR SPECIAL mInPre IZ (bool)$preOpenMatch;\r
+ NOWAI\r
+ BTW Don't interpret any other prefixes in preformatted text\r
+ I HAS prefixLength IZ 0\r
+ I HAS prefix IZ $prefix2 = ''\r
+ I HAS t IZ $oLine\r
+ KTHX\r
+\r
+ BTW List generation\r
+ IZ $prefixLength && $lastPrefix === $prefix2\r
+ BTW Same as the last item, so no need to deal with nesting or opening stuff\r
+ output HAS MOAR $this->nextItem( substr( $prefix, -1 ) );\r
+ I HAS paragraphStack IZ false\r
+\r
+ if ( substr( $prefix, -1 ) === ';') {\r
+ BTW The one nasty exception: definition lists work like this:\r
+ BTW ; title : definition text\r
+ BTW So we check for : in the remainder text to split up the\r
+ BTW title and definition, without b0rking links.\r
+ I HAS term IZ $t2 = ''\r
+ IZ $this->findColonNoLinks( $t, $term, $t2 ) !== false\r
+ I HAS t IZ $t2\r
+ output HAS MOAR $term . $this->nextItem( ':' );\r
+ KTHX\r
+ KTHX\r
+ ORLY $prefixLength || $lastPrefixLength\r
+ BTW We need to open or close prefixes, or both.\r
+\r
+ BTW Either open or close a level...\r
+ I HAS commonPrefixLength IZ $this->getCommon( $prefix, $lastPrefix )\r
+ I HAS paragraphStack IZ false\r
+\r
+ BTW Close all the prefixes which aren't shared.\r
+ STEALIN UR $commonPrefixLength < $lastPrefixLength\r
+ output HAS MOAR $this->closeList( $lastPrefix[$lastPrefixLength-1] );\r
+ --$lastPrefixLength;\r
+ KTHX\r
+\r
+ BTW Continue the current prefix if appropriate.\r
+ IZ $prefixLength <= $commonPrefixLength && $commonPrefixLength > 0\r
+ output HAS MOAR $this->nextItem( $prefix[$commonPrefixLength-1] );\r
+ KTHX\r
+\r
+ BTW Open prefixes where appropriate.\r
+ STEALIN UR $prefixLength > $commonPrefixLength\r
+ I HAS char IZ substr( $prefix, $commonPrefixLength, 1 )\r
+ output HAS MOAR $this->openList( $char );\r
+\r
+ IZ ';' === $char\r
+ BTW FIXME: This is dupe of code above\r
+ IZ $this->findColonNoLinks( $t, $term, $t2 ) !== false\r
+ I HAS t IZ $t2\r
+ output HAS MOAR $term . $this->nextItem( ':' );\r
+ KTHX\r
+ KTHX\r
+ ++$commonPrefixLength;\r
+ KTHX\r
+ I HAS lastPrefix IZ $prefix2\r
+ KTHX\r
+\r
+ BTW If we have no prefixes, go to paragraph mode.\r
+ IZ 0 == $prefixLength\r
+ IM ON UR wfProfileIn DOING __METHOD__."-paragraph"\r
+ BTW No prefix (not in list)--go to paragraph mode\r
+ BTW XXX: use a stack for nestable elements like span, table and div\r
+ I HAS openmatch IZ preg_match('/(?:<table|<blockquote|<h1|<h2|<h3|<h4|<h5|<h6|<pre|<tr|<p|<ul|<ol|<li|<\\/tr|<\\/td|<\\/th)/iS', $t )\r
+ closematch IZ preg_match(\r
+ '/(?:<\\/table|<\\/blockquote|<\\/h1|<\\/h2|<\\/h3|<\\/h4|<\\/h5|<\\/h6|'.\r
+ '<td|<th|<\\/?div|<hr|<\\/pre|<\\/p|'.$this->mUniqPrefix.'-pre|<\\/li|<\\/ul|<\\/ol|<\\/?center)/iS', $t );\r
+ IZ $openmatch or $closematch\r
+ I HAS paragraphStack IZ false\r
+ #Â TODO bug 5718: paragraph closed\r
+ output HAS MOAR $this->closeParagraph();\r
+ IZ $preOpenMatch and !$preCloseMatch\r
+ UR SPECIAL mInPre IZ true;\r
+ KTHX\r
+ IZ $closematch\r
+ I HAS inBlockElem IZ false\r
+ NOWAI\r
+ I HAS inBlockElem IZ true\r
+ KTHX\r
+ ORLY !$inBlockElem && !$this->mInPre\r
+ IZ ' ' == substr( $t, 0, 1 ) and ( $this->mLastSection === 'pre' || trim( $t ) != '' )\r
+ BTW pre\r
+ IZ $this->mLastSection !== 'pre'\r
+ I HAS paragraphStack IZ false\r
+ output HAS MOAR $this->closeParagraph().'<pre>';\r
+ UR SPECIAL mLastSection IZ 'pre';\r
+ KTHX\r
+ I HAS t IZ substr( $t, 1 )\r
+ NOWAI\r
+ BTW paragraph\r
+ IZ trim( $t ) == ''\r
+ IZ $paragraphStack\r
+ output HAS MOAR $paragraphStack.'<br />';\r
+ I HAS paragraphStack IZ false\r
+ UR SPECIAL mLastSection IZ 'p';\r
+ NOWAI\r
+ IZ $this->mLastSection !== 'p'\r
+ output HAS MOAR $this->closeParagraph();\r
+ UR SPECIAL mLastSection IZ '';\r
+ I HAS paragraphStack IZ '<p>'\r
+ NOWAI\r
+ I HAS paragraphStack IZ '</p><p>'\r
+ KTHX\r
+ KTHX\r
+ NOWAI\r
+ IZ $paragraphStack\r
+ output HAS MOAR $paragraphStack;\r
+ I HAS paragraphStack IZ false\r
+ UR SPECIAL mLastSection IZ 'p';\r
+ ORLY $this->mLastSection !== 'p'\r
+ output HAS MOAR $this->closeParagraph().'<p>';\r
+ UR SPECIAL mLastSection IZ 'p';\r
+ KTHX\r
+ KTHX\r
+ KTHX\r
+ KTHX\r
+ IM ON UR wfProfileOut DOING __METHOD__."-paragraph"\r
+ KTHX\r
+ BTW somewhere above we forget to get out of pre block (bug 785)\r
+ IZ $preCloseMatch && $this->mInPre\r
+ UR SPECIAL mInPre IZ false;\r
+ KTHX\r
+ IZ $paragraphStack === false\r
+ output HAS MOAR $t."\n";\r
+ KTHX\r
+ KTHX\r
+ STEALIN UR $prefixLength\r
+ output HAS MOAR $this->closeList( $prefix2[$prefixLength-1] );\r
+ --$prefixLength;\r
+ KTHX\r
+ IZ $this->mLastSection != ''\r
+ output HAS MOAR '</' . $this->mLastSection . '>';\r
+ UR SPECIAL mLastSection IZ '';\r
+ KTHX\r
+\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ I FOUND MAH $output\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Split up a string on ':', ignoring any occurences inside tags\r
+ NOT WANT to prevent illegal overlapping.\r
+ NOT WANT @param string $str the string to split\r
+ NOT WANT @param string &$before set to everything before the ':'\r
+ NOT WANT @param string &$after set to everything after the ':'\r
+ NOT WANT return string the position of the ':', or false if none found\r
+ WANT\r
+ SO IM LIKE findColonNoLinks WITH UR $str, &$before, &$after\r
+ IM ON UR wfProfileIn DOING __METHOD__\r
+\r
+ I HAS pos IZ strpos( $str, ':' )\r
+ IZ $pos === false\r
+ BTW Nothing to find!\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ I FOUND MAH false\r
+ KTHX\r
+\r
+ I HAS lt IZ strpos( $str, '<' )\r
+ IZ $lt === false || $lt > $pos\r
+ BTW Easy; no tag nesting to worry about\r
+ I HAS before IZ substr( $str, 0, $pos )\r
+ I HAS after IZ substr( $str, $pos+1 )\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ I FOUND MAH $pos\r
+ KTHX\r
+\r
+ BTW Ugly state machine to walk through avoiding tags.\r
+ I HAS state IZ self::COLON_STATE_TEXT\r
+ I HAS stack IZ 0\r
+ I HAS len IZ strlen( $str )\r
+ for( $i = 0; $i < $len; $i++ ) {\r
+ I HAS c IZ $str{$i}\r
+\r
+ switch( $state ) {\r
+ BTW (Using the number is a performance hack for common cases)\r
+ case 0: # self::COLON_STATE_TEXT:\r
+ switch( $c ) {\r
+ case "<":\r
+ BTW Could be either a <start> tag or an </end> tag\r
+ I HAS state IZ self::COLON_STATE_TAGSTART\r
+ break;\r
+ case ":":\r
+ IZ $stack == 0\r
+ BTW We found it!\r
+ I HAS before IZ substr( $str, 0, $i )\r
+ I HAS after IZ substr( $str, $i + 1 )\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ I FOUND MAH $i\r
+ KTHX\r
+ BTW Embedded in a tag; don't break it.\r
+ break;\r
+ default:\r
+ BTW Skip ahead looking for something interesting\r
+ I HAS colon IZ strpos( $str, ':', $i )\r
+ IZ $colon === false\r
+ BTW Nothing else interesting\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ I FOUND MAH false\r
+ KTHX\r
+ I HAS lt IZ strpos( $str, '<', $i )\r
+ IZ $stack === 0\r
+ IZ $lt === false || $colon < $lt\r
+ BTW We found it!\r
+ I HAS before IZ substr( $str, 0, $colon )\r
+ I HAS after IZ substr( $str, $colon + 1 )\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ I FOUND MAH $i\r
+ KTHX\r
+ KTHX\r
+ IZ $lt === false\r
+ BTW Nothing else interesting to find; abort!\r
+ BTW We're nested, but there's no close tags left. Abort!\r
+ break 2;\r
+ KTHX\r
+ BTW Skip ahead to next tag start\r
+ I HAS i IZ $lt\r
+ I HAS state IZ self::COLON_STATE_TAGSTART\r
+ KTHX\r
+ break;\r
+ case 1: # self::COLON_STATE_TAG:\r
+ BTW In a <tag>\r
+ switch( $c ) {\r
+ case ">":\r
+ $stack++;\r
+ I HAS state IZ self::COLON_STATE_TEXT\r
+ break;\r
+ case "/":\r
+ BTW Slash may be followed by >?\r
+ I HAS state IZ self::COLON_STATE_TAGSLASH\r
+ break;\r
+ default:\r
+ BTW ignore\r
+ KTHX\r
+ break;\r
+ case 2: # self::COLON_STATE_TAGSTART:\r
+ switch( $c ) {\r
+ case "/":\r
+ I HAS state IZ self::COLON_STATE_CLOSETAG\r
+ break;\r
+ case "!":\r
+ I HAS state IZ self::COLON_STATE_COMMENT\r
+ break;\r
+ case ">":\r
+ BTW Illegal early close? This shouldn't happen D:\r
+ I HAS state IZ self::COLON_STATE_TEXT\r
+ break;\r
+ default:\r
+ I HAS state IZ self::COLON_STATE_TAG\r
+ KTHX\r
+ break;\r
+ case 3: # self::COLON_STATE_CLOSETAG:\r
+ BTW In a </tag>\r
+ IZ $c === ">"\r
+ I HAS stack--\r
+ IZ $stack < 0\r
+ IM ON UR wfDebug DOING __METHOD__.": Invalid input; too many close tags\n"\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ I FOUND MAH false\r
+ KTHX\r
+ I HAS state IZ self::COLON_STATE_TEXT\r
+ KTHX\r
+ break;\r
+ case self::COLON_STATE_TAGSLASH:\r
+ IZ $c === ">"\r
+ BTW Yes, a self-closed tag <blah/>\r
+ I HAS state IZ self::COLON_STATE_TEXT\r
+ NOWAI\r
+ BTW Probably we're jumping the gun, and this is an attribute\r
+ I HAS state IZ self::COLON_STATE_TAG\r
+ KTHX\r
+ break;\r
+ case 5: # self::COLON_STATE_COMMENT:\r
+ IZ $c === "-"\r
+ I HAS state IZ self::COLON_STATE_COMMENTDASH\r
+ KTHX\r
+ break;\r
+ case self::COLON_STATE_COMMENTDASH:\r
+ IZ $c === "-"\r
+ I HAS state IZ self::COLON_STATE_COMMENTDASHDASH\r
+ NOWAI\r
+ I HAS state IZ self::COLON_STATE_COMMENT\r
+ KTHX\r
+ break;\r
+ case self::COLON_STATE_COMMENTDASHDASH:\r
+ IZ $c === ">"\r
+ I HAS state IZ self::COLON_STATE_TEXT\r
+ NOWAI\r
+ I HAS state IZ self::COLON_STATE_COMMENT\r
+ KTHX\r
+ break;\r
+ default:\r
+ throw new MWException( "State machine error in " . __METHOD__ );\r
+ KTHX\r
+ KTHX\r
+ IZ $stack > 0\r
+ IM ON UR wfDebug DOING __METHOD__.": Invalid input; not enough close tags (stack $stack, state $state)\n"\r
+ I FOUND MAH false\r
+ KTHX\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ I FOUND MAH false\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Return value of a magic variable (like PAGENAME)\r
+ NOT WANT \r
+ NOT WANT @private\r
+ WANT\r
+ SO IM LIKE getVariableValue WITH UR $index, $frame=false\r
+ I HAS UR $wgContLang, $wgSitename, $wgServer, $wgServerName ON UR INTERNETS\r
+ I HAS UR $wgScriptPath, $wgStylePath ON UR INTERNETS\r
+\r
+ DO NOT WANT\r
+ NOT WANT Some of these require message or data lookups and can be\r
+ NOT WANT expensive to check many times.\r
+ WANT\r
+ IZ wfRunHooks( 'ParserGetVariableValueVarCache', array( &$this, &$this->mVarCache ) )\r
+ IZ isset( $this->mVarCache[$index] )\r
+ I FOUND MAH $this->mVarCache[$index]\r
+ KTHX\r
+ KTHX\r
+\r
+ I HAS ts IZ wfTimestamp( TS_UNIX, $this->mOptions->getTimestamp() )\r
+ IM ON UR wfRunHooks DOING 'ParserGetVariableValueTs', array( &$this, &$ts )\r
+\r
+ BTW Use the time zone\r
+ I HAS UR $wgLocaltimezone ON UR INTERNETS\r
+ IZ isset( $wgLocaltimezone )\r
+ I HAS oldtz IZ date_default_timezone_get()\r
+ IM ON UR date_default_timezone_set DOING $wgLocaltimezone\r
+ KTHX\r
+\r
+ I HAS localTimestamp IZ date( 'YmdHis', $ts )\r
+ I HAS localMonth IZ date( 'm', $ts )\r
+ I HAS localMonth1 IZ date( 'n', $ts )\r
+ I HAS localMonthName IZ date( 'n', $ts )\r
+ I HAS localDay IZ date( 'j', $ts )\r
+ I HAS localDay2 IZ date( 'd', $ts )\r
+ I HAS localDayOfWeek IZ date( 'w', $ts )\r
+ I HAS localWeek IZ date( 'W', $ts )\r
+ I HAS localYear IZ date( 'Y', $ts )\r
+ I HAS localHour IZ date( 'H', $ts )\r
+ IZ isset( $wgLocaltimezone )\r
+ IM ON UR date_default_timezone_set DOING $oldtz\r
+ KTHX\r
+\r
+ switch ( $index ) {\r
+ case 'currentmonth':\r
+ I HAS value IZ $wgContLang->formatNum( gmdate( 'm', $ts ) )\r
+ break;\r
+ case 'currentmonth1':\r
+ I HAS value IZ $wgContLang->formatNum( gmdate( 'n', $ts ) )\r
+ break;\r
+ case 'currentmonthname':\r
+ I HAS value IZ $wgContLang->getMonthName( gmdate( 'n', $ts ) )\r
+ break;\r
+ case 'currentmonthnamegen':\r
+ I HAS value IZ $wgContLang->getMonthNameGen( gmdate( 'n', $ts ) )\r
+ break;\r
+ case 'currentmonthabbrev':\r
+ I HAS value IZ $wgContLang->getMonthAbbreviation( gmdate( 'n', $ts ) )\r
+ break;\r
+ case 'currentday':\r
+ I HAS value IZ $wgContLang->formatNum( gmdate( 'j', $ts ) )\r
+ break;\r
+ case 'currentday2':\r
+ I HAS value IZ $wgContLang->formatNum( gmdate( 'd', $ts ) )\r
+ break;\r
+ case 'localmonth':\r
+ I HAS value IZ $wgContLang->formatNum( $localMonth )\r
+ break;\r
+ case 'localmonth1':\r
+ I HAS value IZ $wgContLang->formatNum( $localMonth1 )\r
+ break;\r
+ case 'localmonthname':\r
+ I HAS value IZ $wgContLang->getMonthName( $localMonthName )\r
+ break;\r
+ case 'localmonthnamegen':\r
+ I HAS value IZ $wgContLang->getMonthNameGen( $localMonthName )\r
+ break;\r
+ case 'localmonthabbrev':\r
+ I HAS value IZ $wgContLang->getMonthAbbreviation( $localMonthName )\r
+ break;\r
+ case 'localday':\r
+ I HAS value IZ $wgContLang->formatNum( $localDay )\r
+ break;\r
+ case 'localday2':\r
+ I HAS value IZ $wgContLang->formatNum( $localDay2 )\r
+ break;\r
+ case 'pagename':\r
+ I HAS value IZ wfEscapeWikiText( $this->mTitle->getText() )\r
+ break;\r
+ case 'pagenamee':\r
+ I HAS value IZ $this->mTitle->getPartialURL()\r
+ break;\r
+ case 'fullpagename':\r
+ I HAS value IZ wfEscapeWikiText( $this->mTitle->getPrefixedText() )\r
+ break;\r
+ case 'fullpagenamee':\r
+ I HAS value IZ $this->mTitle->getPrefixedURL()\r
+ break;\r
+ case 'subpagename':\r
+ I HAS value IZ wfEscapeWikiText( $this->mTitle->getSubpageText() )\r
+ break;\r
+ case 'subpagenamee':\r
+ I HAS value IZ $this->mTitle->getSubpageUrlForm()\r
+ break;\r
+ case 'basepagename':\r
+ I HAS value IZ wfEscapeWikiText( $this->mTitle->getBaseText() )\r
+ break;\r
+ case 'basepagenamee':\r
+ I HAS value IZ wfUrlEncode( str_replace( ' ', '_', $this->mTitle->getBaseText() ) )\r
+ break;\r
+ case 'talkpagename':\r
+ IZ $this->mTitle->canTalk()\r
+ I HAS talkPage IZ $this->mTitle->getTalkPage()\r
+ I HAS value IZ wfEscapeWikiText( $talkPage->getPrefixedText() )\r
+ NOWAI\r
+ I HAS value IZ ''\r
+ KTHX\r
+ break;\r
+ case 'talkpagenamee':\r
+ IZ $this->mTitle->canTalk()\r
+ I HAS talkPage IZ $this->mTitle->getTalkPage()\r
+ I HAS value IZ $talkPage->getPrefixedUrl()\r
+ NOWAI\r
+ I HAS value IZ ''\r
+ KTHX\r
+ break;\r
+ case 'subjectpagename':\r
+ I HAS subjPage IZ $this->mTitle->getSubjectPage()\r
+ I HAS value IZ wfEscapeWikiText( $subjPage->getPrefixedText() )\r
+ break;\r
+ case 'subjectpagenamee':\r
+ I HAS subjPage IZ $this->mTitle->getSubjectPage()\r
+ I HAS value IZ $subjPage->getPrefixedUrl()\r
+ break;\r
+ case 'revisionid':\r
+ BTW Let the edit saving system know we should parse the page\r
+ BTW *after* a revision ID has been assigned.\r
+ IM ON UR SPECIAL mOutput->setFlag DOING 'vary-revision'\r
+ IM ON UR wfDebug DOING __METHOD__ . ": {{REVISIONID}} used, setting vary-revision...\n"\r
+ I HAS value IZ $this->mRevisionId\r
+ break;\r
+ case 'revisionday':\r
+ BTW Let the edit saving system know we should parse the page\r
+ BTW *after* a revision ID has been assigned. This is for null edits.\r
+ IM ON UR SPECIAL mOutput->setFlag DOING 'vary-revision'\r
+ IM ON UR wfDebug DOING __METHOD__ . ": {{REVISIONDAY}} used, setting vary-revision...\n"\r
+ I HAS value IZ intval( substr( $this->getRevisionTimestamp(), 6, 2 ) )\r
+ break;\r
+ case 'revisionday2':\r
+ BTW Let the edit saving system know we should parse the page\r
+ BTW *after* a revision ID has been assigned. This is for null edits.\r
+ IM ON UR SPECIAL mOutput->setFlag DOING 'vary-revision'\r
+ IM ON UR wfDebug DOING __METHOD__ . ": {{REVISIONDAY2}} used, setting vary-revision...\n"\r
+ I HAS value IZ substr( $this->getRevisionTimestamp(), 6, 2 )\r
+ break;\r
+ case 'revisionmonth':\r
+ BTW Let the edit saving system know we should parse the page\r
+ BTW *after* a revision ID has been assigned. This is for null edits.\r
+ IM ON UR SPECIAL mOutput->setFlag DOING 'vary-revision'\r
+ IM ON UR wfDebug DOING __METHOD__ . ": {{REVISIONMONTH}} used, setting vary-revision...\n"\r
+ I HAS value IZ intval( substr( $this->getRevisionTimestamp(), 4, 2 ) )\r
+ break;\r
+ case 'revisionyear':\r
+ BTW Let the edit saving system know we should parse the page\r
+ BTW *after* a revision ID has been assigned. This is for null edits.\r
+ IM ON UR SPECIAL mOutput->setFlag DOING 'vary-revision'\r
+ IM ON UR wfDebug DOING __METHOD__ . ": {{REVISIONYEAR}} used, setting vary-revision...\n"\r
+ I HAS value IZ substr( $this->getRevisionTimestamp(), 0, 4 )\r
+ break;\r
+ case 'revisiontimestamp':\r
+ BTW Let the edit saving system know we should parse the page\r
+ BTW *after* a revision ID has been assigned. This is for null edits.\r
+ IM ON UR SPECIAL mOutput->setFlag DOING 'vary-revision'\r
+ IM ON UR wfDebug DOING __METHOD__ . ": {{REVISIONTIMESTAMP}} used, setting vary-revision...\n"\r
+ I HAS value IZ $this->getRevisionTimestamp()\r
+ break;\r
+ case 'revisionuser':\r
+ BTW Let the edit saving system know we should parse the page\r
+ BTW *after* a revision ID has been assigned. This is for null edits.\r
+ IM ON UR SPECIAL mOutput->setFlag DOING 'vary-revision'\r
+ IM ON UR wfDebug DOING __METHOD__ . ": {{REVISIONUSER}} used, setting vary-revision...\n"\r
+ I HAS value IZ $this->getRevisionUser()\r
+ break;\r
+ case 'namespace':\r
+ I HAS value IZ str_replace( '_',' ',$wgContLang->getNsText( $this->mTitle->getNamespace() ) )\r
+ break;\r
+ case 'namespacee':\r
+ I HAS value IZ wfUrlencode( $wgContLang->getNsText( $this->mTitle->getNamespace() ) )\r
+ break;\r
+ case 'talkspace':\r
+ I HAS value IZ $this->mTitle->canTalk() ? str_replace( '_',' ',$this->mTitle->getTalkNsText() ) : ''\r
+ break;\r
+ case 'talkspacee':\r
+ I HAS value IZ $this->mTitle->canTalk() ? wfUrlencode( $this->mTitle->getTalkNsText() ) : ''\r
+ break;\r
+ case 'subjectspace':\r
+ I HAS value IZ $this->mTitle->getSubjectNsText()\r
+ break;\r
+ case 'subjectspacee':\r
+ I HAS value IZ ( wfUrlencode( $this->mTitle->getSubjectNsText() ) )\r
+ break;\r
+ case 'currentdayname':\r
+ I HAS value IZ $wgContLang->getWeekdayName( gmdate( 'w', $ts ) + 1 )\r
+ break;\r
+ case 'currentyear':\r
+ I HAS value IZ $wgContLang->formatNum( gmdate( 'Y', $ts ), true )\r
+ break;\r
+ case 'currenttime':\r
+ I HAS value IZ $wgContLang->time( wfTimestamp( TS_MW, $ts ), false, false )\r
+ break;\r
+ case 'currenthour':\r
+ I HAS value IZ $wgContLang->formatNum( gmdate( 'H', $ts ), true )\r
+ break;\r
+ case 'currentweek':\r
+ BTW @bug 4594 PHP5 has it zero padded, PHP4 does not, cast to\r
+ BTW int to remove the padding\r
+ I HAS value IZ $wgContLang->formatNum( (int)gmdate( 'W', $ts ) )\r
+ break;\r
+ case 'currentdow':\r
+ I HAS value IZ $wgContLang->formatNum( gmdate( 'w', $ts ) )\r
+ break;\r
+ case 'localdayname':\r
+ I HAS value IZ $wgContLang->getWeekdayName( $localDayOfWeek + 1 )\r
+ break;\r
+ case 'localyear':\r
+ I HAS value IZ $wgContLang->formatNum( $localYear, true )\r
+ break;\r
+ case 'localtime':\r
+ I HAS value IZ $wgContLang->time( $localTimestamp, false, false )\r
+ break;\r
+ case 'localhour':\r
+ I HAS value IZ $wgContLang->formatNum( $localHour, true )\r
+ break;\r
+ case 'localweek':\r
+ BTW @bug 4594 PHP5 has it zero padded, PHP4 does not, cast to\r
+ BTW int to remove the padding\r
+ I HAS value IZ $wgContLang->formatNum( (int)$localWeek )\r
+ break;\r
+ case 'localdow':\r
+ I HAS value IZ $wgContLang->formatNum( $localDayOfWeek )\r
+ break;\r
+ case 'numberofarticles':\r
+ I HAS value IZ $wgContLang->formatNum( SiteStats::articles() )\r
+ break;\r
+ case 'numberoffiles':\r
+ I HAS value IZ $wgContLang->formatNum( SiteStats::images() )\r
+ break;\r
+ case 'numberofusers':\r
+ I HAS value IZ $wgContLang->formatNum( SiteStats::users() )\r
+ break;\r
+ case 'numberofactiveusers':\r
+ I HAS value IZ $wgContLang->formatNum( SiteStats::activeUsers() )\r
+ break;\r
+ case 'numberofpages':\r
+ I HAS value IZ $wgContLang->formatNum( SiteStats::pages() )\r
+ break;\r
+ case 'numberofadmins':\r
+ I HAS value IZ $wgContLang->formatNum( SiteStats::numberingroup( 'sysop' ) )\r
+ break;\r
+ case 'numberofedits':\r
+ I HAS value IZ $wgContLang->formatNum( SiteStats::edits() )\r
+ break;\r
+ case 'numberofviews':\r
+ I HAS value IZ $wgContLang->formatNum( SiteStats::views() )\r
+ break;\r
+ case 'currenttimestamp':\r
+ I HAS value IZ wfTimestamp( TS_MW, $ts )\r
+ break;\r
+ case 'localtimestamp':\r
+ I HAS value IZ $localTimestamp\r
+ break;\r
+ case 'currentversion':\r
+ I HAS value IZ SpecialVersion::getVersion()\r
+ break;\r
+ case 'sitename':\r
+ I FOUND MAH $wgSitename\r
+ case 'server':\r
+ I FOUND MAH $wgServer\r
+ case 'servername':\r
+ I FOUND MAH $wgServerName\r
+ case 'scriptpath':\r
+ I FOUND MAH $wgScriptPath\r
+ case 'stylepath':\r
+ I FOUND MAH $wgStylePath\r
+ case 'directionmark':\r
+ I FOUND MAH $wgContLang->getDirMark()\r
+ case 'contentlanguage':\r
+ I HAS UR $wgContLanguageCode ON UR INTERNETS\r
+ I FOUND MAH $wgContLanguageCode\r
+ default:\r
+ I HAS ret\r
+ IZ wfRunHooks( 'ParserGetVariableValueSwitch', array( &$this, &$this->mVarCache, &$index, &$ret, &$frame ) )\r
+ I FOUND MAH $ret\r
+ NOWAI\r
+ I FOUND MAH null\r
+ KTHX\r
+ KTHX\r
+\r
+ if ( $index )\r
+ $this->mVarCache[$index] = $value;\r
+\r
+ I FOUND MAH $value\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT initialise the magic variables (like CURRENTMONTHNAME) and substitution modifiers \r
+ NOT WANT \r
+ NOT WANT @private\r
+ WANT\r
+ SO IM LIKE initialiseVariables\r
+ IM ON UR wfProfileIn DOING __METHOD__\r
+ I HAS variableIDs IZ MagicWord::getVariableIDs()\r
+ I HAS substIDs IZ MagicWord::getSubstIDs()\r
+\r
+ UR SPECIAL mVariables IZ new MagicWordArray( $variableIDs );\r
+ UR SPECIAL mSubstWords IZ new MagicWordArray( $substIDs );\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Preprocess some wikitext and return the document tree.\r
+ NOT WANT This is the ghost of replace_variables().\r
+ NOT WANT \r
+ NOT WANT @param string $text The text to parse\r
+ NOT WANT @param integer flags Bitwise combination of:\r
+ NOT WANT self::PTD_FOR_INCLUSION Handle <noinclude>/<includeonly> as if the text is being\r
+ NOT WANT included. Default is to assume a direct page view.\r
+ NOT WANT \r
+ NOT WANT The generated DOM tree must depend only on the input text and the flags.\r
+ NOT WANT The DOM tree must be the same in OT_HTML and OT_WIKI mode, to avoid a regression of bug 4899.\r
+ NOT WANT \r
+ NOT WANT Any flag added to the $flags parameter here, or any other parameter liable to cause a\r
+ NOT WANT change in the DOM tree for a given text, must be passed through the section identifier\r
+ NOT WANT in the section edit link and thus back to extractSections().\r
+ NOT WANT \r
+ NOT WANT The output of this function is currently only cached in process memory, but a persistent\r
+ NOT WANT cache may be implemented at a later date which takes further advantage of these strict\r
+ NOT WANT dependency requirements.\r
+ NOT WANT \r
+ NOT WANT @private\r
+ WANT\r
+ SO IM LIKE preprocessToDom WITH UR $text, $flags = 0\r
+ I HAS dom IZ $this->getPreprocessor()->preprocessToObj( $text, $flags )\r
+ I FOUND MAH $dom\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Return a three-element array: leading whitespace, string contents, trailing whitespace\r
+ WANT\r
+ SO IM ALWAYS LIKE splitWhitespace WITH UR $s\r
+ I HAS ltrimmed IZ ltrim( $s )\r
+ I HAS w1 IZ substr( $s, 0, strlen( $s ) - strlen( $ltrimmed ) )\r
+ I HAS trimmed IZ rtrim( $ltrimmed )\r
+ I HAS diff IZ strlen( $ltrimmed ) - strlen( $trimmed )\r
+ IZ $diff > 0\r
+ I HAS w2 IZ substr( $ltrimmed, -$diff )\r
+ NOWAI\r
+ I HAS w2 IZ ''\r
+ KTHX\r
+ I FOUND MAH array( $w1, $trimmed, $w2 )\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Replace magic variables, templates, and template arguments\r
+ NOT WANT with the appropriate text. Templates are substituted recursively,\r
+ NOT WANT taking care to avoid infinite loops.\r
+ NOT WANT \r
+ NOT WANT Note that the substitution depends on value of $mOutputType:\r
+ NOT WANT self::OT_WIKI: only {{subst:}} templates\r
+ NOT WANT self::OT_PREPROCESS: templates but not extension tags\r
+ NOT WANT self::OT_HTML: all templates and extension tags\r
+ NOT WANT \r
+ NOT WANT @param string $tex The text to transform\r
+ NOT WANT @param PPFrame $frame Object describing the arguments passed to the template.\r
+ NOT WANT Arguments may also be provided as an associative array, as was the usual case before MW1.12.\r
+ NOT WANT Providing arguments this way may be useful for extensions wishing to perform variable replacement explicitly.\r
+ NOT WANT @param bool $argsOnly Only do argument (triple-brace) expansion, not double-brace expansion\r
+ NOT WANT @private\r
+ WANT\r
+ SO IM LIKE replaceVariables WITH UR $text, $frame = false, $argsOnly = false\r
+ BTW Is there any text? Also, Prevent too big inclusions!\r
+ IZ strlen( $text ) < 1 || strlen( $text ) > $this->mOptions->getMaxIncludeSize()\r
+ I FOUND MAH $text\r
+ KTHX\r
+ IM ON UR wfProfileIn DOING __METHOD__\r
+\r
+ IZ $frame === false\r
+ I HAS frame IZ $this->getPreprocessor()->newFrame()\r
+ ORLY !( $frame instanceof PPFrame )\r
+ IM ON UR wfDebug DOING __METHOD__." called using plain parameters instead of a PPFrame instance. Creating custom frame.\n"\r
+ I HAS frame IZ $this->getPreprocessor()->newCustomFrame( $frame )\r
+ KTHX\r
+\r
+ I HAS dom IZ $this->preprocessToDom( $text )\r
+ I HAS flags IZ $argsOnly ? PPFrame::NO_TEMPLATES : 0\r
+ I HAS text IZ $frame->expand( $dom, $flags )\r
+\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ I FOUND MAH $text\r
+ KTHX\r
+\r
+ BTW Clean up argument array - refactored in 1.9 so parserfunctions can use it, too.\r
+ SO IM ALWAYS LIKE createAssocArgs WITH UR $args\r
+ I HAS assocArgs IZ EMPTY\r
+ I HAS index IZ 1\r
+ IM IN UR args ITZA arg\r
+ I HAS eqpos IZ strpos( $arg, '=' )\r
+ IZ $eqpos === false\r
+ $assocArgs[$index++] = $arg;\r
+ NOWAI\r
+ I HAS name IZ trim( substr( $arg, 0, $eqpos ) )\r
+ I HAS value IZ trim( substr( $arg, $eqpos+1 ) )\r
+ IZ $value === false\r
+ I HAS value IZ ''\r
+ KTHX\r
+ IZ $name !== false\r
+ $assocArgs[$name] = $value;\r
+ KTHX\r
+ KTHX\r
+ KTHX\r
+\r
+ I FOUND MAH $assocArgs\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Warn the user when a parser limitation is reached\r
+ NOT WANT Will warn at most once the user per limitation type\r
+ NOT WANT \r
+ NOT WANT @param string $limitationType, should be one of:\r
+ NOT WANT 'expensive-parserfunction' (corresponding messages: \r
+ NOT WANT 'expensive-parserfunction-warning', \r
+ NOT WANT 'expensive-parserfunction-category')\r
+ NOT WANT 'post-expand-template-argument' (corresponding messages: \r
+ NOT WANT 'post-expand-template-argument-warning', \r
+ NOT WANT 'post-expand-template-argument-category')\r
+ NOT WANT 'post-expand-template-inclusion' (corresponding messages: \r
+ NOT WANT 'post-expand-template-inclusion-warning', \r
+ NOT WANT 'post-expand-template-inclusion-category')\r
+ NOT WANT @params int $current, $max When an explicit limit has been\r
+ NOT WANT exceeded, provide the values (optional)\r
+ WANT\r
+ function limitationWarn( $limitationType, $current=null, $max=null) {\r
+ BTW does no harm if $current and $max are present but are unnecessary for the message\r
+ I HAS warning IZ wfMsgExt( "$limitationType-warning", array( 'parsemag', 'escape' ), $current, $max )\r
+ IM ON UR SPECIAL mOutput->addWarning DOING $warning\r
+ IM ON UR SPECIAL addTrackingCategory DOING "$limitationType-category"\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Return the text of a template, after recursively\r
+ NOT WANT replacing any variables or templates within the template.\r
+ NOT WANT \r
+ NOT WANT @param array $piece The parts of the template\r
+ NOT WANT $piece['title']: the title, i.e. the part before the |\r
+ NOT WANT $piece['parts']: the parameter array\r
+ NOT WANT $piece['lineStart']: whether the brace was at the start of a line\r
+ NOT WANT @param PPFrame The current frame, contains template arguments\r
+ NOT WANT @return string the text of the template\r
+ NOT WANT @private\r
+ WANT\r
+ SO IM LIKE braceSubstitution WITH UR $piece, $frame\r
+ I HAS UR $wgContLang, $wgNonincludableNamespaces ON UR INTERNETS\r
+ IM ON UR wfProfileIn DOING __METHOD__\r
+ IM ON UR wfProfileIn DOING __METHOD__.'-setup'\r
+\r
+ BTW Flags\r
+ I HAS found IZ false # $text has been filled\r
+ I HAS nowiki IZ false # wiki markup in $text should be escaped\r
+ I HAS isHTML IZ false # $text is HTML, armour it against wikitext transformation\r
+ I HAS forceRawInterwiki IZ false # Force interwiki transclusion to be done in raw mode not rendered\r
+ I HAS isChildObj IZ false # $text is a DOM node needing expansion in a child frame\r
+ I HAS isLocalObj IZ false # $text is a DOM node needing expansion in the current frame\r
+\r
+ BTW Title object, where $text came from\r
+ I HAS title\r
+\r
+ BTW $part1 is the bit before the first |, and must contain only title characters.\r
+ BTW Various prefixes will be stripped from it later.\r
+ I HAS titleWithSpaces IZ $frame->expand( $piece['title'] )\r
+ I HAS part1 IZ trim( $titleWithSpaces )\r
+ I HAS titleText IZ false\r
+\r
+ BTW Original title text preserved for various purposes\r
+ I HAS originalTitle IZ $part1\r
+\r
+ BTW $args is a list of argument nodes, starting from index 0, not including $part1\r
+ I HAS args IZ ( null == $piece['parts'] ) ? array() : $piece['parts']\r
+ IM ON UR wfProfileOut DOING __METHOD__.'-setup'\r
+\r
+ BTW SUBST\r
+ IM ON UR wfProfileIn DOING __METHOD__.'-modifiers'\r
+ IZ !$found\r
+\r
+ I HAS substMatch IZ $this->mSubstWords->matchStartAndRemove( $part1 )\r
+\r
+ BTW Possibilities for substMatch: "subst", "safesubst" or FALSE\r
+ BTW Decide whether to expand template or keep wikitext as-is.\r
+ IZ $this->ot['wiki']\r
+ IZ $substMatch === false\r
+ I HAS literal IZ true # literal when in PST with no prefix\r
+ NOWAI\r
+ I HAS literal IZ false # expand when in PST with subst: or safesubst:\r
+ KTHX\r
+ NOWAI\r
+ IZ $substMatch == 'subst'\r
+ I HAS literal IZ true # literal when not in PST with plain subst:\r
+ NOWAI\r
+ I HAS literal IZ false # expand when not in PST with safesubst: or no prefix\r
+ KTHX\r
+ KTHX\r
+ IZ $literal\r
+ I HAS text IZ $frame->virtualBracketedImplode( '{{', '|', '}}', $titleWithSpaces, $args )\r
+ I HAS isLocalObj IZ true\r
+ I HAS found IZ true\r
+ KTHX\r
+ KTHX\r
+\r
+ BTW Variables\r
+ IZ !$found && $args->getLength() == 0\r
+ I HAS id IZ $this->mVariables->matchStartToEnd( $part1 )\r
+ IZ $id !== false\r
+ I HAS text IZ $this->getVariableValue( $id, $frame )\r
+ IZ MagicWord::getCacheTTL( $id ) > -1\r
+ UR SPECIAL mOutput->mContainsOldMagic IZ true;\r
+ KTHX\r
+ I HAS found IZ true\r
+ KTHX\r
+ KTHX\r
+\r
+ BTW MSG, MSGNW and RAW\r
+ IZ !$found\r
+ BTW Check for MSGNW:\r
+ I HAS mwMsgnw IZ MagicWord::get( 'msgnw' )\r
+ IZ $mwMsgnw->matchStartAndRemove( $part1 )\r
+ I HAS nowiki IZ true\r
+ NOWAI\r
+ BTW Remove obsolete MSG:\r
+ I HAS mwMsg IZ MagicWord::get( 'msg' )\r
+ $mwMsg->matchStartAndRemove( $part1 );\r
+ KTHX\r
+\r
+ BTW Check for RAW:\r
+ I HAS mwRaw IZ MagicWord::get( 'raw' )\r
+ IZ $mwRaw->matchStartAndRemove( $part1 )\r
+ I HAS forceRawInterwiki IZ true\r
+ KTHX\r
+ KTHX\r
+ IM ON UR wfProfileOut DOING __METHOD__.'-modifiers'\r
+\r
+ BTW Parser functions\r
+ IZ !$found\r
+ IM ON UR wfProfileIn DOING __METHOD__ . '-pfunc'\r
+\r
+ I HAS colonPos IZ strpos( $part1, ':' )\r
+ IZ $colonPos !== false\r
+ BTW Case sensitive functions\r
+ I HAS function IZ substr( $part1, 0, $colonPos )\r
+ IZ isset( $this->mFunctionSynonyms[1][$function] )\r
+ I HAS function IZ $this->mFunctionSynonyms[1][$function]\r
+ NOWAI\r
+ BTW Case insensitive functions\r
+ I HAS function IZ $wgContLang->lc( $function )\r
+ IZ isset( $this->mFunctionSynonyms[0][$function] )\r
+ I HAS function IZ $this->mFunctionSynonyms[0][$function]\r
+ NOWAI\r
+ I HAS function IZ false\r
+ KTHX\r
+ KTHX\r
+ IZ $function\r
+ list( $callback, $flags ) = $this->mFunctionHooks[$function];\r
+ I HAS initialArgs IZ BUCKET &$this );\r
+ I HAS funcArgs IZ BUCKET trim( substr( $part1, $colonPos + 1 ) ) );\r
+ IZ $flags & SFH_OBJECT_ARGS\r
+ BTW Add a frame parameter, and pass the arguments as an array\r
+ I HAS allArgs IZ $initialArgs\r
+ $allArgs[] = $frame;\r
+ for ( $i = 0; $i < $args->getLength(); $i++ ) {\r
+ $funcArgs[] = $args->item( $i );\r
+ KTHX\r
+ $allArgs[] = $funcArgs;\r
+ NOWAI\r
+ BTW Convert arguments to plain text\r
+ for ( $i = 0; $i < $args->getLength(); $i++ ) {\r
+ $funcArgs[] = trim( $frame->expand( $args->item( $i ) ) );\r
+ KTHX\r
+ I HAS allArgs IZ array_merge( $initialArgs, $funcArgs )\r
+ KTHX\r
+\r
+ BTW Workaround for PHP bug 35229 and similar\r
+ IZ !is_callable( $callback )\r
+ IM ON UR wfProfileOut DOING __METHOD__ . '-pfunc'\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ throw new MWException( "Tag hook for $function is not callable\n" );\r
+ KTHX\r
+ I HAS result IZ call_user_func_array( $callback, $allArgs )\r
+ I HAS found IZ true\r
+ I HAS noparse IZ true\r
+ I HAS preprocessFlags IZ 0\r
+\r
+ IZ is_array( $result )\r
+ IZ isset( $result[0] )\r
+ I HAS text IZ $result[0]\r
+ IM ON UR unset DOING $result[0]\r
+ KTHX\r
+\r
+ BTW Extract flags into the local scope\r
+ BTW This allows callers to set flags such as nowiki, found, etc.\r
+ IM ON UR extract DOING $result\r
+ NOWAI\r
+ I HAS text IZ $result\r
+ KTHX\r
+ IZ !$noparse\r
+ I HAS text IZ $this->preprocessToDom( $text, $preprocessFlags )\r
+ I HAS isChildObj IZ true\r
+ KTHX\r
+ KTHX\r
+ KTHX\r
+ IM ON UR wfProfileOut DOING __METHOD__ . '-pfunc'\r
+ KTHX\r
+\r
+ BTW Finish mangling title and then check for loops.\r
+ BTW Set $title to a Title object and $titleText to the PDBK\r
+ IZ !$found\r
+ I HAS ns IZ NS_TEMPLATE\r
+ BTW Split the title into page and subpage\r
+ I HAS subpage IZ ''\r
+ I HAS part1 IZ $this->maybeDoSubpageLink( $part1, $subpage )\r
+ IZ $subpage !== ''\r
+ I HAS ns IZ $this->mTitle->getNamespace()\r
+ KTHX\r
+ I HAS title IZ Title::newFromText( $part1, $ns )\r
+ IZ $title\r
+ I HAS titleText IZ $title->getPrefixedText()\r
+ BTW Check for language variants if the template is not found\r
+ IZ $wgContLang->hasVariants() && $title->getArticleID() == 0\r
+ $wgContLang->findVariantLink( $part1, $title, true );\r
+ KTHX\r
+ BTW Do recursion depth check\r
+ I HAS limit IZ $this->mOptions->getMaxTemplateDepth()\r
+ IZ $frame->depth >= $limit\r
+ I HAS found IZ true\r
+ text IZ '<span class="error">' \r
+ . wfMsgForContent( 'parser-template-recursion-depth-warning', $limit ) \r
+ . '</span>';\r
+ KTHX\r
+ KTHX\r
+ KTHX\r
+\r
+ BTW Load from database\r
+ IZ !$found && $title\r
+ IM ON UR wfProfileIn DOING __METHOD__ . '-loadtpl'\r
+ IZ !$title->isExternal()\r
+ if ( $title->getNamespace() == NS_SPECIAL \r
+ && $this->mOptions->getAllowSpecialInclusion() \r
+ && $this->ot['html'] ) \r
+ {\r
+ I HAS text IZ SpecialPage::capturePath( $title )\r
+ IZ is_string( $text )\r
+ I HAS found IZ true\r
+ I HAS isHTML IZ true\r
+ IM ON UR SPECIAL disableCache\r
+ KTHX\r
+ ORLY $wgNonincludableNamespaces && in_array( $title->getNamespace(), $wgNonincludableNamespaces )\r
+ I HAS found IZ false # access denied\r
+ IM ON UR wfDebug DOING __METHOD__.": template inclusion denied for " . $title->getPrefixedDBkey()\r
+ NOWAI\r
+ IM ON UR list DOING $text, $title ) = $this->getTemplateDom( $title\r
+ IZ $text !== false\r
+ I HAS found IZ true\r
+ I HAS isChildObj IZ true\r
+ KTHX\r
+ KTHX\r
+\r
+ BTW If the title is valid but undisplayable, make a link to it\r
+ IZ !$found && ( $this->ot['html'] || $this->ot['pre'] )\r
+ I HAS text IZ "[[:$titleText]]"\r
+ I HAS found IZ true\r
+ KTHX\r
+ ORLY $title->isTrans()\r
+ BTW Interwiki transclusion\r
+ IZ $this->ot['html'] && !$forceRawInterwiki\r
+ I HAS text IZ $this->interwikiTransclude( $title, 'render' )\r
+ I HAS isHTML IZ true\r
+ NOWAI\r
+ I HAS text IZ $this->interwikiTransclude( $title, 'raw' )\r
+ BTW Preprocess it like a template\r
+ I HAS text IZ $this->preprocessToDom( $text, self::PTD_FOR_INCLUSION )\r
+ I HAS isChildObj IZ true\r
+ KTHX\r
+ I HAS found IZ true\r
+ KTHX\r
+\r
+ BTW Do infinite loop check\r
+ BTW This has to be done after redirect resolution to avoid infinite loops via redirects\r
+ IZ !$frame->loopCheck( $title )\r
+ I HAS found IZ true\r
+ I HAS text IZ '<span class="error">' . wfMsgForContent( 'parser-template-loop-warning', $titleText ) . '</span>'\r
+ IM ON UR wfDebug DOING __METHOD__.": template loop broken at '$titleText'\n"\r
+ KTHX\r
+ IM ON UR wfProfileOut DOING __METHOD__ . '-loadtpl'\r
+ KTHX\r
+\r
+ BTW If we haven't found text to substitute by now, we're done\r
+ BTW Recover the source wikitext and return it\r
+ IZ !$found\r
+ I HAS text IZ $frame->virtualBracketedImplode( '{{', '|', '}}', $titleWithSpaces, $args )\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ I FOUND MAH array( 'object' => $text )\r
+ KTHX\r
+\r
+ BTW Expand DOM-style return values in a child frame\r
+ IZ $isChildObj\r
+ BTW Clean up argument array\r
+ I HAS newFrame IZ $frame->newChild( $args, $title )\r
+\r
+ IZ $nowiki\r
+ I HAS text IZ $newFrame->expand( $text, PPFrame::RECOVER_ORIG )\r
+ ORLY $titleText !== false && $newFrame->isEmpty()\r
+ BTW Expansion is eligible for the empty-frame cache\r
+ IZ isset( $this->mTplExpandCache[$titleText] )\r
+ I HAS text IZ $this->mTplExpandCache[$titleText]\r
+ NOWAI\r
+ I HAS text IZ $newFrame->expand( $text )\r
+ $this->mTplExpandCache[$titleText] = $text;\r
+ KTHX\r
+ NOWAI\r
+ BTW Uncached expansion\r
+ I HAS text IZ $newFrame->expand( $text )\r
+ KTHX\r
+ KTHX\r
+ IZ $isLocalObj && $nowiki\r
+ I HAS text IZ $frame->expand( $text, PPFrame::RECOVER_ORIG )\r
+ I HAS isLocalObj IZ false\r
+ KTHX\r
+\r
+ BTW Replace raw HTML by a placeholder\r
+ BTW Add a blank line preceding, to prevent it from mucking up\r
+ BTW immediately preceding headings\r
+ IZ $isHTML\r
+ I HAS text IZ "\n\n" . $this->insertStripItem( $text )\r
+ ORLY $nowiki && ( $this->ot['html'] || $this->ot['pre'] )\r
+ BTW Escape nowiki-style return values\r
+ I HAS text IZ wfEscapeWikiText( $text )\r
+ KTHX elseif ( is_string( $text )\r
+ && !$piece['lineStart'] \r
+ && preg_match( '/^(?:{\\||:|;|#|\*)/', $text ) )\r
+ {\r
+ BTW Bug 529: if the template begins with a table or block-level\r
+ BTW element, it should be treated as beginning a new line.\r
+ BTW This behaviour is somewhat controversial.\r
+ I HAS text IZ "\n" . $text\r
+ KTHX\r
+\r
+ IZ is_string( $text ) && !$this->incrementIncludeSize( 'post-expand', strlen( $text ) )\r
+ BTW Error, oversize inclusion\r
+ text IZ "[[$originalTitle]]" .\r
+ IM ON UR SPECIAL insertStripItem DOING '<!-- WARNING: template omitted, post-expand include size too large -->'\r
+ IM ON UR SPECIAL limitationWarn DOING 'post-expand-template-inclusion'\r
+ KTHX\r
+\r
+ IZ $isLocalObj\r
+ I HAS ret IZ BUCKET 'object' => $text );\r
+ NOWAI\r
+ I HAS ret IZ BUCKET 'text' => $text );\r
+ KTHX\r
+\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ I FOUND MAH $ret\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Get the semi-parsed DOM representation of a template with a given title,\r
+ NOT WANT and its redirect destination title. Cached.\r
+ WANT\r
+ SO IM LIKE getTemplateDom WITH UR $title\r
+ I HAS cacheTitle IZ $title\r
+ I HAS titleText IZ $title->getPrefixedDBkey()\r
+\r
+ IZ isset( $this->mTplRedirCache[$titleText] )\r
+ list( $ns, $dbk ) = $this->mTplRedirCache[$titleText];\r
+ I HAS title IZ Title::makeTitle( $ns, $dbk )\r
+ I HAS titleText IZ $title->getPrefixedDBkey()\r
+ KTHX\r
+ IZ isset( $this->mTplDomCache[$titleText] )\r
+ I FOUND MAH array( $this->mTplDomCache[$titleText], $title )\r
+ KTHX\r
+\r
+ BTW Cache miss, go to the database\r
+ IM ON UR list DOING $text, $title ) = $this->fetchTemplateAndTitle( $title\r
+\r
+ IZ $text === false\r
+ $this->mTplDomCache[$titleText] = false;\r
+ I FOUND MAH array( false, $title )\r
+ KTHX\r
+\r
+ I HAS dom IZ $this->preprocessToDom( $text, self::PTD_FOR_INCLUSION )\r
+ $this->mTplDomCache[ $titleText ] = $dom;\r
+\r
+ IZ !$title->equals( $cacheTitle )\r
+ $this->mTplRedirCache[$cacheTitle->getPrefixedDBkey()] =\r
+ IM ON UR array DOING $title->getNamespace(),$cdb = $title->getDBkey()\r
+ KTHX\r
+\r
+ I FOUND MAH array( $dom, $title )\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Fetch the unparsed text of a template and register a reference to it.\r
+ WANT\r
+ SO IM LIKE fetchTemplateAndTitle WITH UR $title\r
+ I HAS templateCb IZ $this->mOptions->getTemplateCallback()\r
+ I HAS stuff IZ call_user_func( $templateCb, $title, $this )\r
+ I HAS text IZ $stuff['text']\r
+ I HAS finalTitle IZ isset( $stuff['finalTitle'] ) ? $stuff['finalTitle'] : $title\r
+ IZ isset( $stuff['deps'] )\r
+ foreach ( $stuff['deps'] as $dep ) {\r
+ IM ON UR SPECIAL mOutput->addTemplate DOING $dep['title'], $dep['page_id'], $dep['rev_id']\r
+ KTHX\r
+ KTHX\r
+ I FOUND MAH array( $text, $finalTitle )\r
+ KTHX\r
+\r
+ SO IM LIKE fetchTemplate WITH UR $title\r
+ I HAS rv IZ $this->fetchTemplateAndTitle( $title )\r
+ I FOUND MAH $rv[0]\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Static function to get a template\r
+ NOT WANT Can be overridden via ParserOptions::setTemplateCallback().\r
+ WANT\r
+ SO IM ALWAYS LIKE statelessFetchTemplate WITH UR $title, $parser=false\r
+ I HAS text IZ $skip = false\r
+ I HAS finalTitle IZ $title\r
+ I HAS deps IZ EMPTY\r
+\r
+ BTW Loop to fetch the article, with up to 1 redirect\r
+ for ( $i = 0; $i < 2 && is_object( $title ); $i++ ) {\r
+ BTW Give extensions a chance to select the revision instead\r
+ I HAS id IZ false # Assume current\r
+ IM ON UR wfRunHooks DOING 'BeforeParserFetchTemplateAndtitle', array( $parser, &$title, &$skip, &$id )\r
+\r
+ IZ $skip\r
+ I HAS text IZ false\r
+ $deps[] = array(\r
+ 'title' => $title,\r
+ 'page_id' => $title->getArticleID(),\r
+ 'rev_id' => null );\r
+ break;\r
+ KTHX\r
+ I HAS rev IZ $id ? Revision::newFromId( $id ) : Revision::newFromTitle( $title )\r
+ I HAS rev_id IZ $rev ? $rev->getId() : 0\r
+ BTW If there is no current revision, there is no page\r
+ IZ $id === false && !$rev\r
+ I HAS linkCache IZ LinkCache::singleton()\r
+ $linkCache->addBadLinkObj( $title );\r
+ KTHX\r
+\r
+ $deps[] = array(\r
+ 'title' => $title,\r
+ 'page_id' => $title->getArticleID(),\r
+ 'rev_id' => $rev_id );\r
+\r
+ IZ $rev\r
+ I HAS text IZ $rev->getText()\r
+ ORLY $title->getNamespace() == NS_MEDIAWIKI\r
+ I HAS UR $wgContLang ON UR INTERNETS\r
+ I HAS message IZ $wgContLang->lcfirst( $title->getText() )\r
+ I HAS text IZ wfMsgForContentNoTrans( $message )\r
+ IZ wfEmptyMsg( $message, $text )\r
+ I HAS text IZ false\r
+ break;\r
+ KTHX\r
+ NOWAI\r
+ break;\r
+ KTHX\r
+ IZ $text === false\r
+ break;\r
+ KTHX\r
+ BTW Redirect?\r
+ I HAS finalTitle IZ $title\r
+ I HAS title IZ Title::newFromRedirect( $text )\r
+ KTHX\r
+ return array(\r
+ 'text' => $text,\r
+ 'finalTitle' => $finalTitle,\r
+ 'deps' => $deps );\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Transclude an interwiki link.\r
+ WANT\r
+ SO IM LIKE interwikiTransclude WITH UR $title, $action\r
+ I HAS UR $wgEnableScaryTranscluding ON UR INTERNETS\r
+\r
+ IZ !$wgEnableScaryTranscluding\r
+ I FOUND MAH wfMsg('scarytranscludedisabled')\r
+ KTHX\r
+\r
+ I HAS url IZ $title->getFullUrl( "action=$action" )\r
+\r
+ IZ strlen( $url ) > 255\r
+ I FOUND MAH wfMsg( 'scarytranscludetoolong' )\r
+ KTHX\r
+ I FOUND MAH $this->fetchScaryTemplateMaybeFromCache( $url )\r
+ KTHX\r
+\r
+ SO IM LIKE fetchScaryTemplateMaybeFromCache WITH UR $url\r
+ I HAS UR $wgTranscludeCacheExpiry ON UR INTERNETS\r
+ I HAS dbr IZ wfGetDB( DB_SLAVE )\r
+ I HAS tsCond IZ $dbr->timestamp( time() - $wgTranscludeCacheExpiry )\r
+ obj IZ $dbr->selectRow( 'transcache', array('tc_time', 'tc_contents' ),\r
+ IM ON UR array DOING 'tc_url' => $url, "tc_time >= " . $dbr->addQuotes( $tsCond ) )\r
+ IZ $obj\r
+ I FOUND MAH $obj->tc_contents\r
+ KTHX\r
+\r
+ I HAS text IZ Http::get( $url )\r
+ IZ !$text\r
+ I FOUND MAH wfMsg( 'scarytranscludefailed', $url )\r
+ KTHX\r
+\r
+ I HAS dbw IZ wfGetDB( DB_MASTER )\r
+ $dbw->replace( 'transcache', array('tc_url'), array(\r
+ 'tc_url' => $url,\r
+ 'tc_time' => $dbw->timestamp( time() ),\r
+ 'tc_contents' => $text)\r
+ BUCKET\r
+ I FOUND MAH $text\r
+ KTHX\r
+\r
+\r
+ DO NOT WANT\r
+ NOT WANT Triple brace replacement -- used for template arguments\r
+ NOT WANT @private\r
+ WANT\r
+ SO IM LIKE argSubstitution WITH UR $piece, $frame\r
+ IM ON UR wfProfileIn DOING __METHOD__\r
+\r
+ I HAS error IZ false\r
+ I HAS parts IZ $piece['parts']\r
+ I HAS nameWithSpaces IZ $frame->expand( $piece['title'] )\r
+ I HAS argName IZ trim( $nameWithSpaces )\r
+ I HAS object IZ false\r
+ I HAS text IZ $frame->getArgument( $argName )\r
+ if ( $text === false && $parts->getLength() > 0\r
+ && (\r
+ $this->ot['html']\r
+ || $this->ot['pre']\r
+ || ( $this->ot['wiki'] && $frame->isTemplate() )\r
+ )\r
+ ) {\r
+ BTW No match in frame, use the supplied default\r
+ I HAS object IZ $parts->item( 0 )->getChildren()\r
+ KTHX\r
+ IZ !$this->incrementIncludeSize( 'arg', strlen( $text ) )\r
+ I HAS error IZ '<!-- WARNING: argument omitted, expansion size too large -->'\r
+ IM ON UR SPECIAL limitationWarn DOING 'post-expand-template-argument'\r
+ KTHX\r
+\r
+ IZ $text === false && $object === false\r
+ BTW No match anywhere\r
+ I HAS object IZ $frame->virtualBracketedImplode( '{{{', '|', '}}}', $nameWithSpaces, $parts )\r
+ KTHX\r
+ IZ $error !== false\r
+ text HAS MOAR $error;\r
+ KTHX\r
+ IZ $object !== false\r
+ I HAS ret IZ BUCKET 'object' => $object );\r
+ NOWAI\r
+ I HAS ret IZ BUCKET 'text' => $text );\r
+ KTHX\r
+\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ I FOUND MAH $ret\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Return the text to be used for a given extension tag.\r
+ NOT WANT This is the ghost of strip().\r
+ NOT WANT \r
+ NOT WANT @param array $params Associative array of parameters:\r
+ NOT WANT name PPNode for the tag name\r
+ NOT WANT attr PPNode for unparsed text where tag attributes are thought to be\r
+ NOT WANT attributes Optional associative array of parsed attributes\r
+ NOT WANT inner Contents of extension element\r
+ NOT WANT noClose Original text did not have a close tag\r
+ NOT WANT @param PPFrame $frame\r
+ WANT\r
+ SO IM LIKE extensionSubstitution WITH UR $params, $frame\r
+ I HAS UR $wgRawHtml, $wgContLang ON UR INTERNETS\r
+\r
+ I HAS name IZ $frame->expand( $params['name'] )\r
+ I HAS attrText IZ !isset( $params['attr'] ) ? null : $frame->expand( $params['attr'] )\r
+ I HAS content IZ !isset( $params['inner'] ) ? null : $frame->expand( $params['inner'] )\r
+ I HAS marker IZ "{$this->mUniqPrefix}-$name-" . sprintf( '%08X', $this->mMarkerIndex++ ) . self::MARKER_SUFFIX\r
+\r
+ isFunctionTag IZ isset( $this->mFunctionTagHooks[strtolower($name)] ) &&\r
+ ( $this->ot['html'] || $this->ot['pre'] );\r
+ IZ $isFunctionTag\r
+ I HAS markerType IZ 'none'\r
+ NOWAI\r
+ I HAS markerType IZ 'general'\r
+ KTHX\r
+ IZ $this->ot['html'] || $isFunctionTag\r
+ I HAS name IZ strtolower( $name )\r
+ I HAS attributes IZ Sanitizer::decodeTagAttributes( $attrText )\r
+ IZ isset( $params['attributes'] )\r
+ I HAS attributes IZ $attributes + $params['attributes']\r
+ KTHX\r
+\r
+ IZ isset( $this->mTagHooks[$name] )\r
+ BTW Workaround for PHP bug 35229 and similar\r
+ IZ !is_callable( $this->mTagHooks[$name] )\r
+ throw new MWException( "Tag hook for $name is not callable\n" );\r
+ KTHX\r
+ output IZ call_user_func_array( $this->mTagHooks[$name],\r
+ IM ON UR array DOING $content, $attributes, $this, $frame )\r
+ ORLY isset( $this->mFunctionTagHooks[$name] )\r
+ list( $callback, $flags ) = $this->mFunctionTagHooks[$name];\r
+ IZ !is_callable( $callback )\r
+ throw new MWException( "Tag hook for $name is not callable\n" );\r
+ KTHX\r
+\r
+ I HAS output IZ call_user_func_array( $callback, array( &$this, $frame, $content, $attributes ) )\r
+ NOWAI\r
+ output IZ '<span class="error">Invalid tag extension name: ' .\r
+ htmlspecialchars( $name ) . '</span>';\r
+ KTHX\r
+\r
+ IZ is_array( $output )\r
+ BTW Extract flags to local scope (to override $markerType)\r
+ I HAS flags IZ $output\r
+ I HAS output IZ $flags[0]\r
+ IM ON UR unset DOING $flags[0]\r
+ IM ON UR extract DOING $flags\r
+ KTHX\r
+ NOWAI\r
+ IZ is_null( $attrText )\r
+ I HAS attrText IZ ''\r
+ KTHX\r
+ IZ isset( $params['attributes'] )\r
+ foreach ( $params['attributes'] as $attrName => $attrValue ) {\r
+ attrText HAS MOAR ' ' . htmlspecialchars( $attrName ) . '="' .\r
+ htmlspecialchars( $attrValue ) . '"';\r
+ KTHX\r
+ KTHX\r
+ IZ $content === null\r
+ I HAS output IZ "<$name$attrText/>"\r
+ NOWAI\r
+ I HAS close IZ is_null( $params['close'] ) ? '' : $frame->expand( $params['close'] )\r
+ I HAS output IZ "<$name$attrText>$content$close"\r
+ KTHX\r
+ KTHX\r
+\r
+ IZ $markerType === 'none'\r
+ I FOUND MAH $output\r
+ ORLY $markerType === 'nowiki'\r
+ IM ON UR SPECIAL mStripState->nowiki->setPair DOING $marker, $output\r
+ ORLY $markerType === 'general'\r
+ IM ON UR SPECIAL mStripState->general->setPair DOING $marker, $output\r
+ NOWAI\r
+ throw new MWException( __METHOD__.': invalid marker type' );\r
+ KTHX\r
+ I FOUND MAH $marker\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Increment an include size counter\r
+ NOT WANT \r
+ NOT WANT @param string $type The type of expansion\r
+ NOT WANT @param integer $size The size of the text\r
+ NOT WANT @return boolean False if this inclusion would take it over the maximum, true otherwise\r
+ WANT\r
+ SO IM LIKE incrementIncludeSize WITH UR $type, $size\r
+ IZ $this->mIncludeSizes[$type] + $size > $this->mOptions->getMaxIncludeSize( $type )\r
+ I FOUND MAH false\r
+ NOWAI\r
+ $this->mIncludeSizes[$type] += $size;\r
+ I FOUND MAH true\r
+ KTHX\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Increment the expensive function count\r
+ NOT WANT \r
+ NOT WANT @return boolean False if the limit has been exceeded\r
+ WANT\r
+ SO IM LIKE incrementExpensiveFunctionCount\r
+ I HAS UR $wgExpensiveParserFunctionLimit ON UR INTERNETS\r
+ $this->mExpensiveFunctionCount++;\r
+ IZ $this->mExpensiveFunctionCount <= $wgExpensiveParserFunctionLimit\r
+ I FOUND MAH true\r
+ KTHX\r
+ I FOUND MAH false\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Strip double-underscore items like __NOGALLERY__ and __NOTOC__\r
+ NOT WANT Fills $this->mDoubleUnderscores, returns the modified text\r
+ WANT\r
+ SO IM LIKE doDoubleUnderscore WITH UR $text\r
+ IM ON UR wfProfileIn DOING __METHOD__\r
+\r
+ BTW The position of __TOC__ needs to be recorded\r
+ I HAS mw IZ MagicWord::get( 'toc' )\r
+ IZ $mw->match( $text )\r
+ UR SPECIAL mShowToc IZ true;\r
+ UR SPECIAL mForceTocPosition IZ true;\r
+\r
+ BTW Set a placeholder. At the end we'll fill it in with the TOC.\r
+ I HAS text IZ $mw->replace( '<!--MWTOC-->', $text, 1 )\r
+\r
+ BTW Only keep the first one.\r
+ I HAS text IZ $mw->replace( '', $text )\r
+ KTHX\r
+\r
+ BTW Now match and remove the rest of them\r
+ I HAS mwa IZ MagicWord::getDoubleUnderscoreArray()\r
+ UR SPECIAL mDoubleUnderscores IZ $mwa->matchAndRemove( $text );\r
+\r
+ IZ isset( $this->mDoubleUnderscores['nogallery'] )\r
+ UR SPECIAL mOutput->mNoGallery IZ true;\r
+ KTHX\r
+ IZ isset( $this->mDoubleUnderscores['notoc'] ) && !$this->mForceTocPosition\r
+ UR SPECIAL mShowToc IZ false;\r
+ KTHX\r
+ IZ isset( $this->mDoubleUnderscores['hiddencat'] ) && $this->mTitle->getNamespace() == NS_CATEGORY\r
+ IM ON UR SPECIAL mOutput->setProperty DOING 'hiddencat', 'y'\r
+ IM ON UR SPECIAL addTrackingCategory DOING 'hidden-category-category'\r
+ KTHX\r
+ BTW (bug 8068) Allow control over whether robots index a page.\r
+ BTW \r
+ BTW FIXME (bug 14899): __INDEX__ always overrides __NOINDEX__ here! This\r
+ BTW is not desirable, the last one on the page should win.\r
+ IZ isset( $this->mDoubleUnderscores['noindex'] ) && $this->mTitle->canUseNoindex()\r
+ IM ON UR SPECIAL mOutput->setIndexPolicy DOING 'noindex'\r
+ IM ON UR SPECIAL addTrackingCategory DOING 'noindex-category'\r
+ KTHX\r
+ IZ isset( $this->mDoubleUnderscores['index'] ) && $this->mTitle->canUseNoindex()\r
+ IM ON UR SPECIAL mOutput->setIndexPolicy DOING 'index'\r
+ IM ON UR SPECIAL addTrackingCategory DOING 'index-category'\r
+ KTHX\r
+\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ I FOUND MAH $text\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Add a tracking category, getting the title from a system message,\r
+ NOT WANT or print a debug message if the title is invalid.\r
+ NOT WANT @param $msg String message key\r
+ NOT WANT @return Bool whether the addition was successful\r
+ WANT\r
+ SO IM LIKE addTrackingCategory WITH UR $msg\r
+ I HAS cat IZ wfMsgForContent( $msg )\r
+\r
+ BTW Allow tracking categories to be disabled by setting them to "-"\r
+ IZ $cat === '-'\r
+ I FOUND MAH false\r
+ KTHX\r
+\r
+ I HAS containerCategory IZ Title::makeTitleSafe( NS_CATEGORY, $cat )\r
+ IZ $containerCategory\r
+ IM ON UR SPECIAL mOutput->addCategory DOING $containerCategory->getDBkey(), $this->getDefaultSort()\r
+ I FOUND MAH true\r
+ NOWAI\r
+ IM ON UR wfDebug DOING __METHOD__.": [[MediaWiki:$msg]] is not a valid title!\n"\r
+ I FOUND MAH false\r
+ KTHX\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT This function accomplishes several tasks:\r
+ NOT WANT 1) Auto-number headings if that option is enabled\r
+ NOT WANT 2) Add an [edit] link to sections for users who have enabled the option and can edit the page\r
+ NOT WANT 3) Add a Table of contents on the top for users who have enabled the option\r
+ NOT WANT 4) Auto-anchor headings\r
+ NOT WANT \r
+ NOT WANT It loops through all headlines, collects the necessary data, then splits up the\r
+ NOT WANT string and re-inserts the newly formatted headlines.\r
+ NOT WANT \r
+ NOT WANT @param string $text\r
+ NOT WANT @param string $origText Original, untouched wikitext\r
+ NOT WANT @param boolean $isMain\r
+ NOT WANT @private\r
+ WANT\r
+ SO IM LIKE formatHeadings WITH UR $text, $origText, $isMain=true\r
+ I HAS UR $wgMaxTocLevel, $wgContLang, $wgHtml5, $wgExperimentalHtmlIds ON UR INTERNETS\r
+\r
+ I HAS doNumberHeadings IZ $this->mOptions->getNumberHeadings()\r
+ I HAS showEditLink IZ $this->mOptions->getEditSection()\r
+\r
+ BTW Do not call quickUserCan unless necessary\r
+ IZ $showEditLink && !$this->mTitle->quickUserCan( 'edit' )\r
+ I HAS showEditLink IZ 0\r
+ KTHX\r
+\r
+ BTW Inhibit editsection links if requested in the page\r
+ IZ isset( $this->mDoubleUnderscores['noeditsection'] ) || $this->mOptions->getIsPrintable()\r
+ I HAS showEditLink IZ 0\r
+ KTHX\r
+\r
+ BTW Get all headlines for numbering them and adding funky stuff like [edit]\r
+ BTW links - this is for later, but we need the number of headlines right now\r
+ I HAS matches IZ EMPTY\r
+ I HAS numMatches IZ preg_match_all( '/<H(?P<level>[1-6])(?P<attrib>.*?'.'>)(?P<header>.*?)<\/H[1-6] *>/i', $text, $matches )\r
+\r
+ BTW if there are fewer than 4 headlines in the article, do not show TOC\r
+ BTW unless it's been explicitly enabled.\r
+ enoughToc IZ $this->mShowToc &&\r
+ ( ( $numMatches >= 4 ) || $this->mForceTocPosition );\r
+\r
+ BTW Allow user to stipulate that a page should have a "new section"\r
+ BTW link added via __NEWSECTIONLINK__\r
+ IZ isset( $this->mDoubleUnderscores['newsectionlink'] )\r
+ IM ON UR SPECIAL mOutput->setNewSection DOING true\r
+ KTHX\r
+\r
+ BTW Allow user to remove the "new section"\r
+ BTW link via __NONEWSECTIONLINK__\r
+ IZ isset( $this->mDoubleUnderscores['nonewsectionlink'] )\r
+ IM ON UR SPECIAL mOutput->hideNewSection DOING true\r
+ KTHX\r
+\r
+ BTW if the string __FORCETOC__ (not case-sensitive) occurs in the HTML,\r
+ BTW override above conditions and always show TOC above first header\r
+ IZ isset( $this->mDoubleUnderscores['forcetoc'] )\r
+ UR SPECIAL mShowToc IZ true;\r
+ I HAS enoughToc IZ true\r
+ KTHX\r
+\r
+ BTW We need this to perform operations on the HTML\r
+ I HAS sk IZ $this->mOptions->getSkin()\r
+\r
+ BTW headline counter\r
+ I HAS headlineCount IZ 0\r
+ I HAS numVisible IZ 0\r
+\r
+ BTW Ugh .. the TOC should have neat indentation levels which can be\r
+ BTW passed to the skin functions. These are determined here\r
+ I HAS toc IZ ''\r
+ I HAS full IZ ''\r
+ I HAS head IZ EMPTY\r
+ I HAS sublevelCount IZ EMPTY\r
+ I HAS levelCount IZ EMPTY\r
+ I HAS toclevel IZ 0\r
+ I HAS level IZ 0\r
+ I HAS prevlevel IZ 0\r
+ I HAS toclevel IZ 0\r
+ I HAS prevtoclevel IZ 0\r
+ I HAS markerRegex IZ "{$this->mUniqPrefix}-h-(\d+)-" . self::MARKER_SUFFIX\r
+ I HAS baseTitleText IZ $this->mTitle->getPrefixedDBkey()\r
+ I HAS oldType IZ $this->mOutputType\r
+ IM ON UR SPECIAL setOutputType DOING self::OT_WIKI\r
+ I HAS frame IZ $this->getPreprocessor()->newFrame()\r
+ I HAS root IZ $this->preprocessToDom( $origText )\r
+ I HAS node IZ $root->getFirstChild()\r
+ I HAS byteOffset IZ 0\r
+ I HAS tocraw IZ EMPTY\r
+\r
+ foreach ( $matches[3] as $headline ) {\r
+ I HAS isTemplate IZ false\r
+ I HAS titleText IZ false\r
+ I HAS sectionIndex IZ false\r
+ I HAS numbering IZ ''\r
+ I HAS markerMatches IZ EMPTY\r
+ IZ preg_match("/^$markerRegex/", $headline, $markerMatches )\r
+ I HAS serial IZ $markerMatches[1]\r
+ list( $titleText, $sectionIndex ) = $this->mHeadings[$serial];\r
+ I HAS isTemplate IZ ( $titleText != $baseTitleText )\r
+ I HAS headline IZ preg_replace( "/^$markerRegex/", "", $headline )\r
+ KTHX\r
+\r
+ IZ $toclevel\r
+ I HAS prevlevel IZ $level\r
+ I HAS prevtoclevel IZ $toclevel\r
+ KTHX\r
+ I HAS level IZ $matches[1][$headlineCount]\r
+\r
+ IZ $level > $prevlevel\r
+ BTW Increase TOC level\r
+ $toclevel++;\r
+ $sublevelCount[$toclevel] = 0;\r
+ IZ $toclevel<$wgMaxTocLevel\r
+ I HAS prevtoclevel IZ $toclevel\r
+ toc HAS MOAR $sk->tocIndent();\r
+ $numVisible++;\r
+ KTHX\r
+ ORLY $level < $prevlevel && $toclevel > 1\r
+ BTW Decrease TOC level, find level to jump to\r
+\r
+ for ( $i = $toclevel; $i > 0; $i-- ) {\r
+ IZ $levelCount[$i] == $level\r
+ BTW Found last matching level\r
+ I HAS toclevel IZ $i\r
+ break;\r
+ ORLY $levelCount[$i] < $level\r
+ BTW Found first matching level below current level\r
+ I HAS toclevel IZ $i + 1\r
+ break;\r
+ KTHX\r
+ KTHX\r
+ IZ $i == 0\r
+ I HAS toclevel IZ 1\r
+ KTHX\r
+ IZ $toclevel<$wgMaxTocLevel\r
+ IZ $prevtoclevel < $wgMaxTocLevel\r
+ BTW Unindent only if the previous toc level was shown :p\r
+ toc HAS MOAR $sk->tocUnindent( $prevtoclevel - $toclevel );\r
+ I HAS prevtoclevel IZ $toclevel\r
+ NOWAI\r
+ toc HAS MOAR $sk->tocLineEnd();\r
+ KTHX\r
+ KTHX\r
+ NOWAI\r
+ BTW No change in level, end TOC line\r
+ IZ $toclevel<$wgMaxTocLevel\r
+ toc HAS MOAR $sk->tocLineEnd();\r
+ KTHX\r
+ KTHX\r
+\r
+ $levelCount[$toclevel] = $level;\r
+\r
+ BTW count number of headlines for each level\r
+ @$sublevelCount[$toclevel]++;\r
+ I HAS dot IZ 0\r
+ for( $i = 1; $i <= $toclevel; $i++ ) {\r
+ IZ !empty( $sublevelCount[$i] )\r
+ IZ $dot\r
+ numbering HAS MOAR '.';\r
+ KTHX\r
+ numbering HAS MOAR $wgContLang->formatNum( $sublevelCount[$i] );\r
+ I HAS dot IZ 1\r
+ KTHX\r
+ KTHX\r
+\r
+ BTW The safe header is a version of the header text safe to use for links\r
+ BTW Avoid insertion of weird stuff like <math> by expanding the relevant sections\r
+ I HAS safeHeadline IZ $this->mStripState->unstripBoth( $headline )\r
+\r
+ BTW Remove link placeholders by the link text.\r
+ BTW <!--LINK number-->\r
+ BTW turns into\r
+ BTW link text with suffix\r
+ I HAS safeHeadline IZ $this->replaceLinkHoldersText( $safeHeadline )\r
+\r
+ BTW Strip out HTML (other than plain <sup> and <sub>: bug 8393)\r
+ tocline IZ preg_replace(\r
+ array( '#<(?!/?(sup|sub)).*?'.'>#', '#<(/?(sup|sub)).*?'.'>#' ),\r
+ array( '', '<$1>' ),\r
+ $safeHeadline\r
+ BUCKET\r
+ I HAS tocline IZ trim( $tocline )\r
+\r
+ BTW For the anchor, strip out HTML-y stuff period\r
+ I HAS safeHeadline IZ preg_replace( '/<.*?'.'>/', '', $safeHeadline )\r
+ I HAS safeHeadline IZ preg_replace( '/[ _]+/', ' ', $safeHeadline )\r
+ I HAS safeHeadline IZ trim( $safeHeadline )\r
+\r
+ BTW Save headline for section edit hint before it's escaped\r
+ I HAS headlineHint IZ $safeHeadline\r
+\r
+ IZ $wgHtml5 && $wgExperimentalHtmlIds\r
+ BTW For reverse compatibility, provide an id that's\r
+ BTW HTML4-compatible, like we used to.\r
+ BTW \r
+ BTW It may be worth noting, academically, that it's possible for\r
+ BTW the legacy anchor to conflict with a non-legacy headline\r
+ BTW anchor on the page. In this case likely the "correct" thing\r
+ BTW would be to either drop the legacy anchors or make sure\r
+ BTW they're numbered first. However, this would require people\r
+ BTW to type in section names like "abc_.D7.93.D7.90.D7.A4"\r
+ BTW manually, so let's not bother worrying about it.\r
+ legacyHeadline IZ Sanitizer::escapeId( $safeHeadline,\r
+ IM ON UR array DOING 'noninitial', 'legacy' )\r
+ I HAS safeHeadline IZ Sanitizer::escapeId( $safeHeadline )\r
+\r
+ IZ $legacyHeadline == $safeHeadline\r
+ BTW No reason to have both (in fact, we can't)\r
+ I HAS legacyHeadline IZ false\r
+ KTHX\r
+ NOWAI\r
+ I HAS legacyHeadline IZ false\r
+ safeHeadline IZ Sanitizer::escapeId( $safeHeadline,\r
+ 'noninitial' );\r
+ KTHX\r
+\r
+ BTW HTML names must be case-insensitively unique (bug 10721). FIXME:\r
+ BTW Does this apply to Unicode characters? Because we aren't\r
+ BTW handling those here.\r
+ I HAS arrayKey IZ strtolower( $safeHeadline )\r
+ IZ $legacyHeadline === false\r
+ I HAS legacyArrayKey IZ false\r
+ NOWAI\r
+ I HAS legacyArrayKey IZ strtolower( $legacyHeadline )\r
+ KTHX\r
+\r
+ BTW count how many in assoc. array so we can track dupes in anchors\r
+ IZ isset( $refers[$arrayKey] )\r
+ $refers[$arrayKey]++;\r
+ NOWAI\r
+ $refers[$arrayKey] = 1;\r
+ KTHX\r
+ IZ isset( $refers[$legacyArrayKey] )\r
+ $refers[$legacyArrayKey]++;\r
+ NOWAI\r
+ $refers[$legacyArrayKey] = 1;\r
+ KTHX\r
+\r
+ BTW Don't number the heading if it is the only one (looks silly)\r
+ if ( $doNumberHeadings && count( $matches[3] ) > 1) {\r
+ BTW the two are different if the line contains a link\r
+ I HAS headline IZ $numbering . ' ' . $headline\r
+ KTHX\r
+\r
+ BTW Create the anchor for linking from the TOC to the section\r
+ I HAS anchor IZ $safeHeadline\r
+ I HAS legacyAnchor IZ $legacyHeadline\r
+ IZ $refers[$arrayKey] > 1\r
+ anchor HAS MOAR '_' . $refers[$arrayKey];\r
+ KTHX\r
+ IZ $legacyHeadline !== false && $refers[$legacyArrayKey] > 1\r
+ legacyAnchor HAS MOAR '_' . $refers[$legacyArrayKey];\r
+ KTHX\r
+ IZ $enoughToc && ( !isset( $wgMaxTocLevel ) || $toclevel < $wgMaxTocLevel )\r
+ toc HAS MOAR $sk->tocLine( $anchor, $tocline,\r
+ $numbering, $toclevel, ( $isTemplate ? false : $sectionIndex ) );\r
+ KTHX\r
+\r
+ BTW Add the section to the section tree\r
+ BTW Find the DOM node for this header\r
+ STEALIN UR $node && !$isTemplate\r
+ IZ $node->getName() === 'h'\r
+ I HAS bits IZ $node->splitHeading()\r
+ if ( $bits['i'] == $sectionIndex )\r
+ break;\r
+ KTHX\r
+ $byteOffset += mb_strlen( $this->mStripState->unstripBoth(\r
+ $frame->expand( $node, PPFrame::RECOVER_ORIG ) ) );\r
+ I HAS node IZ $node->getNextSibling()\r
+ KTHX\r
+ $tocraw[] = array(\r
+ 'toclevel' => $toclevel,\r
+ 'level' => $level,\r
+ 'line' => $tocline,\r
+ 'number' => $numbering,\r
+ 'index' => ( $isTemplate ? 'T-' : '' ) . $sectionIndex,\r
+ 'fromtitle' => $titleText,\r
+ 'byteoffset' => ( $isTemplate ? null : $byteOffset ),\r
+ 'anchor' => $anchor,\r
+ BUCKET\r
+\r
+ BTW give headline the correct <h#> tag\r
+ IZ $showEditLink && $sectionIndex !== false\r
+ IZ $isTemplate\r
+ BTW Put a T flag in the section identifier, to indicate to extractSections()\r
+ BTW that sections inside <includeonly> should be counted.\r
+ I HAS editlink IZ $sk->doEditSectionLink( Title::newFromText( $titleText ), "T-$sectionIndex" )\r
+ NOWAI\r
+ I HAS editlink IZ $sk->doEditSectionLink( $this->mTitle, $sectionIndex, $headlineHint )\r
+ KTHX\r
+ NOWAI\r
+ I HAS editlink IZ ''\r
+ KTHX\r
+ $head[$headlineCount] = $sk->makeHeadline( $level,\r
+ $matches['attrib'][$headlineCount], $anchor, $headline,\r
+ $editlink, $legacyAnchor );\r
+\r
+ $headlineCount++;\r
+ KTHX\r
+\r
+ IM ON UR SPECIAL setOutputType DOING $oldType\r
+\r
+ BTW Never ever show TOC if no headers\r
+ IZ $numVisible < 1\r
+ I HAS enoughToc IZ false\r
+ KTHX\r
+\r
+ IZ $enoughToc\r
+ IZ $prevtoclevel > 0 && $prevtoclevel < $wgMaxTocLevel\r
+ toc HAS MOAR $sk->tocUnindent( $prevtoclevel - 1 );\r
+ KTHX\r
+ I HAS toc IZ $sk->tocList( $toc )\r
+ IM ON UR SPECIAL mOutput->setTOCHTML DOING $toc\r
+ KTHX\r
+\r
+ IZ $isMain\r
+ IM ON UR SPECIAL mOutput->setSections DOING $tocraw\r
+ KTHX\r
+\r
+ BTW split up and insert constructed headlines\r
+\r
+ I HAS blocks IZ preg_split( '/<H[1-6].*?' . '>.*?<\/H[1-6]>/i', $text )\r
+ I HAS i IZ 0\r
+\r
+ IM IN UR blocks ITZA block\r
+ IZ $showEditLink && $headlineCount > 0 && $i == 0 && $block !== "\n"\r
+ BTW This is the [edit] link that appears for the top block of text when\r
+ BTW section editing is enabled\r
+\r
+ BTW Disabled because it broke block formatting\r
+ BTW For example, a bullet point in the top line\r
+ BTW $full .= $sk->editSectionLink(0);\r
+ KTHX\r
+ full HAS MOAR $block;\r
+ IZ $enoughToc && !$i && $isMain && !$this->mForceTocPosition\r
+ BTW Top anchor now in skin\r
+ I HAS full IZ $full.$toc\r
+ KTHX\r
+\r
+ IZ !empty( $head[$i] )\r
+ full HAS MOAR $head[$i];\r
+ KTHX\r
+ $i++;\r
+ KTHX\r
+ IZ $this->mForceTocPosition\r
+ I FOUND MAH str_replace( '<!--MWTOC-->', $toc, $full )\r
+ NOWAI\r
+ I FOUND MAH $full\r
+ KTHX\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Merge $tree2 into $tree1 by replacing the section with index\r
+ NOT WANT $section in $tree1 and its descendants with the sections in $tree2.\r
+ NOT WANT Note that in the returned section tree, only the 'index' and\r
+ NOT WANT 'byteoffset' fields are guaranteed to be correct.\r
+ NOT WANT @param $tree1 array Section tree from ParserOutput::getSectons()\r
+ NOT WANT @param $tree2 array Section tree\r
+ NOT WANT @param $section int Section index\r
+ NOT WANT @param $title Title Title both section trees come from\r
+ NOT WANT @param $len2 int Length of the original wikitext for $tree2\r
+ NOT WANT @return array Merged section tree\r
+ WANT\r
+ SO IM ALWAYS LIKE mergeSectionTrees WITH UR $tree1, $tree2, $section, $title, $len2\r
+ I HAS UR $wgContLang ON UR INTERNETS\r
+ I HAS newTree IZ EMPTY\r
+ I HAS targetLevel IZ false\r
+ I HAS merged IZ false\r
+ I HAS lastLevel IZ 1\r
+ I HAS nextIndex IZ 1\r
+ I HAS numbering IZ BUCKET 0 );\r
+ I HAS titletext IZ $title->getPrefixedDBkey()\r
+ IM IN UR tree1 ITZA s\r
+ IZ $targetLevel !== false\r
+ IZ $s['level'] <= $targetLevel\r
+ BTW We've skipped enough\r
+ I HAS targetLevel IZ false\r
+ NOWAI\r
+ continue;\r
+ KTHX\r
+ KTHX\r
+ if ( $s['index'] != $section ||\r
+ $s['fromtitle'] != $titletext ) {\r
+ self::incrementNumbering( $numbering,\r
+ $s['toclevel'], $lastLevel );\r
+\r
+ BTW Rewrite index, byteoffset and number\r
+ IZ $s['fromtitle'] == $titletext\r
+ $s['index'] = $nextIndex++;\r
+ IZ $merged\r
+ $s['byteoffset'] += $len2;\r
+ KTHX\r
+ KTHX\r
+ $s['number'] = implode( '.', array_map(\r
+ array( $wgContLang, 'formatnum' ),\r
+ $numbering ) );\r
+ I HAS lastLevel IZ $s['toclevel']\r
+ $newTree[] = $s;\r
+ NOWAI\r
+ BTW We're at $section\r
+ BTW Insert sections from $tree2 here\r
+ IM IN UR tree2 ITZA s2\r
+ BTW Rewrite the fields in $s2\r
+ BTW before inserting it\r
+ $s2['toclevel'] += $s['toclevel'] - 1;\r
+ $s2['level'] += $s['level'] - 1;\r
+ $s2['index'] = $nextIndex++;\r
+ $s2['byteoffset'] += $s['byteoffset'];\r
+\r
+ self::incrementNumbering( $numbering,\r
+ $s2['toclevel'], $lastLevel );\r
+ $s2['number'] = implode( '.', array_map(\r
+ array( $wgContLang, 'formatnum' ),\r
+ $numbering ) );\r
+ I HAS lastLevel IZ $s2['toclevel']\r
+ $newTree[] = $s2;\r
+ KTHX\r
+ BTW Skip all descendants of $section in $tree1\r
+ I HAS targetLevel IZ $s['level']\r
+ I HAS merged IZ true\r
+ KTHX\r
+ KTHX\r
+ I FOUND MAH $newTree\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Increment a section number. Helper function for mergeSectionTrees()\r
+ NOT WANT @param $number array Array representing a section number\r
+ NOT WANT @param $level int Current TOC level (depth)\r
+ NOT WANT @param $lastLevel int Level of previous TOC entry\r
+ WANT\r
+ SO IM ALWAYS LIKE incrementNumbering WITH UR &$number, $level, $lastLevel\r
+ IZ $level > $lastLevel\r
+ $number[$level - 1] = 1;\r
+ ORLY $level < $lastLevel\r
+ foreach ( $number as $key => $unused )\r
+ IZ $key >= $level\r
+ IM ON UR unset DOING $number[$key]\r
+ KTHX\r
+ $number[$level - 1]++;\r
+ NOWAI\r
+ $number[$level - 1]++;\r
+ KTHX\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Transform wiki markup when saving a page by doing \r\n -> \n\r
+ NOT WANT conversion, substitting signatures, {{subst:}} templates, etc.\r
+ NOT WANT \r
+ NOT WANT @param string $text the text to transform\r
+ NOT WANT @param Title &$title the Title object for the current article\r
+ NOT WANT @param User $user the User object describing the current user\r
+ NOT WANT @param ParserOptions $options parsing options\r
+ NOT WANT @param bool $clearState whether to clear the parser state first\r
+ NOT WANT @return string the altered wiki markup\r
+ NOT WANT @public\r
+ WANT\r
+ SO IM LIKE preSaveTransform WITH UR $text, Title $title, $user, $options, $clearState = true\r
+ UR SPECIAL mOptions IZ $options;\r
+ IM ON UR SPECIAL setTitle DOING $title\r
+ IM ON UR SPECIAL setOutputType DOING self::OT_WIKI\r
+\r
+ IZ $clearState\r
+ IM ON UR SPECIAL clearState\r
+ KTHX\r
+\r
+ I HAS pairs IZ BUCKET\r
+ "\r\n" => "\n",\r
+ BUCKET\r
+ I HAS text IZ str_replace( array_keys( $pairs ), array_values( $pairs ), $text )\r
+ I HAS text IZ $this->pstPass2( $text, $user )\r
+ I HAS text IZ $this->mStripState->unstripBoth( $text )\r
+ I FOUND MAH $text\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Pre-save transform helper function\r
+ NOT WANT @private\r
+ WANT\r
+ SO IM LIKE pstPass2 WITH UR $text, $user\r
+ I HAS UR $wgContLang, $wgLocaltimezone ON UR INTERNETS\r
+\r
+ BTW Note: This is the timestamp saved as hardcoded wikitext to\r
+ BTW the database, we use $wgContLang here in order to give\r
+ BTW everyone the same signature and use the default one rather\r
+ BTW than the one selected in each user's preferences.\r
+ BTW (see also bug 12815)\r
+ I HAS ts IZ $this->mOptions->getTimestamp()\r
+ IZ isset( $wgLocaltimezone )\r
+ I HAS tz IZ $wgLocaltimezone\r
+ NOWAI\r
+ I HAS tz IZ date_default_timezone_get()\r
+ KTHX\r
+\r
+ I HAS unixts IZ wfTimestamp( TS_UNIX, $ts )\r
+ I HAS oldtz IZ date_default_timezone_get()\r
+ IM ON UR date_default_timezone_set DOING $tz\r
+ I HAS ts IZ date( 'YmdHis', $unixts )\r
+ I HAS tzMsg IZ date( 'T', $unixts ) # might vary on DST changeover!\r
+\r
+ BTW Allow translation of timezones trough wiki. date() can return\r
+ BTW whatever crap the system uses, localised or not, so we cannot\r
+ BTW ship premade translations.\r
+ I HAS key IZ 'timezone-' . strtolower( trim( $tzMsg ) )\r
+ I HAS value IZ wfMsgForContent( $key )\r
+ IZ !wfEmptyMsg( $key, $value )\r
+ I HAS tzMsg IZ $value\r
+ KTHX\r
+\r
+ IM ON UR date_default_timezone_set DOING $oldtz\r
+\r
+ I HAS d IZ $wgContLang->timeanddate( $ts, false, false ) . " ($tzMsg)"\r
+\r
+ BTW Variable replacement\r
+ BTW Because mOutputType is OT_WIKI, this will only process {{subst:xxx}} type tags\r
+ I HAS text IZ $this->replaceVariables( $text )\r
+\r
+ BTW Signatures\r
+ I HAS sigText IZ $this->getUserSig( $user )\r
+ text IZ strtr( $text, array(\r
+ '~~~~~' => $d,\r
+ '~~~~' => "$sigText $d",\r
+ '~~~' => $sigText\r
+ ) );\r
+\r
+ BTW Context links: [[|name]] and [[name (context)|]]\r
+ I HAS UR $wgLegalTitleChars ON UR INTERNETS\r
+ I HAS tc IZ "[$wgLegalTitleChars]"\r
+ I HAS nc IZ '[ _0-9A-Za-z\x80-\xff-]' # Namespaces can use non-ascii!\r
+\r
+ I HAS p1 IZ "/\[\[(:?$nc+:|:|)($tc+?)( \\($tc+\\))\\|]]/" # [[ns:page (context)|]]\r
+ I HAS p4 IZ "/\[\[(:?$nc+:|:|)($tc+?)(($tc+))\\|]]/" # [[ns:page(context)|]]\r
+ I HAS p3 IZ "/\[\[(:?$nc+:|:|)($tc+?)( \\($tc+\\)|)(, $tc+|)\\|]]/" # [[ns:page (context), context|]]\r
+ I HAS p2 IZ "/\[\[\\|($tc+)]]/" # [[|page]]\r
+\r
+ BTW try $p1 first, to turn "[[A, B (C)|]]" into "[[A, B (C)|A, B]]"\r
+ I HAS text IZ preg_replace( $p1, '[[\\1\\2\\3|\\2]]', $text )\r
+ I HAS text IZ preg_replace( $p4, '[[\\1\\2\\3|\\2]]', $text )\r
+ I HAS text IZ preg_replace( $p3, '[[\\1\\2\\3\\4|\\2]]', $text )\r
+\r
+ I HAS t IZ $this->mTitle->getText()\r
+ I HAS m IZ EMPTY\r
+ IZ preg_match( "/^($nc+:|)$tc+?( \\($tc+\\))$/", $t, $m )\r
+ I HAS text IZ preg_replace( $p2, "[[$m[1]\\1$m[2]|\\1]]", $text )\r
+ ORLY preg_match( "/^($nc+:|)$tc+?(, $tc+|)$/", $t, $m ) && "$m[1]$m[2]" != ''\r
+ I HAS text IZ preg_replace( $p2, "[[$m[1]\\1$m[2]|\\1]]", $text )\r
+ NOWAI\r
+ BTW if there's no context, don't bother duplicating the title\r
+ I HAS text IZ preg_replace( $p2, '[[\\1]]', $text )\r
+ KTHX\r
+\r
+ BTW Trim trailing whitespace\r
+ I HAS text IZ rtrim( $text )\r
+\r
+ I FOUND MAH $text\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Fetch the user's signature text, if any, and normalize to\r
+ NOT WANT validated, ready-to-insert wikitext.\r
+ NOT WANT If you have pre-fetched the nickname or the fancySig option, you can\r
+ NOT WANT specify them here to save a database query.\r
+ NOT WANT \r
+ NOT WANT @param User $user\r
+ NOT WANT @return string\r
+ WANT\r
+ SO IM LIKE getUserSig WITH UR &$user, $nickname = false, $fancySig = null\r
+ I HAS UR $wgMaxSigChars ON UR INTERNETS\r
+\r
+ I HAS username IZ $user->getName()\r
+\r
+ BTW If not given, retrieve from the user object.\r
+ if ( $nickname === false )\r
+ I HAS nickname IZ $user->getOption( 'nickname' )\r
+\r
+ IZ is_null( $fancySig )\r
+ I HAS fancySig IZ $user->getBoolOption( 'fancysig' )\r
+ KTHX\r
+\r
+ I HAS nickname IZ $nickname == null ? $username : $nickname\r
+\r
+ IZ mb_strlen( $nickname ) > $wgMaxSigChars\r
+ I HAS nickname IZ $username\r
+ IM ON UR wfDebug DOING __METHOD__ . ": $username has overlong signature.\n"\r
+ ORLY $fancySig !== false\r
+ BTW Sig. might contain markup; validate this\r
+ IZ $this->validateSig( $nickname ) !== false\r
+ BTW Validated; clean up (if needed) and return it\r
+ I FOUND MAH $this->cleanSig( $nickname, true )\r
+ NOWAI\r
+ BTW Failed to validate; fall back to the default\r
+ I HAS nickname IZ $username\r
+ IM ON UR wfDebug DOING __METHOD__.": $username has bad XML tags in signature.\n"\r
+ KTHX\r
+ KTHX\r
+\r
+ BTW Make sure nickname doesnt get a sig in a sig\r
+ I HAS nickname IZ $this->cleanSigInSig( $nickname )\r
+\r
+ BTW If we're still here, make it a link to the user page\r
+ I HAS userText IZ wfEscapeWikiText( $username )\r
+ I HAS nickText IZ wfEscapeWikiText( $nickname )\r
+ if ( $user->isAnon() ) {\r
+ I FOUND MAH wfMsgExt( 'signature-anon', array( 'content', 'parsemag' ), $userText, $nickText )\r
+ NOWAI\r
+ I FOUND MAH wfMsgExt( 'signature', array( 'content', 'parsemag' ), $userText, $nickText )\r
+ KTHX\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Check that the user's signature contains no bad XML\r
+ NOT WANT \r
+ NOT WANT @param string $text\r
+ NOT WANT @return mixed An expanded string, or false if invalid.\r
+ WANT\r
+ SO IM LIKE validateSig WITH UR $text\r
+ IM ON UR return DOING Xml::isWellFormedXmlFragment( $text ) ? $text : false\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Clean up signature text\r
+ NOT WANT \r
+ NOT WANT 1) Strip ~~~, ~~~~ and ~~~~~ out of signatures @see cleanSigInSig\r
+ NOT WANT 2) Substitute all transclusions\r
+ NOT WANT \r
+ NOT WANT @param string $text\r
+ NOT WANT @param $parsing Whether we're cleaning (preferences save) or parsing\r
+ NOT WANT @return string Signature text\r
+ WANT\r
+ SO IM LIKE cleanSig WITH UR $text, $parsing = false\r
+ IZ !$parsing\r
+ I HAS UR $wgTitle ON UR INTERNETS\r
+ IM ON UR SPECIAL clearState\r
+ IM ON UR SPECIAL setTitle DOING $wgTitle\r
+ UR SPECIAL mOptions IZ new ParserOptions;\r
+ UR SPECIAL setOutputType IZ self::OT_PREPROCESS;\r
+ KTHX\r
+\r
+ BTW Option to disable this feature\r
+ IZ !$this->mOptions->getCleanSignatures()\r
+ I FOUND MAH $text\r
+ KTHX\r
+\r
+ BTW FIXME: regex doesn't respect extension tags or nowiki\r
+ BTW => Move this logic to braceSubstitution()\r
+ I HAS substWord IZ MagicWord::get( 'subst' )\r
+ I HAS substRegex IZ '/\{\{(?!(?:' . $substWord->getBaseRegex() . '))/x' . $substWord->getRegexCase()\r
+ I HAS substText IZ '{{' . $substWord->getSynonym( 0 )\r
+\r
+ I HAS text IZ preg_replace( $substRegex, $substText, $text )\r
+ I HAS text IZ $this->cleanSigInSig( $text )\r
+ I HAS dom IZ $this->preprocessToDom( $text )\r
+ I HAS frame IZ $this->getPreprocessor()->newFrame()\r
+ I HAS text IZ $frame->expand( $dom )\r
+\r
+ IZ !$parsing\r
+ I HAS text IZ $this->mStripState->unstripBoth( $text )\r
+ KTHX\r
+\r
+ I FOUND MAH $text\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Strip ~~~, ~~~~ and ~~~~~ out of signatures\r
+ NOT WANT @param string $text\r
+ NOT WANT @return string Signature text with /~{3,5}/ removed\r
+ WANT\r
+ SO IM LIKE cleanSigInSig WITH UR $text\r
+ I HAS text IZ preg_replace( '/~{3,5}/', '', $text )\r
+ I FOUND MAH $text\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Set up some variables which are usually set up in parse()\r
+ NOT WANT so that an external function can call some class members with confidence\r
+ NOT WANT @public\r
+ WANT\r
+ SO IM LIKE startExternalParse WITH UR &$title, $options, $outputType, $clearState = true\r
+ IM ON UR SPECIAL setTitle DOING $title\r
+ UR SPECIAL mOptions IZ $options;\r
+ IM ON UR SPECIAL setOutputType DOING $outputType\r
+ IZ $clearState\r
+ IM ON UR SPECIAL clearState\r
+ KTHX\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Wrapper for preprocess()\r
+ NOT WANT \r
+ NOT WANT @param string $text the text to preprocess\r
+ NOT WANT @param ParserOptions $options options\r
+ NOT WANT @return string\r
+ NOT WANT @public\r
+ WANT\r
+ SO IM LIKE transformMsg WITH UR $text, $options\r
+ I HAS UR $wgTitle ON UR INTERNETS\r
+ static $executing = false;\r
+\r
+ BTW Guard against infinite recursion\r
+ IZ $executing\r
+ I FOUND MAH $text\r
+ KTHX\r
+ I HAS executing IZ true\r
+\r
+ IM ON UR wfProfileIn DOING __METHOD__\r
+ I HAS text IZ $this->preprocess( $text, $wgTitle, $options )\r
+\r
+ I HAS executing IZ false\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ I FOUND MAH $text\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Create an HTML-style tag, e.g. <yourtag>special text</yourtag>\r
+ NOT WANT The callback should have the following form:\r
+ NOT WANT function myParserHook( $text, $params, &$parser ) { ... }\r
+ NOT WANT \r
+ NOT WANT Transform and return $text. Use $parser for any required context, e.g. use\r
+ NOT WANT $parser->getTitle() and $parser->getOptions() not $wgTitle or $wgOut->mParserOptions\r
+ NOT WANT \r
+ NOT WANT @public\r
+ NOT WANT \r
+ NOT WANT @param mixed $tag The tag to use, e.g. 'hook' for <hook>\r
+ NOT WANT @param mixed $callback The callback function (and object) to use for the tag\r
+ NOT WANT \r
+ NOT WANT @return The old value of the mTagHooks array associated with the hook\r
+ WANT\r
+ SO IM LIKE setHook WITH UR $tag, $callback\r
+ I HAS tag IZ strtolower( $tag )\r
+ I HAS oldVal IZ isset( $this->mTagHooks[$tag] ) ? $this->mTagHooks[$tag] : null\r
+ $this->mTagHooks[$tag] = $callback;\r
+ IZ !in_array( $tag, $this->mStripList )\r
+ $this->mStripList[] = $tag;\r
+ KTHX\r
+\r
+ I FOUND MAH $oldVal\r
+ KTHX\r
+\r
+ SO IM LIKE setTransparentTagHook WITH UR $tag, $callback\r
+ I HAS tag IZ strtolower( $tag )\r
+ I HAS oldVal IZ isset( $this->mTransparentTagHooks[$tag] ) ? $this->mTransparentTagHooks[$tag] : null\r
+ $this->mTransparentTagHooks[$tag] = $callback;\r
+\r
+ I FOUND MAH $oldVal\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Remove all tag hooks\r
+ WANT\r
+ SO IM LIKE clearTagHooks\r
+ UR SPECIAL mTagHooks IZ EMPTY;\r
+ UR SPECIAL mStripList IZ $this->mDefaultStripList;\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Create a function, e.g. {{sum:1|2|3}}\r
+ NOT WANT The callback function should have the form:\r
+ NOT WANT function myParserFunction( &$parser, $arg1, $arg2, $arg3 ) { ... }\r
+ NOT WANT \r
+ NOT WANT Or with SFH_OBJECT_ARGS:\r
+ NOT WANT function myParserFunction( $parser, $frame, $args ) { ... }\r
+ NOT WANT \r
+ NOT WANT The callback may either return the text result of the function, or an array with the text\r
+ NOT WANT in element 0, and a number of flags in the other elements. The names of the flags are\r
+ NOT WANT specified in the keys. Valid flags are:\r
+ NOT WANT found The text returned is valid, stop processing the template. This\r
+ NOT WANT is on by default.\r
+ NOT WANT nowiki Wiki markup in the return value should be escaped\r
+ NOT WANT isHTML The returned text is HTML, armour it against wikitext transformation\r
+ NOT WANT \r
+ NOT WANT @public\r
+ NOT WANT \r
+ NOT WANT @param string $id The magic word ID\r
+ NOT WANT @param mixed $callback The callback function (and object) to use\r
+ NOT WANT @param integer $flags a combination of the following flags:\r
+ NOT WANT SFH_NO_HASH No leading hash, i.e. {{plural:...}} instead of {{#if:...}}\r
+ NOT WANT \r
+ NOT WANT SFH_OBJECT_ARGS Pass the template arguments as PPNode objects instead of text. This\r
+ NOT WANT allows for conditional expansion of the parse tree, allowing you to eliminate dead\r
+ NOT WANT branches and thus speed up parsing. It is also possible to analyse the parse tree of\r
+ NOT WANT the arguments, and to control the way they are expanded.\r
+ NOT WANT \r
+ NOT WANT The $frame parameter is a PPFrame. This can be used to produce expanded text from the\r
+ NOT WANT arguments, for instance:\r
+ NOT WANT $text = isset( $args[0] ) ? $frame->expand( $args[0] ) : '';\r
+ NOT WANT \r
+ NOT WANT For technical reasons, $args[0] is pre-expanded and will be a string. This may change in\r
+ NOT WANT future versions. Please call $frame->expand() on it anyway so that your code keeps\r
+ NOT WANT working if/when this is changed.\r
+ NOT WANT \r
+ NOT WANT If you want whitespace to be trimmed from $args, you need to do it yourself, post-\r
+ NOT WANT expansion.\r
+ NOT WANT \r
+ NOT WANT Please read the documentation in includes/parser/Preprocessor.php for more information\r
+ NOT WANT about the methods available in PPFrame and PPNode.\r
+ NOT WANT \r
+ NOT WANT @return The old callback function for this name, if any\r
+ WANT\r
+ SO IM LIKE setFunctionHook WITH UR $id, $callback, $flags = 0\r
+ I HAS UR $wgContLang ON UR INTERNETS\r
+\r
+ I HAS oldVal IZ isset( $this->mFunctionHooks[$id] ) ? $this->mFunctionHooks[$id][0] : null\r
+ $this->mFunctionHooks[$id] = array( $callback, $flags );\r
+\r
+ BTW Add to function cache\r
+ I HAS mw IZ MagicWord::get( $id )\r
+ if ( !$mw )\r
+ throw new MWException( __METHOD__.'() expecting a magic word identifier.' );\r
+\r
+ I HAS synonyms IZ $mw->getSynonyms()\r
+ I HAS sensitive IZ intval( $mw->isCaseSensitive() )\r
+\r
+ IM IN UR synonyms ITZA syn\r
+ BTW Case\r
+ IZ !$sensitive\r
+ I HAS syn IZ $wgContLang->lc( $syn )\r
+ KTHX\r
+ BTW Add leading hash\r
+ IZ !( $flags & SFH_NO_HASH )\r
+ I HAS syn IZ '#' . $syn\r
+ KTHX\r
+ BTW Remove trailing colon\r
+ IZ substr( $syn, -1, 1 ) === ':'\r
+ I HAS syn IZ substr( $syn, 0, -1 )\r
+ KTHX\r
+ $this->mFunctionSynonyms[$sensitive][$syn] = $id;\r
+ KTHX\r
+ I FOUND MAH $oldVal\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Get all registered function hook identifiers\r
+ NOT WANT \r
+ NOT WANT @return array\r
+ WANT\r
+ SO IM LIKE getFunctionHooks\r
+ I FOUND MAH array_keys( $this->mFunctionHooks )\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Create a tag function, e.g. <test>some stuff</test>.\r
+ NOT WANT Unlike tag hooks, tag functions are parsed at preprocessor level.\r
+ NOT WANT Unlike parser functions, their content is not preprocessed.\r
+ WANT\r
+ SO IM LIKE setFunctionTagHook WITH UR $tag, $callback, $flags\r
+ I HAS tag IZ strtolower( $tag )\r
+ old IZ isset( $this->mFunctionTagHooks[$tag] ) ?\r
+ $this->mFunctionTagHooks[$tag] : null;\r
+ $this->mFunctionTagHooks[$tag] = array( $callback, $flags );\r
+\r
+ IZ !in_array( $tag, $this->mStripList )\r
+ $this->mStripList[] = $tag;\r
+ KTHX\r
+\r
+ I FOUND MAH $old\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT FIXME: update documentation. makeLinkObj() is deprecated.\r
+ NOT WANT Replace <!--LINK--> link placeholders with actual links, in the buffer\r
+ NOT WANT Placeholders created in Skin::makeLinkObj()\r
+ NOT WANT Returns an array of link CSS classes, indexed by PDBK.\r
+ WANT\r
+ SO IM LIKE replaceLinkHolders WITH UR &$text, $options = 0\r
+ I FOUND MAH $this->mLinkHolders->replace( $text )\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Replace <!--LINK--> link placeholders with plain text of links\r
+ NOT WANT (not HTML-formatted).\r
+ NOT WANT @param string $text\r
+ NOT WANT @return string\r
+ WANT\r
+ SO IM LIKE replaceLinkHoldersText WITH UR $text\r
+ I FOUND MAH $this->mLinkHolders->replaceText( $text )\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Renders an image gallery from a text with one line per image.\r
+ NOT WANT text labels may be given by using |-style alternative text. E.g.\r
+ NOT WANT Image:one.jpg|The number "1"\r
+ NOT WANT Image:tree.jpg|A tree\r
+ NOT WANT given as text will return the HTML of a gallery with two images,\r
+ NOT WANT labeled 'The number "1"' and\r
+ NOT WANT 'A tree'.\r
+ WANT\r
+ SO IM LIKE renderImageGallery WITH UR $text, $params\r
+ I HAS ig IZ new ImageGallery()\r
+ $ig->setContextTitle( $this->mTitle );\r
+ $ig->setShowBytes( false );\r
+ $ig->setShowFilename( false );\r
+ $ig->setParser( $this );\r
+ $ig->setHideBadImages();\r
+ $ig->setAttributes( Sanitizer::validateTagAttributes( $params, 'table' ) );\r
+ $ig->useSkin( $this->mOptions->getSkin() );\r
+ $ig->mRevisionId = $this->mRevisionId;\r
+\r
+ IZ isset( $params['showfilename'] )\r
+ $ig->setShowFilename( true );\r
+ NOWAI\r
+ $ig->setShowFilename( false );\r
+ KTHX\r
+ IZ isset( $params['caption'] )\r
+ I HAS caption IZ $params['caption']\r
+ I HAS caption IZ htmlspecialchars( $caption )\r
+ I HAS caption IZ $this->replaceInternalLinks( $caption )\r
+ $ig->setCaptionHtml( $caption );\r
+ KTHX\r
+ IZ isset( $params['perrow'] )\r
+ $ig->setPerRow( $params['perrow'] );\r
+ KTHX\r
+ IZ isset( $params['widths'] )\r
+ $ig->setWidths( $params['widths'] );\r
+ KTHX\r
+ IZ isset( $params['heights'] )\r
+ $ig->setHeights( $params['heights'] );\r
+ KTHX\r
+\r
+ IM ON UR wfRunHooks DOING 'BeforeParserrenderImageGallery', array( &$this, &$ig )\r
+\r
+ I HAS lines IZ StringUtils::explode( "\n", $text )\r
+ IM IN UR lines ITZA line\r
+ BTW match lines like these:\r
+ BTW Image:someimage.jpg|This is some image\r
+ I HAS matches IZ EMPTY\r
+ IM ON UR preg_match DOING "/^([^|]+)(\\|(.*))?$/", $line, $matches\r
+ BTW Skip empty lines\r
+ IZ count( $matches ) == 0\r
+ continue;\r
+ KTHX\r
+\r
+ IZ strpos( $matches[0], '%' ) !== false\r
+ $matches[1] = urldecode( $matches[1] );\r
+ KTHX\r
+ I HAS tp IZ Title::newFromText( $matches[1] )\r
+ $nt =& $tp;\r
+ IZ is_null( $nt )\r
+ BTW Bogus title. Ignore these so we don't bomb out later.\r
+ continue;\r
+ KTHX\r
+ IZ isset( $matches[3] )\r
+ I HAS label IZ $matches[3]\r
+ NOWAI\r
+ I HAS label IZ ''\r
+ KTHX\r
+\r
+ I HAS html IZ $this->recursiveTagParse( trim( $label ) )\r
+\r
+ $ig->add( $nt, $html );\r
+\r
+ BTW Only add real images (bug #5586)\r
+ IZ $nt->getNamespace() == NS_FILE\r
+ IM ON UR SPECIAL mOutput->addImage DOING $nt->getDBkey()\r
+ KTHX\r
+ KTHX\r
+ I FOUND MAH $ig->toHTML()\r
+ KTHX\r
+\r
+ SO IM LIKE getImageParams WITH UR $handler\r
+ IZ $handler\r
+ I HAS handlerClass IZ get_class( $handler )\r
+ NOWAI\r
+ I HAS handlerClass IZ ''\r
+ KTHX\r
+ IZ !isset( $this->mImageParams[$handlerClass] )\r
+ BTW Initialise static lists\r
+ static $internalParamNames = array(\r
+ 'horizAlign' => array( 'left', 'right', 'center', 'none' ),\r
+ 'vertAlign' => array( 'baseline', 'sub', 'super', 'top', 'text-top', 'middle',\r
+ 'bottom', 'text-bottom' ),\r
+ 'frame' => array( 'thumbnail', 'manualthumb', 'framed', 'frameless',\r
+ 'upright', 'border', 'link', 'alt' ),\r
+ BUCKET\r
+ static $internalParamMap;\r
+ IZ !$internalParamMap\r
+ I HAS internalParamMap IZ EMPTY\r
+ IM IN UR internalParamNames ITZA type => $names\r
+ IM IN UR names ITZA name\r
+ I HAS magicName IZ str_replace( '-', '_', "img_$name" )\r
+ $internalParamMap[$magicName] = array( $type, $name );\r
+ KTHX\r
+ KTHX\r
+ KTHX\r
+\r
+ BTW Add handler params\r
+ I HAS paramMap IZ $internalParamMap\r
+ IZ $handler\r
+ I HAS handlerParamMap IZ $handler->getParamMap()\r
+ IM IN UR handlerParamMap ITZA magic => $paramName\r
+ $paramMap[$magic] = array( 'handler', $paramName );\r
+ KTHX\r
+ KTHX\r
+ $this->mImageParams[$handlerClass] = $paramMap;\r
+ $this->mImageParamsMagicArray[$handlerClass] = new MagicWordArray( array_keys( $paramMap ) );\r
+ KTHX\r
+ I FOUND MAH array( $this->mImageParams[$handlerClass], $this->mImageParamsMagicArray[$handlerClass] )\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Parse image options text and use it to make an image\r
+ NOT WANT @param Title $title\r
+ NOT WANT @param string $options\r
+ NOT WANT @param LinkHolderArray $holders\r
+ WANT\r
+ SO IM LIKE makeImage WITH UR $title, $options, $holders = false\r
+ BTW Check if the options text is of the form "options|alt text"\r
+ BTW Options are:\r
+ BTW * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang\r
+ BTW * left no resizing, just left align. label is used for alt= only\r
+ BTW * right same, but right aligned\r
+ BTW * none same, but not aligned\r
+ BTW * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox\r
+ BTW * center center the image\r
+ BTW * frame Keep original image size, no magnify-button.\r
+ BTW * framed Same as "frame"\r
+ BTW * frameless like 'thumb' but without a frame. Keeps user preferences for width\r
+ BTW * upright reduce width for upright images, rounded to full __0 px\r
+ BTW * border draw a 1px border around the image\r
+ BTW * alt Text for HTML alt attribute (defaults to empty)\r
+ BTW * link Set the target of the image link. Can be external, interwiki, or local\r
+ BTW vertical-align values (no % or length right now):\r
+ BTW * baseline\r
+ BTW * sub\r
+ BTW * super\r
+ BTW * top\r
+ BTW * text-top\r
+ BTW * middle\r
+ BTW * bottom\r
+ BTW * text-bottom\r
+\r
+ I HAS parts IZ StringUtils::explode( "|", $options )\r
+ I HAS sk IZ $this->mOptions->getSkin()\r
+\r
+ BTW Give extensions a chance to select the file revision for us\r
+ I HAS skip IZ $time = $descQuery = false\r
+ IM ON UR wfRunHooks DOING 'BeforeParserMakeImageLinkObj', array( &$this, &$title, &$skip, &$time, &$descQuery )\r
+\r
+ IZ $skip\r
+ I FOUND MAH $sk->link( $title )\r
+ KTHX\r
+\r
+ BTW Get the file\r
+ I HAS imagename IZ $title->getDBkey()\r
+ I HAS file IZ wfFindFile( $title, array( 'time' => $time ) )\r
+ BTW Get parameter map\r
+ I HAS handler IZ $file ? $file->getHandler() : false\r
+\r
+ IM ON UR list DOING $paramMap, $mwArray ) = $this->getImageParams( $handler\r
+\r
+ BTW Process the input parameters\r
+ I HAS caption IZ ''\r
+ I HAS params IZ BUCKET 'frame' => array(), 'handler' => array(),\r
+ 'horizAlign' => array(), 'vertAlign' => array() );\r
+ IM IN UR parts ITZA part\r
+ I HAS part IZ trim( $part )\r
+ IM ON UR list DOING $magicName, $value ) = $mwArray->matchVariableStartToEnd( $part\r
+ I HAS validated IZ false\r
+ IZ isset( $paramMap[$magicName] )\r
+ list( $type, $paramName ) = $paramMap[$magicName];\r
+\r
+ BTW Special case; width and height come in one variable together\r
+ IZ $type === 'handler' && $paramName === 'width'\r
+ I HAS m IZ EMPTY\r
+ BTW (bug 13500) In both cases (width/height and width only),\r
+ BTW permit trailing "px" for backward compatibility.\r
+ IZ preg_match( '/^([0-9]*)x([0-9]*)\s*(?:px)?\s*$/', $value, $m )\r
+ I HAS width IZ intval( $m[1] )\r
+ I HAS height IZ intval( $m[2] )\r
+ IZ $handler->validateParam( 'width', $width )\r
+ $params[$type]['width'] = $width;\r
+ I HAS validated IZ true\r
+ KTHX\r
+ IZ $handler->validateParam( 'height', $height )\r
+ $params[$type]['height'] = $height;\r
+ I HAS validated IZ true\r
+ KTHX\r
+ ORLY preg_match( '/^[0-9]*\s*(?:px)?\s*$/', $value )\r
+ I HAS width IZ intval( $value )\r
+ IZ $handler->validateParam( 'width', $width )\r
+ $params[$type]['width'] = $width;\r
+ I HAS validated IZ true\r
+ KTHX\r
+ KTHX # else no validation -- bug 13436\r
+ NOWAI\r
+ IZ $type === 'handler'\r
+ BTW Validate handler parameter\r
+ I HAS validated IZ $handler->validateParam( $paramName, $value )\r
+ NOWAI\r
+ BTW Validate internal parameters\r
+ switch( $paramName ) {\r
+ case 'manualthumb':\r
+ case 'alt':\r
+ BTW @todo Fixme: possibly check validity here for\r
+ BTW manualthumb? downstream behavior seems odd with\r
+ BTW missing manual thumbs.\r
+ I HAS validated IZ true\r
+ I HAS value IZ $this->stripAltText( $value, $holders )\r
+ break;\r
+ case 'link':\r
+ I HAS chars IZ self::EXT_LINK_URL_CLASS\r
+ I HAS prots IZ $this->mUrlProtocols\r
+ IZ $value === ''\r
+ I HAS paramName IZ 'no-link'\r
+ I HAS value IZ true\r
+ I HAS validated IZ true\r
+ ORLY preg_match( "/^$prots/", $value )\r
+ IZ preg_match( "/^($prots)$chars+$/", $value, $m )\r
+ I HAS paramName IZ 'link-url'\r
+ IM ON UR SPECIAL mOutput->addExternalLink DOING $value\r
+ I HAS validated IZ true\r
+ KTHX\r
+ NOWAI\r
+ I HAS linkTitle IZ Title::newFromText( $value )\r
+ IZ $linkTitle\r
+ I HAS paramName IZ 'link-title'\r
+ I HAS value IZ $linkTitle\r
+ IM ON UR SPECIAL mOutput->addLink DOING $linkTitle\r
+ I HAS validated IZ true\r
+ KTHX\r
+ KTHX\r
+ break;\r
+ default:\r
+ BTW Most other things appear to be empty or numeric...\r
+ I HAS validated IZ ( $value === false || is_numeric( trim( $value ) ) )\r
+ KTHX\r
+ KTHX\r
+\r
+ IZ $validated\r
+ $params[$type][$paramName] = $value;\r
+ KTHX\r
+ KTHX\r
+ KTHX\r
+ IZ !$validated\r
+ I HAS caption IZ $part\r
+ KTHX\r
+ KTHX\r
+\r
+ BTW Process alignment parameters\r
+ IZ $params['horizAlign']\r
+ $params['frame']['align'] = key( $params['horizAlign'] );\r
+ KTHX\r
+ IZ $params['vertAlign']\r
+ $params['frame']['valign'] = key( $params['vertAlign'] );\r
+ KTHX\r
+\r
+ $params['frame']['caption'] = $caption;\r
+\r
+ BTW Will the image be presented in a frame, with the caption below?\r
+ imageIsFramed IZ isset( $params['frame']['frame'] ) ||\r
+ isset( $params['frame']['framed'] ) ||\r
+ isset( $params['frame']['thumbnail'] ) ||\r
+ IM ON UR isset DOING $params['frame']['manualthumb']\r
+\r
+ BTW In the old days, [[Image:Foo|text...]] would set alt text. Later it\r
+ BTW came to also set the caption, ordinary text after the image -- which\r
+ BTW makes no sense, because that just repeats the text multiple times in\r
+ BTW screen readers. It *also* came to set the title attribute.\r
+ BTW \r
+ BTW Now that we have an alt attribute, we should not set the alt text to\r
+ BTW equal the caption: that's worse than useless, it just repeats the\r
+ BTW text. This is the framed/thumbnail case. If there's no caption, we\r
+ BTW use the unnamed parameter for alt text as well, just for the time be-\r
+ BTW ing, if the unnamed param is set and the alt param is not.\r
+ BTW \r
+ BTW For the future, we need to figure out if we want to tweak this more,\r
+ BTW e.g., introducing a title= parameter for the title; ignoring the un-\r
+ BTW named parameter entirely for images without a caption; adding an ex-\r
+ BTW plicit caption= parameter and preserving the old magic unnamed para-\r
+ BTW meter for BC; ...\r
+ IZ $imageIsFramed # Framed image\r
+ IZ $caption === '' && !isset( $params['frame']['alt'] )\r
+ BTW No caption or alt text, add the filename as the alt text so\r
+ BTW that screen readers at least get some description of the image\r
+ $params['frame']['alt'] = $title->getText();\r
+ KTHX\r
+ BTW Do not set $params['frame']['title'] because tooltips don't make sense\r
+ BTW for framed images\r
+ NOWAI # Inline image\r
+ IZ !isset( $params['frame']['alt'] )\r
+ BTW No alt text, use the "caption" for the alt text\r
+ if ( $caption !== '') {\r
+ $params['frame']['alt'] = $this->stripAltText( $caption, $holders );\r
+ NOWAI\r
+ BTW No caption, fall back to using the filename for the\r
+ BTW alt text\r
+ $params['frame']['alt'] = $title->getText();\r
+ KTHX\r
+ KTHX\r
+ BTW Use the "caption" for the tooltip text\r
+ $params['frame']['title'] = $this->stripAltText( $caption, $holders );\r
+ KTHX\r
+\r
+ IM ON UR wfRunHooks DOING 'ParserMakeImageParams', array( $title, $file, &$params )\r
+\r
+ BTW Linker does the rest\r
+ I HAS ret IZ $sk->makeImageLink2( $title, $file, $params['frame'], $params['handler'], $time, $descQuery )\r
+\r
+ BTW Give the handler a chance to modify the parser object\r
+ IZ $handler\r
+ $handler->parserTransformHook( $this, $file );\r
+ KTHX\r
+\r
+ I FOUND MAH $ret\r
+ KTHX\r
+\r
+ SO IM LIKE stripAltText WITH UR $caption, $holders\r
+ BTW Strip bad stuff out of the title (tooltip). We can't just use\r
+ BTW replaceLinkHoldersText() here, because if this function is called\r
+ BTW from replaceInternalLinks2(), mLinkHolders won't be up-to-date.\r
+ IZ $holders\r
+ I HAS tooltip IZ $holders->replaceText( $caption )\r
+ NOWAI\r
+ I HAS tooltip IZ $this->replaceLinkHoldersText( $caption )\r
+ KTHX\r
+\r
+ BTW make sure there are no placeholders in thumbnail attributes\r
+ BTW that are later expanded to html- so expand them now and\r
+ BTW remove the tags\r
+ I HAS tooltip IZ $this->mStripState->unstripBoth( $tooltip )\r
+ I HAS tooltip IZ Sanitizer::stripAllTags( $tooltip )\r
+\r
+ I FOUND MAH $tooltip\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Set a flag in the output object indicating that the content is dynamic and\r
+ NOT WANT shouldn't be cached.\r
+ WANT\r
+ SO IM LIKE disableCache\r
+ IM ON UR wfDebug DOING "Parser output marked as uncacheable.\n"\r
+ UR SPECIAL mOutput->mCacheTime IZ -1;\r
+ KTHX\r
+\r
+ DO NOT WANT#@+\r
+ NOT WANT Callback from the Sanitizer for expanding items found in HTML attribute\r
+ NOT WANT values, so they can be safely tested and escaped.\r
+ NOT WANT @param string $text\r
+ NOT WANT @param PPFrame $frame\r
+ NOT WANT @return string\r
+ NOT WANT @private\r
+ WANT\r
+ SO IM LIKE attributeStripCallback WITH UR &$text, $frame = false\r
+ I HAS text IZ $this->replaceVariables( $text, $frame )\r
+ I HAS text IZ $this->mStripState->unstripBoth( $text )\r
+ I FOUND MAH $text\r
+ KTHX\r
+\r
+ DO NOT WANT#@-*/\r
+\r
+ DO NOT WANT#@+\r
+ NOT WANT Accessor/mutator\r
+ WANT\r
+ SO IM LIKE Title WITH UR $x = null TESTING UR return wfSetVar( $this->mTitle, $x );\r
+ SO IM LIKE Options WITH UR $x = null TESTING UR return wfSetVar( $this->mOptions, $x );\r
+ SO IM LIKE OutputType WITH UR $x = null TESTING UR return wfSetVar( $this->mOutputType, $x );\r
+ DO NOT WANT#@-*/\r
+\r
+ DO NOT WANT#@+\r
+ NOT WANT Accessor\r
+ WANT\r
+ SO IM LIKE getTags \r
+ I FOUND MAH array_merge( array_keys( $this->mTransparentTagHooks ), array_keys( $this->mTagHooks ) ) \r
+ KTHX\r
+ DO NOT WANT#@-*/\r
+\r
+\r
+ DO NOT WANT\r
+ NOT WANT Break wikitext input into sections, and either pull or replace\r
+ NOT WANT some particular section's text.\r
+ NOT WANT \r
+ NOT WANT External callers should use the getSection and replaceSection methods.\r
+ NOT WANT \r
+ NOT WANT @param string $text Page wikitext\r
+ NOT WANT @param string $section A section identifier string of the form:\r
+ NOT WANT <flag1> - <flag2> - ... - <section number>\r
+ NOT WANT \r
+ NOT WANT Currently the only recognised flag is "T", which means the target section number\r
+ NOT WANT was derived during a template inclusion parse, in other words this is a template\r
+ NOT WANT section edit link. If no flags are given, it was an ordinary section edit link.\r
+ NOT WANT This flag is required to avoid a section numbering mismatch when a section is\r
+ NOT WANT enclosed by <includeonly> (bug 6563).\r
+ NOT WANT \r
+ NOT WANT The section number 0 pulls the text before the first heading; other numbers will\r
+ NOT WANT pull the given section along with its lower-level subsections. If the section is\r
+ NOT WANT not found, $mode=get will return $newtext, and $mode=replace will return $text.\r
+ NOT WANT \r
+ NOT WANT @param string $mode One of "get" or "replace"\r
+ NOT WANT @param string $newText Replacement text for section data.\r
+ NOT WANT @return string for "get", the extracted section text.\r
+ NOT WANT for "replace", the whole page with the section replaced.\r
+ WANT\r
+ SO IM LIKE extractSections WITH UR $text, $section, $mode, $newText=''\r
+ I HAS UR $wgTitle ON UR INTERNETS\r
+ IM ON UR SPECIAL clearState\r
+ IM ON UR SPECIAL setTitle DOING $wgTitle # not generally used but removes an ugly failure mode\r
+ UR SPECIAL mOptions IZ new ParserOptions;\r
+ IM ON UR SPECIAL setOutputType DOING self::OT_PLAIN\r
+ I HAS outText IZ ''\r
+ I HAS frame IZ $this->getPreprocessor()->newFrame()\r
+\r
+ BTW Process section extraction flags\r
+ I HAS flags IZ 0\r
+ I HAS sectionParts IZ explode( '-', $section )\r
+ I HAS sectionIndex IZ array_pop( $sectionParts )\r
+ IM IN UR sectionParts ITZA part\r
+ IZ $part === 'T'\r
+ $flags |= self::PTD_FOR_INCLUSION;\r
+ KTHX\r
+ KTHX\r
+ BTW Preprocess the text\r
+ I HAS root IZ $this->preprocessToDom( $text, $flags )\r
+\r
+ BTW <h> nodes indicate section breaks\r
+ BTW They can only occur at the top level, so we can find them by iterating the root's children\r
+ I HAS node IZ $root->getFirstChild()\r
+\r
+ BTW Find the target section\r
+ IZ $sectionIndex == 0\r
+ BTW Section zero doesn't nest, level=big\r
+ I HAS targetLevel IZ 1000\r
+ NOWAI\r
+ STEALIN UR $node\r
+ IZ $node->getName() === 'h'\r
+ I HAS bits IZ $node->splitHeading()\r
+ IZ $bits['i'] == $sectionIndex\r
+ I HAS targetLevel IZ $bits['level']\r
+ break;\r
+ KTHX\r
+ KTHX\r
+ IZ $mode === 'replace'\r
+ outText HAS MOAR $frame->expand( $node, PPFrame::RECOVER_ORIG );\r
+ KTHX\r
+ I HAS node IZ $node->getNextSibling()\r
+ KTHX\r
+ KTHX\r
+\r
+ IZ !$node\r
+ BTW Not found\r
+ IZ $mode === 'get'\r
+ I FOUND MAH $newText\r
+ NOWAI\r
+ I FOUND MAH $text\r
+ KTHX\r
+ KTHX\r
+\r
+ BTW Find the end of the section, including nested sections\r
+ do {\r
+ IZ $node->getName() === 'h'\r
+ I HAS bits IZ $node->splitHeading()\r
+ I HAS curLevel IZ $bits['level']\r
+ IZ $bits['i'] != $sectionIndex && $curLevel <= $targetLevel\r
+ break;\r
+ KTHX\r
+ KTHX\r
+ IZ $mode === 'get'\r
+ outText HAS MOAR $frame->expand( $node, PPFrame::RECOVER_ORIG );\r
+ KTHX\r
+ I HAS node IZ $node->getNextSibling()\r
+ KTHX while ( $node );\r
+\r
+ BTW Write out the remainder (in replace mode only)\r
+ IZ $mode === 'replace'\r
+ BTW Output the replacement text\r
+ BTW Add two newlines on -- trailing whitespace in $newText is conventionally\r
+ BTW stripped by the editor, so we need both newlines to restore the paragraph gap\r
+ BTW Only add trailing whitespace if there is newText\r
+ IZ $newText != ""\r
+ outText HAS MOAR $newText . "\n\n";\r
+ KTHX\r
+\r
+ STEALIN UR $node\r
+ outText HAS MOAR $frame->expand( $node, PPFrame::RECOVER_ORIG );\r
+ I HAS node IZ $node->getNextSibling()\r
+ KTHX\r
+ KTHX\r
+\r
+ IZ is_string( $outText )\r
+ BTW Re-insert stripped tags\r
+ I HAS outText IZ rtrim( $this->mStripState->unstripBoth( $outText ) )\r
+ KTHX\r
+\r
+ I FOUND MAH $outText\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT This function returns the text of a section, specified by a number ($section).\r
+ NOT WANT A section is text under a heading like == Heading == or \<h1\>Heading\</h1\>, or\r
+ NOT WANT the first section before any such heading (section 0).\r
+ NOT WANT \r
+ NOT WANT If a section contains subsections, these are also returned.\r
+ NOT WANT \r
+ NOT WANT @param string $text text to look in\r
+ NOT WANT @param string $section section identifier\r
+ NOT WANT @param string $deftext default to return if section is not found\r
+ NOT WANT @return string text of the requested section\r
+ WANT\r
+ SO IM LIKE getSection WITH UR $text, $section, $deftext=''\r
+ I FOUND MAH $this->extractSections( $text, $section, "get", $deftext )\r
+ KTHX\r
+\r
+ SO IM LIKE replaceSection WITH UR $oldtext, $section, $text\r
+ I FOUND MAH $this->extractSections( $oldtext, $section, "replace", $text )\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Get the timestamp associated with the current revision, adjusted for\r
+ NOT WANT the default server-local timestamp\r
+ WANT\r
+ SO IM LIKE getRevisionTimestamp\r
+ IZ is_null( $this->mRevisionTimestamp )\r
+ IM ON UR wfProfileIn DOING __METHOD__\r
+ I HAS UR $wgContLang ON UR INTERNETS\r
+ I HAS dbr IZ wfGetDB( DB_SLAVE )\r
+ timestamp IZ $dbr->selectField( 'revision', 'rev_timestamp',\r
+ IM ON UR array DOING 'rev_id' => $this->mRevisionId ), __METHOD__\r
+\r
+ BTW Normalize timestamp to internal MW format for timezone processing.\r
+ BTW This has the added side-effect of replacing a null value with\r
+ BTW the current time, which gives us more sensible behavior for\r
+ BTW previews.\r
+ I HAS timestamp IZ wfTimestamp( TS_MW, $timestamp )\r
+\r
+ BTW The cryptic '' timezone parameter tells to use the site-default\r
+ BTW timezone offset instead of the user settings.\r
+ BTW \r
+ BTW Since this value will be saved into the parser cache, served\r
+ BTW to other users, and potentially even used inside links and such,\r
+ BTW it needs to be consistent for all visitors.\r
+ UR SPECIAL mRevisionTimestamp IZ $wgContLang->userAdjust( $timestamp, '' );\r
+\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ KTHX\r
+ I FOUND MAH $this->mRevisionTimestamp\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Get the name of the user that edited the last revision\r
+ WANT\r
+ SO IM LIKE getRevisionUser\r
+ BTW if this template is subst: the revision id will be blank,\r
+ BTW so just use the current user's name\r
+ IZ $this->mRevisionId\r
+ I HAS revision IZ Revision::newFromId( $this->mRevisionId )\r
+ I HAS revuser IZ $revision->getUserText()\r
+ NOWAI\r
+ I HAS UR $wgUser ON UR INTERNETS\r
+ I HAS revuser IZ $wgUser->getName()\r
+ KTHX\r
+ I FOUND MAH $revuser\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Mutator for $mDefaultSort\r
+ NOT WANT \r
+ NOT WANT @param $sort New value\r
+ WANT\r
+ SO IM LIKE setDefaultSort WITH UR $sort\r
+ UR SPECIAL mDefaultSort IZ $sort;\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Accessor for $mDefaultSort\r
+ NOT WANT Will use the title/prefixed title if none is set\r
+ NOT WANT \r
+ NOT WANT @return string\r
+ WANT\r
+ SO IM LIKE getDefaultSort\r
+ I HAS UR $wgCategoryPrefixedDefaultSortkey ON UR INTERNETS\r
+ IZ $this->mDefaultSort !== false\r
+ I FOUND MAH $this->mDefaultSort\r
+ KTHX elseif ( $this->mTitle->getNamespace() == NS_CATEGORY ||\r
+ !$wgCategoryPrefixedDefaultSortkey ) \r
+ {\r
+ I FOUND MAH $this->mTitle->getText()\r
+ NOWAI\r
+ I FOUND MAH $this->mTitle->getPrefixedText()\r
+ KTHX\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Accessor for $mDefaultSort\r
+ NOT WANT Unlike getDefaultSort(), will return false if none is set\r
+ NOT WANT \r
+ NOT WANT @return string or false\r
+ WANT\r
+ SO IM LIKE getCustomDefaultSort\r
+ I FOUND MAH $this->mDefaultSort\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Try to guess the section anchor name based on a wikitext fragment\r
+ NOT WANT presumably extracted from a heading, for example "Header" from\r
+ NOT WANT "== Header ==".\r
+ WANT\r
+ SO IM LIKE guessSectionNameFromWikiText WITH UR $text\r
+ BTW Strip out wikitext links(they break the anchor)\r
+ I HAS text IZ $this->stripSectionName( $text )\r
+ I HAS headline IZ Sanitizer::decodeCharReferences( $text )\r
+ BTW strip out HTML\r
+ I HAS headline IZ StringUtils::delimiterReplace( '<', '>', '', $headline )\r
+ I HAS headline IZ trim( $headline )\r
+ I HAS sectionanchor IZ '#' . urlencode( str_replace( ' ', '_', $headline ) )\r
+ I HAS replacearray IZ BUCKET\r
+ '%3A' => ':',\r
+ '%' => '.'\r
+ BUCKET\r
+ return str_replace(\r
+ array_keys( $replacearray ),\r
+ array_values( $replacearray ),\r
+ $sectionanchor );\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT Strips a text string of wikitext for use in a section anchor\r
+ NOT WANT \r
+ NOT WANT Accepts a text string and then removes all wikitext from the\r
+ NOT WANT string and leaves only the resultant text (i.e. the result of\r
+ NOT WANT [[User:WikiSysop|Sysop]] would be "Sysop" and the result of\r
+ NOT WANT [[User:WikiSysop]] would be "User:WikiSysop") - this is intended\r
+ NOT WANT to create valid section anchors by mimicing the output of the\r
+ NOT WANT parser when headings are parsed.\r
+ NOT WANT \r
+ NOT WANT @param $text string Text string to be stripped of wikitext\r
+ NOT WANT for use in a Section anchor\r
+ NOT WANT @return Filtered text string\r
+ WANT\r
+ SO IM LIKE stripSectionName WITH UR $text\r
+ BTW Strip internal link markup\r
+ I HAS text IZ preg_replace( '/\[\[:?([^[|]+)\|([^[]+)\]\]/', '$2', $text )\r
+ I HAS text IZ preg_replace( '/\[\[:?([^[]+)\|?\]\]/', '$1', $text )\r
+\r
+ BTW Strip external link markup (FIXME: Not Tolerant to blank link text\r
+ BTW I.E. [http://www.mediawiki.org] will render as [1] or something depending\r
+ BTW on how many empty links there are on the page - need to figure that out.\r
+ I HAS text IZ preg_replace( '/\[(?:' . wfUrlProtocols() . ')([^ ]+?) ([^[]+)\]/', '$2', $text )\r
+\r
+ BTW Parse wikitext quotes (italics & bold)\r
+ I HAS text IZ $this->doQuotes( $text )\r
+\r
+ BTW Strip HTML tags\r
+ I HAS text IZ StringUtils::delimiterReplace( '<', '>', '', $text )\r
+ I FOUND MAH $text\r
+ KTHX\r
+\r
+ SO IM LIKE srvus WITH UR $text\r
+ I FOUND MAH $this->testSrvus( $text, $this->mOutputType )\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT strip/replaceVariables/unstrip for preprocessor regression testing\r
+ WANT\r
+ SO IM LIKE testSrvus WITH UR $text, $title, $options, $outputType = self::OT_HTML\r
+ IM ON UR SPECIAL clearState\r
+ IZ !$title instanceof Title\r
+ I HAS title IZ Title::newFromText( $title )\r
+ KTHX\r
+ UR SPECIAL mTitle IZ $title;\r
+ UR SPECIAL mOptions IZ $options;\r
+ IM ON UR SPECIAL setOutputType DOING $outputType\r
+ I HAS text IZ $this->replaceVariables( $text )\r
+ I HAS text IZ $this->mStripState->unstripBoth( $text )\r
+ I HAS text IZ Sanitizer::removeHTMLtags( $text )\r
+ I FOUND MAH $text\r
+ KTHX\r
+\r
+ SO IM LIKE testPst WITH UR $text, $title, $options\r
+ I HAS UR $wgUser ON UR INTERNETS\r
+ IZ !$title instanceof Title\r
+ I HAS title IZ Title::newFromText( $title )\r
+ KTHX\r
+ I FOUND MAH $this->preSaveTransform( $text, $title, $wgUser, $options )\r
+ KTHX\r
+\r
+ SO IM LIKE testPreprocess WITH UR $text, $title, $options\r
+ IZ !$title instanceof Title\r
+ I HAS title IZ Title::newFromText( $title )\r
+ KTHX\r
+ I FOUND MAH $this->testSrvus( $text, $title, $options, self::OT_PREPROCESS )\r
+ KTHX\r
+\r
+ SO IM LIKE markerSkipCallback WITH UR $s, $callback\r
+ I HAS i IZ 0\r
+ I HAS out IZ ''\r
+ STEALIN UR $i < strlen( $s )\r
+ I HAS markerStart IZ strpos( $s, $this->mUniqPrefix, $i )\r
+ IZ $markerStart === false\r
+ out HAS MOAR call_user_func( $callback, substr( $s, $i ) );\r
+ break;\r
+ NOWAI\r
+ out HAS MOAR call_user_func( $callback, substr( $s, $i, $markerStart - $i ) );\r
+ I HAS markerEnd IZ strpos( $s, self::MARKER_SUFFIX, $markerStart )\r
+ IZ $markerEnd === false\r
+ out HAS MOAR substr( $s, $markerStart );\r
+ break;\r
+ NOWAI\r
+ $markerEnd += strlen( self::MARKER_SUFFIX );\r
+ out HAS MOAR substr( $s, $markerStart, $markerEnd - $markerStart );\r
+ I HAS i IZ $markerEnd\r
+ KTHX\r
+ KTHX\r
+ KTHX\r
+ I FOUND MAH $out\r
+ KTHX\r
+\r
+ SO IM LIKE serialiseHalfParsedText WITH UR $text\r
+ I HAS data IZ EMPTY\r
+ $data['text'] = $text;\r
+\r
+ BTW First, find all strip markers, and store their\r
+ BTW data in an array.\r
+ I HAS stripState IZ new StripState\r
+ I HAS pos IZ 0\r
+ while ( ( $start_pos = strpos( $text, $this->mUniqPrefix, $pos ) ) \r
+ && ( $end_pos = strpos( $text, self::MARKER_SUFFIX, $pos ) ) ) \r
+ {\r
+ $end_pos += strlen( self::MARKER_SUFFIX );\r
+ I HAS marker IZ substr( $text, $start_pos, $end_pos-$start_pos )\r
+\r
+ IZ !empty( $this->mStripState->general->data[$marker] )\r
+ I HAS replaceArray IZ $stripState->general\r
+ I HAS stripText IZ $this->mStripState->general->data[$marker]\r
+ ORLY !empty( $this->mStripState->nowiki->data[$marker] )\r
+ I HAS replaceArray IZ $stripState->nowiki\r
+ I HAS stripText IZ $this->mStripState->nowiki->data[$marker]\r
+ NOWAI\r
+ throw new MWException( "Hanging strip marker: '$marker'." );\r
+ KTHX\r
+\r
+ $replaceArray->setPair( $marker, $stripText );\r
+ I HAS pos IZ $end_pos\r
+ KTHX\r
+ $data['stripstate'] = $stripState;\r
+\r
+ BTW Now, find all of our links, and store THEIR\r
+ BTW data in an array! :)\r
+ I HAS links IZ BUCKET 'internal' => array(), 'interwiki' => array() );\r
+ I HAS pos IZ 0\r
+\r
+ BTW Internal links\r
+ STEALIN UR ( $start_pos = strpos( $text, '<!--LINK ', $pos ) )\r
+ IM ON UR list DOING $ns, $trail ) = explode( ':', substr( $text, $start_pos + strlen( '<!--LINK ' ) ), 2\r
+\r
+ I HAS ns IZ trim( $ns )\r
+ IZ empty( $links['internal'][$ns] )\r
+ $links['internal'][$ns] = array();\r
+ KTHX\r
+\r
+ I HAS key IZ trim( substr( $trail, 0, strpos( $trail, '-->' ) ) )\r
+ $links['internal'][$ns][] = $this->mLinkHolders->internals[$ns][$key];\r
+ I HAS pos IZ $start_pos + strlen( "<!--LINK $ns:$key-->" )\r
+ KTHX\r
+\r
+ I HAS pos IZ 0\r
+\r
+ BTW Interwiki links\r
+ STEALIN UR ( $start_pos = strpos( $text, '<!--IWLINK ', $pos ) )\r
+ I HAS data IZ substr( $text, $start_pos )\r
+ I HAS key IZ trim( substr( $data, 0, strpos( $data, '-->' ) ) )\r
+ $links['interwiki'][] = $this->mLinkHolders->interwiki[$key];\r
+ I HAS pos IZ $start_pos + strlen( "<!--IWLINK $key-->" )\r
+ KTHX\r
+\r
+ $data['linkholder'] = $links;\r
+\r
+ I FOUND MAH $data\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT TODO: document\r
+ NOT WANT @param $data Array\r
+ NOT WANT @param $intPrefix String unique identifying prefix\r
+ NOT WANT @return String\r
+ WANT\r
+ SO IM LIKE unserialiseHalfParsedText WITH UR $data, $intPrefix = null\r
+ IZ !$intPrefix\r
+ I HAS intPrefix IZ $this->getRandomString()\r
+ KTHX\r
+\r
+ BTW First, extract the strip state.\r
+ I HAS stripState IZ $data['stripstate']\r
+ IM ON UR SPECIAL mStripState->general->merge DOING $stripState->general\r
+ IM ON UR SPECIAL mStripState->nowiki->merge DOING $stripState->nowiki\r
+\r
+ BTW Now, extract the text, and renumber links\r
+ I HAS text IZ $data['text']\r
+ I HAS links IZ $data['linkholder']\r
+\r
+ BTW Internal...\r
+ foreach ( $links['internal'] as $ns => $nsLinks ) {\r
+ IM IN UR nsLinks ITZA key => $entry\r
+ I HAS newKey IZ $intPrefix . '-' . $key\r
+ $this->mLinkHolders->internals[$ns][$newKey] = $entry;\r
+\r
+ I HAS text IZ str_replace( "<!--LINK $ns:$key-->", "<!--LINK $ns:$newKey-->", $text )\r
+ KTHX\r
+ KTHX\r
+\r
+ BTW Interwiki...\r
+ foreach ( $links['interwiki'] as $key => $entry ) {\r
+ I HAS newKey IZ "$intPrefix-$key"\r
+ $this->mLinkHolders->interwikis[$newKey] = $entry;\r
+\r
+ I HAS text IZ str_replace( "<!--IWLINK $key-->", "<!--IWLINK $newKey-->", $text )\r
+ KTHX\r
+\r
+ BTW Should be good to go.\r
+ I FOUND MAH $text\r
+ KTHX\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT @todo document, briefly.\r
+ NOT WANT @ingroup Parser\r
+ WANT\r
+ IM IN UR SPECIAL StripState\r
+ I HAS UR $general, $nowiki\r
+\r
+ SO IM LIKE __construct\r
+ UR SPECIAL general IZ new ReplacementArray;\r
+ UR SPECIAL nowiki IZ new ReplacementArray;\r
+ KTHX\r
+\r
+ SO IM LIKE unstripGeneral WITH UR $text\r
+ IM ON UR wfProfileIn DOING __METHOD__\r
+ do {\r
+ I HAS oldText IZ $text\r
+ I HAS text IZ $this->general->replace( $text )\r
+ KTHX while ( $text !== $oldText );\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ I FOUND MAH $text\r
+ KTHX\r
+\r
+ SO IM LIKE unstripNoWiki WITH UR $text\r
+ IM ON UR wfProfileIn DOING __METHOD__\r
+ do {\r
+ I HAS oldText IZ $text\r
+ I HAS text IZ $this->nowiki->replace( $text )\r
+ KTHX while ( $text !== $oldText );\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ I FOUND MAH $text\r
+ KTHX\r
+\r
+ SO IM LIKE unstripBoth WITH UR $text\r
+ IM ON UR wfProfileIn DOING __METHOD__\r
+ do {\r
+ I HAS oldText IZ $text\r
+ I HAS text IZ $this->general->replace( $text )\r
+ I HAS text IZ $this->nowiki->replace( $text )\r
+ KTHX while ( $text !== $oldText );\r
+ IM ON UR wfProfileOut DOING __METHOD__\r
+ I FOUND MAH $text\r
+ KTHX\r
+ KTHX\r
+\r
+ DO NOT WANT\r
+ NOT WANT @todo document, briefly.\r
+ NOT WANT @ingroup Parser\r
+ WANT\r
+ IM IN UR SPECIAL OnlyIncludeReplacer\r
+ var $output = '';\r
+\r
+ SO IM LIKE replace WITH UR $matches\r
+ IZ substr( $matches[1], -1 ) === "\n"\r
+ $this->output .= substr( $matches[1], 0, -1 );\r
+ NOWAI\r
+ $this->output .= $matches[1];\r
+ KTHX\r
+ KTHX\r
+ KTHX\r
\ No newline at end of file