r35980 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r35979‎ | r35980 | r35981 >
Date:20:38, 6 June 2008
Author:brion
Status:old
Tags:
Comment:
Update a bunch of extensions to avoid unstubbing $wgParser early for setHook() on current MW versions.
Modified paths:
  • /trunk/extensions/Cite/Cite.php (modified) (history)
  • /trunk/extensions/Cite/Cite_body.php (added) (history)
  • /trunk/extensions/FixedImage/FixedImage.php (modified) (history)
  • /trunk/extensions/ImageMap/ImageMap.php (modified) (history)
  • /trunk/extensions/Poem/Poem.php (modified) (history)
  • /trunk/extensions/Quiz/Quiz.php (modified) (history)
  • /trunk/extensions/inputbox/inputbox.php (modified) (history)
  • /trunk/extensions/intersection/DynamicPageList.php (modified) (history)
  • /trunk/extensions/timeline/Timeline.php (modified) (history)
  • /trunk/extensions/wikihiero/wikihiero.php (modified) (history)

Diff [purge]

Index: trunk/extensions/ImageMap/ImageMap.php
@@ -3,7 +3,11 @@
44 $dir = dirname(__FILE__) . '/';
55 $wgExtensionMessagesFiles['ImageMap'] = $dir . 'ImageMap.i18n.php';
66 $wgAutoloadClasses['ImageMap'] = $dir . 'ImageMap_body.php';
7 -$wgExtensionFunctions[] = 'wfSetupImageMap';
 7+if ( defined( 'MW_SUPPORTS_PARSERFIRSTCALLINIT' ) ) {
 8+ $wgHooks['ParserFirstCallInit'][] = 'wfSetupImageMap';
 9+} else {
 10+ $wgExtensionFunctions[] = 'wfSetupImageMap';
 11+}
812
913 $wgExtensionCredits['parserhook']['ImageMap'] = array(
1014 'name' => 'ImageMap',
@@ -18,4 +22,5 @@
1923 function wfSetupImageMap() {
2024 global $wgParser;
2125 $wgParser->setHook( 'imagemap', array( 'ImageMap', 'render' ) );
 26+ return true;
2227 }
Index: trunk/extensions/inputbox/inputbox.php
@@ -19,7 +19,11 @@
2020 /**
2121 * Register the Inputbox extension with MediaWiki
2222 */
23 -$wgExtensionFunctions[] = 'efInputBoxSetup';
 23+if ( defined( 'MW_SUPPORTS_PARSERFIRSTCALLINIT' ) ) {
 24+ $wgHooks['ParserFirstCallInit'][] = 'efInputBoxSetup';
 25+} else {
 26+ $wgExtensionFunctions[] = 'efInputBoxSetup';
 27+}
2428 $wgExtensionCredits['parserhook'][] = array(
2529 'name' => 'Inputbox',
2630 'author' => array( 'Erik Moeller', 'Leonardo Pimenta', 'Rob Church' ),
@@ -37,6 +41,7 @@
3842 function efInputBoxSetup() {
3943 global $wgParser;
4044 $wgParser->setHook( 'inputbox', 'efInputBoxRender' );
 45+ return true;
4146 }
4247
4348 function efInputBoxRender( $input, $params, $parser ) {
Index: trunk/extensions/Quiz/Quiz.php
@@ -51,7 +51,11 @@
5252 $dir = dirname(__FILE__) . '/';
5353 $wgExtensionMessagesFiles['QuizExtension'] = $dir . 'Quiz.i18n.php';
5454
55 -$wgExtensionFunctions[] = "wfQuizExtension";
 55+if ( defined( 'MW_SUPPORTS_PARSERFIRSTCALLINIT' ) ) {
 56+ $wgHooks['ParserFirstCallInit'][] = 'wfQuizExtension';
 57+} else {
 58+ $wgExtensionFunctions[] = 'wfQuizExtension';
 59+}
5660
5761 $wgHooks['ParserClearState'][] = 'Quiz::resetQuizID';
5862 $wgHooks['LoadAllMessages'][] = 'Quiz::loadMessages';
@@ -64,6 +68,7 @@
6569 function wfQuizExtension() {
6670 global $wgParser;
6771 $wgParser->setHook("quiz", "renderQuiz");
 72+ return true;
6873 }
6974
7075 /**
Index: trunk/extensions/intersection/DynamicPageList.php
@@ -42,7 +42,12 @@
4343 $wgDLPAllowUnlimitedResults = true; // Allow unlimited results
4444 $wgDLPAllowUnlimitedCategories = false; // Allow unlimited categories
4545
46 -$wgExtensionFunctions[] = "wfDynamicPageList";
 46+if ( defined( 'MW_SUPPORTS_PARSERFIRSTCALLINIT' ) ) {
 47+ $wgHooks['ParserFirstCallInit'][] = 'wfDynamicPageList';
 48+} else {
 49+ $wgExtensionFunctions[] = 'wfDynamicPageList';
 50+}
 51+
4752 $wgExtensionCredits['parserhook'][] = array(
4853 'name' => 'DynamicPageList',
4954 'description' => 'outputs a bulleted list of the most recent items residing in a category, or a union of several categories',
@@ -58,6 +63,7 @@
5964 global $wgParser;
6065 wfLoadExtensionMessages( 'DynamicPageList' );
6166 $wgParser->setHook( "DynamicPageList", "DynamicPageList" );
 67+ return true;
6268 }
6369
6470 // The callback function for converting the input text to HTML output
Index: trunk/extensions/timeline/Timeline.php
@@ -11,7 +11,12 @@
1212 $wgTimelineSettings->ploticusCommand = "/usr/bin/ploticus";
1313 $wgTimelineSettings->perlCommand = "/usr/bin/perl";
1414
15 -$wgExtensionFunctions[] = "wfTimelineExtension";
 15+if ( defined( 'MW_SUPPORTS_PARSERFIRSTCALLINIT' ) ) {
 16+ $wgHooks['ParserFirstCallInit'][] = 'wfTimelineExtension';
 17+} else {
 18+ $wgExtensionFunctions[] = 'wfTimelineExtension';
 19+}
 20+
1621 $wgExtensionCredits['parserhook'][] = array(
1722 'name' => 'EasyTimeline',
1823 'author' => 'Erik Zachte',
@@ -26,6 +31,7 @@
2732 function wfTimelineExtension() {
2833 global $wgParser;
2934 $wgParser->setHook( "timeline", "renderTimeline" );
 35+ return true;
3036 }
3137
3238 function renderTimeline( $timelinesrc )
Index: trunk/extensions/FixedImage/FixedImage.php
@@ -44,7 +44,11 @@
4545 );
4646 $wgExtensionMessagesFiles['FixedImage'] = dirname(__FILE__) . '/FixedImage.i18n.php';
4747
48 -$wgExtensionFunctions[] = 'fixedImageSetup';
 48+if ( defined( 'MW_SUPPORTS_PARSERFIRSTCALLINIT' ) ) {
 49+ $wgHooks['ParserFirstCallInit'][] = 'fixedImageSetup';
 50+} else {
 51+ $wgExtensionFunctions[] = 'fixedImageSetup';
 52+}
4953
5054 function fixedImageSetup() {
5155 global $wgParser, $wgFixedImageHooks;
@@ -53,6 +57,7 @@
5458 "return fixedImageHandler('$key', \$text, \$params);" );
5559 $wgParser->setHook( $key, $wrapper );
5660 }
 61+ return true;
5762 }
5863
5964 /**
Index: trunk/extensions/Cite/Cite_body.php
@@ -0,0 +1,713 @@
 2+<?php
 3+
 4+/**#@+
 5+ * A parser extension that adds two tags, <ref> and <references> for adding
 6+ * citations to pages
 7+ *
 8+ * @addtogroup Extensions
 9+ *
 10+ * @link http://meta.wikimedia.org/wiki/Cite/Cite.php Documentation
 11+ * @link http://www.w3.org/TR/html4/struct/text.html#edef-CITE <cite> definition in HTML
 12+ * @link http://www.w3.org/TR/2005/WD-xhtml2-20050527/mod-text.html#edef_text_cite <cite> definition in XHTML 2.0
 13+ *
 14+ * @bug 4579
 15+ *
 16+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
 17+ * @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason
 18+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
 19+ */
 20+
 21+class Cite {
 22+ /**#@+
 23+ * @access private
 24+ */
 25+
 26+ /**
 27+ * Datastructure representing <ref> input, in the format of:
 28+ * <code>
 29+ * array(
 30+ * 'user supplied' => array(
 31+ * 'text' => 'user supplied reference & key',
 32+ * 'count' => 1, // occurs twice
 33+ * 'number' => 1, // The first reference, we want
 34+ * // all occourances of it to
 35+ * // use the same number
 36+ * ),
 37+ * 0 => 'Anonymous reference',
 38+ * 1 => 'Another anonymous reference',
 39+ * 'some key' => array(
 40+ * 'text' => 'this one occurs once'
 41+ * 'count' => 0,
 42+ * 'number' => 4
 43+ * ),
 44+ * 3 => 'more stuff'
 45+ * );
 46+ * </code>
 47+ *
 48+ * This works because:
 49+ * * PHP's datastructures are guarenteed to be returned in the
 50+ * order that things are inserted into them (unless you mess
 51+ * with that)
 52+ * * User supplied keys can't be integers, therefore avoiding
 53+ * conflict with anonymous keys
 54+ *
 55+ * @var array
 56+ **/
 57+ var $mRefs = array();
 58+
 59+ /**
 60+ * Count for user displayed output (ref[1], ref[2], ...)
 61+ *
 62+ * @var int
 63+ */
 64+ var $mOutCnt = 0;
 65+ var $mGroupCnt = array();
 66+
 67+ /**
 68+ * Internal counter for anonymous references, seperate from
 69+ * $mOutCnt because anonymous references won't increment it,
 70+ * but will incremement $mOutCnt
 71+ *
 72+ * @var int
 73+ */
 74+ var $mInCnt = 0;
 75+
 76+ /**
 77+ * The backlinks, in order, to pass as $3 to
 78+ * 'cite_references_link_many_format', defined in
 79+ * 'cite_references_link_many_format_backlink_labels
 80+ *
 81+ * @var array
 82+ */
 83+ var $mBacklinkLabels;
 84+
 85+ /**
 86+ * @var object
 87+ */
 88+ var $mParser;
 89+
 90+ /**
 91+ * True when a <ref> or <references> tag is being processed.
 92+ * Used to avoid infinite recursion
 93+ *
 94+ * @var boolean
 95+ */
 96+ var $mInCite = false;
 97+
 98+ /**#@-*/
 99+
 100+ /**
 101+ * Constructor
 102+ */
 103+ function Cite() {
 104+ $this->setHooks();
 105+ }
 106+
 107+ /**#@+ @access private */
 108+
 109+ /**
 110+ * Callback function for <ref>
 111+ *
 112+ * @param string $str Input
 113+ * @param array $argv Arguments
 114+ * @return string
 115+ */
 116+ function ref( $str, $argv, $parser ) {
 117+ wfLoadExtensionMessages( 'Cite' );
 118+ if ( $this->mInCite ) {
 119+ return htmlspecialchars( "<ref>$str</ref>" );
 120+ } else {
 121+ $this->mInCite = true;
 122+ $ret = $this->guardedRef( $str, $argv, $parser );
 123+ $this->mInCite = false;
 124+ return $ret;
 125+ }
 126+ }
 127+
 128+ function guardedRef( $str, $argv, $parser, $default_group=CITE_DEFAULT_GROUP ) {
 129+ $this->mParser = $parser;
 130+
 131+ # The key here is the "name" attribute.
 132+ list($key,$group) = $this->refArg( $argv );
 133+
 134+ if( $str === '' ) {
 135+ # <ref ...></ref>. This construct is always invalid: either
 136+ # it's a contentful ref, or it's a named duplicate and should
 137+ # be <ref ... />.
 138+ return $this->error( 'cite_error_ref_no_input' );
 139+ }
 140+
 141+ if( $key === false ) {
 142+ # TODO: Comment this case; what does this condition mean?
 143+ return $this->error( 'cite_error_ref_too_many_keys' );
 144+ }
 145+
 146+ if( $str === null and $key === null ) {
 147+ # Something like <ref />; this makes no sense.
 148+ return $this->error( 'cite_error_ref_no_key' );
 149+ }
 150+
 151+ if( preg_match( '/^[0-9]+$/', $key ) ) {
 152+ # Numeric names mess up the resulting id's, potentially produ-
 153+ # cing duplicate id's in the XHTML. The Right Thing To Do
 154+ # would be to mangle them, but it's not really high-priority
 155+ # (and would produce weird id's anyway).
 156+ return $this->error( 'cite_error_ref_numeric_key' );
 157+ }
 158+
 159+ #Split these into groups.
 160+ if( $group === null ) {
 161+ $group = $default_group;
 162+ }
 163+
 164+ if( is_string( $key ) or is_string( $str ) ) {
 165+ # We don't care about the content: if the key exists, the ref
 166+ # is presumptively valid. Either it stores a new ref, or re-
 167+ # fers to an existing one. If it refers to a nonexistent ref,
 168+ # we'll figure that out later. Likewise it's definitely valid
 169+ # if there's any content, regardless of key.
 170+ return $this->stack( $str, $key, $group );
 171+ }
 172+
 173+ # Not clear how we could get here, but something is probably
 174+ # wrong with the types. Let's fail fast.
 175+ $this->croak( 'cite_error_key_str_invalid', serialize( "$str; $key" ) );
 176+ }
 177+
 178+ /**
 179+ * Parse the arguments to the <ref> tag
 180+ *
 181+ * @static
 182+ *
 183+ * @param array $argv The argument vector
 184+ * @return mixed false on invalid input, a string on valid
 185+ * input and null on no input
 186+ */
 187+ function refArg( $argv ) {
 188+ global $wgAllowCiteGroups;
 189+ $cnt = count( $argv );
 190+ $group = null;
 191+ $key = null;
 192+
 193+ if ( $cnt > 2 )
 194+ // There should only be one key and one group
 195+ return false;
 196+ else if ( $cnt >= 1 ) {
 197+ if ( isset( $argv['name'] ) ) {
 198+ // Key given.
 199+ $key = $this->validateName( $argv['name'] );
 200+ unset( $argv['name']);
 201+ --$cnt;
 202+ }
 203+ if ( isset( $argv['group'] ) ){
 204+ if (! $wgAllowCiteGroups ) return array(false); //remove when groups are fully tested.
 205+ // Group given.
 206+ $group = $this->validateName( $argv['group'] );
 207+ unset( $argv['group']);
 208+ --$cnt;
 209+ }
 210+
 211+ if ( $cnt == 0)
 212+ return array ($key,$group);
 213+ else
 214+ // Invalid key
 215+ return array(false);
 216+ }
 217+ else
 218+ // No key
 219+ return array(null,$group);
 220+ }
 221+
 222+ /**
 223+ * Since the key name is used in an XHTML id attribute, it must
 224+ * conform to the validity rules. The restriction to begin with
 225+ * a letter is lifted since references have their own prefix.
 226+ *
 227+ * @fixme merge this code with the various section name transformations
 228+ * @fixme double-check for complete validity
 229+ * @return string if valid, false if invalid
 230+ */
 231+ function validateName( $name ) {
 232+ if( preg_match( '/^[A-Za-z0-9:_.-]*$/i', $name ) ) {
 233+ return $name;
 234+ } else {
 235+ // WARNING: CRAPPY CUT AND PASTE MAKES BABY JESUS CRY
 236+ $text = urlencode( str_replace( ' ', '_', $name ) );
 237+ $replacearray = array(
 238+ '%3A' => ':',
 239+ '%' => '.'
 240+ );
 241+ return str_replace(
 242+ array_keys( $replacearray ),
 243+ array_values( $replacearray ),
 244+ $text );
 245+ }
 246+ }
 247+
 248+ /**
 249+ * Populate $this->mRefs based on input and arguments to <ref>
 250+ *
 251+ * @param string $str Input from the <ref> tag
 252+ * @param mixed $key Argument to the <ref> tag as returned by $this->refArg()
 253+ * @return string
 254+ */
 255+ function stack( $str, $key = null, $group ) {
 256+ if (! isset($this->mRefs[$group]))
 257+ $this->mRefs[$group]=array();
 258+ if (! isset($this->mGroupCnt[$group]))
 259+ $this->mGroupCnt[$group]=0;
 260+
 261+ if ( $key === null ) {
 262+ // No key
 263+ //$this->mRefs[$group][] = $str;
 264+ $this->mRefs[$group][] = array('count'=>-1, 'text'=>$str, 'key'=>++$this->mOutCnt);
 265+
 266+ return $this->linkRef( $group, $this->mInCnt++ );
 267+ } else if ( is_string( $key ) ) {
 268+ // Valid key
 269+ if ( ! isset( $this->mRefs[$group][$key] ) || ! is_array( $this->mRefs[$group][$key] ) ) {
 270+ // First occurance
 271+ $this->mRefs[$group][$key] = array(
 272+ 'text' => $str,
 273+ 'count' => 0,
 274+ 'key' => ++$this->mOutCnt,
 275+ 'number' => ++$this->mGroupCnt[$group]
 276+ );
 277+ $this->mInCnt++;
 278+ return
 279+ $this->linkRef(
 280+ $group,
 281+ $key,
 282+ $this->mRefs[$group][$key]['key']."-".$this->mRefs[$group][$key]['count'],
 283+ $this->mRefs[$group][$key]['number'],
 284+ "-".$this->mRefs[$group][$key]['key']
 285+ );
 286+ } else {
 287+ // We've been here before
 288+ if ( $this->mRefs[$group][$key]['text'] === null && $str !== '' ) {
 289+ // If no text found before, use this text
 290+ $this->mRefs[$group][$key]['text'] = $str;
 291+ };
 292+ return
 293+ $this->linkRef(
 294+ $group,
 295+ $key,
 296+ $this->mRefs[$group][$key]['key']."-".++$this->mRefs[$group][$key]['count'],
 297+ $this->mRefs[$group][$key]['number'],
 298+ "-".$this->mRefs[$group][$key]['key']
 299+ ); }
 300+ }
 301+
 302+ else
 303+ $this->croak( 'cite_error_stack_invalid_input', serialize( array( $key, $str ) ) );
 304+ }
 305+
 306+ /**
 307+ * Callback function for <references>
 308+ *
 309+ * @param string $str Input
 310+ * @param array $argv Arguments
 311+ * @return string
 312+ */
 313+ function references( $str, $argv, $parser ) {
 314+ wfLoadExtensionMessages( 'Cite' );
 315+ if ( $this->mInCite ) {
 316+ if ( is_null( $str ) ) {
 317+ return htmlspecialchars( "<references/>" );
 318+ } else {
 319+ return htmlspecialchars( "<references>$str</references>" );
 320+ }
 321+ } else {
 322+ $this->mInCite = true;
 323+ $ret = $this->guardedReferences( $str, $argv, $parser );
 324+ $this->mInCite = false;
 325+ return $ret;
 326+ }
 327+ }
 328+
 329+ function guardedReferences( $str, $argv, $parser, $group = CITE_DEFAULT_GROUP ) {
 330+ global $wgAllowCiteGroups;
 331+
 332+ $this->mParser = $parser;
 333+
 334+ if ( strval( $str ) !== '' )
 335+ return $this->error( 'cite_error_references_invalid_input' );
 336+
 337+
 338+ if ( isset( $argv['group'] ) and $wgAllowCiteGroups) {
 339+ $group = $argv['group'];
 340+ unset ($argv['group']);
 341+
 342+ }
 343+
 344+ if ( count( $argv ) )
 345+ return $this->error( 'cite_error_references_invalid_parameters' );
 346+ else
 347+ return $this->referencesFormat($group);
 348+ }
 349+
 350+ /**
 351+ * Make output to be returned from the references() function
 352+ *
 353+ * @return string XHTML ready for output
 354+ */
 355+ function referencesFormat($group) {
 356+ if (( count( $this->mRefs ) == 0 ) or (empty( $this->mRefs[$group] ) ))
 357+ return '';
 358+
 359+ wfProfileIn( __METHOD__ );
 360+ wfProfileIn( __METHOD__ .'-entries' );
 361+ $ent = array();
 362+ foreach ( $this->mRefs[$group] as $k => $v )
 363+ $ent[] = $this->referencesFormatEntry( $k, $v );
 364+
 365+ $prefix = wfMsgForContentNoTrans( 'cite_references_prefix' );
 366+ $suffix = wfMsgForContentNoTrans( 'cite_references_suffix' );
 367+ $content = implode( "\n", $ent );
 368+
 369+ wfProfileOut( __METHOD__ .'-entries' );
 370+ wfProfileIn( __METHOD__ .'-parse' );
 371+ // Live hack: parse() adds two newlines on WM, can't reproduce it locally -ævar
 372+ $ret = rtrim( $this->parse( $prefix . $content . $suffix ), "\n" );
 373+ wfProfileOut( __METHOD__ .'-parse' );
 374+ wfProfileOut( __METHOD__ );
 375+
 376+ //done, clean up so we can reuse the group
 377+ unset ($this->mRefs[$group]);
 378+ unset($this->mGroupCnt[$group]);
 379+
 380+ return $ret;
 381+ }
 382+
 383+ /**
 384+ * Format a single entry for the referencesFormat() function
 385+ *
 386+ * @param string $key The key of the reference
 387+ * @param mixed $val The value of the reference, string for anonymous
 388+ * references, array for user-suppplied
 389+ * @return string Wikitext
 390+ */
 391+ function referencesFormatEntry( $key, $val ) {
 392+ // Anonymous reference
 393+ if ( ! is_array( $val ) )
 394+ return
 395+ wfMsgForContentNoTrans(
 396+ 'cite_references_link_one',
 397+ $this->referencesKey( $key ),
 398+ $this->refKey( $key ),
 399+ $val
 400+ );
 401+ else if ($val['text']=='') return
 402+ wfMsgForContentNoTrans(
 403+ 'cite_references_link_one',
 404+ $this->referencesKey( $key ),
 405+ $this->refKey( $key, $val['count'] ),
 406+ $this->error( 'cite_error_references_no_text', $key )
 407+ );
 408+ if ( $val['count'] < 0 )
 409+ return
 410+ wfMsgForContentNoTrans(
 411+ 'cite_references_link_one',
 412+ $this->referencesKey( $val['key'] ),
 413+ #$this->refKey( $val['key'], $val['count'] ),
 414+ $this->refKey( $val['key'] ),
 415+
 416+ ( $val['text'] != '' ? $val['text'] : $this->error( 'cite_error_references_no_text', $key ) )
 417+ );
 418+ // Standalone named reference, I want to format this like an
 419+ // anonymous reference because displaying "1. 1.1 Ref text" is
 420+ // overkill and users frequently use named references when they
 421+ // don't need them for convenience
 422+ else if ( $val['count'] === 0 )
 423+ return
 424+ wfMsgForContentNoTrans(
 425+ 'cite_references_link_one',
 426+ $this->referencesKey( $key ."-" . $val['key'] ),
 427+ #$this->refKey( $key, $val['count'] ),
 428+ $this->refKey( $key, $val['key']."-".$val['count'] ),
 429+ ( $val['text'] != '' ? $val['text'] : $this->error( 'cite_error_references_no_text', $key ) )
 430+ );
 431+ // Named references with >1 occurrences
 432+ else {
 433+ $links = array();
 434+//for group handling, we have an extra key here.
 435+ for ( $i = 0; $i <= $val['count']; ++$i ) {
 436+ $links[] = wfMsgForContentNoTrans(
 437+ 'cite_references_link_many_format',
 438+ $this->refKey( $key, $val['key']."-$i" ),
 439+ $this->referencesFormatEntryNumericBacklinkLabel( $val['number'], $i, $val['count'] ),
 440+ $this->referencesFormatEntryAlternateBacklinkLabel( $i )
 441+ );
 442+ }
 443+
 444+ $list = $this->listToText( $links );
 445+
 446+ return
 447+ wfMsgForContentNoTrans( 'cite_references_link_many',
 448+ $this->referencesKey( $key ."-" . $val['key'] ),
 449+ $list,
 450+ ( $val['text'] != '' ? $val['text'] : $this->error( 'cite_error_references_no_text', $key ) )
 451+ );
 452+ }
 453+ }
 454+
 455+ /**
 456+ * Generate a numeric backlink given a base number and an
 457+ * offset, e.g. $base = 1, $offset = 2; = 1.2
 458+ * Since bug #5525, it correctly does 1.9 -> 1.10 as well as 1.099 -> 1.100
 459+ *
 460+ * @static
 461+ *
 462+ * @param int $base The base
 463+ * @param int $offset The offset
 464+ * @param int $max Maximum value expected.
 465+ * @return string
 466+ */
 467+ function referencesFormatEntryNumericBacklinkLabel( $base, $offset, $max ) {
 468+ global $wgContLang;
 469+ $scope = strlen( $max );
 470+ $ret = $wgContLang->formatNum(
 471+ sprintf("%s.%0{$scope}s", $base, $offset)
 472+ );
 473+ return $ret;
 474+ }
 475+
 476+ /**
 477+ * Generate a custom format backlink given an offset, e.g.
 478+ * $offset = 2; = c if $this->mBacklinkLabels = array( 'a',
 479+ * 'b', 'c', ...). Return an error if the offset > the # of
 480+ * array items
 481+ *
 482+ * @param int $offset The offset
 483+ *
 484+ * @return string
 485+ */
 486+ function referencesFormatEntryAlternateBacklinkLabel( $offset ) {
 487+ if ( !isset( $this->mBacklinkLabels ) ) {
 488+ $this->genBacklinkLabels();
 489+ }
 490+ if ( isset( $this->mBacklinkLabels[$offset] ) ) {
 491+ return $this->mBacklinkLabels[$offset];
 492+ } else {
 493+ // Feed me!
 494+ return $this->error( 'cite_error_references_no_backlink_label' );
 495+ }
 496+ }
 497+
 498+ /**
 499+ * Return an id for use in wikitext output based on a key and
 500+ * optionally the number of it, used in <references>, not <ref>
 501+ * (since otherwise it would link to itself)
 502+ *
 503+ * @static
 504+ *
 505+ * @param string $key The key
 506+ * @param int $num The number of the key
 507+ * @return string A key for use in wikitext
 508+ */
 509+ function refKey( $key, $num = null ) {
 510+ $prefix = wfMsgForContent( 'cite_reference_link_prefix' );
 511+ $suffix = wfMsgForContent( 'cite_reference_link_suffix' );
 512+ if ( isset( $num ) )
 513+ $key = wfMsgForContentNoTrans( 'cite_reference_link_key_with_num', $key, $num );
 514+
 515+ return $prefix . $key . $suffix;
 516+ }
 517+
 518+ /**
 519+ * Return an id for use in wikitext output based on a key and
 520+ * optionally the number of it, used in <ref>, not <references>
 521+ * (since otherwise it would link to itself)
 522+ *
 523+ * @static
 524+ *
 525+ * @param string $key The key
 526+ * @param int $num The number of the key
 527+ * @return string A key for use in wikitext
 528+ */
 529+ function referencesKey( $key, $num = null ) {
 530+ $prefix = wfMsgForContent( 'cite_references_link_prefix' );
 531+ $suffix = wfMsgForContent( 'cite_references_link_suffix' );
 532+ if ( isset( $num ) )
 533+ $key = wfMsgForContentNoTrans( 'cite_reference_link_key_with_num', $key, $num );
 534+
 535+ return $prefix . $key . $suffix;
 536+ }
 537+
 538+ /**
 539+ * Generate a link (<sup ...) for the <ref> element from a key
 540+ * and return XHTML ready for output
 541+ *
 542+ * @param string $key The key for the link
 543+ * @param int $count The index of the key, used for distinguishing
 544+ * multiple occurances of the same key
 545+ * @param int $label The label to use for the link, I want to
 546+ * use the same label for all occourances of
 547+ * the same named reference.
 548+ * @return string
 549+ */
 550+ function linkRef( $group, $key, $count = null, $label = null, $subkey = '' ) {
 551+ global $wgContLang;
 552+ return
 553+ $this->parse(
 554+ wfMsgForContentNoTrans(
 555+ 'cite_reference_link',
 556+ $this->refKey( $key, $count ),
 557+ $this->referencesKey( $key . $subkey ),
 558+ (($group == CITE_DEFAULT_GROUP)?'':"$group ").$wgContLang->formatNum( is_null( $label ) ? ++$this->mGroupCnt[$group] : $label )
 559+ )
 560+ );
 561+ }
 562+
 563+ /**
 564+ * This does approximately the same thing as
 565+ * Language::listToText() but due to this being used for a
 566+ * slightly different purpose (people might not want , as the
 567+ * first seperator and not 'and' as the second, and this has to
 568+ * use messages from the content language) I'm rolling my own.
 569+ *
 570+ * @static
 571+ *
 572+ * @param array $arr The array to format
 573+ * @return string
 574+ */
 575+ function listToText( $arr ) {
 576+ $cnt = count( $arr );
 577+
 578+ $sep = wfMsgForContentNoTrans( 'cite_references_link_many_sep' );
 579+ $and = wfMsgForContentNoTrans( 'cite_references_link_many_and' );
 580+
 581+ if ( $cnt == 1 )
 582+ // Enforce always returning a string
 583+ return (string)$arr[0];
 584+ else {
 585+ $t = array_slice( $arr, 0, $cnt - 1 );
 586+ return implode( $sep, $t ) . $and . $arr[$cnt - 1];
 587+ }
 588+ }
 589+
 590+ /**
 591+ * Parse a given fragment and fix up Tidy's trail of blood on
 592+ * it...
 593+ *
 594+ * @param string $in The text to parse
 595+ * @return string The parsed text
 596+ */
 597+ function parse( $in ) {
 598+ if ( method_exists( $this->mParser, 'recursiveTagParse' ) ) {
 599+ // New fast method
 600+ return $this->mParser->recursiveTagParse( $in );
 601+ } else {
 602+ // Old method
 603+ $ret = $this->mParser->parse(
 604+ $in,
 605+ $this->mParser->mTitle,
 606+ $this->mParser->mOptions,
 607+ // Avoid whitespace buildup
 608+ false,
 609+ // Important, otherwise $this->clearState()
 610+ // would get run every time <ref> or
 611+ // <references> is called, fucking the whole
 612+ // thing up.
 613+ false
 614+ );
 615+ $text = $ret->getText();
 616+
 617+ return $this->fixTidy( $text );
 618+ }
 619+ }
 620+
 621+ /**
 622+ * Tidy treats all input as a block, it will e.g. wrap most
 623+ * input in <p> if it isn't already, fix that and return the fixed text
 624+ *
 625+ * @static
 626+ *
 627+ * @param string $text The text to fix
 628+ * @return string The fixed text
 629+ */
 630+ function fixTidy( $text ) {
 631+ global $wgUseTidy;
 632+
 633+ if ( ! $wgUseTidy )
 634+ return $text;
 635+ else {
 636+ $text = preg_replace( '~^<p>\s*~', '', $text );
 637+ $text = preg_replace( '~\s*</p>\s*~', '', $text );
 638+ $text = preg_replace( '~\n$~', '', $text );
 639+
 640+ return $text;
 641+ }
 642+ }
 643+
 644+ /**
 645+ * Generate the labels to pass to the
 646+ * 'cite_references_link_many_format' message, the format is an
 647+ * arbitary number of tokens seperated by [\t\n ]
 648+ */
 649+ function genBacklinkLabels() {
 650+ wfProfileIn( __METHOD__ );
 651+ $text = wfMsgForContentNoTrans( 'cite_references_link_many_format_backlink_labels' );
 652+ $this->mBacklinkLabels = preg_split( '#[\n\t ]#', $text );
 653+ wfProfileOut( __METHOD__ );
 654+ }
 655+
 656+ /**
 657+ * Gets run when Parser::clearState() gets run, since we don't
 658+ * want the counts to transcend pages and other instances
 659+ */
 660+ function clearState() {
 661+ $this->mGroupCnt = array();
 662+ $this->mOutCnt = -1;
 663+ $this->mInCnt = 0;
 664+ $this->mRefs = array();
 665+
 666+ return true;
 667+ }
 668+
 669+ /**
 670+ * Initialize the parser hooks
 671+ */
 672+ function setHooks() {
 673+ global $wgParser, $wgHooks;
 674+
 675+ $wgParser->setHook( 'ref' , array( &$this, 'ref' ) );
 676+ $wgParser->setHook( 'references' , array( &$this, 'references' ) );
 677+
 678+ $wgHooks['ParserClearState'][] = array( &$this, 'clearState' );
 679+ }
 680+
 681+ /**
 682+ * Return an error message based on an error ID
 683+ *
 684+ * @param string $key Message name for the error
 685+ * @param string $param Parameter to pass to the message
 686+ * @return string XHTML ready for output
 687+ */
 688+ function error( $key, $param=null ) {
 689+ # We rely on the fact that PHP is okay with passing unused argu-
 690+ # ments to functions. If $1 is not used in the message, wfMsg will
 691+ # just ignore the extra parameter.
 692+ return
 693+ $this->parse(
 694+ '<strong class="error">' .
 695+ wfMsg( 'cite_error', wfMsg( $key, $param ) ) .
 696+ '</strong>'
 697+ );
 698+ }
 699+
 700+ /**
 701+ * Die with a backtrace if something happens in the code which
 702+ * shouldn't have
 703+ *
 704+ * @param int $error ID for the error
 705+ * @param string $data Serialized error data
 706+ */
 707+ function croak( $error, $data ) {
 708+ wfDebugDieBacktrace( wfMsgForContent( 'cite_croak', $this->error( $error ), $data ) );
 709+ }
 710+
 711+ /**#@-*/
 712+}
 713+
 714+?>
\ No newline at end of file
Property changes on: trunk/extensions/Cite/Cite_body.php
___________________________________________________________________
Added: svn:eol-style
1715 + native
Index: trunk/extensions/Cite/Cite.php
@@ -18,7 +18,12 @@
1919 * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
2020 */
2121
22 -$wgExtensionFunctions[] = 'wfCite';
 22+if ( defined( 'MW_SUPPORTS_PARSERFIRSTCALLINIT' ) ) {
 23+ $wgHooks['ParserFirstCallInit'][] = 'wfCite';
 24+} else {
 25+ $wgExtensionFunctions[] = 'wfCite';
 26+}
 27+
2328 $wgExtensionCredits['parserhook'][] = array(
2429 'name' => 'Cite',
2530 'svn-date' => '$LastChangedDate$',
@@ -30,6 +35,7 @@
3136 );
3237 $wgParserTestFiles[] = dirname( __FILE__ ) . "/citeParserTests.txt";
3338 $wgExtensionMessagesFiles['Cite'] = dirname( __FILE__ ) . "/Cite.i18n.php";
 39+$wgAutoloadClasses['Cite'] = dirname( __FILE__ ) . "/Cite_body.php";
3440
3541 define( 'CITE_DEFAULT_GROUP', '');
3642 /**
@@ -39,700 +45,8 @@
4046 $wgAllowCiteGroups = true;
4147
4248 function wfCite() {
43 - class Cite {
44 - /**#@+
45 - * @access private
46 - */
47 -
48 - /**
49 - * Datastructure representing <ref> input, in the format of:
50 - * <code>
51 - * array(
52 - * 'user supplied' => array(
53 - * 'text' => 'user supplied reference & key',
54 - * 'count' => 1, // occurs twice
55 - * 'number' => 1, // The first reference, we want
56 - * // all occourances of it to
57 - * // use the same number
58 - * ),
59 - * 0 => 'Anonymous reference',
60 - * 1 => 'Another anonymous reference',
61 - * 'some key' => array(
62 - * 'text' => 'this one occurs once'
63 - * 'count' => 0,
64 - * 'number' => 4
65 - * ),
66 - * 3 => 'more stuff'
67 - * );
68 - * </code>
69 - *
70 - * This works because:
71 - * * PHP's datastructures are guarenteed to be returned in the
72 - * order that things are inserted into them (unless you mess
73 - * with that)
74 - * * User supplied keys can't be integers, therefore avoiding
75 - * conflict with anonymous keys
76 - *
77 - * @var array
78 - **/
79 - var $mRefs = array();
80 -
81 - /**
82 - * Count for user displayed output (ref[1], ref[2], ...)
83 - *
84 - * @var int
85 - */
86 - var $mOutCnt = 0;
87 - var $mGroupCnt = array();
88 -
89 - /**
90 - * Internal counter for anonymous references, seperate from
91 - * $mOutCnt because anonymous references won't increment it,
92 - * but will incremement $mOutCnt
93 - *
94 - * @var int
95 - */
96 - var $mInCnt = 0;
97 -
98 - /**
99 - * The backlinks, in order, to pass as $3 to
100 - * 'cite_references_link_many_format', defined in
101 - * 'cite_references_link_many_format_backlink_labels
102 - *
103 - * @var array
104 - */
105 - var $mBacklinkLabels;
106 -
107 - /**
108 - * @var object
109 - */
110 - var $mParser;
111 -
112 - /**
113 - * True when a <ref> or <references> tag is being processed.
114 - * Used to avoid infinite recursion
115 - *
116 - * @var boolean
117 - */
118 - var $mInCite = false;
119 -
120 - /**#@-*/
121 -
122 - /**
123 - * Constructor
124 - */
125 - function Cite() {
126 - $this->setHooks();
127 - }
128 -
129 - /**#@+ @access private */
130 -
131 - /**
132 - * Callback function for <ref>
133 - *
134 - * @param string $str Input
135 - * @param array $argv Arguments
136 - * @return string
137 - */
138 - function ref( $str, $argv, $parser ) {
139 - wfLoadExtensionMessages( 'Cite' );
140 - if ( $this->mInCite ) {
141 - return htmlspecialchars( "<ref>$str</ref>" );
142 - } else {
143 - $this->mInCite = true;
144 - $ret = $this->guardedRef( $str, $argv, $parser );
145 - $this->mInCite = false;
146 - return $ret;
147 - }
148 - }
149 -
150 - function guardedRef( $str, $argv, $parser, $default_group=CITE_DEFAULT_GROUP ) {
151 - $this->mParser = $parser;
152 -
153 - # The key here is the "name" attribute.
154 - list($key,$group) = $this->refArg( $argv );
155 -
156 - if( $str === '' ) {
157 - # <ref ...></ref>. This construct is always invalid: either
158 - # it's a contentful ref, or it's a named duplicate and should
159 - # be <ref ... />.
160 - return $this->error( 'cite_error_ref_no_input' );
161 - }
162 -
163 - if( $key === false ) {
164 - # TODO: Comment this case; what does this condition mean?
165 - return $this->error( 'cite_error_ref_too_many_keys' );
166 - }
167 -
168 - if( $str === null and $key === null ) {
169 - # Something like <ref />; this makes no sense.
170 - return $this->error( 'cite_error_ref_no_key' );
171 - }
172 -
173 - if( preg_match( '/^[0-9]+$/', $key ) ) {
174 - # Numeric names mess up the resulting id's, potentially produ-
175 - # cing duplicate id's in the XHTML. The Right Thing To Do
176 - # would be to mangle them, but it's not really high-priority
177 - # (and would produce weird id's anyway).
178 - return $this->error( 'cite_error_ref_numeric_key' );
179 - }
180 -
181 - #Split these into groups.
182 - if( $group === null ) {
183 - $group = $default_group;
184 - }
185 -
186 - if( is_string( $key ) or is_string( $str ) ) {
187 - # We don't care about the content: if the key exists, the ref
188 - # is presumptively valid. Either it stores a new ref, or re-
189 - # fers to an existing one. If it refers to a nonexistent ref,
190 - # we'll figure that out later. Likewise it's definitely valid
191 - # if there's any content, regardless of key.
192 - return $this->stack( $str, $key, $group );
193 - }
194 -
195 - # Not clear how we could get here, but something is probably
196 - # wrong with the types. Let's fail fast.
197 - $this->croak( 'cite_error_key_str_invalid', serialize( "$str; $key" ) );
198 - }
199 -
200 - /**
201 - * Parse the arguments to the <ref> tag
202 - *
203 - * @static
204 - *
205 - * @param array $argv The argument vector
206 - * @return mixed false on invalid input, a string on valid
207 - * input and null on no input
208 - */
209 - function refArg( $argv ) {
210 - global $wgAllowCiteGroups;
211 - $cnt = count( $argv );
212 - $group = null;
213 - $key = null;
214 -
215 - if ( $cnt > 2 )
216 - // There should only be one key and one group
217 - return false;
218 - else if ( $cnt >= 1 ) {
219 - if ( isset( $argv['name'] ) ) {
220 - // Key given.
221 - $key = $this->validateName( $argv['name'] );
222 - unset( $argv['name']);
223 - --$cnt;
224 - }
225 - if ( isset( $argv['group'] ) ){
226 - if (! $wgAllowCiteGroups ) return array(false); //remove when groups are fully tested.
227 - // Group given.
228 - $group = $this->validateName( $argv['group'] );
229 - unset( $argv['group']);
230 - --$cnt;
231 - }
232 -
233 - if ( $cnt == 0)
234 - return array ($key,$group);
235 - else
236 - // Invalid key
237 - return array(false);
238 - }
239 - else
240 - // No key
241 - return array(null,$group);
242 - }
243 -
244 - /**
245 - * Since the key name is used in an XHTML id attribute, it must
246 - * conform to the validity rules. The restriction to begin with
247 - * a letter is lifted since references have their own prefix.
248 - *
249 - * @fixme merge this code with the various section name transformations
250 - * @fixme double-check for complete validity
251 - * @return string if valid, false if invalid
252 - */
253 - function validateName( $name ) {
254 - if( preg_match( '/^[A-Za-z0-9:_.-]*$/i', $name ) ) {
255 - return $name;
256 - } else {
257 - // WARNING: CRAPPY CUT AND PASTE MAKES BABY JESUS CRY
258 - $text = urlencode( str_replace( ' ', '_', $name ) );
259 - $replacearray = array(
260 - '%3A' => ':',
261 - '%' => '.'
262 - );
263 - return str_replace(
264 - array_keys( $replacearray ),
265 - array_values( $replacearray ),
266 - $text );
267 - }
268 - }
269 -
270 - /**
271 - * Populate $this->mRefs based on input and arguments to <ref>
272 - *
273 - * @param string $str Input from the <ref> tag
274 - * @param mixed $key Argument to the <ref> tag as returned by $this->refArg()
275 - * @return string
276 - */
277 - function stack( $str, $key = null, $group ) {
278 - if (! isset($this->mRefs[$group]))
279 - $this->mRefs[$group]=array();
280 - if (! isset($this->mGroupCnt[$group]))
281 - $this->mGroupCnt[$group]=0;
282 -
283 - if ( $key === null ) {
284 - // No key
285 - //$this->mRefs[$group][] = $str;
286 - $this->mRefs[$group][] = array('count'=>-1, 'text'=>$str, 'key'=>++$this->mOutCnt);
287 -
288 - return $this->linkRef( $group, $this->mInCnt++ );
289 - } else if ( is_string( $key ) ) {
290 - // Valid key
291 - if ( ! isset( $this->mRefs[$group][$key] ) || ! is_array( $this->mRefs[$group][$key] ) ) {
292 - // First occurance
293 - $this->mRefs[$group][$key] = array(
294 - 'text' => $str,
295 - 'count' => 0,
296 - 'key' => ++$this->mOutCnt,
297 - 'number' => ++$this->mGroupCnt[$group]
298 - );
299 - $this->mInCnt++;
300 - return
301 - $this->linkRef(
302 - $group,
303 - $key,
304 - $this->mRefs[$group][$key]['key']."-".$this->mRefs[$group][$key]['count'],
305 - $this->mRefs[$group][$key]['number'],
306 - "-".$this->mRefs[$group][$key]['key']
307 - );
308 - } else {
309 - // We've been here before
310 - if ( $this->mRefs[$group][$key]['text'] === null && $str !== '' ) {
311 - // If no text found before, use this text
312 - $this->mRefs[$group][$key]['text'] = $str;
313 - };
314 - return
315 - $this->linkRef(
316 - $group,
317 - $key,
318 - $this->mRefs[$group][$key]['key']."-".++$this->mRefs[$group][$key]['count'],
319 - $this->mRefs[$group][$key]['number'],
320 - "-".$this->mRefs[$group][$key]['key']
321 - ); }
322 - }
323 -
324 - else
325 - $this->croak( 'cite_error_stack_invalid_input', serialize( array( $key, $str ) ) );
326 - }
327 -
328 - /**
329 - * Callback function for <references>
330 - *
331 - * @param string $str Input
332 - * @param array $argv Arguments
333 - * @return string
334 - */
335 - function references( $str, $argv, $parser ) {
336 - wfLoadExtensionMessages( 'Cite' );
337 - if ( $this->mInCite ) {
338 - if ( is_null( $str ) ) {
339 - return htmlspecialchars( "<references/>" );
340 - } else {
341 - return htmlspecialchars( "<references>$str</references>" );
342 - }
343 - } else {
344 - $this->mInCite = true;
345 - $ret = $this->guardedReferences( $str, $argv, $parser );
346 - $this->mInCite = false;
347 - return $ret;
348 - }
349 - }
350 -
351 - function guardedReferences( $str, $argv, $parser, $group = CITE_DEFAULT_GROUP ) {
352 - global $wgAllowCiteGroups;
353 -
354 - $this->mParser = $parser;
355 -
356 - if ( strval( $str ) !== '' )
357 - return $this->error( 'cite_error_references_invalid_input' );
358 -
359 -
360 - if ( isset( $argv['group'] ) and $wgAllowCiteGroups) {
361 - $group = $argv['group'];
362 - unset ($argv['group']);
363 -
364 - }
365 -
366 - if ( count( $argv ) )
367 - return $this->error( 'cite_error_references_invalid_parameters' );
368 - else
369 - return $this->referencesFormat($group);
370 - }
371 -
372 - /**
373 - * Make output to be returned from the references() function
374 - *
375 - * @return string XHTML ready for output
376 - */
377 - function referencesFormat($group) {
378 - if (( count( $this->mRefs ) == 0 ) or (empty( $this->mRefs[$group] ) ))
379 - return '';
380 -
381 - wfProfileIn( __METHOD__ );
382 - wfProfileIn( __METHOD__ .'-entries' );
383 - $ent = array();
384 - foreach ( $this->mRefs[$group] as $k => $v )
385 - $ent[] = $this->referencesFormatEntry( $k, $v );
386 -
387 - $prefix = wfMsgForContentNoTrans( 'cite_references_prefix' );
388 - $suffix = wfMsgForContentNoTrans( 'cite_references_suffix' );
389 - $content = implode( "\n", $ent );
390 -
391 - wfProfileOut( __METHOD__ .'-entries' );
392 - wfProfileIn( __METHOD__ .'-parse' );
393 - // Live hack: parse() adds two newlines on WM, can't reproduce it locally -ævar
394 - $ret = rtrim( $this->parse( $prefix . $content . $suffix ), "\n" );
395 - wfProfileOut( __METHOD__ .'-parse' );
396 - wfProfileOut( __METHOD__ );
397 -
398 - //done, clean up so we can reuse the group
399 - unset ($this->mRefs[$group]);
400 - unset($this->mGroupCnt[$group]);
401 -
402 - return $ret;
403 - }
404 -
405 - /**
406 - * Format a single entry for the referencesFormat() function
407 - *
408 - * @param string $key The key of the reference
409 - * @param mixed $val The value of the reference, string for anonymous
410 - * references, array for user-suppplied
411 - * @return string Wikitext
412 - */
413 - function referencesFormatEntry( $key, $val ) {
414 - // Anonymous reference
415 - if ( ! is_array( $val ) )
416 - return
417 - wfMsgForContentNoTrans(
418 - 'cite_references_link_one',
419 - $this->referencesKey( $key ),
420 - $this->refKey( $key ),
421 - $val
422 - );
423 - else if ($val['text']=='') return
424 - wfMsgForContentNoTrans(
425 - 'cite_references_link_one',
426 - $this->referencesKey( $key ),
427 - $this->refKey( $key, $val['count'] ),
428 - $this->error( 'cite_error_references_no_text', $key )
429 - );
430 - if ( $val['count'] < 0 )
431 - return
432 - wfMsgForContentNoTrans(
433 - 'cite_references_link_one',
434 - $this->referencesKey( $val['key'] ),
435 - #$this->refKey( $val['key'], $val['count'] ),
436 - $this->refKey( $val['key'] ),
437 -
438 - ( $val['text'] != '' ? $val['text'] : $this->error( 'cite_error_references_no_text', $key ) )
439 - );
440 - // Standalone named reference, I want to format this like an
441 - // anonymous reference because displaying "1. 1.1 Ref text" is
442 - // overkill and users frequently use named references when they
443 - // don't need them for convenience
444 - else if ( $val['count'] === 0 )
445 - return
446 - wfMsgForContentNoTrans(
447 - 'cite_references_link_one',
448 - $this->referencesKey( $key ."-" . $val['key'] ),
449 - #$this->refKey( $key, $val['count'] ),
450 - $this->refKey( $key, $val['key']."-".$val['count'] ),
451 - ( $val['text'] != '' ? $val['text'] : $this->error( 'cite_error_references_no_text', $key ) )
452 - );
453 - // Named references with >1 occurrences
454 - else {
455 - $links = array();
456 -//for group handling, we have an extra key here.
457 - for ( $i = 0; $i <= $val['count']; ++$i ) {
458 - $links[] = wfMsgForContentNoTrans(
459 - 'cite_references_link_many_format',
460 - $this->refKey( $key, $val['key']."-$i" ),
461 - $this->referencesFormatEntryNumericBacklinkLabel( $val['number'], $i, $val['count'] ),
462 - $this->referencesFormatEntryAlternateBacklinkLabel( $i )
463 - );
464 - }
465 -
466 - $list = $this->listToText( $links );
467 -
468 - return
469 - wfMsgForContentNoTrans( 'cite_references_link_many',
470 - $this->referencesKey( $key ."-" . $val['key'] ),
471 - $list,
472 - ( $val['text'] != '' ? $val['text'] : $this->error( 'cite_error_references_no_text', $key ) )
473 - );
474 - }
475 - }
476 -
477 - /**
478 - * Generate a numeric backlink given a base number and an
479 - * offset, e.g. $base = 1, $offset = 2; = 1.2
480 - * Since bug #5525, it correctly does 1.9 -> 1.10 as well as 1.099 -> 1.100
481 - *
482 - * @static
483 - *
484 - * @param int $base The base
485 - * @param int $offset The offset
486 - * @param int $max Maximum value expected.
487 - * @return string
488 - */
489 - function referencesFormatEntryNumericBacklinkLabel( $base, $offset, $max ) {
490 - global $wgContLang;
491 - $scope = strlen( $max );
492 - $ret = $wgContLang->formatNum(
493 - sprintf("%s.%0{$scope}s", $base, $offset)
494 - );
495 - return $ret;
496 - }
497 -
498 - /**
499 - * Generate a custom format backlink given an offset, e.g.
500 - * $offset = 2; = c if $this->mBacklinkLabels = array( 'a',
501 - * 'b', 'c', ...). Return an error if the offset > the # of
502 - * array items
503 - *
504 - * @param int $offset The offset
505 - *
506 - * @return string
507 - */
508 - function referencesFormatEntryAlternateBacklinkLabel( $offset ) {
509 - if ( !isset( $this->mBacklinkLabels ) ) {
510 - $this->genBacklinkLabels();
511 - }
512 - if ( isset( $this->mBacklinkLabels[$offset] ) ) {
513 - return $this->mBacklinkLabels[$offset];
514 - } else {
515 - // Feed me!
516 - return $this->error( 'cite_error_references_no_backlink_label' );
517 - }
518 - }
519 -
520 - /**
521 - * Return an id for use in wikitext output based on a key and
522 - * optionally the number of it, used in <references>, not <ref>
523 - * (since otherwise it would link to itself)
524 - *
525 - * @static
526 - *
527 - * @param string $key The key
528 - * @param int $num The number of the key
529 - * @return string A key for use in wikitext
530 - */
531 - function refKey( $key, $num = null ) {
532 - $prefix = wfMsgForContent( 'cite_reference_link_prefix' );
533 - $suffix = wfMsgForContent( 'cite_reference_link_suffix' );
534 - if ( isset( $num ) )
535 - $key = wfMsgForContentNoTrans( 'cite_reference_link_key_with_num', $key, $num );
536 -
537 - return $prefix . $key . $suffix;
538 - }
539 -
540 - /**
541 - * Return an id for use in wikitext output based on a key and
542 - * optionally the number of it, used in <ref>, not <references>
543 - * (since otherwise it would link to itself)
544 - *
545 - * @static
546 - *
547 - * @param string $key The key
548 - * @param int $num The number of the key
549 - * @return string A key for use in wikitext
550 - */
551 - function referencesKey( $key, $num = null ) {
552 - $prefix = wfMsgForContent( 'cite_references_link_prefix' );
553 - $suffix = wfMsgForContent( 'cite_references_link_suffix' );
554 - if ( isset( $num ) )
555 - $key = wfMsgForContentNoTrans( 'cite_reference_link_key_with_num', $key, $num );
556 -
557 - return $prefix . $key . $suffix;
558 - }
559 -
560 - /**
561 - * Generate a link (<sup ...) for the <ref> element from a key
562 - * and return XHTML ready for output
563 - *
564 - * @param string $key The key for the link
565 - * @param int $count The index of the key, used for distinguishing
566 - * multiple occurances of the same key
567 - * @param int $label The label to use for the link, I want to
568 - * use the same label for all occourances of
569 - * the same named reference.
570 - * @return string
571 - */
572 - function linkRef( $group, $key, $count = null, $label = null, $subkey = '' ) {
573 - global $wgContLang;
574 - return
575 - $this->parse(
576 - wfMsgForContentNoTrans(
577 - 'cite_reference_link',
578 - $this->refKey( $key, $count ),
579 - $this->referencesKey( $key . $subkey ),
580 - (($group == CITE_DEFAULT_GROUP)?'':"$group ").$wgContLang->formatNum( is_null( $label ) ? ++$this->mGroupCnt[$group] : $label )
581 - )
582 - );
583 - }
584 -
585 - /**
586 - * This does approximately the same thing as
587 - * Language::listToText() but due to this being used for a
588 - * slightly different purpose (people might not want , as the
589 - * first seperator and not 'and' as the second, and this has to
590 - * use messages from the content language) I'm rolling my own.
591 - *
592 - * @static
593 - *
594 - * @param array $arr The array to format
595 - * @return string
596 - */
597 - function listToText( $arr ) {
598 - $cnt = count( $arr );
599 -
600 - $sep = wfMsgForContentNoTrans( 'cite_references_link_many_sep' );
601 - $and = wfMsgForContentNoTrans( 'cite_references_link_many_and' );
602 -
603 - if ( $cnt == 1 )
604 - // Enforce always returning a string
605 - return (string)$arr[0];
606 - else {
607 - $t = array_slice( $arr, 0, $cnt - 1 );
608 - return implode( $sep, $t ) . $and . $arr[$cnt - 1];
609 - }
610 - }
611 -
612 - /**
613 - * Parse a given fragment and fix up Tidy's trail of blood on
614 - * it...
615 - *
616 - * @param string $in The text to parse
617 - * @return string The parsed text
618 - */
619 - function parse( $in ) {
620 - if ( method_exists( $this->mParser, 'recursiveTagParse' ) ) {
621 - // New fast method
622 - return $this->mParser->recursiveTagParse( $in );
623 - } else {
624 - // Old method
625 - $ret = $this->mParser->parse(
626 - $in,
627 - $this->mParser->mTitle,
628 - $this->mParser->mOptions,
629 - // Avoid whitespace buildup
630 - false,
631 - // Important, otherwise $this->clearState()
632 - // would get run every time <ref> or
633 - // <references> is called, fucking the whole
634 - // thing up.
635 - false
636 - );
637 - $text = $ret->getText();
638 -
639 - return $this->fixTidy( $text );
640 - }
641 - }
642 -
643 - /**
644 - * Tidy treats all input as a block, it will e.g. wrap most
645 - * input in <p> if it isn't already, fix that and return the fixed text
646 - *
647 - * @static
648 - *
649 - * @param string $text The text to fix
650 - * @return string The fixed text
651 - */
652 - function fixTidy( $text ) {
653 - global $wgUseTidy;
654 -
655 - if ( ! $wgUseTidy )
656 - return $text;
657 - else {
658 - $text = preg_replace( '~^<p>\s*~', '', $text );
659 - $text = preg_replace( '~\s*</p>\s*~', '', $text );
660 - $text = preg_replace( '~\n$~', '', $text );
661 -
662 - return $text;
663 - }
664 - }
665 -
666 - /**
667 - * Generate the labels to pass to the
668 - * 'cite_references_link_many_format' message, the format is an
669 - * arbitary number of tokens seperated by [\t\n ]
670 - */
671 - function genBacklinkLabels() {
672 - wfProfileIn( __METHOD__ );
673 - $text = wfMsgForContentNoTrans( 'cite_references_link_many_format_backlink_labels' );
674 - $this->mBacklinkLabels = preg_split( '#[\n\t ]#', $text );
675 - wfProfileOut( __METHOD__ );
676 - }
677 -
678 - /**
679 - * Gets run when Parser::clearState() gets run, since we don't
680 - * want the counts to transcend pages and other instances
681 - */
682 - function clearState() {
683 - $this->mGroupCnt = array();
684 - $this->mOutCnt = -1;
685 - $this->mInCnt = 0;
686 - $this->mRefs = array();
687 -
688 - return true;
689 - }
690 -
691 - /**
692 - * Initialize the parser hooks
693 - */
694 - function setHooks() {
695 - global $wgParser, $wgHooks;
696 -
697 - $wgParser->setHook( 'ref' , array( &$this, 'ref' ) );
698 - $wgParser->setHook( 'references' , array( &$this, 'references' ) );
699 -
700 - $wgHooks['ParserClearState'][] = array( &$this, 'clearState' );
701 - }
702 -
703 - /**
704 - * Return an error message based on an error ID
705 - *
706 - * @param string $key Message name for the error
707 - * @param string $param Parameter to pass to the message
708 - * @return string XHTML ready for output
709 - */
710 - function error( $key, $param=null ) {
711 - # We rely on the fact that PHP is okay with passing unused argu-
712 - # ments to functions. If $1 is not used in the message, wfMsg will
713 - # just ignore the extra parameter.
714 - return
715 - $this->parse(
716 - '<strong class="error">' .
717 - wfMsg( 'cite_error', wfMsg( $key, $param ) ) .
718 - '</strong>'
719 - );
720 - }
721 -
722 - /**
723 - * Die with a backtrace if something happens in the code which
724 - * shouldn't have
725 - *
726 - * @param int $error ID for the error
727 - * @param string $data Serialized error data
728 - */
729 - function croak( $error, $data ) {
730 - wfDebugDieBacktrace( wfMsgForContent( 'cite_croak', $this->error( $error ), $data ) );
731 - }
732 -
733 - /**#@-*/
734 - }
735 -
73649 new Cite;
 50+ return true;
73751 }
73852
73953 /**#@-*/
Index: trunk/extensions/wikihiero/wikihiero.php
@@ -25,7 +25,12 @@
2626 //////////////////////////////////////////////////////////////////////////
2727
2828 // Register MediaWiki extension
29 -$wgExtensionFunctions[] = 'WH_Register';
 29+if ( defined( 'MW_SUPPORTS_PARSERFIRSTCALLINIT' ) ) {
 30+ $wgHooks['ParserFirstCallInit'][] = 'WH_Register';
 31+} else {
 32+ $wgExtensionFunctions[] = 'WH_Register';
 33+}
 34+
3035 $wgExtensionCredits['parserhook'][] = array(
3136 'name' => 'WikiHiero',
3237 'author' => 'Guillaume Blanchard',
@@ -40,6 +45,7 @@
4146 function WH_Register() {
4247 global $wgParser;
4348 $wgParser->setHook( 'hiero', 'WikiHieroLoader' );
 49+ return true;
4450 }
4551
4652 function WikiHieroLoad() {
Index: trunk/extensions/Poem/Poem.php
@@ -18,7 +18,11 @@
1919 # For more information see its page at
2020 # http://meta.wikimedia.org/wiki/Poem_Extension
2121
22 -$wgExtensionFunctions[]="wfPoemExtension";
 22+if ( defined( 'MW_SUPPORTS_PARSERFIRSTCALLINIT' ) ) {
 23+ $wgHooks['ParserFirstCallInit'][] = 'wfPoemExtension';
 24+} else {
 25+ $wgExtensionFunctions[] = 'wfPoemExtension';
 26+}
2327 $wgExtensionCredits['parserhook'][] = array(
2428 'name' => 'Poem',
2529 'author' => array( 'Nikola Smolenski', 'Brion Vibber', 'Steve Sanbeg' ),
@@ -33,6 +37,7 @@
3438
3539 function wfPoemExtension() {
3640 $GLOBALS['wgParser']->setHook("poem","PoemExtension");
 41+ return true;
3742 }
3843
3944 function PoemExtension( $in, $param=array(), $parser=null ) {

Follow-up revisions

RevisionCommit summaryAuthorDate
r35996CreateBox:...ashley14:43, 7 June 2008
r37843Just revert to r35980 for now, can't get even the fixed version working right...brion12:04, 19 July 2008

Status & tagging log