User:Jeblad/Cite body.php

* This works because: * * PHP's datastructures are guarenteed to be returned in the *  order that things are inserted into them (unless you mess	 *   with that) * * User supplied keys can't be integers, therefore avoiding *  conflict with anonymous keys *	 * @var array **/	var $mRefs = array; /**	 * Count for user displayed output (ref[1], ref[2], ...) *	 * @var int */	var $mOutCnt = 0; var $mGroupCnt = array;

/**	 * Internal counter for anonymous references, seperate from * $mOutCnt because anonymous references won't increment it, * but will incremement $mOutCnt *	 * @var int */	var $mInCnt = 0;

/**	 * The backlinks, in order, to pass as $3 to	 * 'cite_references_link_many_format', defined in	 * 'cite_references_link_many_format_backlink_labels *	 * @var array */	var $mBacklinkLabels; /**	 * @var object */	var $mParser; /**	 * True when a or " );			}		} else {			$this->mInCite = true;			$ret = $this->guardedReferences( $str, $argv, $parser );			$this->mInCite = false;			return $ret;		}	}

function guardedReferences( $str, $argv, $parser, $group = CITE_DEFAULT_GROUP ) { global $wgAllowCiteGroups;

$this->mParser = $parser; if ( isset( $argv['group'] ) and $wgAllowCiteGroups) { $group = $argv['group']; unset ($argv['group']); }		if ( count( $argv ) ) return $this->error( 'cite_error_references_invalid_parameters' ); else return $this->referencesFormat($str, $group); }

/**	 * Make output to be returned from the references function *	 * @param string $str The content of the reference * @return string XHTML ready for output */	function referencesFormat($str, $group) { global $wgAllowTailDefs; if ((strval( $str ) == '') && (( count( $this->mRefs ) == 0 ) or (empty( $this->mRefs[$group] ) ))) return ''; wfProfileIn( __METHOD__ ); wfProfileIn( __METHOD__ .'-addentries' ); $str = "\n". $str. "\n"; $used = array; $addents = array; $fragments = array; # match lines like these: # somename|This is the reference text for some text # lines may continue on following lines if indented $count = 0; if ($wgAllowTailDefs) { preg_match_all( "/\\n([^:\\n\\t ]*?)[\\t ]*:[\\t ]*([^\\n]*(?:\\n[\\t ][^\\n]*)*)/s", $str, $fragments, PREG_SET_ORDER ); foreach ( $fragments as $fragment ) { $count++; # Skip empty lines if ( count( $fragment ) == 0 ) { continue; }				if ($fragment[1] == '' && is_array($this->mRefs[$group]) && !isset( $this->mRefs[$group][$group. '-anon-'. $count] )) $addents[$group. '-anon-'. $count] = $fragment[2]; else $addents[$fragment[1]] = $fragment[2]; }		}		wfProfileOut( __METHOD__ .'-addentries' ); wfProfileIn( __METHOD__ .'-entries' ); $ent = array; if (is_array($this->mRefs[$group])) { foreach ( $this->mRefs[$group] as $k => $v ) { if (is_array( $v ) && $v['text']=='') { $used[$k]++; $ent[] = $this->referencesFormatEntry( $k, $addents[$k] ); }				else $ent[] = $this->referencesFormatEntry( $k, $v ); }		}		foreach ( $addents as $k => $v ) { if (!$used[$k]) { $ent[] = wfMsgForContentNoTrans(					'cite_references_link_none',					$addents[$k],					$this->error( 'cite_error_references_no_text', $k )				); }		}		$prefix = wfMsgForContentNoTrans( 'cite_references_prefix' ); $suffix = wfMsgForContentNoTrans( 'cite_references_suffix' ); $content = implode( "\n", $ent ); wfProfileOut( __METHOD__ .'-entries' ); wfProfileIn( __METHOD__ .'-parse' ); // Live hack: parse adds two newlines on WM, can't reproduce it locally -ævar $ret = rtrim( $this->parse( $prefix. $content. $suffix ), "\n" ); wfProfileOut( __METHOD__ .'-parse' ); wfProfileOut( __METHOD__ ); //done, clean up so we can reuse the group unset ($this->mRefs[$group]); unset($this->mGroupCnt[$group]); return $ret; }

/**	 * Format a single entry for the referencesFormat function *	 * @param string $key The key of the reference * @param mixed $val The value of the reference, string for anonymous *                  references, array for user-suppplied * @return string Wikitext */	function referencesFormatEntry( $key, $val ) { // Anonymous reference if ( ! is_array( $val ) ) return wfMsgForContentNoTrans(					'cite_references_link_one',					$this->referencesKey( $key ),					$this->refKey( $key ),					$val				); else if ($val['text']=='') return wfMsgForContentNoTrans(					'cite_references_link_one',					$this->referencesKey( $key ),					$this->refKey( $key, $val['count'] ),					$this->error( 'cite_error_references_no_text', $key )				); if ( $val['count'] < 0 ) return wfMsgForContentNoTrans(					'cite_references_link_one',					$this->referencesKey( $val['key'] ),					#$this->refKey( $val['key'], $val['count'] ),					$this->refKey( $val['key'] ),

( $val['text'] != '' ? $val['text'] : $this->error( 'cite_error_references_no_text', $key ) ) );		// Standalone named reference, I want to format this like an		// anonymous reference because displaying "1. 1.1 Ref text" is		// overkill and users frequently use named references when they		// don't need them for convenience		else if ( $val['count'] === 0 )			return				wfMsgForContentNoTrans( 'cite_references_link_one', $this->referencesKey( $key ."-" . $val['key'] ), #$this->refKey( $key, $val['count'] ), $this->refKey( $key, $val['key']."-".$val['count'] ), ( $val['text'] != '' ? $val['text'] : $this->error( 'cite_error_references_no_text', $key ) ) );		// Named references with >1 occurrences		else {			$links = array; //for group handling, we have an extra key here.			for ( $i = 0; $i <= $val['count']; ++$i ) {				$links[] = wfMsgForContentNoTrans( 'cite_references_link_many_format', $this->refKey( $key, $val['key']."-$i" ), $this->referencesFormatEntryNumericBacklinkLabel( $val['number'], $i, $val['count'] ), $this->referencesFormatEntryAlternateBacklinkLabel( $i ) );			}

$list = $this->listToText( $links );

return wfMsgForContentNoTrans( 'cite_references_link_many',					$this->referencesKey( $key ."-". $val['key'] ),					$list,					( $val['text'] != '' ? $val['text'] : $this->error( 'cite_error_references_no_text', $key ) )				); }	}

/**	 * Generate a numeric backlink given a base number and an * offset, e.g. $base = 1, $offset = 2; = 1.2 * Since bug #5525, it correctly does 1.9 -> 1.10 as well as 1.099 -> 1.100 *	 * @static *	 * @param int $base The base * @param int $offset The offset * @param int $max Maximum value expected. * @return string */	function referencesFormatEntryNumericBacklinkLabel( $base, $offset, $max ) { global $wgContLang; $scope = strlen( $max ); $ret = $wgContLang->formatNum(			sprintf("%s.%0{$scope}s", $base, $offset)		); return $ret; }

/**	 * Generate a custom format backlink given an offset, e.g.	 * $offset = 2; = c if $this->mBacklinkLabels = array( 'a',	 * 'b', 'c', ...). Return an error if the offset > the # of	 * array items *	 * @param int $offset The offset *	 * @return string */	function referencesFormatEntryAlternateBacklinkLabel( $offset ) { if ( !isset( $this->mBacklinkLabels ) ) { $this->genBacklinkLabels; }		if ( isset( $this->mBacklinkLabels[$offset] ) ) { return $this->mBacklinkLabels[$offset]; } else { // Feed me! return $this->error( 'cite_error_references_no_backlink_label' ); }	}

/**	 * Return an id for use in wikitext output based on a key and * optionally the number of it, used in