Extension:HarvardReferences

From MediaWiki.org
Jump to: navigation, search
MediaWiki extensions manual - list
Crystal Clear action run.png
HarvardReferences

Release status: beta

Harvard References Example Animation (frame 2 of 6).jpg
Implementation Tag
Description Allows to use the author-date ("Harvard system") referencing style, e.g. Smith 2008:1
Author(s) X-romix
Latest version 1.6
MediaWiki 1.15+
Database changes No
License Creative Commons Attribution/Share-Alike License 3.0 and GFDL
Download http://x-romix.narod.ru/HarvardReferences_1_6.zip
Example http://wikiext.org/index.php/Harvard_references_sample
Parameters
  • $wgHarvardReferencesOn
Hooks used
ParserFirstCallInit

ParserBeforeStrip
ParserBeforeTidy

Translate the HarvardReferences extension if possible

Check usage and version matrix; code metrics

The HarvardReferences extension allows to use the author-date ("Harvard system") referencing style, e.g. Smith 2008:1

Referencing systems[edit | edit source]

There is common scientific standard (Harvard referencing system).

The two most common types of referencing systems used are:

  • author-date systems — such as the Harvard system, APA and MLA
  • numerical systems — such as Chicago or Turabian, Vancouver and Footnote [1]

This MediaWiki extension implements an author-date (Harvard) system.

Working example[edit | edit source]

You can test this extension here: http://wikiext.org/index.php/Harvard_references_sample Use backspace key to return from references to the main text.

Sandbox to test extension[edit | edit source]

Please use sandbox to test extension: http://wikiext.org/index.php/Sandbox:Test_page

Description[edit | edit source]

This extension supports Author-date ("Harvard system") referencing style, e.g. Smith 2008:1, as commonly used standard in scientific literature.

  • Link - in square brackets:
    [Smith 2008]
    
  • Anchor to link -
    [*Smith 2008]
    

Compatibility with Cite.php[edit | edit source]

This extension is compatible with Extension:Cite/Cite.php - links in both systems can be used in same article. Moreover, links in "Harvard" system can be inserted into description of ref-link, and vice versa. For example,

<ref>This is a test subnote. [Smith 2010:21]</ref>

Example[edit | edit source]

==Example of Harvard References==
According to scientists, the Sun is pretty big.[Miller 2005]
The Moon, however, is not so big.[Smith 1978:121] 

===Notes===
* [*Miller 2005] E. Miller, The Sun, (New York: Academic Press, 2005), 23-5.
* [*Smith 1978] R. Smith, "Size of the Moon", Scientific American, 46 (April 1978): 44-6.
<HarvardReferences />

Page numbers in references[edit | edit source]

Optional page numbers can be used after ":" symbol in link. Several links with one name and different page numbers can refer to one anchor. For example,

[Smith 2008:121]
[Smith 2008:51]

refers to one anchor with same name:

[*Smith 2008]

You may use "|" instead of ":" as a separator.

Setup[edit | edit source]

Extension was tested on 1.15.3 version of MediaWiki.

To install this extension, make HarvardReferences.php (source code is below) in folder extensions/HarvardReferences.

Then write

require_once("$IP/extensions/HarvardReferences/HarvardReferences.php");

in bottom of file LocalSettings.php.

If you want extended highlighting, you can use additional JS and CSS written for this extension, see Extension:HarvardReferences/Scripts. This will provide your wiki with highlighting of the references and backlinks. These scripts also allow user to change their appearance.

Switching on[edit | edit source]

To enable this advanced syntax globally, put

 $wgHarvardReferencesOn = true;

right after the "require_once" line.

Or, if it wasn't done, you may use tag <HarvardReferences/> (anywhere in the article text) to enable this extension on a per-page basis.

Gallery[edit | edit source]

Source code[edit | edit source]

Make file HarvardReferences.php in ANSI encoding (do not add any spaces before starting "<?php" and after end "?>"). Installing of this code into MediaWiki site see above.

<?php
// This extension provides references in Harvard (Author-date) style to MediaWiki.
// Instructions and samples see at http://www.mediawiki.org/wiki/Extension:HarvardReferences
 
if ( ! defined( 'MEDIAWIKI' ) )	die();
 
// function wfHarvardReferences - see below 
if ( defined( 'MW_SUPPORTS_PARSERFIRSTCALLINIT' ) ) {
	$wgHooks['ParserFirstCallInit'][] = 'wfHarvardReferences';
} else {
	$wgExtensionFunctions[] = 'wfHarvardReferences';
}
 
// Extension credits that will show up on the page [[Special:Version]]    
$wgExtensionCredits['parserhook'][] = array(
	'path'         => __FILE__,
	'name'         => 'HarvardReferences',
	'version'      => '1.6',
	'author'       => 'X-romix',
	'url'          => 'https://www.mediawiki.org/wiki/Extension:HarvardReferences',
	'description'  => 'Allows to use the author-date ("Harvard system") referencing style'
);
 
$wgHarvardReferencesOn = false;
 
// Main class 
class HarvardReferences {
	var $refs = array();
	var $refs_count = array();
	var $cntParserBeforeStrip = 0;
 
	function HarvardReferences() { // Constructor
		$this->setHooks();
	}
 
	function setHooks() {
		global $wgParser, $wgHooks;
 
		// Hook to ParserBeforeStrip event - "Used to process the raw wiki code before any internal processing is applied"
		// See http://www.mediawiki.org/wiki/Manual:Hooks/ParserBeforeStrip
		// http://www.mediawiki.org/wiki/Manual:Hooks
		$wgHooks['ParserBeforeStrip'][] = array( &$this, 'hookParserBeforeStrip' );
		// function hookParserBeforeStrip() - is below
 
		// Hook to ParserBeforeTidy event - "Used to process the nearly-rendered html code for the page (but before any html tidying occurs)"
		// See http://www.mediawiki.org/wiki/Manual:Hooks/ParserBeforeTidy
		// http://www.mediawiki.org/wiki/Manual:Hooks
		$wgHooks['ParserBeforeTidy'][] = array( &$this, 'hookParserBeforeTidy' );
		// function hookParserBeforeTidy() - is below
 
		// Hook for new tag <HarvardReferences> 
		// see http://www.mediawiki.org/wiki/Manual:Tag_extensions for details
		$wgParser->setHook( 'HarvardReferences' , array( &$this, 'hookHarvardReferences' ) );
		// function hookHarvardReferences) - is below
 
	}
 
	// Hook for tag <HarvardReferences>  - setup see above
	function hookHarvardReferences( $str, $argv, $parser ) {
                global $wgHarvardReferencesOn;
 
		$wgHarvardReferencesOn = true;
		$str = $parser->recursiveTagParse( $str );
		// Comments, nowiki-blocks and wiki-links are already processed and is not visible here
		return $str;
	}
 
	// Hook for mediawiki event - setup see above
	// We need to prevent processing of <nowiki>[xxx]</nowiki> sequences, so we replace it to <nowiki>&#91;xxx&#93;</nowiki>
	function hookParserBeforeStrip( &$parser, &$text, &$strip_state ) {
		$this->cntParserBeforeStrip++;
		if ( $this->cntParserBeforeStrip > 1 ) return true; // as recommended in the documentation
		// Not do anything if there is not explicit switch-on tag
		$p = strpos( $text, "<HarvardReferences" );
		if ( $p === false ) return true;
 
		$p = strpos( $text, "<nowiki>" );
		if ( $p === false ) return true;
 
		$text = preg_replace_callback( "/
			(<nowiki>) 	#open tag
			(.*?)		#lazy search
			(<\/nowiki>)	#close tag.
			/x",
			array( __CLASS__, 'hookParserBeforeStripCallback' ),
			$text );
 
		$text = preg_replace_callback( "/
			(<\!\-\-) 	#open comment
			(.*?)		#lazy search
			(\-\-\>)	#close comment.
			/x",
			array( __CLASS__, 'hookParserBeforeStripCallback_1' ),
			$text );
 
		return true;
	}
 
 	// Callback function for preg_replace_callback - see it above
	// Replacing [ ] chars to &#91; &#93; HTML-equivalents in the nowiki block
	function hookParserBeforeStripCallback( $matches ) {
		$s = $matches[2];
		$s = str_replace ( "[", "&#91;", $s );
		$s = str_replace ( "]", "&#93;", $s );
		return "<nowiki>" . $s . "</nowiki>";
 
	}
 
	function hookParserBeforeStripCallback_1( $matches ) {
		$s = $matches[2];
		$s = str_replace ( "[", "&#91;", $s );
		$s = str_replace ( "]", "&#93;", $s );
		return "<!--" . $s . "-->";
 
	}
 
	// Hook for mediawiki event - setup see above
	function hookParserBeforeTidy( &$parser, &$text ) {
                global $wgHarvardReferencesOn;
 
		if($wgHarvardReferencesOn == false) return true;
		preg_match_all( "/
			(\[\*)    # [* characters
			([^\]]+)  # any text, e.g. Smith 2010
			(\])      # ] character
			/x", $text, $matches, PREG_SET_ORDER );
 
		foreach ( $matches as $match ) {
			$s = $match[2];
			$this->refs[] = $s; // fill global array refs[]  with names of labels ( e.g. "Smith 2010") 
		}
 
		// process links
		$text = preg_replace_callback( "/
			(\[)				# [ character
			([^\]\:\*\|]+)			# any text, e.g. Smith 2010 without ] * : | characters
			(\] | \:[^\]]+\] | \|[^\]]+\])	# ] character or  :page number or |page number etc. and ] character.
			/x",
			array( __CLASS__, 'refCallback' ),
			$text );
 
		// process anchors	
		$text = preg_replace_callback( "/
			(\[\*)      	# [* characters
			([^\]]+)	# any text, e.g. Smith 2010 without ] characters
			(\])        	# ] character 
			/x",
			array( __CLASS__, 'anchorsCallback' ),
			$text );
 
		return true;
	}
 
	// deletes some chars from link and replaces it for _
 
	// Callback function for preg_replace_callback - see it above
	// Processing references
	function refCallback( $matches ) {
		$s = $matches[2];
 
		if ( !in_array( $s, $this->refs ) ) {
			return $matches[0]; // not do any changes
		}
 
		$pages = $matches[3];
		$pages = str_replace( ']', '', $pages );
		$pages = str_replace( '|', '', $pages );
		$pages = str_replace( ':', '', $pages );
		$pages = trim( $pages );
		if ( $pages ) {
			$pages = ':' . $pages;
		}
 
		if ( !isset( $this->refs_count[$s] ) ) {
			$this->refs_count[$s] = 1;
		} else {
			$this->refs_count[$s]++;
		}
 
		$cnt = $this->refs_count[$s];
		// convert non-latin chars in link into dot-form
		$name = Sanitizer::escapeId( $s );
 
		$r = '<sup id="harv_ref-' . $name . '-' . $cnt . '" class="reference">' .
		"<a href='#harv_note-" . $name . "'>" .
		"[" . $s . "]" . "</a>" . $pages . "</sup>";
 
		return $r;
	}
 
	// Callback function for preg_replace_callback - see it above
	// Processing anchors
	function anchorsCallback( $matches ) {
		$s = $matches[2];
 		if ( !in_array( $s, $this->refs ) ) {
			return $matches[0]; // not do any changes
		}
 
		if ( !isset( $this->refs_count[$s] ) ) {
			$cnt = 0;
		} else {
			$cnt = $this->refs_count[$s];
		}
 
		// convert non-latin chars in link into dot-form
		$name = Sanitizer::escapeId( $s );
 
		if ( $cnt == 0 ) { // no links to this anchor
			$r = "<sup>[$s]</sup>";
		} else if ( $cnt == 1 ) { // 1 link to anchor
			$r = '<sup id="harv_note-' . $name . '" class="reference">' .
			'<a href="#harv_ref-' . $name . '-1">[' . $s . ']</a> ^</sup>';
		} else if ( $cnt >= 2 ) { // more than 1 link to anchor
			$r = '<sup id="harv_note-' . $name . '" class="reference">' .
			'<a href="#harv_ref-' . $name . '-1">[' . $s . ']</a> ^ </sup> ';
 
			for ( $i = 1; $i <= $cnt; $i++ ) {
				$r .= ' <sup id="harv_note-' . $name . '-' . $i . '" class="reference">' .
				'<a href="#harv_ref-' . $name . '-' . $i . '" class="reference">' . $i . '</a></sup> ';
			}
		}
		return $r;
	}
}
// Creates main object
function wfHarvardReferences() {
	new HarvardReferences;
	return true;
}

See also[edit | edit source]