You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
250 lines
7.9 KiB
250 lines
7.9 KiB
<?php |
|
|
|
/** |
|
* @file |
|
* Implementation of some citeproc alters. |
|
*/ |
|
|
|
/** |
|
* Implements citeproc_convert_mods_to_citeproc_jsons_alter |
|
* |
|
* @param $output |
|
* @param $mods |
|
*/ |
|
function udm_citeproc_convert_mods_to_citeproc_jsons_alter(&$output, $mods) { |
|
module_load_include('inc', 'citeproc', 'includes/converter'); |
|
if(empty($output['author'])){ |
|
$names = udm_convert_mods_to_citeproc_json_names($mods); |
|
$output = array_merge($output, $names); |
|
} |
|
} |
|
|
|
/** |
|
* Gets the type property for the Citation. |
|
* |
|
* There are a number of name-type vars which may be populated. |
|
* We will concern ourselves with the following: |
|
* 1. Author |
|
* 2. Editor |
|
* 3. Translator |
|
* There is no CSL var for "contributor", we will treat them as additional |
|
* authors. |
|
* |
|
* Each name may be either "corporate" or "given name / family name" |
|
* |
|
* As it's unlikely we'll have participles, suffixes, etc properly parsed |
|
* out, we will always pass the ("parse-names" : "true") flag with personal |
|
* names. |
|
* |
|
* mods namepart types (given, family) correspond to citeproc elements, |
|
* however, more precise mods elements (nonsort, etc.) do not. |
|
* @todo Make all name handling better. |
|
* |
|
* NAME(s) of RELATED ITEMS (host, series) |
|
* Zotero vs Bibutils do this a bit differently, but in bibutils it's common for |
|
* the editor of a book (containing a chapter, which is our bibliographic item) |
|
* to be associated with the relatedItem(host). |
|
* Also It'S A Shot In The Dark, But |
|
* Relateditem(series)->name->role->roleTerm=editor is plausible. |
|
* |
|
* Note also this section is *highly* repetitive of the section above and this |
|
* should probably be generalized, but for now a strict procedural reckoning |
|
* will have to suffice. The difference is in the very last section, where the |
|
* appropriate cs:names type is specified. |
|
* |
|
* @param SimpleXMLElement $mods |
|
* A MODS document. |
|
* |
|
* @return string |
|
* The type property for the Citation. |
|
*/ |
|
function udm_convert_mods_to_citeproc_json_names(SimpleXMLElement $mods) { |
|
$queries = array( |
|
0 => array( |
|
// Path. |
|
variable_get('islandora_scholar_xpaths_local_author', '//mods:mods[1]/mods:name[normalize-space(mods:namePart)]'), |
|
// Default Role. |
|
'author', |
|
// Valid Roles. |
|
array( |
|
'editor' => 'editor', |
|
'translator' => 'translator', |
|
'interviewer' => 'interviewer', |
|
'composer' => 'composer', |
|
'original' => 'original-author', |
|
'recipient' => 'recipient', |
|
'author' => 'author', |
|
), |
|
), |
|
1 => array( |
|
variable_get('islandora_scholar_xpaths_local_container-author', '//mods:mods[1]/mods:relatedItem[@type="host"]/mods:name'), |
|
'container-author', |
|
array( |
|
'editor' => 'editor', |
|
'translator' => 'translator', |
|
'author' => 'container-author', |
|
), |
|
), |
|
2 => array( |
|
variable_get('islandora_scholar_xpaths_local_collection-editor', '//mods:mods[1]/mods:relatedItem[@type="series"]/mods:name'), |
|
NULL, |
|
array( |
|
'editor' => 'collection-editor', |
|
), |
|
), |
|
); |
|
$output = array(); |
|
foreach ($queries as $query) { |
|
list($path, $default_role, $valid_roles) = $query; |
|
$names = $mods->xpath($path); |
|
if (!empty($names)) { |
|
foreach ($names as $name) { |
|
|
|
add_mods_namespace($name); |
|
$role = udm_convert_mods_to_citeproc_json_name_role($name, $valid_roles, $default_role); |
|
if ($role !== FALSE) { |
|
$parsed_name = udm_convert_mods_to_citeproc_json_name($name); |
|
|
|
if ($parsed_name) { |
|
$output[$role][] = $parsed_name; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
return $output; |
|
} |
|
|
|
/** |
|
* Gets the array repersentation of the javascript Citation's name properties. |
|
* |
|
* @param SimpleXMLElement $name |
|
* A name element. |
|
* |
|
* @return array |
|
* An array that embodies the name properties of a Citation javascript object. |
|
*/ |
|
function udm_convert_mods_to_citeproc_json_name(SimpleXMLElement $name) { |
|
$type = (string) $name->attributes()->type; |
|
$output = ($type == 'personal') ? |
|
udm_convert_mods_to_citeproc_json_name_personal($name) : |
|
udm_convert_mods_to_citeproc_json_name_corporate($name); |
|
|
|
$output = array_map('trim', $output); |
|
$output = array_map('ucfirst', $output); |
|
$output = array_filter($output); |
|
return $output; |
|
} |
|
|
|
/** |
|
* Gets the array repersentation of the Citation's personal name properties. |
|
* |
|
* @param SimpleXMLElement $name |
|
* A name element. |
|
* |
|
* @return array |
|
* An array that embodies the name properties of a Citation javascript object. |
|
*/ |
|
function udm_convert_mods_to_citeproc_json_name_personal(SimpleXMLElement $name) { |
|
$output = array(); |
|
$name_parts = $name->xpath('mods:namePart'); |
|
|
|
foreach ($name_parts as $name_part) { |
|
$type = (string) $name_part->attributes()->type; |
|
$content = (string) $name_part; |
|
|
|
// If the type is empty, it is a combined name last, first. |
|
if (empty($type)) { |
|
// Filter empty things out of the output, so we may potentially replace |
|
// them. |
|
$output = array_filter(array_map('trim', $output)); |
|
|
|
$names = array_map('trim', explode(',', $content)); |
|
$exploded = array(); |
|
$exploded['family'] = array_shift($names); |
|
$exploded['given'] = array_shift($names); |
|
|
|
// If we appear to have a family (and potentially given) name part in our |
|
// combined field and are not currently outputting them, make them get |
|
// output. |
|
// XXX: May combine unexpectedly in the case a "given" typed part name is |
|
// specified, and our untyped field only contains a "family" name. |
|
$non_empty = array_filter($exploded); |
|
$parts_not_present = array_diff_key($non_empty, $output); |
|
if (!empty($parts_not_present)) { |
|
$output = $non_empty + $output; |
|
} |
|
} |
|
else { |
|
// Throw a period after single character values, as they likely represent |
|
// initials. |
|
$content .= (strlen($content) == 1) ? '. ' : ' '; |
|
$output[$type] = isset($output[$type]) ? |
|
$output[$type] . $content : |
|
$content; |
|
} |
|
} |
|
return $output; |
|
} |
|
|
|
/** |
|
* Gets the array repersentation of the Citation's corporate name properties. |
|
* |
|
* @param SimpleXMLElement $name |
|
* A name element. |
|
* |
|
* @return array |
|
* An array that embodies the name properties of a Citation javascript object. |
|
*/ |
|
function udm_convert_mods_to_citeproc_json_name_corporate(SimpleXMLElement $name) { |
|
$output = array(); |
|
$name_parts = $name->xpath(variable_get('islandora_scholar_xpaths_local_author', 'mods:namePart')); |
|
foreach ($name_parts as $name_part) { |
|
$content = (string) $name_part . ' '; |
|
$output['literal'] = isset($output['literal']) ? $output['literal'] . $content : $content; |
|
} |
|
return $output; |
|
} |
|
|
|
|
|
|
|
/** |
|
* Gets the role for the given name element. |
|
* |
|
* If no role can be determined it returns 'author' as a default. |
|
* |
|
* @param SimpleXMLElement $name |
|
* A MODS name element. |
|
* @param array $valid_roles |
|
* A map of mods role names to their citeproc equivalents. |
|
* @param string $default_role |
|
* The role to use if a valid role is not found. |
|
* |
|
* @return string |
|
* Gets the role of the given name. |
|
*/ |
|
function udm_convert_mods_to_citeproc_json_name_role(SimpleXMLElement $name, array $valid_roles, $default_role) { |
|
module_load_include('inc', 'citeproc', 'includes/marcrelator_conversion'); |
|
$role_term = $name->xpath(variable_get('islandora_scholar_xpaths_role_term', 'mods:role/mods:roleTerm')); |
|
|
|
if (isset($role_term[0])) { |
|
$role = strtolower((string) $role_term[0]); |
|
$role_term = $role_term[0]; |
|
} |
|
else { |
|
$role = NULL; |
|
} |
|
|
|
if ($role) { |
|
$role_authority = (string) $role_term->attributes()->authority; |
|
$role_type = (string) $role_term->attributes()->type; |
|
|
|
if ($role_authority == 'marcrelator' && $role_type == 'code') { |
|
$role = marcrelator_code_to_term($role); |
|
} |
|
$role = ($role == 'auteur') ? 'author' : $role; |
|
|
|
return array_key_exists($role, $valid_roles) ? $valid_roles[$role] : FALSE; |
|
} |
|
return $default_role; |
|
} |