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
3 years ago
|
<?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;
|
||
|
}
|