Index: Cite.i18n.php =================================================================== --- Cite.i18n.php (revision 15973) +++ Cite.i18n.php (working copy) @@ -31,7 +31,7 @@ '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", - + 'cite_error_' . CITE_ERROR_REFDEFINE_NOT_USED => "Unexpected input; refdefine ''$1'' not used", 'cite_error_' . CITE_ERROR_REF_REDEFINITION => "Invalid input; attempt to redefine ''$1''", /* Output formatting */ @@ -44,6 +44,7 @@ 'cite_references_link_suffix' => '', 'cite_reference_link' => '[[#$2|[$3]]]', + 'cite_reference_link_with_text' => '[[#$2|[$3 - $4]]]', 'cite_references_link_one' => '
  • [[#$2|↑]] $3
  • ', 'cite_references_link_many' => '
  • ↑ $2 $3
  • ', 'cite_references_link_many_format' => '[[#$1|$2]]', Index: Cite.php =================================================================== --- Cite.php (revision 15973) +++ Cite.php (working copy) @@ -2,7 +2,7 @@ if ( ! defined( 'MEDIAWIKI' ) ) die(); /**#@+ - * A parser extension that adds two tags, and for adding + * A parser extension that adds three tags, , , and for adding * citations to pages * * @package MediaWiki @@ -44,7 +44,9 @@ 'CITE_ERROR_REF_NO_INPUT', 'CITE_ERROR_REFERENCES_INVALID_INPUT', 'CITE_ERROR_REFERENCES_INVALID_PARAMETERS', - 'CITE_ERROR_REFERENCES_NO_BACKLINK_LABEL' + 'CITE_ERROR_REFERENCES_NO_BACKLINK_LABEL', + 'CITE_ERROR_REFDEFINE_NOT_USED', + 'CITE_ERROR_REF_REDEFINITION', ) ); @@ -77,7 +79,8 @@ * 'user supplied' => array( * 'text' => 'user supplied reference & key', * 'count' => 1, // occurs twice - * 'number' => 1, // The first reference, we want + * 'label' => 'user supplied label', //optional label + * 'number' => 1, // The first reference, we want * // all occourances of it to * // use the same number * ), @@ -86,7 +89,8 @@ * 'some key' => array( * 'text' => 'this one occurs once' * 'count' => 0, - * 'number' => 4 + * 'label' => 'some other label' + * 'number' => 4 * ), * 3 => 'more stuff' * ); @@ -170,10 +174,30 @@ } } - function guardedRef( $str, $argv, $parser ) { + /** + * Callback function for + * + * @param string $str Input + * @param array $argv Arguments + * @return string + */ + function refdefine( $str, $argv, $parser ) { + if ( $this->mInCite ) { + return htmlspecialchars( "$str" ); + } else { + $this->mInCite = true; + $ret = $this->guardedRef( $str, $argv, $parser, false ); + $this->mInCite = false; + return $ret; + } + } + + function guardedRef( $str, $argv, $parser, $display = true ) { $this->mParser = $parser; - $key = $this->refArg( $argv ); - + $args = $this->refArg( $argv ); + $key = $args['key']; + $label = $args['label']; + if ( $str !== null ) { if ( $str === '' ) return $this->error( CITE_ERROR_REF_NO_INPUT ); @@ -184,19 +208,24 @@ if ( sprintf( '%d', $key ) === (string)$key ) return $this->error( CITE_ERROR_REF_NUMERIC_KEY ); else - return $this->stack( $str, $key ); + return $this->stack( $str, $key, $label, $display ); else if ( $key === null ) - return $this->stack( $str ); + if( !$display ) + return $this->error( CITE_ERROR_REF_NO_KEY ); + else + return $this->stack( $str, $key, $label, $display ); 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 ( !$display ) + return $this->error( CITE_ERROR_REF_NO_INPUT ); if ( is_string( $key ) ) if ( sprintf( '%d', $key ) === (string)$key ) return $this->error( CITE_ERROR_REF_NUMERIC_KEY ); else - return $this->stack( $str, $key ); + return $this->stack( $str, $key, $label, $display ); else if ( $key === false ) return $this->error( CITE_ERROR_REF_TOO_MANY_KEYS ); else if ( $key === null ) @@ -219,21 +248,17 @@ */ function refArg( $argv ) { - $cnt = count( $argv ); - - if ( $cnt > 1 ) - // There should only be one key - return false; - else if ( $cnt == 1 ) - if ( isset( $argv['name'] ) ) - // Key given. - return $this->validateName( array_shift( $argv ) ); - else - // Invalid key - return false; - else - // No key - return null; + $args = array( 'key' => null, 'display' => null ); + + if ( isset( $argv['name'] ) ) + // Key given. + $args['key'] = $this->validateName( $argv['name'] ); + + if ( isset( $argv['text'] ) ) + // Display string given. + $args['label'] = htmlspecialchars( $argv['text'] ); + + return $args; } /** @@ -265,38 +290,88 @@ /** * Populate $this->mRefs based on input and arguments to * - * @param string $str Input from the tag - * @param mixed $key Argument to the tag as returned by $this->refArg() + * @param string $str Input from the tag + * @param mixed $key Argument to the tag as returned by $this->refArg() + * @param mixed $label Argument to the tag as returned by $this->refArg() + * @param bool $display Whether to output a linkref or merely stack and exit. * @return string */ - function stack( $str, $key = null ) { + function stack( $str, $key = null, $label = null, $display = true ) { if ( $key === null ) { // No key $this->mRefs[] = $str; - return $this->linkRef( $this->mInCnt++ ); + + if( is_null( $label ) ) + return $this->linkRef( $this->mInCnt++ ); + + return $this->linkRef( $this->mInCnt++, null, ++$this->mOutCnt, $label ); } else if ( is_string( $key ) ) // Valid key if ( ! @is_array( $this->mRefs[$key] ) ) { // First occourance + + if( !$display ) { + $this->mRefs[$key] = array( + 'text' => $str, + 'count' => -1, //don't count toward number displayed + 'label' => $label, + 'number' => -999 //indicator for refdefine + ); + + //Use blank comment to avoid annoying parser newline behavior + return ''; + } + $this->mRefs[$key] = array( 'text' => $str, 'count' => 0, + 'label' => $label, 'number' => ++$this->mOutCnt ); + return $this->linkRef( $key, $this->mRefs[$key]['count'], - $this->mRefs[$key]['number'] + $this->mRefs[$key]['number'], + $this->mRefs[$key]['label'] ); - } else + } else { // We've been here before + + //Check for previously defined label + if( is_null( $label ) ) + $label = $this->mRefs[$key]['label']; + + if( ( $this->mRefs[$key]['text'] != '' ) && ( $str != '' ) ) + return $this->error( CITE_ERROR_REF_REDEFINITION, $key ); + + //If ref text was not defined earlier, try to define it now + if( $this->mRefs[$key]['text'] == '' ) + $this->mRefs[$key]['text'] = $str; + + if( !$display ) + //Use blank comment to avoid annoying parser newline behavior + return ''; + + //-999 indicates a refdefine, which means we need a new number. + if( $this->mRefs[$key]['number'] == -999 ) { + $this->mRefs[$key]['number'] = ++$this->mOutCnt; + + //Since we rely on the array order, we need to reset the refdefine order + $temp = $this->mRefs[$key]; + unset($this->mRefs[$key]); + $this->mRefs[$key] = $temp; + } + return $this->linkRef( $key, ++$this->mRefs[$key]['count'], - $this->mRefs[$key]['number'] + $this->mRefs[$key]['number'], + $label ); + } else $this->croak( CITE_ERROR_STACK_INVALID_INPUT, serialize( array( $key, $str ) ) ); } @@ -342,7 +417,11 @@ $ent = array(); foreach ( $this->mRefs as $k => $v ) - $ent[] = $this->referencesFormatEntry( $k, $v ); + //Check for refdefines that aren't actually referenced + if( $v['number'] != -999 ) + $ent[] = $this->referencesFormatEntry( $k, $v ); + else + $ent[] = $this->error( CITE_ERROR_REFDEFINE_NOT_USED, $k ); $prefix = wfMsgForContentNoTrans( 'cite_references_prefix' ); $suffix = wfMsgForContentNoTrans( 'cite_references_suffix' ); @@ -374,7 +453,7 @@ // 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 ) + else if ( $val['count'] <= 0 ) return wfMsgForContentNoTrans( 'cite_references_link_one', @@ -493,26 +572,47 @@ * Generate a link ( element from a key * and return XHTML ready for output * - * @param string $key The key for the link - * @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. + * @param string $key The key for the link + * @param int $count The # of the key, used for distinguishing + * multiple occourances of the same key + * @param int $number The number to use for the link, I want to + * use the same number for all occourances of + * the same named reference. + * @param string $label Optional text label to pass with link * @return string */ - function linkRef( $key, $count = null, $label = null ) { + function linkRef( $key, $count = null, $number = null, $label = null ) { global $wgContLang; - return - $this->parse( - wfMsgForContentNoTrans( - 'cite_reference_link', - $this->refKey( $key, $count ), - $this->referencesKey( $key ), - $wgContLang->formatNum( is_null( $label ) ? ++$this->mOutCnt : $label ) - ) - ); + //False cancels output of reference link. + if( $label === false ) + //Use blank comment to avoid annoying parser newline behavior + return ''; + + if( is_null( $number ) ) + $number = ++$this->mOutCnt; + + if( is_null( $label ) || $label === '' ) + return + $this->parse( + wfMsgForContentNoTrans( + 'cite_reference_link', + $this->refKey( $key, $count ), + $this->referencesKey( $key ), + $wgContLang->formatNum( $number ) + ) + ); + else + return + $this->parse( + wfMsgForContentNoTrans( + 'cite_reference_link_with_text', + $this->refKey( $key, $count ), + $this->referencesKey( $key ), + $wgContLang->formatNum( $number ), + $label + ) + ); } /** @@ -619,6 +719,7 @@ function setHooks() { global $wgParser, $wgHooks; + $wgParser->setHook( 'refdefine' , array( &$this, 'refdefine' ) ); $wgParser->setHook( 'ref' , array( &$this, 'ref' ) ); $wgParser->setHook( 'references' , array( &$this, 'references' ) ); @@ -631,13 +732,13 @@ * @param int $id ID for the error * @return string XHTML ready for output */ - function error( $id ) { + function error( $id, $name = '' ) { if ( $id > 0 ) // User errors are positive return $this->parse( '' . - wfMsgforContent( 'cite_error', $id, wfMsgForContent( "cite_error_$id" ) ) . + wfMsgforContent( 'cite_error', $id, wfMsgForContent( "cite_error_$id" , $name ) ) . '' ); else if ( $id < 0 )