preview = $preview; if(!$this->preview) // Not javascript preview { $dir = trim($dir); if(!$dir){ $this->dir = dirname(__FILE__) . "/"; } else{ $this->dir = $dir; if($dir[strlen($dir)-1] != "/"){ $this->dir .= "/"; } } $this->bibtexParsePath = $this->dir . "format/bibtexParse"; } else // preview $this->dir = ''; $this->bibtex = $bibtex; if($this->bibtex) { include_once($this->dir."STYLEMAPBIBTEX.php"); $this->styleMap = new STYLEMAPBIBTEX(); } else { include_once($this->dir."STYLEMAP.php"); $this->styleMap = new STYLEMAP(); } include_once($this->dir."UTF8.php"); $this->utf8 = new UTF8(); /** * Highlight preg pattern and CSS class for HTML display */ $this->patterns = FALSE; $this->patternHighlight = FALSE; /** * Output medium: * Defaul 'html' */ $this->output = 'html'; $this->previousCreator = ''; /** * Switch editor and author positions in the style definition for a book in which there are only editors */ $this->editorSwitch = FALSE; /** * Load month arrays */ $this->loadArrays(); /** * Convert the entry to produce utf8 * Defaut: 'FALSE', we assume that the entries are already clean */ $this->convertEntry=FALSE; } /** * Read the chosen bibliographic style and create arrays based on resource type. * * @author Mark Grimshaw * @version 1 * * @param $stylePath The path where the styles are. * @param $style The requested bibliographic output style. * @return BOOLEAN */ function loadStyle($stylePath, $style) { //05/05/2005 G.GARDEY: add a last "/" to $stylePath if not present. $stylePath = trim($stylePath); if($stylePath[strlen($stylePath)-1] != "/"){ $stylePath .= "/"; } $uc = $stylePath . strtolower($style) . "/" . strtolower($style) . ".xml"; $lc = $stylePath . strtolower($style) . "/" . strtoupper($style) . ".xml"; $styleFile = file_exists($uc) ? $uc : $lc; if(!$fh = fopen($styleFile, "r")) return array(FALSE, FALSE, FALSE); include_once($this->dir."PARSEXML.php"); $parseXML = new PARSEXML($this); list($info, $citation, $common, $types) = $parseXML->extractEntries($fh); fclose($fh); return array($info, $citation, $common, $types); } /** * Transform the raw data from the XML file into usable arrays * * @author Mark Grimshaw * @version 1 * * @param $common Array of global formatting data * @param $types Array of style definitions for each resource type */ function getStyle($common, $types) { $this->commonToArray($common); $this->typesToArray($types); } /** * Reformat the array representation of common styling into a more useable format. * 'common' styling refers to formatting that is common to all resource types such as creator formatting, title * capitalization etc. * * @author Mark Grimshaw * @version 1 * * @param $common nodal array representation of XML data * @return flattened array representation for easier use. */ function commonToArray($common) { foreach($common as $array) { if(array_key_exists('_NAME', $array) && array_key_exists('_DATA', $array)) $this->style[$array['_NAME']] = $array['_DATA']; } } /** * Reformat the array representation of resource types into arrays based on the type. * * @param $types nodal array representation of XML data */ function typesToArray($types) { foreach($types as $resourceArray) { /** * The resource type which will be our array name */ $type = $resourceArray['_ATTRIBUTES']['name']; $styleDefinition = $resourceArray['_ELEMENTS']; foreach($styleDefinition as $array) { if(array_key_exists('_NAME', $array) && array_key_exists('_DATA', $array) && array_key_exists('_ELEMENTS', $array)) { if($array['_NAME'] == 'fallbackstyle') { $this->fallback[$type] = $array['_DATA']; break; } if($array['_NAME'] == 'ultimate') { $this->{$type}['ultimate'] = $array['_DATA']; continue; } foreach($array['_ELEMENTS'] as $elements) { if($array['_NAME'] == 'independent') { $split = split("_", $elements['_NAME']); $this->{$type}[$array['_NAME']][$split[1]] = $elements['_DATA']; } else $this->{$type}[$array['_NAME']][$elements['_NAME']] = $elements['_DATA']; } } } /** * Backup each $this->$type array. If we need to switch editors, it's faster to restore each * $this->$type array from this backup than to reload the style file and parse it. */ if(isset($this->$type)) $this->backup[$type] = $this->$type; } } /** * Restore each $this->type array from $this->backup * * @author Mark Grimshaw * @version 1 */ function restoreTypes() { foreach($this->backup as $type => $array) $this->$type = $array; } /** * Perform pre-processing on the raw SQL array * * @author Mark Grimshaw * @version 1 * * @param $type The resource type * @param $row Associate array of raw SQL data * @return $row Processed row of raw SQL data */ function preProcess($type, $row) { /** * Ensure that $this->item is empty for each resource!!!!!!!!!! */ $this->item = array(); // Map this system's resource type to OSBib's resource type $this->type = array_search($type, $this->styleMap->types); if($this->bibtex && array_key_exists('author', $row)) { $row['creator1'] = $row['author']; unset($row['author']); } if($this->bibtex && array_key_exists('editor', $row)) { $row['creator2'] = $row['editor']; unset($row['editor']); } /** * Set any author/editor re-ordering for book and book_article type. */ if(!$this->preview && (($type == 'book') || ($type == 'book_article')) && $row['creator2'] && !$row['creator1'] && $this->style['editorSwitch'] && array_key_exists('author', $this->$type)) { $row['creator1'] = $row['creator2']; $row['creator2'] = FALSE; include_once($this->dir . "PARSESTYLE.php"); $editorArray = PARSESTYLE::parseStringToArray($type, $this->style['editorSwitchIfYes'], $this->styleMap); if(!empty($editorArray) && array_key_exists('editor', $editorArray)) { $this->{$type}['author'] = $editorArray['editor']; unset($this->{$type}['editor']); $this->editorSwitch = TRUE; } } /** * If $row comes in in BibTeX format, process and add items to $this->item */ if($this->bibtex) { if(!$this->type) { list($type, $row) = $this->preProcessBibtex($row, $type); } else list($type, $row) = $this->preProcessBibtex($row, $this->type); } /** * Ensure that for theses types, the first letter of type and label are capitalized (e.g. 'Master's Thesis'). */ if($type == 'thesis') { if(($key = array_search('type', $this->styleMap->$type)) !== FALSE) { if(isset($row[$key])) $row[$key] = ucfirst($row[$key]); } if(($key = array_search('label', $this->styleMap->$type)) !== FALSE) { if(isset($row[$key])) $row[$key] = ucfirst($row[$key]); } } /** * Set to catch-all generic style. For all keys except named database fields, creator1 and year1, * we only print if the value in $this->styleMap matches the value in * $this->styleMap->generic for each key. */ if(!isset($this->$type)) { $fallback = $this->fallback[$type]; $type = $fallback; } $this->type = $type; /** * Add BibTeX entry to $this->item */ if($this->bibtex) { foreach($row as $field => $value) { if(array_key_exists($field, $this->styleMap->$type) && !array_key_exists($this->styleMap->{$type}[$field], $this->item)) $this->addItem($row[$field], $field); } } return $row; } /** * Preprocess BibTeX-type entries * @author Mark Grimshaw * @version 1 * * @param assoc. array of elements for one bibtex entry * @param string resource type * @return string resource type * @return array resource assoc. array of elements for one bibtex entry */ function preProcessBibtex(&$row, $type) { //05/05/2005 G.GARDEY: change bibtexParse name. /** * This set of includes is for the OSBib public release and should be uncommented for that and * the WIKINDX-specific includes below commented out! */ include_once($this->bibtexParsePath . "/PARSECREATORS.php"); $parseCreator = new PARSECREATORS(); include_once($this->bibtexParsePath . "/PARSEMONTH.php"); $parseDate = new PARSEMONTH(); include_once($this->bibtexParsePath . "/PARSEPAGE.php"); $parsePages = new PARSEPAGE(); // WIKINDX naming of above files /* include_once($this->bibtexParsePath . "/BIBTEXCREATORPARSE.php"); $parseCreator = new BIBTEXCREATORPARSE(); include_once($this->bibtexParsePath . "/BIBTEXMONTHPARSE.php"); $parseDate = new BIBTEXMONTHPARSE(); include_once($this->bibtexParsePath . "/BIBTEXPAGEPARSE.php"); $parsePages = new BIBTEXPAGEPARSE(); */ // Added by Christophe Ambroise: convert the bibtex entry to utf8 (for storage or printing) if ($this->cleanEntry) {$row=$this->convertEntry($row);} // /** * Bibtex-specific types not defined in STYLEMAPBIBTEX */ if(!$this->type) { if($type == 'mastersthesis') { $type = 'thesis'; $row['type'] = "Master's Dissertation"; } if($type == 'phdthesis') { $type = 'thesis'; $row['type'] = "PhD Thesis"; } else if($type == 'booklet') $type = 'miscellaneous'; else if($type == 'conference') $type = 'proceedings_article'; else if($type == 'incollection') $type = 'book_article'; else if($type == 'manual') $type = 'report'; } /** * 'article' could be journal, newspaper or magazine article */ else if($type == 'journal_article') { if(array_key_exists('month', $row) && array_key_exists('date', $this->styleMap->$type)) { list($startMonth, $startDay, $endMonth, $endDay) = $parseDate->init($row['month']); if($startDay) $type = 'newspaper_article'; else if($startMonth) $type = 'magazine_article'; $this->formatDate($startDay, $startMonth, $endDay, $endMonth); } else $type = 'journal_article'; } /** * Is this a web article? */ else if(($type == 'miscellaneous') && array_key_exists('howpublished', $row)) { if(preg_match("#^\\\url{(.*://.*)}#", $row['howpublished'], $match)) { $row['URL'] = $match[1]; $type = 'web_article'; } } $this->type = $type; if(array_key_exists('creator1', $row) && $row['creator1'] && array_key_exists('creator1', $this->styleMap->$type)) { $creators = $parseCreator->parse($row['creator1']); foreach($creators as $cArray) { $temp[] = array( 'surname' => trim($cArray[2]), 'firstname' => trim($cArray[0]), 'initials' => trim($cArray[1]), 'prefix' => trim($cArray[3]), ); } $this->formatNames($temp, 'creator1'); unset($temp); } if(array_key_exists('creator2', $row) && $row['creator2'] && array_key_exists('creator2', $this->styleMap->$type)) { $creators = $parseCreator->parse($row['creator2']); foreach($creators as $cArray) { $temp[] = array( 'surname' => trim($cArray[2]), 'firstname' => trim($cArray[0]), 'initials' => trim($cArray[1]), 'prefix' => trim($cArray[3]), ); } $this->formatNames($temp, 'creator2'); } if(array_key_exists('pages', $row) && array_key_exists('pages', $this->styleMap->$type)) { list($start, $end) = $parsePages->init($row['pages']); $this->formatPages(trim($start), trim($end)); } $this->formatTitle($row['title'], "{", "}"); return array($type, $row); } /** * Map the $item array against the style array ($this->$type) for this resource type and produce a string ready to be * formatted for bold, italics etc. * * @author Mark Grimshaw * @version 1 * * @param $template If called from CITEFORMAT, this is the array of template elements. * @return string ready for printing to the output medium. */ function map($template = FALSE) { /** * Output medium: * 'html', 'rtf', or 'plain' */ include_once($this->dir . "format/EXPORTFILTER.php"); $this->export = new EXPORTFILTER($this, $this->output); if($template) { $this->citation = $template; $this->type = 'citation'; } $type = $this->type; $ultimate = ''; $index = 0; $previousFieldExists = $nextFieldExists = TRUE; if(array_key_exists('independent', $this->$type)) $independent = $this->{$type}['independent']; /** * For dependency on next field, we must grab array keys of $this->$type, shift the first element then, in the loop, * check each element exists in $item. If it doesn't, $nextFieldExists is set to FALSE */ $checkPost = array_keys($this->$type); array_shift($checkPost); foreach($this->$type as $key => $value) { if($key == 'ultimate') { $ultimate = $value; continue; } if(!array_key_exists($key, $this->item) || !$this->item[$key]) { $keyNotExists[] = $index; $index++; array_shift($checkPost); $previousFieldExists = FALSE; continue; } $checkPostShift = array_shift($checkPost); if(!array_key_exists($checkPostShift, $this->item) || !$this->item[$checkPostShift]) $nextFieldExists = FALSE; $pre = array_key_exists('pre', $value) ? $value['pre'] : ''; $post = array_key_exists('post', $value) ? $value['post'] : ''; /** * Deal with __DEPENDENT_ON_PREVIOUS_FIELD__ for characters dependent on previous field's existence and * __DEPENDENT_ON_NEXT_FIELD__ for characters dependent on the next field's existence */ if($previousFieldExists && array_key_exists('dependentPre', $value)) $pre = preg_replace("/__DEPENDENT_ON_PREVIOUS_FIELD__/", $value['dependentPre'], $pre); else if(array_key_exists('dependentPreAlternative', $value)) $pre = preg_replace("/__DEPENDENT_ON_PREVIOUS_FIELD__/", $value['dependentPreAlternative'], $pre); else $pre = preg_replace("/__DEPENDENT_ON_PREVIOUS_FIELD__/", '', $pre); if($nextFieldExists && array_key_exists('dependentPost', $value)) $post = str_replace("__DEPENDENT_ON_NEXT_FIELD__", $value['dependentPost'], $post); else if(array_key_exists('dependentPostAlternative', $value)) $post = preg_replace("/__DEPENDENT_ON_NEXT_FIELD__/", $value['dependentPostAlternative'], $post); else $post = preg_replace("/__DEPENDENT_ON_NEXT_FIELD__/", '', $post); /** * Deal with __SINGULAR_PLURAL__ for creator lists and pages */ if($styleKey = array_search($key, $this->styleMap->$type)) $pluralKey = $styleKey . "_plural"; if(isset($this->$pluralKey) && $this->$pluralKey) // plural alternative for this key { $pre = array_key_exists('plural', $value) ? preg_replace("/__SINGULAR_PLURAL__/", $value['plural'], $pre) : $pre; $post = array_key_exists('plural', $value) ? preg_replace("/__SINGULAR_PLURAL__/", $value['plural'], $post) : $post; } else if(isset($this->$pluralKey)) // singular alternative for this key { $pre = array_key_exists('singular', $value) ? preg_replace("/__SINGULAR_PLURAL__/", $value['singular'], $pre) : $pre; $post = array_key_exists('singular', $value) ? preg_replace("/__SINGULAR_PLURAL__/", $value['singular'], $post) : $post; } /** * Make sure we don't have duplicate punctuation characters */ $lastPre = substr($post, -1); $firstItem = substr($this->item[$key], 0, 1); if($firstItem === $lastPre) $this->item[$key] = substr($this->item[$key], 1); $firstPost = substr($post, 0, 1); $lastItem = substr($this->item[$key], -1); // if(preg_match("/\.|,|;|:\?!/", $lastItem) && preg_match("/\.|,|;|:|\?|!/", $firstPost)) if(preg_match("/\.|,|;|:\?!/", $lastItem) && ($firstPost == $lastItem)) $post = substr($post, 1); // take a guess at removing first character of $post /** * Strip backticks used in template */ $pre = str_replace("`", '', $pre); $post = str_replace("`", '', $post); $pre = ($this->output == 'html') ? $this->utf8->utf8_htmlspecialchars($pre) : $pre; $post = ($this->output == 'html') ? $this->utf8->utf8_htmlspecialchars($post) : $post; if($this->item[$key]) $itemArray[$index] = $pre . $this->item[$key] . $post; $previousFieldExists = $nextFieldExists = TRUE; $index++; } /** * Check for independent characters. These (should) come in pairs. */ if(isset($independent)) { $independentKeys = array_keys($independent); while($independent) { $preAlternative = $postAlternative = FALSE; $startFound = $endFound = FALSE; $pre = array_shift($independent); $post = array_shift($independent); if(preg_match("/%(.*)%(.*)%|%(.*)%/U", $pre, $dependent)) { if(sizeof($dependent) == 4) $pre = $dependent[3]; else { $pre = $dependent[1]; $preAlternative = $dependent[2]; } } if(preg_match("/%(.*)%(.*)%|%(.*)%/U", $post, $dependent)) { if(sizeof($dependent) == 4) $post = $dependent[3]; else { $post = $dependent[1]; $postAlternative = $dependent[2]; } } /** * Strip backticks used in template */ $preAlternative = str_replace("`", '', $preAlternative); $postAlternative = str_replace("`", '', $postAlternative); $firstKey = array_shift($independentKeys); $secondKey = array_shift($independentKeys); for($index = $firstKey; $index <= $secondKey; $index++) { if(array_key_exists($index, $itemArray)) { $startFound = $index; break; } } for($index = $secondKey; $index >= $firstKey; $index--) { if(array_key_exists($index, $itemArray)) { $endFound = $index; break; } } if(($startFound !== FALSE) && ($endFound !== FALSE)) // intervening fields found { $itemArray[$startFound] = $pre . $itemArray[$startFound]; $itemArray[$endFound] = $itemArray[$endFound] . $post; } else // intervening fields not found - do we have an alternative? { if(array_key_exists($firstKey - 1, $itemArray) && $preAlternative) $itemArray[$firstKey - 1] .= $preAlternative; if(array_key_exists($secondKey + 1, $itemArray) && $postAlternative) $itemArray[$secondKey + 1] = $postAlternative . $itemArray[$secondKey + 1]; } } } $pString = join('', $itemArray); /** * if last character is punctuation (which it may be with missing fields etc.), and $ultimate is also * punctuation, remove last character. */ if(isset($ultimate) && $ultimate) { $last = substr(trim($pString), -1); /** * Don't do ';' in case last element is URL with > ...! */ if(preg_match("/^\.|^,||^:^\?^\!/", $ultimate) && preg_match("/\.|,|:|\?|!/", $last)) $pString = substr(trim($pString), 0, -1); } // If $this->editorSwitch, we have altered $this->$bibformat->$type so need to reload styles if($this->editorSwitch) { $this->restoreTypes(); $this->editorSwitch = FALSE; } return $this->export->format(trim($pString) . $ultimate); } /** * Format creator name lists (authors, editors, etc.) * * @author Mark Grimshaw * @version 1 * * @param $creators Multi-associative array of creator names e.g. this array might be of * the primary authors: *
   *	array([0] => array(['surname'] => 'Grimshaw', ['firstname'] => Mark, ['initials'] => 'N', ['prefix'] => ),
   *	   [1] => array(['surname'] => 'Witt', ['firstname'] => Jan, ['initials'] => , ['prefix'] => 'de'))
   * 
* @param $nameType 'creator1', 'creator2' etc. If $nameType == 'citation', this method is called * from CITEFORMAT for formatting citation creators in which case we expect the 3rd parameter $citation. * @param $citation If called from CITEFORMAT, this is the array of citation stylings. * @return Optional if $nameType == 'citation': formatted string of all creator names in the input array. */ function formatNames($creators, $nameType, $citation = FALSE) { $style = $citation ? $citation : $this->style; $first = TRUE; /** * Set default plural behaviour for creator lists */ $pluralKey = $nameType . "_plural"; $this->$pluralKey = FALSE; // $this->creator1_plural = $this->creator2_plural = // $this->creator3_plural = $this->creator4_plural = $this->creator5_plural = FALSE; /** * Citation creators */ if($nameType == 'citation') { $limit = 'creatorListLimit'; $moreThan = 'creatorListMore'; $abbreviation = 'creatorListAbbreviation'; $initialsStyle = 'creatorInitials'; $firstNameInitial = 'creatorFirstName'; $delimitTwo = 'twoCreatorsSep'; $delimitFirstBetween = 'creatorSepFirstBetween'; $delimitNextBetween = 'creatorSepNextBetween'; $delimitLast = 'creatorSepNextLast'; $uppercase = 'creatorUppercase'; $italics = 'creatorListAbbreviationItalic'; if($first) $nameStyle = 'creatorStyle'; else $nameStyle = 'creatorOtherStyle'; } /** * Primary creator */ else if($nameType == 'creator1') { $limit = 'primaryCreatorListLimit'; $moreThan = 'primaryCreatorListMore'; $abbreviation = 'primaryCreatorListAbbreviation'; $initialsStyle = 'primaryCreatorInitials'; $firstNameInitial = 'primaryCreatorFirstName'; $delimitTwo = 'primaryTwoCreatorsSep'; $delimitFirstBetween = 'primaryCreatorSepFirstBetween'; $delimitNextBetween = 'primaryCreatorSepNextBetween'; $delimitLast = 'primaryCreatorSepNextLast'; $uppercase = 'primaryCreatorUppercase'; $italics = 'primaryCreatorListAbbreviationItalic'; if($first) $nameStyle = 'primaryCreatorFirstStyle'; else $nameStyle = 'primaryCreatorOtherStyle'; } else { $limit = 'otherCreatorListLimit'; $moreThan = 'otherCreatorListMore'; $abbreviation = 'otherCreatorListAbbreviation'; $initialsStyle = 'otherCreatorInitials'; $firstNameInitial = 'otherCreatorFirstName'; $delimitTwo = 'otherTwoCreatorsSep'; $delimitFirstBetween = 'otherCreatorSepFirstBetween'; $delimitNextBetween = 'otherCreatorSepNextBetween'; $delimitLast = 'otherCreatorSepNextLast'; $uppercase = 'otherCreatorUppercase'; $italics = 'otherCreatorListAbbreviationItalic'; if($first) $nameStyle = 'otherCreatorFirstStyle'; else $nameStyle = 'otherCreatorOtherStyle'; } $type = $this->type; foreach($creators as $creator) { $firstName = trim($this->checkInitials($creator, $style[$initialsStyle], $style[$firstNameInitial])); $prefix = $creator['prefix'] ? trim(stripslashes($creator['prefix'])) . ' ' : ''; if($style[$nameStyle] == 0) // Joe Bloggs { $nameString = $firstName . ' ' . $prefix . stripslashes($creator['surname']); } else if($style[$nameStyle] == 1) // Bloggs, Joe { $prefixDelimit = $firstName ? ', ' : ''; $nameString = stripslashes($creator['prefix']) . ' ' . stripslashes($creator['surname']) . $prefixDelimit . $firstName; } else if($style[$nameStyle] == 2) // Bloggs Joe { $nameString = stripslashes($creator['prefix']) . ' ' . stripslashes($creator['surname']) . ' ' . $firstName; } else // Last name only { $nameString = stripslashes($creator['prefix']) . ' ' . stripslashes($creator['surname']); } if(isset($style[$uppercase])) $nameString = $this->utf8->utf8_strtoupper($nameString); $cArray[] = trim($nameString); $first = FALSE; } /** * Keep only some elements in array if we've exceeded $moreThan */ $etAl = FALSE; if($style[$limit] && (sizeof($cArray) > $style[$moreThan])) { array_splice($cArray, $style[$limit]); if(isset($style[$italics])) $etAl = "[i]" . $style[$abbreviation] . "[/i]"; else $etAl = $style[$abbreviation]; } /** * add delimiters */ if(sizeof($cArray) > 1) { if(sizeof($cArray) == 2) $cArray[0] .= $style[$delimitTwo]; else { for($index = 0; $index < (sizeof($cArray) - 2); $index++) { if(!$index) $cArray[$index] .= $style[$delimitFirstBetween]; else $cArray[$index] .= $style[$delimitNextBetween]; } $cArray[sizeof($cArray) - 2] .= $style[$delimitLast]; } } /** * If sizeof of $cArray > 1 or $etAl != FALSE, set this $nameType_plural to TRUE */ if((sizeof($cArray) > 1) || $etAl) { $pluralKey = $nameType . "_plural"; $this->$pluralKey = TRUE; } /** * Finally flatten array */ if($etAl) $pString = implode('', $cArray) . $etAl; else $pString = implode('', $cArray); /** * Check for repeating primary creator list in subsequent bibliographic item. */ if($nameType == 'creator1') { $tempString = $pString; if(($style['primaryCreatorRepeat'] == 2) && ($this->previousCreator == $pString)) $pString = $style['primaryCreatorRepeatString']; else if(($style['primaryCreatorRepeat'] == 1) && ($this->previousCreator == $pString)) $pString = ''; // don't print creator list $this->previousCreator = $tempString; } else if($nameType == 'citation') return $pString; $this->item[$this->styleMap->{$type}[$nameType]] = $pString; } /** * Handle initials. * @see formatNames() * * @author Mark Grimshaw * @version 1 * * @param $creator Associative array of creator name e.g. *
   *	array(['surname'] => 'Grimshaw', ['firstname'] => Mark, ['initials'] => 'M N G', ['prefix'] => ))
   * 
* Initials must be space-delimited. * * @param $initialsStyle * @param $firstNameInitial * @return Formatted string of initials. */ function checkInitials(&$creator, $initialsStyle, $firstNameInitial) { /** * Format firstname */ if($creator['firstname'] && !$firstNameInitial) // Full name $firstName = stripslashes($creator['firstname']); else if($creator['firstname']) // Initial only of first name. 'firstname' field may actually have several 'firstnames' { $fn = split(" ", stripslashes($creator['firstname'])); $firstTime = TRUE; foreach($fn as $name) { if($firstTime) { // May be the first name is a hyphenated name // We separate each part of the name separated by a - $fn2 = split("-", trim($name)); $firstNameInitialMake = ""; foreach($fn2 as $nameparts) { if ($firstNameInitialMake != "") { $firstNameInitialMake .= "-"; } $firstNameInitialMake .= $this->utf8->utf8_strtoupper($this->utf8->utf8_substr($nameparts, 0, 1)); $firstTime = FALSE; } } else $initials[] = $this->utf8->utf8_strtoupper($this->utf8->utf8_substr(trim($name), 0, 1)); } if(isset($initials)) { if($creator['initials']) $creator['initials'] = join(" " , $initials) . ' ' . $creator['initials']; else $creator['initials'] = join(" " , $initials); } } /** * Initials are stored as space-delimited characters. * If no initials, return just the firstname or its initial in the correct format. */ if(!$creator['initials']) { if(isset($firstName)) // full first name only return $firstName; if(isset($firstNameInitialMake) && $initialsStyle > 1) // First name initial with no '.' return $firstNameInitialMake; if(isset($firstNameInitialMake)) // First name initial with '.' { // If the name is hyphaned, we have to add a . after each initial. $fn2 = split("-", $firstNameInitialMake); $firstNameInitialMakeResult = ""; foreach($fn2 as $initial) { if ($firstNameInitialMakeResult != "") { $firstNameInitialMakeResult .= "-"; } $firstNameInitialMakeResult .= $initial . "."; } return $firstNameInitialMakeResult; } return ''; // nothing here } $initialsArray = explode(' ', $creator['initials']); /** * If firstname is initial only, prepend to array */ if(isset($firstNameInitialMake)) array_unshift($initialsArray, $firstNameInitialMake); if($initialsStyle == 0) // 'T. U. ' $initials = implode('. ', $initialsArray) . '.'; else if($initialsStyle == 1) // 'T.U.' $initials = implode('.', $initialsArray) . '.'; else if($initialsStyle == 2) // 'T U ' $initials = implode(' ', $initialsArray); else // 'TU ' $initials = implode('', $initialsArray); /** * If we have a full first name, prepend it to $initials. */ if(isset($firstName)) return ($firstName . ' ' . $initials); return $initials; } /** * Add an item to $this->item array * * @author Mark Grimshaw * @version 1 * * @param $item The item to be added. * @param $fieldName The database fieldName of the item to be added */ function addItem($item, $fieldName) { $type = $this->type; if($item === FALSE) return; /** * This item may already exist (e.g. edition field for WIKINDX) */ if(isset($this->item) && array_key_exists($this->styleMap->{$type}[$fieldName], $this->item)) return FALSE; $this->item[$this->styleMap->{$type}[$fieldName]] = $item; } /** * Add all remaining items to $this->item array * * @author Mark Grimshaw * @version 1 * * @param $row The items to be added. */ function addAllOtherItems($row) { $type = $this->type; foreach($row as $field => $value) { if(array_key_exists($field, $this->styleMap->$type) && !array_key_exists($this->styleMap->{$type}[$field], $this->item)) $this->addItem($row[$field], $field); } } /** * Format a title. Anything enclosed in $delimitLeft...$delimitRight is to be left unchanged * * @author Mark Grimshaw * @version 1 * * @param $pString Raw title string. * @param $delimitLeft * @param $delimitRight * @return Formatted title string. */ function formatTitle($pString, $delimitLeft = FALSE, $delimitRight = FALSE) { if(!$delimitLeft) $delimitLeft = '{'; if(!$delimitRight) $delimitRight = '}'; $delimitLeft = preg_quote($delimitLeft); $delimitRight = preg_quote($delimitRight); $match = "/" . $delimitLeft . "/"; $type = $this->type; if(!array_key_exists('title', $this->styleMap->$type)) $this->item[$this->styleMap->{$type}['title']] = ''; /** * '0' == 'Osbib Bibliographic Formatting' * '1' == 'Osbib bibliographic formatting' */ if($this->style['titleCapitalization']) { // Something here (preg_split probably) interferes with UTF-8 encoding (data is stored in // the database as UTF-8 as long as web browser charset == UTF-8). // So first decode then encode back to UTF-8 at end. // There is a 'u' UTF-8 parameter for preg_xxx but it doesn't work. $pString = $this->utf8->decodeUtf8($pString); $newString = ''; while(preg_match($match, $pString)) { $array = preg_split("/(.*)$delimitLeft(.*)$delimitRight(.*)/U", $pString, 2, PREG_SPLIT_DELIM_CAPTURE); /** * in case user has input {..} incorrectly */ if(sizeof($array) == 1) break; $newString .= $this->utf8->utf8_strtolower($this->utf8->encodeUtf8($array[1])) . $array[2]; $pString = $array[4]; } $newString .= $this->utf8->utf8_strtolower($this->utf8->encodeUtf8($pString)); } $pString = isset($newString) ? $newString : $pString; $title = $this->utf8->encodeUtf8($this->utf8->utf8_ucfirst(trim($pString))); $this->item[$this->styleMap->{$type}['title']] = ($this->output == 'html') ? $this->utf8->utf8_htmlspecialchars($title) : $title; } /** * Format pages. * $this->style['pageFormat']: * 0 == 132-9 * 1 == 132-39 * 2 == 132-139 * * @author Mark Grimshaw * @version 1 * * @param $start Page start. * @param $end Page end. * @param $citation If called from CITEFORMAT, this is the array of citation stylings. * @return string of pages. */ function formatPages($start, $end = FALSE, $citation = FALSE) { $type = $this->type; $style = $citation ? $citation : $this->style; /** * Set default plural behaviour for pages */ $this->pages_plural = FALSE; /** * If no page end, return just $start; */ if(!$end) { $this->item[$this->styleMap->{$type}['pages']] = $start; return; } /** * Pages may be in roman numeral format etc. Return unchanged */ if(!is_numeric($start)) { $this->item[$this->styleMap->{$type}['pages']] = $start . '-' . $end; return; } /** * We have multiple pages... */ $this->pages_plural = TRUE; /** * They've done something wrong so give them back exactly what they entered */ if(($end <= $start) || (strlen($end) < strlen($start))) { $this->item[$this->styleMap->{$type}['pages']] = $start . '-' . $end; return; } else if($style['pageFormat'] == 2) { $this->item[$this->styleMap->{$type}['pages']] = $start . '-' . $end; return; } else { /** * We assume page numbers are not into the 10,000 range - if so, return the complete pages */ if(strlen($start) <= 4) { $startArray = preg_split('//', $start); array_shift($startArray); // always an empty element at start? array_pop($startArray); // always an empty array element at end? if($style['pageFormat'] == 0) { array_pop($startArray); $endPage = substr($end, -1); $index = -2; } else { array_pop($startArray); array_pop($startArray); $endPage = substr($end, -2); $index = -3; } while(!empty($startArray)) { $startPop = array_pop($startArray); $endSub = substr($end, $index--, 1); if($endSub == $startPop) { $this->item[$this->styleMap->{$type}['pages']] = $start . '-' . $endPage; return; } if($endSub > $startPop) $endPage = $endSub . $endPage; } } else { $this->item[$this->styleMap->{$type}['pages']] = $start . '-' . $end; return; } } /** * We should never reach here - in case we do, give back complete range so that something at least is printed */ $this->item[$this->styleMap->{$type}['pages']] = $start . '-' . $end; } /** * Format runningTime for film/broadcast * * @author Mark Grimshaw * @version 1 * * @param $minutes * @param $hours */ function formatRunningTime($minutes, $hours) { $type = $this->type; if($this->style['runningTimeFormat'] == 0) // 3'45" { if(isset($minutes) && $minutes) { if($minutes < 10) $minutes = '0' . $minutes; $runningTime = $hours . "'" . $minutes . "\""; } else $runningTime = $hours . "'00\""; } else if($this->style['runningTimeFormat'] == 1) // 3:45 { if(isset($minutes) && $minutes) { if($minutes < 10) $minutes = '0' . $minutes; $runningTime = $hours . ":" . $minutes; } else $runningTime = $hours . ":00"; } else if($this->style['runningTimeFormat'] == 1) // 3,45 { if(isset($minutes) && $minutes) { if($minutes < 10) $minutes = '0' . $minutes; $runningTime = $hours . "," . $minutes; } else $runningTime = $hours . ",00"; } else if($this->style['runningTimeFormat'] == 3) // 3 hours, 45 minutes { $hours = ($hours == 1) ? $hours . " hour" : $hours . " hours"; if(isset($minutes) && $minutes) { $minutes = ($minutes == 1) ? $minutes . " minute" : $minutes . " minutes"; $runningTime = $hours . ", " . $minutes; } else $runningTime = $hours; } else if($this->style['runningTimeFormat'] == 4) // 3 hours and 45 minutes { $hours = ($hours == 1) ? $hours . " hour" : $hours . " hours"; if(isset($minutes) && $minutes) { $minutes = ($minutes == 1) ? $minutes . " minute" : $minutes . " minutes"; $runningTime = $hours . " and " . $minutes; } else $runningTime = $hours; } $this->item[$this->styleMap->{$type}['runningTime']] = $runningTime; } /** * Format date * * @author Mark Grimshaw * @version 2 * * @param INT $startDay * @param INT $startMonth * @param INT $endDay * @param INT $sendMonth */ function formatDate($startDay, $startMonth, $endDay, $endMonth) { $type = $this->type; if($startDay !== FALSE) { if($this->style['dayFormat']) // e.g. 10th $startDay = $this->cardinalToOrdinal($startDay); else if($startDay < 10) $startDay = '0' . $startDay; } if($endDay !== FALSE) { if($this->style['dayFormat']) // e.g. 10th $endDay = $this->cardinalToOrdinal($endDay); else if($endDay < 10) $endDay = '0' . $endDay; } if($this->style['monthFormat'] == 1) // Full month name $monthArray = $this->longMonth; else if($this->style['monthFormat'] == 2) // User-defined { for($i = 1; $i <= 12; $i++) $monthArray[$i] = $this->style["userMonth_$i"]; } else // Short month name $monthArray = $this->shortMonth; if($startMonth !== FALSE) $startMonth = $monthArray[$startMonth]; if($endMonth !== FALSE) $endMonth = $monthArray[$endMonth]; if(!$endMonth) { if($this->style['dateFormat']) // Order == Month Day { $startDay = ($startDay === FALSE) ? '' : ' ' . $startDay; $date = $startMonth . $startDay; } else // Order == Day Month { $startDay = ($startDay === FALSE) ? '' : $startDay . ' '; $date = $startDay . $startMonth; } } else // date range { if(!$startDay) $delimit = $this->style['dateRangeDelimit2']; else $delimit = $this->style['dateRangeDelimit1']; if(($endMonth !== FALSE) && ($startMonth == $endMonth) && ($this->style['dateRangeSameMonth'] == 1)) { $endMonth = FALSE; if(!$endDay) $delimit = FALSE; } if($this->style['dateFormat']) // Order == Month Day { $startDay = ($startDay === FALSE) ? '' : ' ' . $startDay; $startDate = $startMonth . $startDay; if($endMonth) $endDate = $endMonth . $endDay = ($endDay === FALSE) ? '' : ' ' . $endDay; else $endDate = $endDay; } else // Order == Day Month { if($endMonth) { $startDate = $startDay . ' ' . $startMonth; $endDate = $endDay = ($endDay === FALSE) ? '' : $endDay . ' '; $endDate .= $endMonth; } else { $startDate = $startDay; $endDate = ($endDay === FALSE) ? ' ' : $endDay . ' '; $endDate .= $startMonth; } } $date = $startDate . $delimit . $endDate; } $this->item[$this->styleMap->{$type}['date']] = $date; } /** * Format edition * * @author Mark Grimshaw * @version 1 * * @param INT $edition * @return string of edition. */ function formatEdition($edition) { $type = $this->type; if(!is_numeric($edition)) $edition = ($this->output == 'html') ? $this->utf8->utf8_htmlspecialchars($edition) : $edition; else if($this->style['editionFormat']) // 10th $edition = ($this->output == 'html') ? $this->utf8->utf8_htmlspecialchars($this->cardinalToOrdinal($edition)) : $this->cardinalToOrdinal($edition); $this->item[$this->styleMap->{$type}[array_search('edition', $this->styleMap->$type)]] = $edition; } /** * Create ordinal number from cardinal * * @author Mark Grimshaw * @version 1 * * @param $cardinal * @return $ordinal */ function cardinalToOrdinal($cardinal) { $modulo = $cardinal % 100; if(($modulo == 11) || ($modulo == 12) || ($modulo == 13)) return $cardinal . 'th'; $modulo = $cardinal % 10; if(($modulo >= 4) || !$modulo) return $cardinal . 'th'; if($modulo == 1) return $cardinal . 'st'; if($modulo == 2) return $cardinal . 'nd'; if($modulo == 3) return $cardinal . 'rd'; } /** * Month arrays * @author Mark Grimshaw * @version 1 */ function loadArrays() { $this->longMonth = array( 1 => 'January', 2 => 'February', 3 => 'March', 4 => 'April', 5 => 'May', 6 => 'June', 7 => 'July', 8 => 'August', 9 => 'September', 10 => 'October', 11 => 'November', 12 => 'December', ); $this->shortMonth = array( 1 => 'Jan', 2 => 'Feb', 3 => 'Mar', 4 => 'Apr', 5 => 'May', 6 => 'Jun', 7 => 'Jul', 8 => 'Aug', 9 => 'Sep', 10 => 'Oct', 11 => 'Nov', 12 => 'Dec', ); } /* * convertEntry - convert any laTeX code and convert to UTF-8 ready for storing in the database * * @author Mark Grimshaw, modified by Christophe Ambroise 26/10/2003 * @param array $entry - a bibtex entry * @return $entry converted to utf8 */ function convertEntry($entry) { $this->config = new BIBTEXCONFIG(); $this->config->bibtex(); // Construction of the transformation filter foreach($this->config->bibtexSpCh as $key => $value) { $replaceBibtex[] = chr($key); $matchBibtex[] = preg_quote("/$value/"); } foreach($this->config->bibtexSpChOld as $key => $value) { $replaceBibtex[] = chr($key); $matchBibtex[] = preg_quote("/$value/"); } foreach($this->config->bibtexSpChOld2 as $key => $value) { $replaceBibtex[] = chr($key); $matchBibtex[] = preg_quote("/$value/"); } foreach($this->config->bibtexSpChLatex as $key => $value) { $replaceBibtex[] = chr($key); $matchBibtex[] = preg_quote("/$value/"); } // Processing of the entry foreach($entry as $key => $value){ // The transformation filter has returned latin1 code // We thus need to work with latin1. $value= $this->utf8->smartUtf8_decode($value); $entry[$key] = utf8_encode(preg_replace($matchBibtex, $replaceBibtex, $value)); } return $entry; } } /***** * BIBTEXCONFIG: BibTeX Configuration class *****/ class BIBTEXCONFIG { // Constructor function BIBTEXCONFIG() { } // BibTeX arrays function bibtex() { $this->bibtexSpCh = array( // Deal with '{' and '}' first! 0x007B => "\\textbraceleft", 0x007D => "\\textbraceright", 0x0022 => "{\"}", 0x0023 => "{\#}", 0x0025 => "{\%}", 0x0026 => "{\&}", 0x003C => "\\textless", 0x003E => "\\textgreater", 0x005F => "{\_}", 0x00A3 => "\\textsterling", 0x00C0 => "{\`A}", 0x00C1 => "{\'A}", 0x00C2 => "{\^A}", 0x00C3 => "{\~A}", 0x00C4 => '{\"A}', 0x00C5 => "{\AA}", 0x00C6 => "{\AE}", 0x00C7 => "{\c{C}}", 0x00C8 => "{\`E}", 0x00C9 => "{\'E}", 0x00CA => "{\^E}", 0x00CB => '{\"E}', 0x00CC => "{\`I}", 0x00CD => "{\'I}", 0x00CE => "{\^I}", 0x00CF => '{\"I}', 0x00D1 => "{\~N}", 0x00D2 => "{\`O}", 0x00D3 => "{\'O}", 0x00D4 => "{\^O}", 0x00D5 => "{\~O}", 0x00D6 => '{\"O}', 0x00D8 => "{\O}", 0x00D9 => "{\`U}", 0x00DA => "{\'U}", 0x00DB => "{\^U}", 0x00DC => '{\"U}', 0x00DD => "{\'Y}", 0x00DF => "{\ss}", 0x00E0 => "{\`a}", 0x00E1 => "{\'a}", 0x00E2 => "{\^a}", 0x00E3 => "{\~a}", 0x00E4 => '{\"a}', 0x00E5 => "{\aa}", 0x00E6 => "{\ae}", 0x00E7 => "{\c{c}}", 0x00E8 => "{\`e}", 0x00E9 => "{\'e}", 0x00EA => "{\^e}", 0x00EB => '{\"e}', 0x00EC => "{\`\i}", 0x00ED => "{\'\i}", 0x00EE => "{\^\i}", 0x00EF => '{\"\i}', 0x00F1 => "{\~n}", 0x00F2 => "{\`o}", 0x00F3 => "{\'o}", 0x00F4 => "{\^o}", 0x00F5 => "{\~o}", 0x00F6 => '{\"o}', 0x00F8 => "{\o}", 0x00F9 => "{\`u}", 0x00FA => "{\'u}", 0x00FB => "{\^u}", 0x00FC => '{\"u}', 0x00FD => "{\'y}", 0x00FF => '{\"y}', 0x00A1 => "{\!}", 0x00BF => "{\?}", ); //Old style with extra {} - usually array_flipped $this->bibtexSpChOld = array( 0x00C0 => "{\`{A}}", 0x00C1 => "{\'{A}}", 0x00C2 => "{\^{A}}", 0x00C3 => "{\~{A}}", 0x00C4 => '{\"{A}}', 0x00C5 => "{\A{A}}", 0x00C6 => "{\A{E}}", 0x00C7 => "{\c{C}}", 0x00C8 => "{\`{E}}", 0x00C9 => "{\'{E}}", 0x00CA => "{\^{E}}", 0x00CB => '{\"{E}}', 0x00CC => "{\`{I}}", 0x00CD => "{\'{I}}", 0x00CE => "{\^{I}}", 0x00CF => '{\"{I}}', 0x00D1 => "{\~{N}}", 0x00D2 => "{\`{O}}", 0x00D3 => "{\'{O}}", 0x00D4 => "{\^{O}}", 0x00D5 => "{\~{O}}", 0x00D6 => '{\"{O}}', 0x00D8 => "{\{O}}", 0x00D9 => "{\`{U}}", 0x00DA => "{\'{U}}", 0x00DB => "{\^{U}}", 0x00DC => '{\"{U}}', 0x00DD => "{\'{Y}}", 0x00DF => "{\s{s}}", 0x00E0 => "{\`{a}}", 0x00E1 => "{\'{a}}", 0x00E2 => "{\^{a}}", 0x00E3 => "{\~{a}}", 0x00E4 => '{\"{a}}', 0x00E5 => "{\a{a}}", 0x00E6 => "{\a{e}}", 0x00E7 => "{\c{c}}", 0x00E8 => "{\`{e}}", 0x00E9 => "{\'{e}}", 0x00EA => "{\^{e}}", 0x00EB => '{\"{e}}', 0x00EC => "{\`\i}", 0x00ED => "{\'\i}", 0x00EE => "{\^\i}", 0x00EF => '{\"\i}', 0x00F1 => "{\~{n}}", 0x00F2 => "{\`{o}}", 0x00F3 => "{\'{o}}", 0x00F4 => "{\^{o}}", 0x00F5 => "{\~{o}}", 0x00F6 => '{\"{o}}', 0x00F8 => "{\{o}}", 0x00F9 => "{\`{u}}", 0x00FA => "{\'{u}}", 0x00FB => "{\^{u}}", 0x00FC => '{\"{u}}', 0x00FD => "{\'{y}}", 0x00FF => '{\"{y}}', 0x00A1 => "{\{!}}", 0x00BF => "{\{?}}", ); // And there's more?!?!?!?!? (This is not strict bibtex.....) $this->bibtexSpChOld2 = array( 0x00C0 => "\`{A}", 0x00C1 => "\'{A}", 0x00C2 => "\^{A}", 0x00C3 => "\~{A}", 0x00C4 => '\"{A}', 0x00C5 => "\A{A}", 0x00C6 => "\A{E}", 0x00C7 => "\c{C}", 0x00C8 => "\`{E}", 0x00C9 => "\'{E}", 0x00CA => "\^{E}", 0x00CB => '\"{E}', 0x00CC => "\`{I}", 0x00CD => "\'{I}", 0x00CE => "\^{I}", 0x00CF => '\"{I}', 0x00D1 => "\~{N}", 0x00D2 => "\`{O}", 0x00D3 => "\'{O}", 0x00D4 => "\^{O}", 0x00D5 => "\~{O}", 0x00D6 => '\"{O}', 0x00D8 => "\{O}", 0x00D9 => "\`{U}", 0x00DA => "\'{U}", 0x00DB => "\^{U}", 0x00DC => '\"{U}', 0x00DD => "\'{Y}", 0x00DF => "\s{s}", 0x00E0 => "\`{a}", 0x00E1 => "\'{a}", 0x00E2 => "\^{a}", 0x00E3 => "\~{a}", 0x00E4 => '\"{a}', 0x00E5 => "\a{a}", 0x00E6 => "\a{e}", 0x00E7 => "\c{c}", 0x00E8 => "\`{e}", 0x00E9 => "\'{e}", 0x00EA => "\^{e}", 0x00EB => '\"{e}', 0x00EC => "\`{i}", 0x00ED => "\'{i}", 0x00EE => "\^{i}", 0x00EF => '\"{i}', 0x00F1 => "\~{n}", 0x00F2 => "\`{o}", 0x00F3 => "\'{o}", 0x00F4 => "\^{o}", 0x00F5 => "\~{o}", 0x00F6 => '\"{o}', 0x00F8 => "\{o}", 0x00F9 => "\`{u}", 0x00FA => "\'{u}", 0x00FB => "\^{u}", 0x00FC => '\"{u}', 0x00FD => "\'{y}", 0x00FF => '\"{y}', 0x00A1 => "\{!}", 0x00BF => "\{?}", ); // Latex code that some bibtex users may be using $this->bibtexSpChLatex = array( 0x00C0 => "\`A", 0x00C1 => "\'A", 0x00C2 => "\^A", 0x00C3 => "\~A", 0x00C4 => '\"A', 0x00C5 => "\AA", 0x00C6 => "\AE", 0x00C7 => "\cC", 0x00C8 => "\`E", 0x00C9 => "\'E", 0x00CA => "\^E", 0x00CB => '\"E', 0x00CC => "\`I", 0x00CD => "\'I", 0x00CE => "\^I", 0x00CF => '\"I', 0x00D1 => "\~N", 0x00D2 => "\`O", 0x00D3 => "\'O", 0x00D4 => "\^O", 0x00D5 => "\~O", 0x00D6 => '\"O', 0x00D8 => "\O", 0x00D9 => "\`U", 0x00DA => "\'U", 0x00DB => "\^U", 0x00DC => '\"U', 0x00DD => "\'Y", 0x00DF => "\ss", 0x00E0 => "\`a", 0x00E1 => "\'a", 0x00E2 => "\^a", 0x00E3 => "\~a", 0x00E4 => '\"a', 0x00E5 => "\aa", 0x00E6 => "\ae", 0x00E7 => "\cc", 0x00E8 => "\`e", 0x00E9 => "\'e", 0x00EA => "\^e", 0x00EB => '\"e', 0x00EC => "\`i", 0x00ED => "\'i", 0x00EE => "\^i", 0x00EF => '\"i', 0x00F1 => "\~n", 0x00F2 => "\`o", 0x00F3 => "\'o", 0x00F4 => "\^o", 0x00F5 => "\~o", 0x00F6 => '\"o', 0x00F8 => "\o", 0x00F9 => "\`u", 0x00FA => "\'u", 0x00FB => "\^u", 0x00FC => '\"u', 0x00FD => "\'y", 0x00FF => '\"y', 0x00A1 => "\!", 0x00BF => "\?", ); $this->bibtexSpChPlain = array( 0x00C0 => "A", 0x00C1 => "A", 0x00C2 => "A", 0x00C3 => "A", 0x00C4 => 'A', 0x00C5 => "A", 0x00C6 => "AE", 0x00C7 => "C", 0x00C8 => "E", 0x00C9 => "E", 0x00CA => "E", 0x00CB => 'E', 0x00CC => "I", 0x00CD => "I", 0x00CE => "I", 0x00CF => 'I', 0x00D1 => "N", 0x00D2 => "O", 0x00D3 => "O", 0x00D4 => "O", 0x00D5 => "O", 0x00D6 => 'O', 0x00D8 => "O", 0x00D9 => "U", 0x00DA => "U", 0x00DB => "U", 0x00DC => 'U', 0x00DD => "Y", 0x00DF => "ss", 0x00E0 => "a", 0x00E1 => "a", 0x00E2 => "a", 0x00E3 => "a", 0x00E4 => 'a', 0x00E5 => "aa", 0x00E6 => "ae", 0x00E7 => "c", 0x00E8 => "e", 0x00E9 => "e", 0x00EA => "e", 0x00EB => 'e', 0x00EC => "i", 0x00ED => "i", 0x00EE => "i", 0x00EF => 'i', 0x00F1 => "n", 0x00F2 => "o", 0x00F3 => "o", 0x00F4 => "o", 0x00F5 => "o", 0x00F6 => 'o', 0x00F8 => "o", 0x00F9 => "u", 0x00FA => "u", 0x00FB => "u", 0x00FC => 'u', 0x00FD => "u", 0x00FF => 'u', 0x00A1 => "u", 0x00BF => "u", ); } } ?>