Ejemplo n.º 1
0
	/**
	 * Renders the citation and stores the result in $this->citation.
	 * @param WCStyle $style
	 * @return array = the rendered citation and sorting parts.
	 */
	public function render() {

		# Build the citation
		if ( $this->citationLength->key == WCCitationLengthEnum::short ) {
			switch ( $this->citationType->key ) {
				case WCCitationTypeEnum::note:
					list( $citation, $sortingParts ) = $this->style->renderShortNoteCitation( $this );
					break;
				case WCCitationTypeEnum::inline:
					list( $citation, $sortingParts ) = $this->style->renderShortInlineCitation( $this );
					break;
				case WCCitationTypeEnum::authorDate:
					list( $citation, $sortingParts ) = $this->style->renderShortAuthorDateCitation( $this );
			}
		} else {
			switch ( $this->citationType->key ) {
				case WCCitationTypeEnum::note:
					list( $citation, $sortingParts ) = $this->style->renderLongNoteCitation( $this );
					break;
				case WCCitationTypeEnum::biblio:
					list( $citation, $sortingParts ) = $this->style->renderLongBiblioCitation( $this );
					break;
				case WCCitationTypeEnum::authorDate:
					list( $citation, $sortingParts ) = $this->style->renderLongAuthorDateCitation( $this );
					break;
				default: # case WCCitationTypeEnum::inline:
					list( $citation, $sortingParts ) = $this->style->renderLongInlineCitation( $this );
			}
		}

		# Wrap the entire citation in an HTML span element with classes.
		$classHTML = WCStyle::citationHTML . ' ' .
			$this->style->styleHTML . ' ' .
			$this->reference->getWorkType() . ' ' .
			$this->citationType . ' ' .
			$this->citationLength;

		return array( WCStyle::wrapHTMLSpan( $citation, $classHTML ), $sortingParts );

	}
	/**
	 * Add a reference to the cache, checking for prior duplicates.
	 * @param integer $key = a unique key
	 * @param WCReference $reference
	 * @return integer = number of citations from last use of this reference.
	 */
	public function addUniqueReference( $key, WCReference $reference ) {
		$referenceKey = array( $key );

		$hash = $reference->getHash();
		if ( empty( $hash ) ) {
			# If empty hash, search all prior hashed references.
			foreach( $this->hashTable as &$hashArray ) {
				foreach( $hashArray as &$testKey ) {
					$testReference = $this->references[ $testKey ];
					# If $reference can be considered a short form of prior reference:
					if ( $reference->shortFormMatches( $testReference ) ) {
						$lastKey = end( $testReference ->keys );
						$testReference->keys += $referenceKey;
						# Forget this reference:
						$this->references[ $key ] = $testReference;
						return $key - $lastKey;
					}
					# If prior reference can be considered a short form of $reference:
					elseif ( $testReference->shortFormMatches( $reference ) ) {
						$lastKey = end( $testReference ->keys );
						$reference->keys = $testReference->keys + $referenceKey;
						# Forget the earlier reference.
						unset( $this->referenceList [ $testKey ] );
						$this->referenceList[ $key ] = $reference;
						$this->references[ $testKey ] = $reference;
						$this->references[ $key ] = $reference;
						$testKey = $key;
						return $key - $lastKey;
					}
				}
			}
		}
		# Handle hash table collisions.
		elseif ( isset( $this->hashTable[ $hash ] ) ) {
			# Search collision entries.
			foreach( $this->hashTable[ $hash ] as &$testKey ) {
				$testReference = $this->references[ $testKey ];
				# If $reference can be considered a short form of prior reference:
				if ( $reference->shortFormMatches( $testReference ) ) {
					$lastKey = end( $testReference ->keys );
					$testReference->keys += $referenceKey;
					# Forget this reference:
					$this->references[ $key ] = $testReference;
					return $key - $lastKey;
				}
				# if prior reference can be considered a short form of $reference:
				elseif ( $testReference->shortFormMatches( $reference ) ) {
					$lastKey = end( $testReference ->keys );
					$reference->keys = $testReference->keys + $referenceKey;
					# Forget the earlier reference.
					unset( $this->referenceList [ $testKey ] );
					$this->referenceList[ $key ] = $reference;
					$this->references[ $testKey ] = $reference;
					$this->references[ $key ] = $reference;
					$testKey = $key;
					return $key - $lastKey;
				}
			}
			# If no collision yet, search prior empty hashes.
			foreach( $this->hashTable[ '' ] as $id => &$testKey ) {
				$testReference = $this->references[ $testKey ];
				if ( $testReference->shortFormMatches( $reference ) ) {
					$lastKey = end( $testReference ->keys );
					$reference->keys = $testReference->keys + $referenceKey;
					# Forget the earlier reference.
					unset( $this->referenceList [ $testKey ] );
					$this->referenceList [ $key ] = $reference;
					$this->references[ $testKey ] = $reference;
					$this->references[ $key ] = $reference;
					# Correct hash table
					unset( $this->hashTable[ '' ][ $id ] );
					$this->hashTable[ $hash ][] = $key;
					return $key - $lastKey;
				}
			}
		}
		# If no hash table match:
		$reference->keys = $referenceKey;
		$this->referenceList[ $key ] = $reference;
		$this->references[ $key ] = $reference;
		$this->hashTable[ $hash ][] = $key;
		return 0;
	}
Ejemplo n.º 3
0
	/**
	 * Creates a citation object for each citation parser function.
	 *
	 * Reads flags and parameters from WCArgumentReader object,
	 * then creates an appropriate child of class WCStyle based on the
	 * first parameter after the colon, then returns the citation as text.
	 * @remark Note that this $parser is guaranteed to be the same parser that
	 * initialized the object.
	 *
	 * @param WCArgumentReader $argumentReader
	 * @return string Unique marker for citation.
	 */
	public function parseCitation( WCArgumentReader $argumentReader ) {

		# Use the explicit citation style if defined, or use last style.
		$styleClassName = $argumentReader->getStyleClassName();
		if ( $styleClassName ) {
			# Store citation style in a running database of style object singlets.
			$this->currentDefaultStyle = self::getStyle($styleClassName);
		}

		# A citation function, with no data, may exist merely to define the citation style.
		if ( $argumentReader->isEmpty() ) {
			++$this->citationCount;
			return '';
		}

		$reference = new WCReference();
		$citation = new WCCitation( $reference );
		$citation->readArguments( $argumentReader );
		$reference->finalize();

		# Store reference in database that checks for uniqueness.
		# $citation->reference will be reloaded later, after all citations are read.
		$citation->distance = $this->referenceStore->addUniqueReference( $this->citationCount, $reference );

		# Is this a citation explicitly inserted in bibliography tags?
		# If so, then we will not be leaving behind a marker.
		if ( $this->bibliographyLevel > 0 ) {
			++$this->citationCount;
			return ''; # Only a single marker is left behind per bibliography.
		}

		# Determine whether the citation is in a note, or inline.
		$section = $this->sectionStack[ $this->sectionStackPointer ];
		if ( $this->noteLevel > 0 ) {
			$section->addNoteCite( $this->citationCount, $citation );
		} else {
			$section->addInlineCite( $this->citationCount, $citation );
		}

		# Store citation and leave behind a random marker for later replacement by the citation:
		$this->citations[ $this->citationCount++ ] = $citation;
		return $citation->marker;

	}
Ejemplo n.º 4
0
	/**
	 * Determine if $this can be considered a short form of the argument.
	 * If so, then determine the number of matches.
	 *
	 * @param WCNames $names
	 * @return integer|boolean
	 */
	public function shortFormMatches( WCReference $reference ) {
		$matches = 0;
		# Compare names.
		foreach( $this->names as $scopeKey => $nameTypes ) {
			foreach( $nameTypes as $nameTypeKey => $thisNames ) {
				$otherNames = $reference->getNames( new WCScopeEnum( $scopeKey ), new WCNameTypeEnum( $nameTypeKey ) );
				if ( isset( $otherNames ) ) {
					$subMatches = $thisNames->shortFormMatches( $otherNames );
					if ( $subMatches === False ) {
						return False;
					} else {
						$matches += $subMatches;
					}
				}
			}
		}
		# Compare properties.
		foreach( $this->properties as $scopeKey => $propertyTypes ) {
			foreach( $propertyTypes as $propertyTypeKey => $thisProperty ) {
				$otherProperty = $reference->getProperty( new WCScopeEnum( $scopeKey ), new WCPropertyEnum( $propertyTypeKey ) );
				if ( isset( $otherProperty ) ) {
					$subMatches = $thisProperty->shortFormMatches( $otherProperty );
					if ( $subMatches === False ) {
						return False;
					} else {
						$matches += $subMatches;
					}
				}
			}
		}
		return $matches;

	}