# Handle link renaming [[foo|text]] will show link as "text"
if( $match[3] != "" ) {
$text = $match[3];
- if( $match[1] === "" && $this->commentContextTitle ) {
- $match[1] = Linker::getPipeTrickLink( $text, $this->commentContextTitle );
- }
- } elseif( $match[2] == "|" ) {
- $text = Linker::getPipeTrickText( $match[1] );
} else {
$text = $match[1];
}
return $ret;
}
- /**
- * Returns valid title characters and namespace characters for pipe trick.
- *
- * FIXME: the namespace characters should not be specified like this...
- */
- static function getPipeTrickCharacterClasses() {
- global $wgLegalTitleChars;
- return array( "[$wgLegalTitleChars]", '[ _0-9A-Za-z\x80-\xff-]' );
- }
-
- /**
- * From the [[title|]] return link-text as though the used typed [[title|link-text]]
- *
- * For most links this be as though the user typed [[ns:title|title]]
- * However [[ns:title (context)|]], [[ns:title, context|]] and [[ns:title (context), context|]]
- * [[#title (context)|]] [[../context/title (context), context|]]
- * all return the |title]] with no context or indicative punctuation.
- *
- * @param string $link from [[$link|]]
- * @return string $text for [[$link|$text]]
- */
- static function getPipeTrickText( $link ) {
- static $rexps = FALSE;
- if( !$rexps ) {
- list( $tc, $nc ) = Linker::getPipeTrickCharacterClasses();
- $rexps = array (
- # try this first, to turn "[[A, B (C)|]]" into "A, B"
- "/^(:?$nc+:|[:#\/]|$tc+[\\/#]|)($tc+?)( \\($tc+\\)| ($tc+))$/", # [[ns:page (context)|]]
- "/^(:?$nc+:|[:#\/]|$tc+[\\/#]|)($tc+?)( \\($tc+\\)| ($tc+)|)((?:,|,) $tc+|)$/", # [[ns:page (context), context|]]
- );
- }
- $text = urldecode( $link );
-
- for( $i = 0; $i < count( $rexps ); $i++) {
- if( preg_match( $rexps[$i], $text, $m ) )
- return $m[2];
- }
- return $text;
- }
-
- /**
- * From the [[|link-text]] return the title as though the user typed [[title|link-text]]
- *
- * On most pages this will return link-text or "" if the link-text is not a valid title
- * On pages like [[ns:title (context)]] and [[ns:title, context]] it will act like
- * [[ns:link-text (context)|link-text]] and [[ns:link-text, context|link-text]]
- *
- * @param string $text from [[|$text]]
- * @param Title $title to resolve the link against
- * @return string $link for [[$link|$text]]
- */
- static function getPipeTrickLink( $text, $title ) {
- static $rexps = FALSE, $tc;
- if( !$rexps ) {
- list( $tc, $nc ) = Linker::getPipeTrickCharacterClasses();
- $rexps = array (
- "/^($nc+:|)$tc+?( \\($tc+\\)| ($tc+))$/", # [[ns:page (context)|]]
- "/^($nc+:|)$tc+?(?:(?: \\($tc+\\)| ($tc+)|)((?:,|,) $tc+|))$/" # [[ns:page (context), context|]]
- );
- }
-
- if( !preg_match( "/^$tc+$/", $text ) )
- return '';
-
- $t = $title->getText();
-
- for( $i = 0; $i < count( $rexps ); $i++) {
- if( preg_match( $rexps[$i], $t, $m ) )
- return "$m[1]$text$m[2]";
- }
- return $text;
- }
-
/**
* Wrap a comment in standard punctuation and formatting if
* it's non-empty, otherwise return empty string.
* (which in turn the browser understands, and can display).
*
* <pre>
- * There are six main entry points into the Parser class:
+ * There are five main entry points into the Parser class:
* parse()
* produces HTML output
* preSaveTransform().
* Cleans a signature before saving it to preferences
* extractSections()
* Extracts sections from an article for section editing
- * getTransclusionText()
- * Extracts the text of a template with only <includeonly>, etc., parsed
*
* Globals used:
* objects: $wgLang, $wgContLang
const OT_WIKI = 2;
const OT_PREPROCESS = 3;
const OT_MSG = 3;
- const OT_INCLUDES = 4;
// Marker Suffix needs to be accessible staticly.
const MARKER_SUFFIX = "-QINU\x7f";
wfRunHooks( 'ParserBeforeTidy', array( &$this, &$text ) );
- if ( $this->mTransparentTagHooks ) {
- //!JF Move to its own function
- $uniq_prefix = $this->mUniqPrefix;
- $matches = array();
- $elements = array_keys( $this->mTransparentTagHooks );
- $text = self::extractTagsAndParams( $elements, $text, $matches, $uniq_prefix );
-
- foreach( $matches as $marker => $data ) {
- list( $element, $content, $params, $tag ) = $data;
- $tagName = strtolower( $element );
- if( isset( $this->mTransparentTagHooks[$tagName] ) ) {
- $output = call_user_func_array( $this->mTransparentTagHooks[$tagName],
- array( $content, $params, $this ) );
- } else {
- $output = $tag;
- }
- $this->mStripState->general->setPair( $marker, $output );
+//!JF Move to its own function
+
+ $uniq_prefix = $this->mUniqPrefix;
+ $matches = array();
+ $elements = array_keys( $this->mTransparentTagHooks );
+ $text = self::extractTagsAndParams( $elements, $text, $matches, $uniq_prefix );
+
+ foreach( $matches as $marker => $data ) {
+ list( $element, $content, $params, $tag ) = $data;
+ $tagName = strtolower( $element );
+ if( isset( $this->mTransparentTagHooks[$tagName] ) ) {
+ $output = call_user_func_array( $this->mTransparentTagHooks[$tagName],
+ array( $content, $params, $this ) );
+ } else {
+ $output = $tag;
}
+ $this->mStripState->general->setPair( $marker, $output );
}
-
- # This was originally inserted for transparent tag hooks (now deprecated)
- # but some extensions (notably <poem>) rely on the extra unstripGeneral()
- # after unstripNoWiki() so they can modify the contents of <nowiki> tags.
$text = $this->mStripState->unstripGeneral( $text );
$text = Sanitizer::normalizeCharReferences( $text );
return $text;
}
- /**
- * Get the wikitext of a page as though it was transcluded.
- *
- * Specifically <includeonly> etc. are parsed, redirects are followed, comments
- * are removed, but templates arguments and parser functions are untouched.
- *
- * This is not called by the parser itself, see braceSubstitution for its transclusion.
- */
- public function getTransclusionText( $title, $options ) {
- // Must initialize first
- $this->clearState();
- $this->setOutputType( self::OT_INCLUDES );
- $this->mOptions = $options;
- $this->setTitle( new FakeTitle );
-
- list( $text, $title ) = $this->getTemplateDom( $title );
- $flags = PPFrame::NO_ARGS | PPFrame::NO_TEMPLATES;
- return $this->getPreprocessor()->newFrame()->expand( $text, $flags );
- }
-
/**
* Get a random string
*
if ( !$tc ) {
$tc = Title::legalChars() . '#%';
# Match a link having the form [[namespace:link|alternate]]trail
- $e1 = "/^([{$tc}]*)(\\|.*?)?]](.*)\$/sD";
+ $e1 = "/^([{$tc}]+)(?:\\|(.+?))?]](.*)\$/sD";
# Match cases where there is no "]]", which might still be images
$e1_img = "/^([{$tc}]+)\\|(.*)\$/sD";
}
wfProfileIn( __METHOD__."-e1" );
if ( preg_match( $e1, $line, $m ) ) { # page with normal text or alt
-
- if( $m[2] === '' ) {
- $text = '';
- } elseif( $m[2] === '|' ) {
- $text = $this->getPipeTrickText( $m[1] );
- } else {
- $text = substr( $m[2], 1 );
- }
-
+ $text = $m[2];
# If we get a ] at the beginning of $m[3] that means we have a link that's something like:
# [[Image:Foo.jpg|[http://example.com desc]]] <- having three ] in a row fucks up,
# the real problem is with the $e1 regex
$text .= ']'; # so that replaceExternalLinks($text) works later
$m[3] = substr( $m[3], 1 );
}
-
- # Handle pipe-trick for [[|<blah>]]
- $lnk = $m[1] === '' ? $this->getPipeTrickLink( $text ) : $m[1];
# fix up urlencoded title texts
- if( strpos( $lnk, '%' ) !== false ) {
+ if( strpos( $m[1], '%' ) !== false ) {
# Should anchors '#' also be rejected?
- $lnk = str_replace( array('<', '>'), array('<', '>'), urldecode($lnk) );
+ $m[1] = str_replace( array('<', '>'), array('<', '>'), urldecode($m[1]) );
}
-
$trail = $m[3];
} elseif( preg_match($e1_img, $line, $m) ) { # Invalid, but might be an image with a link in its caption
$might_be_img = true;
$text = $m[2];
- $lnk = strpos( $m[1], '%' ) === false ? $m[1] : urldecode( $m[1] );
+ if ( strpos( $m[1], '%' ) !== false ) {
+ $m[1] = urldecode($m[1]);
+ }
$trail = "";
} else { # Invalid form; output directly
$s .= $prefix . '[[' . $line ;
# Don't allow internal links to pages containing
# PROTO: where PROTO is a valid URL protocol; these
# should be external links.
- if ( preg_match( '/^\b(?:' . wfUrlProtocols() . ')/', $lnk ) ) {
+ if ( preg_match( '/^\b(?:' . wfUrlProtocols() . ')/', $m[1] ) ) {
$s .= $prefix . '[[' . $line ;
wfProfileOut( __METHOD__."-misc" );
continue;
# Make subpage if necessary
if ( $useSubpages ) {
- $link = $this->maybeDoSubpageLink( $lnk, $text );
+ $link = $this->maybeDoSubpageLink( $m[1], $text );
} else {
- $link = $lnk;
+ $link = $m[1];
}
- $noforce = (substr( $lnk, 0, 1 ) !== ':');
+ $noforce = (substr( $m[1], 0, 1 ) !== ':');
if (!$noforce) {
# Strip off leading ':'
$link = substr( $link, 1 );
return Linker::normalizeSubpageLink( $this->mTitle, $target, $text );
}
- /**
- * From the [[title|]] return link-text as though the used typed [[title|link-text]]
- * @param string $link from [[$link|]]
- * @return string $text for [[$link|$text]]
- */
- function getPipeTrickText( $link ) {
- return Linker::getPipeTrickText( $link );
- }
-
- /**
- * From the [[|link-text]] return the title as though the user typed [[title|link-text]]
- * @param string $text from [[|$text]]
- * @param Title $title to resolve the link against
- * @return string $link for [[$link|$text]]
- */
- function getPipeTrickLink( $text ) {
- return Linker::getPipeTrickLink( $text, $this->mTitle );
- }
-
/**#@+
* Used by doBlockLevels()
* @private
$subjPage = $this->mTitle->getSubjectPage();
$value = $subjPage->getPrefixedUrl();
break;
- case 'pipetrick':
- $text = $this->mTitle->getText();
- $value = $this->getPipeTrickText( $text );
- break;
- case 'pipetricke':
- $text = $this->mTitle->getText();
- $value = wfUrlEncode( str_replace( ' ', '_', $this->getPipeTrickText( $text ) ) );
- break;
case 'revisionid':
// Let the edit saving system know we should parse the page
// *after* a revision ID has been assigned.
'~~~' => $sigText
) );
- # Links of the form [[|<blah>]] or [[<blah>|]] perform pipe tricks
- # Note this only allows the # in the position it works.
+ # Context links: [[|name]] and [[name (context)|]]
+ #
global $wgLegalTitleChars;
- $pipeTrickRe = "/\[\[(?:(\\|)([$wgLegalTitleChars]+)|([#$wgLegalTitleChars]+)\\|)\]\]/";
- $text = preg_replace_callback( $pipeTrickRe, array( $this, 'pstPipeTrickCallback' ), $text );
+ $tc = "[$wgLegalTitleChars]";
+ $nc = '[ _0-9A-Za-z\x80-\xff-]'; # Namespaces can use non-ascii!
+
+ $p1 = "/\[\[(:?$nc+:|:|)($tc+?)( \\($tc+\\))\\|]]/"; # [[ns:page (context)|]]
+ $p4 = "/\[\[(:?$nc+:|:|)($tc+?)(($tc+))\\|]]/"; # [[ns:page(context)|]]
+ $p3 = "/\[\[(:?$nc+:|:|)($tc+?)( \\($tc+\\)|)(, $tc+|)\\|]]/"; # [[ns:page (context), context|]]
+ $p2 = "/\[\[\\|($tc+)]]/"; # [[|page]]
+
+ # try $p1 first, to turn "[[A, B (C)|]]" into "[[A, B (C)|A, B]]"
+ $text = preg_replace( $p1, '[[\\1\\2\\3|\\2]]', $text );
+ $text = preg_replace( $p4, '[[\\1\\2\\3|\\2]]', $text );
+ $text = preg_replace( $p3, '[[\\1\\2\\3\\4|\\2]]', $text );
+
+ $t = $this->mTitle->getText();
+ $m = array();
+ if ( preg_match( "/^($nc+:|)$tc+?( \\($tc+\\))$/", $t, $m ) ) {
+ $text = preg_replace( $p2, "[[$m[1]\\1$m[2]|\\1]]", $text );
+ } elseif ( preg_match( "/^($nc+:|)$tc+?(, $tc+|)$/", $t, $m ) && "$m[1]$m[2]" != '' ) {
+ $text = preg_replace( $p2, "[[$m[1]\\1$m[2]|\\1]]", $text );
+ } else {
+ # if there's no context, don't bother duplicating the title
+ $text = preg_replace( $p2, '[[\\1]]', $text );
+ }
# Trim trailing whitespace
$text = rtrim( $text );
return $text;
}
- /**
- * Called from pstPass2 to perform the pipe trick on links.
- * Original was either [[|text]] or [[link|]]
- *
- * @param Array ("|" or "", text, link) $m
- */
- function pstPipeTrickCallback( $m )
- {
- if( $m[1] ) { # [[|<blah>]]
- $text = $m[2];
- $link = $this->getPipeTrickLink( $text );
- } else { # [[<blah>|]]
- $link = $m[3];
- $text = $this->getPipeTrickText( $link );
- }
-
- return $link === $text ? "[[$link]]" : "[[$link|$text]]";
- }
-
/**
* Fetch the user's signature text, if any, and normalize to
* validated, ready-to-insert wikitext.
return $oldVal;
}
- /* An old work-around for bug 2257 - deprecated 2010-02-13 */
function setTransparentTagHook( $tag, $callback ) {
- wfDeprecated( __METHOD__ );
$tag = strtolower( $tag );
$oldVal = isset( $this->mTransparentTagHooks[$tag] ) ? $this->mTransparentTagHooks[$tag] : null;
$this->mTransparentTagHooks[$tag] = $callback;
</p>
!! end
-!! test
-Magic Word: {{PIPETRICK}}
-!! options
-title=[[Some (page)]]
-!! input
-{{PIPETRICK}}
-{{PIPETRICK:Hello (one)}}
-{{PIPETRICK:World, hi|}}
-{{PIPETRICK:|Other}}
-!! result
-<p>Some
-Hello
-World
-Other (page)
-</p>
-!! end
-
-!! test
-Magic Word: {{PIPETRICKE}}
-!! options
-title=[[Some other (page)]]
-!! input
-{{PIPETRICKE}}
-{{PIPETRICKE:User:Ævar Arnfjörð Bjarmason}}
-{{PIPETRICKE:#Something to do|}}
-{{PIPETRICKE:|The?last}}
-!! result
-<p>Some_other
-%C3%86var_Arnfj%C3%B6r%C3%B0_Bjarmason
-Something_to_do
-The%3Flast_(page)
-</p>
-!! end
-
-
!! test
Magic Word: {{REVISIONID}}
!! input
[[:Bar:X (Y) Z|X (Y) Z]]
!! end
-!! test
-pre-save transform: context links ("pipe trick") based on current page
-!! options
-pst
-!! input
-[[#section|]]
-[[#section (context)|]]
-[[/relative|]]
-[[../context/relative|]]
-[[../context/relative (extra)|]]
-!! result
-[[#section|section]]
-[[#section (context)|section]]
-[[/relative|relative]]
-[[../context/relative|relative]]
-[[../context/relative (extra)|relative]]
-!! end
-
-!! test
-pre-save transform: context links ("pipe trick") to sections on other pages
-!! options
-pst
-!! input
-[[other#page|]]
-[[Help:Somewhere/completely (wierd)#section (two)|]]
-!! result
-[[other#page|page]]
-[[Help:Somewhere/completely (wierd)#section (two)|section]]
-!! end
-
-!! test
-pre-save transform: context links ("pipe trick") with full-width characters
-!! options
-pst
-!! input
-[[title, context|]]
-[[title (context)|]]
-!! result
-[[title, context|title]]
-[[title (context)|title]]
-!! end
-
!! test
pre-save transform: context links ("pipe trick") with interwiki prefix
!! options
[[Ns:Article, Context|Article]]
!! end
-!! test
-pre-save transform: context links ("pipe trick") with url escaped page names
-!! options
-pst
-!! input
-[[Hello wo%52ld|]]
-[[Hello wo%52ld (again)|]]
-!! result
-[[Hello wo%52ld|Hello woRld]]
-[[Hello wo%52ld (again)|Hello woRld]]
-!! end
-
-!! test
-pre-save transform: context links ("pipe trick") with variables are not pre-empted
-!! options
-pst title=[[Test (page)]]
-!! input
-[[{{{1|}}}|]]
-[[|{{{1|}}}]]
-[[{{subst:PAGENAME}}|]]
-!! result
-[[{{{1|}}}|]]
-[[|{{{1|}}}]]
-[[Test (page)|Test]]
-!! end
-
-!! article
-Template:pipetest
-!! text
-[[{{{1}}}|]]
-!! endarticle
-
-!! article
-Template:testpipe
-!! text
-[[|{{{1}}}]]
-!! endarticle
-
-!! test
-("pipe trick") should work outside PST
-!!options
-title=[[Help:hello (world)]]
-!! input
-{{pipetest|hi (world)}}
-{{pipetest|hi (world), world}}
-{{pipetest|Help:hi (world), world}}
-{{pipetest|:Help:hi (world), world}}
-{{testpipe|hi}}
-[[{{PAGENAME}}|]]
-!! result
-<p><a href="/index.php?title=Hi_(world)&action=edit&redlink=1" class="new" title="Hi (world) (page does not exist)">hi</a>
-<a href="/index.php?title=Hi_(world),_world&action=edit&redlink=1" class="new" title="Hi (world), world (page does not exist)">hi</a>
-<a href="/index.php?title=Help:Hi_(world),_world&action=edit&redlink=1" class="new" title="Help:Hi (world), world (page does not exist)">hi</a>
-<a href="/index.php?title=Help:Hi_(world),_world&action=edit&redlink=1" class="new" title="Help:Hi (world), world (page does not exist)">hi</a>
-<a href="/index.php?title=Hi_(world)&action=edit&redlink=1" class="new" title="Hi (world) (page does not exist)">hi</a>
-<a href="/index.php?title=Hello_(world)&action=edit&redlink=1" class="new" title="Hello (world) (page does not exist)">Hello</a>
-</p>
-!! end
-
###
### Message transform tests
<a href="/wiki/Main_Page#section" title="Main Page">#section</a>
!! end
-!! test
-Edit comment with pipe trick
-!! options
-comment
-title=[[Article (context)]]
-!! input
-[[Hello (World)|]] [[|Entry]]
-!! result
-<a href="/index.php?title=Hello_(World)&action=edit&redlink=1" class="new" title="Hello (World) (page does not exist)">Hello</a> <a href="/index.php?title=Entry_(context)&action=edit&redlink=1" class="new" title="Entry (context) (page does not exist)">Entry</a>
-!! end
-
!!article
MediaWiki:bad image list
!!text