2005-12-21 01:08:25 +00:00
< ? php
if ( ! defined ( 'MEDIAWIKI' ) )
2006-01-27 10:14:45 +00:00
die ();
2005-12-21 01:08:25 +00:00
/** #@+
2005-12-25 19:39:22 +00:00
* A parser extension that adds two tags , < ref > and < references > for adding
* citations to pages
*
2005-12-21 01:08:25 +00:00
* @ package MediaWiki
* @ subpackage Extensions
*
2005-12-25 19:39:22 +00:00
* @ link http :// meta . wikimedia . org / wiki / Cite / Cite . php Documentation
2006-01-07 09:24:48 +00:00
* @ link http :// www . w3 . org / TR / html4 / struct / text . html #edef-CITE <cite> definition in HTML
* @ link http :// www . w3 . org / TR / 2005 / WD - xhtml2 - 20050527 / mod - text . html #edef_text_cite <cite> definition in XHTML 2.0
2005-12-25 19:39:22 +00:00
*
2006-01-12 15:14:46 +00:00
* @ bug 4579
*
2005-12-21 01:08:25 +00:00
* @ author Ævar Arnfjörð Bjarmason < avarab @ gmail . com >
* @ copyright Copyright © 2005 , Ævar Arnfjörð Bjarmason
* @ license http :// www . gnu . org / copyleft / gpl . html GNU General Public License 2.0 or later
*/
$wgExtensionFunctions [] = 'wfCite' ;
$wgExtensionCredits [ 'parserhook' ][] = array (
'name' => 'Cite' ,
'author' => 'Ævar Arnfjörð Bjarmason' ,
2005-12-24 18:03:21 +00:00
'description' => 'adds <nowiki><ref[ name=id]></nowiki> and <nowiki><references/></nowiki> tags, for citations' ,
2005-12-25 19:39:22 +00:00
'url' => 'http://meta.wikimedia.org/wiki/Cite/Cite.php'
2005-12-21 01:08:25 +00:00
);
/**
* Error codes , first array = internal errors ; second array = user errors
*/
2005-12-23 02:34:39 +00:00
$wgCiteErrors = array (
2005-12-21 01:08:25 +00:00
'system' => array (
'CITE_ERROR_STR_INVALID' ,
'CITE_ERROR_KEY_INVALID_1' ,
'CITE_ERROR_KEY_INVALID_2' ,
'CITE_ERROR_STACK_INVALID_INPUT'
),
'user' => array (
'CITE_ERROR_REF_NUMERIC_KEY' ,
'CITE_ERROR_REF_NO_KEY' ,
'CITE_ERROR_REF_TOO_MANY_KEYS' ,
'CITE_ERROR_REF_NO_INPUT' ,
'CITE_ERROR_REFERENCES_INVALID_INPUT' ,
2005-12-29 21:56:00 +00:00
'CITE_ERROR_REFERENCES_INVALID_PARAMETERS' ,
'CITE_ERROR_REFERENCES_NO_BACKLINK_LABEL'
2005-12-21 01:08:25 +00:00
)
);
2005-12-23 02:34:39 +00:00
for ( $i = 0 ; $i < count ( $wgCiteErrors [ 'system' ] ); ++ $i )
2005-12-21 01:08:25 +00:00
// System errors are negative integers
2005-12-23 02:34:39 +00:00
define ( $wgCiteErrors [ 'system' ][ $i ], - ( $i + 1 ) );
for ( $i = 0 ; $i < count ( $wgCiteErrors [ 'user' ] ); ++ $i )
2005-12-21 01:08:25 +00:00
// User errors are positive integers
2005-12-23 02:34:39 +00:00
define ( $wgCiteErrors [ 'user' ][ $i ], $i + 1 );
2005-12-21 01:08:25 +00:00
2006-01-27 10:14:45 +00:00
function wfCite () {
global $wgMessageCache ;
$wgMessageCache -> addMessages (
array (
/*
Debug & errors
*/
// Internal errors
'cite_croak' => 'Cite croaked; $1: $2' ,
'cite_error_' . CITE_ERROR_STR_INVALID => 'Internal error; invalid $str' ,
'cite_error_' . CITE_ERROR_KEY_INVALID_1 => 'Internal error; invalid key' ,
'cite_error_' . CITE_ERROR_KEY_INVALID_2 => 'Internal error; invalid key' ,
'cite_error_' . CITE_ERROR_STACK_INVALID_INPUT => 'Internal error; invalid stack key' ,
// User errors
'cite_error' => 'Cite error $1; $2' ,
'cite_error_' . CITE_ERROR_REF_NUMERIC_KEY => 'Invalid call; expecting a non-integer key' ,
'cite_error_' . CITE_ERROR_REF_NO_KEY => 'Invalid call; no key specified' ,
'cite_error_' . CITE_ERROR_REF_TOO_MANY_KEYS => 'Invalid call; invalid keys, e.g. too many or wrong key specified' ,
'cite_error_' . CITE_ERROR_REF_NO_INPUT => 'Invalid call; no input specified' ,
'cite_error_' . CITE_ERROR_REFERENCES_INVALID_INPUT => 'Invalid input; expecting none' ,
'cite_error_' . CITE_ERROR_REFERENCES_INVALID_PARAMETERS => 'Invalid parameters; expecting none' ,
'cite_error_' . CITE_ERROR_REFERENCES_NO_BACKLINK_LABEL => " Ran out of custom backlink labels, define more in the \" ''cite_references_link_many_format_backlink_labels'' \" message " ,
/*
Output formatting
*/
'cite_reference_link_key_with_num' => '$1_$2' ,
// Ids produced by <ref>
'cite_reference_link_prefix' => '_ref-' ,
'cite_reference_link_suffix' => '' ,
// Ids produced by <references>
'cite_references_link_prefix' => '_note-' ,
'cite_references_link_suffix' => '' ,
'cite_reference_link' => '<sup id="$1" class="reference">[[#$2|<nowiki>[</nowiki>$3<nowiki>]</nowiki>]]</sup>' ,
2006-02-25 23:36:18 +00:00
'cite_references_link_one' => '<li id="$1">[[#$2|↑]] $3</li>' ,
'cite_references_link_many' => '<li id="$1">↑ $2 $3</li>' ,
2006-01-27 10:14:45 +00:00
'cite_references_link_many_format' => '[[#$1|<sup>$2</sup>]]' ,
// An item from this set is passed as $3 in the message above
'cite_references_link_many_format_backlink_labels' => 'a b c d e f g h i j k l m n o p q r s t u v w x y z' ,
'cite_references_link_many_sep' => " \xc2 \xa0 " , //
'cite_references_link_many_and' => " \xc2 \xa0 " , // &nbps;
// Although I could just use # instead of <li> above and nothing here that
// will break on input that contains linebreaks
'cite_references_prefix' => '<ol class="references">' ,
'cite_references_suffix' => '</ol>' ,
)
);
2005-12-21 01:08:25 +00:00
class Cite {
2005-12-23 02:34:39 +00:00
/** #@+
* @ access private
*/
/**
* Datastructure representing < ref > input , in the format of :
* < code >
* array (
* 'user supplied' => array (
* 'text' => 'user supplied reference & key' ,
* 'count' => 1 , // occurs twice
2005-12-29 21:56:00 +00:00
* 'number' => 1 , // The first reference, we want
* // all occourances of it to
* // use the same number
2005-12-23 02:34:39 +00:00
* ),
* 0 => 'Anonymous reference' ,
* 1 => 'Another anonymous reference' ,
* 'some key' => array (
* 'text' => 'this one occurs once'
2005-12-29 21:56:00 +00:00
* 'count' => 0 ,
* 'number' => 4
2005-12-23 02:34:39 +00:00
* ),
* 3 => 'more stuff'
* );
* </ code >
*
* 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
**/
2005-12-21 01:08:25 +00:00
var $mRefs = array ();
2005-12-23 02:34:39 +00:00
/**
* Count for user displayed output ( ref [ 1 ], ref [ 2 ], ... )
*
* @ var int
*/
var $mOutCnt = 0 ;
/**
* Internal counter for anonymous references , seperate from
* $mOutCnt because anonymous references won ' t increment it ,
* but will incremement $mOutCnt
*
* @ var int
*/
var $mInCnt = 0 ;
2005-12-29 21:56:00 +00:00
/**
* 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 ;
2005-12-23 02:34:39 +00:00
/**
* @ var object
*/
2006-02-21 19:56:09 +00:00
var $mParser ;
2006-01-27 10:14:45 +00:00
2006-04-16 06:22:42 +00:00
/**
* True when a < ref > or < references > tag is being processed .
* Used to avoid infinite recursion
*
* @ var boolean
*/
var $mInCite = false ;
2005-12-21 01:08:25 +00:00
/**#@-*/
2005-12-23 02:34:39 +00:00
/**
* Constructor
*/
2005-12-21 01:08:25 +00:00
function Cite () {
$this -> setHooks ();
}
/**#@+ @access private */
2005-12-23 02:34:39 +00:00
/**
* Callback function for < ref >
*
* @ param string $str Input
* @ param array $argv Arguments
* @ return string
*/
2006-02-21 19:56:09 +00:00
function ref ( $str , $argv , $parser ) {
2006-04-16 06:22:42 +00:00
if ( $this -> mInCite ) {
return htmlspecialchars ( " <ref> $str </ref> " );
} else {
$this -> mInCite = true ;
$ret = $this -> guardedRef ( $str , $argv , $parser );
$this -> mInCite = false ;
return $ret ;
}
}
function guardedRef ( $str , $argv , $parser ) {
2006-02-21 19:56:09 +00:00
$this -> mParser = $parser ;
2005-12-21 01:08:25 +00:00
$key = $this -> refArg ( $argv );
if ( $str !== null ) {
if ( $str === '' )
return $this -> error ( CITE_ERROR_REF_NO_INPUT );
if ( is_string ( $key ) )
2005-12-23 02:34:39 +00:00
// I don't want keys in the form of /^[0-9]+$/ because they would
// conflict with the php datastructure I'm using, besides, why specify
// a manual key if it's just going to be any old integer?
2006-01-27 10:14:45 +00:00
if ( sprintf ( '%d' , $key ) === ( string ) $key )
2005-12-21 01:08:25 +00:00
return $this -> error ( CITE_ERROR_REF_NUMERIC_KEY );
else
return $this -> stack ( $str , $key );
else if ( $key === null )
return $this -> stack ( $str );
else if ( $key === false )
return $this -> error ( CITE_ERROR_REF_TOO_MANY_KEYS );
else
$this -> croak ( CITE_ERROR_KEY_INVALID_1 , serialize ( $key ) );
} else if ( $str === null ) {
if ( is_string ( $key ) )
2006-01-27 10:14:45 +00:00
if ( sprintf ( '%d' , $key ) === ( string ) $key )
2005-12-21 01:08:25 +00:00
return $this -> error ( CITE_ERROR_REF_NUMERIC_KEY );
else
return $this -> stack ( $str , $key );
else if ( $key === false )
return $this -> error ( CITE_ERROR_REF_TOO_MANY_KEYS );
else if ( $key === null )
return $this -> error ( CITE_ERROR_REF_NO_KEY );
else
$this -> croak ( CITE_ERROR_KEY_INVALID_2 , serialize ( $key ) );
} else
$this -> croak ( CITE_ERROR_STR_INVALID , serialize ( $str ) );
}
/**
* Parse the arguments to the < ref > tag
*
2006-01-07 09:24:48 +00:00
* @ static
2005-12-21 01:08:25 +00:00
*
2006-01-07 09:24:48 +00:00
* @ param array $argv The argument vector
2005-12-21 01:08:25 +00:00
* @ return mixed false on invalid input , a string on valid
* input and null on no input
*/
function refArg ( $argv ) {
2005-12-24 18:03:21 +00:00
$cnt = count ( $argv );
if ( $cnt > 1 )
2005-12-21 01:08:25 +00:00
// There should only be one key
return false ;
2005-12-24 18:03:21 +00:00
else if ( $cnt == 1 )
if ( isset ( $argv [ 'name' ] ) )
// Key given.
2006-05-26 11:54:38 +00:00
return $this -> validateName ( array_shift ( $argv ) );
2005-12-24 18:03:21 +00:00
else
// Invalid key
return false ;
2005-12-21 01:08:25 +00:00
else
// No key
return null ;
}
2006-05-26 11:54:38 +00:00
/**
* Since the key name is used in an XHTML id attribute , it must
* conform to the validity rules . The restriction to begin with
* a letter is lifted since references have their own prefix .
*
* @ fixme merge this code with the various section name transformations
* @ fixme double - check for complete validity
* @ return string if valid , false if invalid
*/
function validateName ( $name ) {
if ( preg_match ( '/^[A-Za-z0-9:_.-]*$/i' , $name ) ) {
return $name ;
} else {
// WARNING: CRAPPY CUT AND PASTE MAKES BABY JESUS CRY
$text = urlencode ( str_replace ( ' ' , '_' , $name ) );
$replacearray = array (
'%3A' => ':' ,
'%' => '.'
);
return str_replace (
array_keys ( $replacearray ),
array_values ( $replacearray ),
$text );
}
}
2005-12-21 01:08:25 +00:00
/**
* Populate $this -> mRefs based on input and arguments to < ref >
*
* @ param string $str Input from the < ref > tag
* @ param mixed $key Argument to the < ref > tag as returned by $this -> refArg ()
* @ return string
*/
function stack ( $str , $key = null ) {
if ( $key === null ) {
// No key
$this -> mRefs [] = $str ;
2005-12-23 02:34:39 +00:00
return $this -> linkRef ( $this -> mInCnt ++ );
2005-12-21 01:08:25 +00:00
} else if ( is_string ( $key ) )
// Valid key
if ( ! @ is_array ( $this -> mRefs [ $key ] ) ) {
// First occourance
$this -> mRefs [ $key ] = array (
'text' => $str ,
2005-12-29 21:56:00 +00:00
'count' => 0 ,
'number' => ++ $this -> mOutCnt
2005-12-21 01:08:25 +00:00
);
2005-12-29 21:56:00 +00:00
return
$this -> linkRef (
$key ,
$this -> mRefs [ $key ][ 'count' ],
$this -> mRefs [ $key ][ 'number' ]
);
2005-12-21 01:08:25 +00:00
} else
// We've been here before
2005-12-29 21:56:00 +00:00
return
$this -> linkRef (
$key ,
++ $this -> mRefs [ $key ][ 'count' ],
$this -> mRefs [ $key ][ 'number' ]
);
2005-12-21 01:08:25 +00:00
else
$this -> croak ( CITE_ERROR_STACK_INVALID_INPUT , serialize ( array ( $key , $str ) ) );
}
/**
2005-12-23 02:34:39 +00:00
* Callback function for < references >
*
* @ param string $str Input
* @ param array $argv Arguments
2005-12-21 01:08:25 +00:00
* @ return string
*/
2006-02-21 19:56:09 +00:00
function references ( $str , $argv , $parser ) {
2006-04-16 06:22:42 +00:00
if ( $this -> mInCite ) {
if ( is_null ( $str ) ) {
return htmlspecialchars ( " <references/> " );
} else {
return htmlspecialchars ( " <references> $str </references> " );
}
} else {
$this -> mInCite = true ;
$ret = $this -> guardedReferences ( $str , $argv , $parser );
$this -> mInCite = false ;
return $ret ;
}
}
function guardedReferences ( $str , $argv , $parser ) {
2006-02-21 19:56:09 +00:00
$this -> mParser = $parser ;
2005-12-21 01:08:25 +00:00
if ( $str !== null )
return $this -> error ( CITE_ERROR_REFERENCES_INVALID_INPUT );
else if ( count ( $argv ) )
return $this -> error ( CITE_ERROR_REFERENCES_INVALID_PARAMETERS );
else
return $this -> referencesFormat ();
}
2005-12-23 02:34:39 +00:00
/**
* Make output to be returned from the references () function
*
* @ return string XHTML ready for output
*/
2005-12-21 01:08:25 +00:00
function referencesFormat () {
$ent = array ();
foreach ( $this -> mRefs as $k => $v )
$ent [] = $this -> referencesFormatEntry ( $k , $v );
$prefix = wfMsgForContentNoTrans ( 'cite_references_prefix' );
$suffix = wfMsgForContentNoTrans ( 'cite_references_suffix' );
$content = implode ( " \n " , $ent );
2006-04-02 03:43:47 +00:00
// Live hack: parse() adds two newlines on WM, can't reproduce it locally -ævar
return rtrim ( $this -> parse ( $prefix . $content . $suffix ), " \n " );
2005-12-21 01:08:25 +00:00
}
2005-12-23 02:34:39 +00:00
/**
* 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
*/
2005-12-21 01:08:25 +00:00
function referencesFormatEntry ( $key , $val ) {
2006-02-23 21:24:57 +00:00
// Anonymous reference
2005-12-21 01:08:25 +00:00
if ( ! is_array ( $val ) )
return
wfMsgForContentNoTrans (
'cite_references_link_one' ,
2005-12-23 02:34:39 +00:00
$this -> referencesKey ( $key ),
$this -> refKey ( $key ),
2005-12-21 01:08:25 +00:00
$val
);
2006-02-23 21:24:57 +00:00
// 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 ),
$this -> refKey ( $key , $val [ 'count' ] ),
$val [ 'text' ]
);
// Named references with >1 occurrences
2005-12-21 01:08:25 +00:00
else {
$links = array ();
for ( $i = 0 ; $i <= $val [ 'count' ]; ++ $i ) {
$links [] = wfMsgForContentNoTrans (
'cite_references_link_many_format' ,
2005-12-23 02:34:39 +00:00
$this -> refKey ( $key , $i ),
2006-05-02 17:02:23 +00:00
$this -> referencesFormatEntryNumericBacklinkLabel ( $val [ 'number' ], $i , $val [ 'count' ] ),
2005-12-29 21:56:00 +00:00
$this -> referencesFormatEntryAlternateBacklinkLabel ( $i )
2005-12-21 01:08:25 +00:00
);
}
$list = $this -> listToText ( $links );
return
wfMsgForContentNoTrans ( 'cite_references_link_many' ,
2005-12-23 02:34:39 +00:00
$this -> referencesKey ( $key ),
2005-12-21 01:08:25 +00:00
$list ,
$val [ 'text' ]
);
}
}
2005-12-29 21:56:00 +00:00
/**
* Generate a numeric backlink given a base number and an
* offset , e . g . $base = 1 , $offset = 2 ; = 1.2
2006-05-02 17:02:23 +00:00
* Since bug #5525, it correctly does 1.9 -> 1.10 as well as 1.099 -> 1.100
2005-12-29 21:56:00 +00:00
*
2006-01-07 09:24:48 +00:00
* @ static
*
2005-12-29 21:56:00 +00:00
* @ param int $base The base
* @ param int $offset The offset
2006-05-02 17:02:23 +00:00
* @ param int $max Maximum value expected .
2005-12-29 21:56:00 +00:00
* @ return string
*/
2006-05-02 17:02:23 +00:00
function referencesFormatEntryNumericBacklinkLabel ( $base , $offset , $max ) {
2005-12-29 21:56:00 +00:00
global $wgContLang ;
2006-05-02 17:02:23 +00:00
$scope = strlen ( $max );
$ret = $wgContLang -> formatNum (
sprintf ( " %s.%0 { $scope } s " , $base , $offset )
);
return $ret ;
2005-12-29 21:56:00 +00:00
}
/**
* 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 ) {
2006-07-02 14:19:45 +00:00
if ( ! isset ( $this -> mBacklinkLabels ) ) {
$this -> genBacklinkLabels ();
}
if ( isset ( $this -> mBacklinkLabels [ $offset ] ) ) {
2005-12-29 21:56:00 +00:00
return $this -> mBacklinkLabels [ $offset ];
2006-07-02 14:19:45 +00:00
} else {
2005-12-29 21:56:00 +00:00
// Feed me!
return $this -> error ( CITE_ERROR_REFERENCES_NO_BACKLINK_LABEL );
2006-07-02 14:19:45 +00:00
}
2005-12-29 21:56:00 +00:00
}
2005-12-23 02:34:39 +00:00
/**
* Return an id for use in wikitext output based on a key and
* optionally the # of it, used in <references>, not <ref>
* ( since otherwise it would link to itself )
*
2006-01-07 09:24:48 +00:00
* @ static
*
2005-12-23 02:34:39 +00:00
* @ param string $key The key
* @ param int $num The number of the key
* @ return string A key for use in wikitext
*/
function refKey ( $key , $num = null ) {
$prefix = wfMsgForContent ( 'cite_reference_link_prefix' );
$suffix = wfMsgForContent ( 'cite_reference_link_suffix' );
if ( isset ( $num ) )
$key = wfMsgForContentNoTrans ( 'cite_reference_link_key_with_num' , $key , $num );
return $prefix . $key . $suffix ;
}
2005-12-21 01:08:25 +00:00
2005-12-23 02:34:39 +00:00
/**
* Return an id for use in wikitext output based on a key and
2005-12-23 05:28:39 +00:00
* optionally the # of it, used in <ref>, not <references>
2005-12-23 02:34:39 +00:00
* ( since otherwise it would link to itself )
*
2006-01-07 09:24:48 +00:00
* @ static
*
2005-12-23 02:34:39 +00:00
* @ param string $key The key
* @ param int $num The number of the key
* @ return string A key for use in wikitext
*/
function referencesKey ( $key , $num = null ) {
$prefix = wfMsgForContent ( 'cite_references_link_prefix' );
$suffix = wfMsgForContent ( 'cite_references_link_suffix' );
if ( isset ( $num ) )
$key = wfMsgForContentNoTrans ( 'cite_reference_link_key_with_num' , $key , $num );
2005-12-21 01:08:25 +00:00
return $prefix . $key . $suffix ;
}
2005-12-23 02:34:39 +00:00
/**
* Generate a link ( < sup ... ) for the < ref > element from a key
* and return XHTML ready for output
*
* @ param string $key The key for the link
2005-12-29 21:56:00 +00:00
* @ param int $count The # of the key, used for distinguishing
* multiple occourances of the same key
* @ param int $label The label to use for the link , I want to
* use the same label for all occourances of
* the same named reference .
2005-12-23 02:34:39 +00:00
* @ return string
*/
2005-12-29 21:56:00 +00:00
function linkRef ( $key , $count = null , $label = null ) {
2005-12-21 01:08:25 +00:00
global $wgContLang ;
2005-12-29 21:56:00 +00:00
2005-12-21 01:08:25 +00:00
return
$this -> parse (
wfMsgForContentNoTrans (
'cite_reference_link' ,
2005-12-29 21:56:00 +00:00
$this -> refKey ( $key , $count ),
2005-12-23 02:34:39 +00:00
$this -> referencesKey ( $key ),
2005-12-29 21:56:00 +00:00
$wgContLang -> formatNum ( is_null ( $label ) ? ++ $this -> mOutCnt : $label )
2005-12-21 01:08:25 +00:00
)
);
}
/**
* This does approximately the same thing as
* Langauge :: listToText () but due to this being used for a
* slightly different purpose ( people might not want , as the
* first seperator and not 'and' as the second , and this has to
* use messages from the content language ) I ' m rolling my own .
*
2006-01-07 09:24:48 +00:00
* @ static
*
2005-12-23 02:34:39 +00:00
* @ param array $arr The array to format
2005-12-21 01:08:25 +00:00
* @ return string
*/
function listToText ( $arr ) {
$cnt = count ( $arr );
$sep = wfMsgForContentNoTrans ( 'cite_references_link_many_sep' );
$and = wfMsgForContentNoTrans ( 'cite_references_link_many_and' );
if ( $cnt == 1 )
2005-12-23 02:34:39 +00:00
// Enforce always returning a string
2005-12-21 01:08:25 +00:00
return ( string ) $arr [ 0 ];
else {
$t = array_slice ( $arr , 0 , $cnt - 1 );
2005-12-23 00:43:23 +00:00
return implode ( $sep , $t ) . $and . $arr [ $cnt - 1 ];
2005-12-21 01:08:25 +00:00
}
}
2005-12-23 02:34:39 +00:00
/**
* Parse a given fragment and fix up Tidy ' s trail of blood on
* it ...
*
* @ param string $in The text to parse
* @ return string The parsed text
*/
2005-12-21 01:08:25 +00:00
function parse ( $in ) {
2005-12-25 00:27:19 +00:00
$ret = $this -> mParser -> parse (
$in ,
2006-02-28 05:05:07 +00:00
$this -> mParser -> mTitle ,
2006-02-21 19:56:09 +00:00
$this -> mParser -> mOptions ,
2005-12-25 00:27:19 +00:00
// Avoid whitespace buildup
false ,
// Important, otherwise $this->clearState()
// would get run every time <ref> or
// <references> is called, fucking the whole
// thing up.
false
);
2005-12-23 00:43:23 +00:00
$text = $ret -> getText ();
return $this -> fixTidy ( $text );
}
2005-12-23 02:34:39 +00:00
/**
* Tidy treats all input as a block , it will e . g . wrap most
* input in < p > if it isn ' t already , fix that and return the fixed text
*
2006-01-07 09:24:48 +00:00
* @ static
*
2005-12-23 02:34:39 +00:00
* @ param string $text The text to fix
* @ return string The fixed text
*/
2005-12-23 00:43:23 +00:00
function fixTidy ( $text ) {
global $wgUseTidy ;
if ( ! $wgUseTidy )
return $text ;
else {
2006-01-07 09:24:48 +00:00
$text = preg_replace ( '~^<p>\s*~' , '' , $text );
$text = preg_replace ( '~\s*</p>\s*~' , '' , $text );
$text = preg_replace ( '~\n$~' , '' , $text );
2005-12-23 00:43:23 +00:00
return $text ;
}
}
2005-12-29 21:56:00 +00:00
/**
* Generate the labels to pass to the
* 'cite_references_link_many_format' message , the format is an
* arbitary number of tokens seperated by [ \t\n ]
*/
function genBacklinkLabels () {
2006-07-02 14:19:45 +00:00
wfProfileIn ( __METHOD__ );
2005-12-29 21:56:00 +00:00
$text = wfMsgForContentNoTrans ( 'cite_references_link_many_format_backlink_labels' );
$this -> mBacklinkLabels = preg_split ( '#[\n\t ]#' , $text );
2006-07-02 14:19:45 +00:00
wfProfileOut ( __METHOD__ );
2005-12-29 21:56:00 +00:00
}
2005-12-23 06:06:57 +00:00
/**
* Gets run when Parser :: clearState () gets run , since we don ' t
* want the counts to transcend pages and other instances
*/
function clearState () {
$this -> mOutCnt = $this -> mInCnt = 0 ;
$this -> mRefs = array ();
return true ;
}
2005-12-21 01:08:25 +00:00
/**
* Initialize the parser hooks
*/
function setHooks () {
2005-12-23 06:06:57 +00:00
global $wgParser , $wgHooks ;
2005-12-21 01:08:25 +00:00
$wgParser -> setHook ( 'ref' , array ( & $this , 'ref' ) );
$wgParser -> setHook ( 'references' , array ( & $this , 'references' ) );
2005-12-23 06:06:57 +00:00
$wgHooks [ 'ParserClearState' ][] = array ( & $this , 'clearState' );
2005-12-21 01:08:25 +00:00
}
/**
2005-12-23 02:34:39 +00:00
* Return an error message based on an error ID
*
2005-12-21 01:08:25 +00:00
* @ param int $id ID for the error
2005-12-23 02:34:39 +00:00
* @ return string XHTML ready for output
2005-12-21 01:08:25 +00:00
*/
function error ( $id ) {
if ( $id > 0 )
// User errors are positive
2005-12-23 05:06:17 +00:00
return
$this -> parse (
'<strong class="error">' .
wfMsgforContent ( 'cite_error' , $id , wfMsgForContent ( " cite_error_ $id " ) ) .
'</strong>'
);
2005-12-21 01:08:25 +00:00
else if ( $id < 0 )
return wfMsgforContent ( 'cite_error' , $id );
}
/**
* Die with a backtrace if something happens in the code which
* shouldn ' t have
*
* @ param int $error ID for the error
* @ param string $data Serialized error data
*/
function croak ( $error , $data ) {
wfDebugDieBacktrace ( wfMsgForContent ( 'cite_croak' , $this -> error ( $error ), $data ) );
}
/**#@-*/
}
2006-01-07 09:24:48 +00:00
new Cite ;
2005-12-21 01:08:25 +00:00
}
/**#@-*/
2006-04-23 18:37:49 +00:00
?>