CiteProc - PHP
A PHP implementation of the CSL citation processor "CiteProc"
|
00001 <?php 00002 // $Id: _cite_proc_8php_source.html,v 1.2 2012-12-13 16:04:54 sbo Exp $ 00023 class citeproc { 00024 public $bibliography; 00025 public $citation; 00026 public $style; 00027 protected $macros; 00028 private $info; 00029 protected $locale; 00030 protected $style_locale; 00031 private $mapper = NULL; 00032 00033 function __construct($csl = NULL, $lang = 'en') { 00034 if ($csl) { 00035 $this->init($csl, $lang); 00036 } 00037 } 00038 00039 function init($csl, $lang) { 00040 // define field values appropriate to your data in the csl_mapper class and un-comment the next line. 00041 //$this->mapper = new csl_mapper(); 00042 00043 $csl_doc = new DOMDocument(); 00044 00045 if ($csl_doc->loadXML($csl)) { 00046 00047 $style_nodes = $csl_doc->getElementsByTagName('style'); 00048 if ($style_nodes) { 00049 foreach ($style_nodes as $style) { 00050 $this->style = new csl_style($style); 00051 } 00052 } 00053 00054 $info_nodes = $csl_doc->getElementsByTagName('info'); 00055 if ($info_nodes) { 00056 foreach ($info_nodes as $info) { 00057 $this->info = new csl_info($info); 00058 } 00059 } 00060 00061 $this->locale = new csl_locale($lang); 00062 $this->locale->set_style_locale($csl_doc); 00063 00064 00065 $macro_nodes = $csl_doc->getElementsByTagName('macro'); 00066 if ($macro_nodes) { 00067 $this->macros = new csl_macros($macro_nodes, $this); 00068 } 00069 00070 $citation_nodes = $csl_doc->getElementsByTagName('citation'); 00071 foreach ($citation_nodes as $citation) { 00072 $this->citation = new csl_citation($citation, $this); 00073 } 00074 00075 $bibliography_nodes = $csl_doc->getElementsByTagName('bibliography'); 00076 foreach ($bibliography_nodes as $bibliography) { 00077 $this->bibliography = new csl_bibliography($bibliography, $this); 00078 } 00079 } 00080 } 00081 function render($data) { 00082 $text = ''; 00083 // $text .= (isset($this->citation))? $this->citation->render($data) : ''; 00084 $text .= (isset($this->bibliography))? $this->bibliography->render($data) : ''; 00085 return $text; 00086 } 00087 00088 function render_macro($name, $data, $mode) { 00089 return $this->macros->render_macro($name, $data, $mode); 00090 } 00091 00092 function get_locale($type, $arg1, $arg2 = NULL, $arg3 = NULL) { 00093 return $this->locale->get_locale($type, $arg1, $arg2, $arg3); 00094 } 00095 00096 function map_field($field) { 00097 if ($this->mapper) { 00098 return $this->mapper->map_field($field); 00099 } 00100 return ($field); 00101 } 00102 function map_type($field) { 00103 if ($this->mapper) { 00104 return $this->mapper->map_type($field); 00105 } 00106 return ($field); 00107 } 00108 } 00109 00110 class csl_factory { 00111 public static function create($dom_node, $citeproc = NULL) { 00112 $class_name = 'csl_' . str_replace('-', '_', $dom_node->nodeName); 00113 if (class_exists($class_name)) { 00114 return new $class_name($dom_node, $citeproc); 00115 } 00116 else { 00117 return NULL; 00118 } 00119 } 00120 } 00121 00122 class csl_collection { 00123 protected $elements = array(); 00124 00125 function add_element($elem) { 00126 $this->elements[] = $elem; 00127 } 00128 00129 function render($data, $mode) {} 00130 00131 function format($text) {return $text;} 00132 00133 } 00134 00135 class csl_element extends csl_collection { 00136 protected $attributes = array(); 00137 protected $citeproc; 00138 00139 function __construct($dom_node = NULL, $citeproc = NULL) { 00140 00141 $this->citeproc = &$citeproc; 00142 $this->attributes = $this->set_attributes($dom_node); 00143 $this->init($dom_node, $citeproc); 00144 00145 } 00146 00147 function init($dom_node, $citeproc) { 00148 if (!$dom_node) return; 00149 00150 foreach ($dom_node->childNodes as $node) { 00151 if ($node->nodeType == 1) { 00152 $this->add_element(csl_factory::create($node, $citeproc)); 00153 } 00154 } 00155 } 00156 00157 function set_attribute($name, $value) { 00158 $this->attributes[$name] = $value; 00159 } 00160 00161 function set_attributes($dom_node) { 00162 $att = array(); 00163 $element_name = $dom_node->nodeName; 00164 if (isset($dom_node->attributes->length)) { 00165 for ($i=0; $i < $dom_node->attributes->length; $i++) { 00166 $value = $dom_node->attributes->item($i)->value; 00167 $name = str_replace(' ', '_', $dom_node->attributes->item($i)->name); 00168 if ($name == 'type' ) { 00169 $value = $this->citeproc->map_type($value); 00170 } 00171 00172 if (($name == 'variable' || $name == 'is-numeric') && $element_name != 'label') { 00173 $value = $this->citeproc->map_field($value); 00174 } 00175 $att[$name] = $value; 00176 } 00177 } 00178 return $att; 00179 } 00180 00181 function get_attributes($name = NULL) { 00182 if ($name) { 00183 return (isset($this->attributes[$name])) ? $this->attributes[$name] : NULL; 00184 } 00185 else { 00186 return $this->attributes; 00187 } 00188 } 00189 00190 function get_hier_attributes() { 00191 $hier_attr = array(); 00192 $hier_names = array('and', 'delimiter-precedes-last', 'et-al-min', 'et-al-use-first', 00193 'et-al-subsequent-min', 'et-al-subsequent-use-first', 'initialize-with', 00194 'name-as-sort-order', 'sort-separator', 'name-form', 'name-delimiter', 00195 'names-delimiter'); 00196 foreach ($hier_names as $name) { 00197 if (isset($this->attributes[$name])) { 00198 $hier_attr[$name] = $this->attributes[$name]; 00199 } 00200 } 00201 return $hier_attr; 00202 } 00203 00204 function name($name = NULL) { 00205 if ($name) { 00206 $this->attributes['name'] = $name; 00207 } 00208 else { 00209 return str_replace(' ', '_', $this->attributes['name']); 00210 } 00211 } 00212 00213 } 00214 00215 class csl_rendering_element extends csl_element { 00216 00217 function render($data, $mode = NULL) { 00218 $text = ''; 00219 $text_parts = array(); 00220 00221 $delim = $this->get_attributes('delimiter'); 00222 foreach ($this->elements as $element) { 00223 $text_parts[] = $element->render($data, $mode); 00224 } 00225 $text = implode($delim, $text_parts); // insert the delimiter if supplied. 00226 00227 return $this->format($text); 00228 } 00229 00230 } 00231 00232 class csl_format extends csl_rendering_element { 00233 protected $no_op; 00234 protected $format; 00235 00236 function __construct($dom_node = NULL, $citeproc = NULL) { 00237 parent::__construct($dom_node, $citeproc); 00238 $this->init_formatting(); 00239 } 00240 00241 function init_formatting() { 00242 $this->no_op = TRUE; 00243 $this->format = ''; 00244 if (isset($this->attributes['quotes'])) { 00245 $this->attributes['quotes'] = array(); 00246 $this->attributes['quotes']['punctuation-in-quote'] = $this->citeproc->get_locale('style_option', 'punctuation-in-quote'); 00247 $this->attributes['quotes']['open-quote'] = $this->citeproc->get_locale('term', 'open-quote'); 00248 $this->attributes['quotes']['close-quote'] = $this->citeproc->get_locale('term', 'close-quote'); 00249 $this->attributes['quotes']['open-inner-quote'] = $this->citeproc->get_locale('term', 'open-inner-quote'); 00250 $this->attributes['quotes']['close-inner-quote'] = $this->citeproc->get_locale('term', 'close-inner-quote'); 00251 $this->no_op = FALSE; 00252 } 00253 if (isset($this->attributes['prefix'])) $this->no_op = FALSE; 00254 if (isset($this->attributes['suffix'])) $this->no_op = FALSE; 00255 if (isset($this->attributes['display'])) $this->no_op = FALSE; 00256 00257 $this->format .= (isset($this->attributes['font-style'])) ? 'font-style: ' . $this->attributes['font-style'] . ';' : ''; 00258 $this->format .= (isset($this->attributes['font-family'])) ? 'font-family: ' . $this->attributes['font-family'] . ';' : ''; 00259 $this->format .= (isset($this->attributes['font-weight'])) ? 'font-weight: ' . $this->attributes['font-weight'] . ';' : ''; 00260 $this->format .= (isset($this->attributes['font-variant'])) ? 'font-variant: ' . $this->attributes['font-variant'] . ';' : ''; 00261 $this->format .= (isset($this->attributes['text-decoration'])) ? 'text-decoration: ' . $this->attributes['text-decoration'] . ';' : ''; 00262 $this->format .= (isset($this->attributes['vertical-align'])) ? 'vertical-align: ' . $this->attributes['vertical-align'] . ';' : ''; 00263 // $this->format .= (isset($this->attributes['display']) && $this->attributes['display'] == 'indent') ? 'padding-left: 25px;' : ''; 00264 00265 if (isset($this->attributes['text-case']) || !empty($this->format)) $this->no_op = FALSE; 00266 00267 } 00268 00269 function format($text) { 00270 00271 if (empty($text) || $this->no_op) return $text; 00272 if (isset($this->attributes['text-case'])) { 00273 switch ($this->attributes['text-case']) { 00274 case 'uppercase': 00275 $text = mb_strtoupper($text); 00276 break; 00277 case 'lowercase': 00278 $text = mb_strtolower($text); 00279 break; 00280 case 'capitalize-all': 00281 case 'title': 00282 $text = mb_convert_case($text, MB_CASE_TITLE); 00283 break; 00284 case 'capitalize-first': 00285 $text[0] = mb_strtoupper($text[0]); 00286 break; 00287 } 00288 } 00289 $open_quote = (isset($this->attributes['quotes']['open-quote'])) ? $this->attributes['quotes']['open-quote'] : ''; 00290 $close_quote = (isset($this->attributes['quotes']['close-quote'])) ? $this->attributes['quotes']['close-quote'] : ''; 00291 $prefix = (isset($this->attributes['prefix'])) ? $this->attributes['prefix'] . $open_quote : '' . $open_quote; 00292 $suffix = (isset($this->attributes['suffix'])) ? $this->attributes['suffix'] : ''; 00293 if ($close_quote && !empty($suffix) && $this->attributes['quotes']['punctuation-in-quote']) { 00294 if (strpos($suffix, '.') !== FALSE || strpos($suffix, ',') !== FALSE) { 00295 $suffix = $suffix . $close_quote; 00296 } 00297 } 00298 elseif ($close_quote) { 00299 $suffix = $close_quote . $suffix; 00300 } 00301 elseif (!empty($suffix)) { 00302 if ($text[(strlen($text)-1)] == $suffix[0]) $text = substr($text, 0, -1); 00303 } 00304 00305 if (!empty($this->format)) { 00306 $text = '<span style="' . $this->format . '">' . $text . '</span>'; 00307 } 00308 if (isset($this->attributes['display']) && $this->attributes['display'] == 'indent') { 00309 return '<div style="text-indent: 0px; padding-left: 45px;">' . $prefix . $text . $suffix . '</div>'; 00310 } 00311 00312 return $prefix . $text . $suffix; 00313 } 00314 00315 } 00316 00317 class csl_info { 00318 public $title; 00319 public $id; 00320 public $authors = array(); 00321 public $links = array(); 00322 00323 function __construct($dom_node) { 00324 $name = array(); 00325 foreach ($dom_node->childNodes as $node) { 00326 if ($node->nodeType == 1) { 00327 switch ($node->nodeName) { 00328 case 'author': 00329 case 'contributor': 00330 foreach ($node->childNodes as $authnode) { 00331 if ($node->nodeType == 1) 00332 $name[$authnode->nodeName] = $authnode->nodeValue; 00333 } 00334 $this->authors[] = $name; 00335 break; 00336 case 'link': 00337 foreach ($node->attributes as $attribute) { 00338 $this->links[] = $attribute->value; 00339 } 00340 break; 00341 default: 00342 $this->{$node->nodeName} = $node->nodeValue; 00343 } 00344 } 00345 } 00346 00347 } 00348 } 00349 00350 class csl_terms { 00351 00352 } 00353 00354 class csl_name extends csl_format { 00355 private $name_parts = array(); 00356 private $attr_init = FALSE; 00357 00358 function __construct($dom_node, $citeproc = NULL) { 00359 00360 $tags = $dom_node->getElementsByTagName('name-part'); 00361 if ($tags) { 00362 foreach ($tags as $tag) { 00363 $name_part = $tag->getAttribute('name'); 00364 $tag->removeAttribute('name'); 00365 for ($i=0; $i < $tag->attributes->length; $i++) { 00366 $value = $tag->attributes->item($i)->value; 00367 $name = str_replace(' ', '_', $tag->attributes->item($i)->name); 00368 $this->name_parts[$name_part][$name] = $value; 00369 } 00370 } 00371 } 00372 00373 parent::__construct($dom_node, $citeproc); 00374 } 00375 00376 function init_formatting() { 00377 $this->no_op = array(); 00378 $this->format = array(); 00379 $this->attributes['base'] = $this->get_attributes(); 00380 $this->format['base'] = ''; 00381 $this->format['family'] = ''; 00382 $this->format['given'] = ''; 00383 $this->no_op['base'] = TRUE; 00384 $this->no_op['family'] = TRUE; 00385 $this->no_op['given'] = TRUE; 00386 00387 if (isset($this->attributes['prefix'])) $this->no_op['base'] = FALSE; 00388 if (isset($this->attributes['suffix'])) $this->no_op['base'] = FALSE; 00389 $this->init_format($this->attributes['base']); 00390 00391 00392 if (!empty($this->name_parts)) { 00393 foreach ($this->name_parts as $name => $formatting) { 00394 $this->init_format($formatting, $name); 00395 } 00396 } 00397 } 00398 00399 function init_attrs($mode) { 00400 // $and = $this->get_attributes('and'); 00401 if (isset($this->attributes['and']) && $this->attributes['and'] == 'text') { 00402 $this->attributes['and'] = $this->citeproc->get_locale('term', 'and'); 00403 } 00404 if (isset($this->attributes['and']) && $this->attributes['and'] == 'symbol') { 00405 $this->attributes['and'] = ' & '; 00406 } 00407 if (isset($this->citeproc)) { 00408 $style_attrs = $this->citeproc->style->get_hier_attributes(); 00409 $mode_attrs = $this->citeproc->{$mode}->get_hier_attributes(); 00410 $this->attributes = array_merge($style_attrs, $mode_attrs, $this->attributes); 00411 } 00412 if (!isset($this->attributes['delimiter'])) { 00413 $this->attributes['delimiter'] = (!empty($this->attributes['name-delimiter'])) ? $this->attributes['name-delimiter'] : ', '; 00414 } 00415 if (!isset($this->alnum)) { 00416 list($this->alnum, $this->alpha, $this->cntrl, $this->dash, 00417 $this->digit, $this->graph, $this->lower, $this->print, 00418 $this->punct, $this->space, $this->upper, $this->word, 00419 $this->patternModifiers) = $this->get_regex_patterns(); 00420 } 00421 $this->dpl = $this->get_attributes('delimiter-precedes-last'); 00422 $this->sort_separator = ($this->get_attributes('sort-separator'))? $this->get_attributes('sort-separator') : ', '; 00423 $this->form = ($this->get_attributes('form'))? $this->get_attributes('form') : 'long'; 00424 $this->attr_init = $mode; 00425 } 00426 00427 function init_format($attribs, $part = 'base') { 00428 if (isset($attribs['quotes'])) { 00429 $this->attributes[$part]['open-quote'] = $this->citeproc->get_locale('term', 'open-quote'); 00430 $this->attributes[$part]['close-quote'] = $this->citeproc->get_locale('term', 'close-quote'); 00431 $this->attributes[$part]['open-inner-quote'] = $this->citeproc->get_locale('term', 'open-inner-quote'); 00432 $this->attributes[$part]['close-inner-quote'] = $this->citeproc->get_locale('term', 'close-inner-quote'); 00433 $this->no_op[$part] = FALSE; 00434 } 00435 00436 if (isset($attribs['prefix'])) $this->attributes[$part]['prefix'] = $attribs['prefix']; 00437 if (isset($attribs['suffix'])) $this->attributes[$part]['suffix'] = $attribs['suffix']; 00438 00439 $this->format[$part] .= (isset($attribs['font-style'])) ? 'font-style: ' . $attribs['font-style'] . ';' : ''; 00440 $this->format[$part] .= (isset($attribs['font-family'])) ? 'font-family: ' . $attribs['font-family'] . ';' : ''; 00441 $this->format[$part] .= (isset($attribs['font-weight'])) ? 'font-weight: ' . $attribs['font-weight'] . ';' : ''; 00442 $this->format[$part] .= (isset($attribs['font-variant'])) ? 'font-variant: ' . $attribs['font-variant'] . ';' : ''; 00443 $this->format[$part] .= (isset($attribs['text-decoration'])) ? 'text-decoration: ' . $attribs['text-decoration'] . ';' : ''; 00444 $this->format[$part] .= (isset($attribs['vertical-align'])) ? 'vertical-align: ' . $attribs['vertical-align'] . ';' : ''; 00445 00446 if (isset($attribs['text-case'])) $this->no_op[$part] = FALSE; 00447 if (!empty($this->format[$part])) $this->no_op[$part] = FALSE; 00448 00449 } 00450 00451 function format($text, $part = 'base') { 00452 00453 if (empty($text) || $this->no_op[$part]) return $text; 00454 if (isset($this->attributes[$part]['text-case'])) { 00455 switch ($this->attributes[$part]['text-case']) { 00456 case 'uppercase': 00457 $text = mb_strtoupper($text); 00458 break; 00459 case 'lowercase': 00460 $text = mb_strtolower($text); 00461 break; 00462 case 'capitalize-all': 00463 $text = mb_convert_case($text, MB_CASE_TITLE); 00464 break; 00465 case 'capitalize-first': 00466 $text[0] = mb_strtoupper($text[0]); 00467 break; 00468 } 00469 } 00470 $open_quote = (isset($this->attributes[$part]['open-quote'])) ? $this->attributes[$part]['open-quote'] : ''; 00471 $close_quote = (isset($this->attributes[$part]['close-quote'])) ? $this->attributes[$part]['close-quote'] : ''; 00472 $prefix = (isset($this->attributes[$part]['prefix'])) ? $this->attributes[$part]['prefix'] : ''; 00473 $suffix = (isset($this->attributes[$part]['suffix'])) ? $this->attributes[$part]['suffix'] : ''; 00474 if ($text[(strlen($text) -1)] == $suffix) unset($suffix); 00475 if (!empty($this->format[$part])) { 00476 $text = '<span style="' . $this->format[$part] . '">' . $text . '</span>'; 00477 } 00478 return $prefix . $open_quote . $text . $close_quote . $suffix; 00479 } 00480 00481 function render($names, $mode = NULL) { 00482 $text = ''; 00483 $authors = array(); 00484 $count = 0; 00485 $auth_count = 0; 00486 $et_al_triggered = FALSE; 00487 $initialize_with = $this->get_attributes('initialize-with'); 00488 00489 if (!$this->attr_init || $this->attr_init != $mode) $this->init_attrs($mode); 00490 00491 foreach ($names as $rank => $name) { 00492 $count++; 00493 //$given = (!empty($name->firstname)) ? $name->firstname : ''; 00494 if (!empty($name->given) && isset($initialize_with)) { 00495 $name->given = preg_replace("/([$this->upper])[$this->lower]+/$this->patternModifiers", '\\1', $name->given); 00496 $name->given = preg_replace("/(?<=[-$this->upper]) +(?=[-$this->upper])/$this->patternModifiers", "", $name->given); 00497 $name->initials = $name->given . $name->initials; 00498 } 00499 if (isset($name->initials)) { 00500 // within initials, remove any dots: 00501 $name->initials = preg_replace("/([$this->upper])\.+/$this->patternModifiers", "\\1", $name->initials); 00502 // within initials, remove any spaces *between* initials: 00503 $name->initials = preg_replace("/(?<=[-$this->upper]) +(?=[-$this->upper])/$this->patternModifiers", "", $name->initials); 00504 // within initials, add a space after a hyphen, but only if ... 00505 if (ereg(" $", $initialize_with)) {// ... the delimiter that separates initials ends with a space 00506 $name->initials = preg_replace("/-(?=[$this->upper])/$this->patternModifiers", "- ", $name->initials); 00507 } 00508 // then, separate initials with the specified delimiter: 00509 $name->initials = preg_replace("/([$this->upper])(?=[^$this->lower]+|$)/$this->patternModifiers", "\\1$initialize_with", $name->initials); 00510 00511 // $shortenInitials = (isset($options['numberOfInitialsToKeep'])) ? $options['numberOfInitialsToKeep'] : FALSE; 00512 // if ($shortenInitials) $given = drupal_substr($given, 0, $shortenInitials); 00513 00514 if (isset($initialize_with) ) { 00515 $name->given = $name->initials; 00516 if ($shortenInitials) $name->given = drupal_substr($name->given, 0, $shortenInitials); 00517 } 00518 elseif(!empty($name->given)) { 00519 $name->given = $name->given.' '.$name->initials; 00520 } 00521 elseif(empty($name->given)) { 00522 $name->given = $name->initials; 00523 } 00524 } 00525 00526 00527 if (isset($name->given)) { 00528 $given = $this->format($name->given, 'given'); 00529 } 00530 if(isset($name->family)) { 00531 $name->family = $this->format($name->family, 'family'); 00532 if ($this->get_attributes('form') == 'short') { 00533 $text = $name->family; 00534 } 00535 else { 00536 switch ($this->get_attributes('name-as-sort-order')) { 00537 case 'first': 00538 case 'all': 00539 $text = $name->family . $this->sort_separator . $given; 00540 break; 00541 default: 00542 $text = $given .' '. $name->family ; 00543 } 00544 } 00545 $authors[] = $this->format($text); 00546 } 00547 if (isset($this->attributes['et-al-min']) && $count >= $this->attributes['et-al-min']) break; 00548 } 00549 if (isset($this->attributes['et-al-min']) && 00550 $count >= $this->attributes['et-al-min'] && 00551 isset($this->attributes['et-al-use-first'])) { 00552 if ($this->attributes['et-al-use-first'] < $this->attributes['et-al-min']) { 00553 for ($i = $this->attributes['et-al-use-first']; $i < $count; $i++) { 00554 unset($authors[$i]); 00555 } 00556 } 00557 $authors[] = $this->citeproc->get_locale('term', 'et-al'); 00558 $et_al_triggered = TRUE; 00559 } 00560 00561 if (!empty($authors) && !$et_al_triggered) { 00562 $auth_count = count($authors); 00563 if (isset($this->attributes['and']) && $auth_count > 1) { 00564 $authors[$auth_count-1] = $this->attributes['and'] .' '. $authors[$auth_count-1]; //stick an "and" in front of the last author if "and" is defined 00565 } 00566 } 00567 $text = implode($this->attributes['delimiter'], $authors); 00568 00569 // strip out the last delimiter if not required 00570 if (isset($this->attributes['and']) && $auth_count > 1) { 00571 $last_delim = strrpos($text, $this->attributes['delimiter']); 00572 switch ($this->dpl) { //dpl == delimiter proceeds last 00573 case 'never': 00574 return substr_replace($text, '', $last_delim, strlen($this->attributes['delimiter'])); 00575 break; 00576 case 'contextual': 00577 default: 00578 if ($auth_count < 3) { 00579 return substr_replace($text, '', $last_delim, strlen($this->attributes['delimiter'])); 00580 } 00581 } 00582 } 00583 00584 return $text; 00585 } 00586 00587 function get_regex_patterns() { 00588 // Checks if PCRE is compiled with UTF-8 and Unicode support 00589 if (!@preg_match('/\pL/u', 'a')) { 00590 // probably a broken PCRE library 00591 return $this->get_latin1_regex(); 00592 } 00593 else { 00594 // Unicode safe filter for the value 00595 return $this->get_utf8_regex(); 00596 } 00597 } 00598 00599 function get_latin1_regex() { 00600 $alnum = "[:alnum:]ÄÅÁÀÂÃÇÉÈÊËÑÖØÓÒÔÕÜÚÙÛÍÌÎÏÆäåáàâãçéèêëñöøóòôõüúùûíìîïæÿß"; 00601 // Matches ISO-8859-1 letters: 00602 $alpha = "[:alpha:]ÄÅÁÀÂÃÇÉÈÊËÑÖØÓÒÔÕÜÚÙÛÍÌÎÏÆäåáàâãçéèêëñöøóòôõüúùûíìîïæÿß"; 00603 // Matches ISO-8859-1 control characters: 00604 $cntrl = "[:cntrl:]"; 00605 // Matches ISO-8859-1 dashes & hyphens: 00606 $dash = "-–"; 00607 // Matches ISO-8859-1 digits: 00608 $digit = "[\d]"; 00609 // Matches ISO-8859-1 printing characters (excluding space): 00610 $graph = "[:graph:]ÄÅÁÀÂÃÇÉÈÊËÑÖØÓÒÔÕÜÚÙÛÍÌÎÏÆäåáàâãçéèêëñöøóòôõüúùûíìîïæÿß"; 00611 // Matches ISO-8859-1 lower case letters: 00612 $lower = "[:lower:]äåáàâãçéèêëñöøóòôõüúùûíìîïæÿß"; 00613 // Matches ISO-8859-1 printing characters (including space): 00614 $print = "[:print:]ÄÅÁÀÂÃÇÉÈÊËÑÖØÓÒÔÕÜÚÙÛÍÌÎÏÆäåáàâãçéèêëñöøóòôõüúùûíìîïæÿß"; 00615 // Matches ISO-8859-1 punctuation: 00616 $punct = "[:punct:]"; 00617 // Matches ISO-8859-1 whitespace (separating characters with no visual representation): 00618 $space = "[\s]"; 00619 // Matches ISO-8859-1 upper case letters: 00620 $upper = "[:upper:]ÄÅÁÀÂÃÇÉÈÊËÑÖØÓÒÔÕÜÚÙÛÍÌÎÏÆ"; 00621 // Matches ISO-8859-1 "word" characters: 00622 $word = "_[:alnum:]ÄÅÁÀÂÃÇÉÈÊËÑÖØÓÒÔÕÜÚÙÛÍÌÎÏÆäåáàâãçéèêëñöøóòôõüúùûíìîïæÿß"; 00623 // Defines the PCRE pattern modifier(s) to be used in conjunction with the above variables: 00624 // More info: <http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php> 00625 $patternModifiers = ""; 00626 00627 return array($alnum, $alpha, $cntrl, $dash, $digit, $graph, $lower, 00628 $print, $punct, $space, $upper, $word, $patternModifiers); 00629 00630 } 00631 function get_utf8_regex() { 00632 // Matches Unicode letters & digits: 00633 $alnum = "\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}"; // Unicode-aware equivalent of "[:alnum:]" 00634 // Matches Unicode letters: 00635 $alpha = "\p{Ll}\p{Lu}\p{Lt}\p{Lo}"; // Unicode-aware equivalent of "[:alpha:]" 00636 // Matches Unicode control codes & characters not in other categories: 00637 $cntrl = "\p{C}"; // Unicode-aware equivalent of "[:cntrl:]" 00638 // Matches Unicode dashes & hyphens: 00639 $dash = "\p{Pd}"; 00640 // Matches Unicode digits: 00641 $digit = "\p{Nd}"; // Unicode-aware equivalent of "[:digit:]" 00642 // Matches Unicode printing characters (excluding space): 00643 $graph = "^\p{C}\t\n\f\r\p{Z}"; // Unicode-aware equivalent of "[:graph:]" 00644 // Matches Unicode lower case letters: 00645 $lower = "\p{Ll}\p{M}"; // Unicode-aware equivalent of "[:lower:]" 00646 // Matches Unicode printing characters (including space): 00647 $print = "\P{C}"; // same as "^\p{C}", Unicode-aware equivalent of "[:print:]" 00648 // Matches Unicode punctuation (printing characters excluding letters & digits): 00649 $punct = "\p{P}"; // Unicode-aware equivalent of "[:punct:]" 00650 // Matches Unicode whitespace (separating characters with no visual representation): 00651 $space = "\t\n\f\r\p{Z}"; // Unicode-aware equivalent of "[:space:]" 00652 // Matches Unicode upper case letters: 00653 $upper = "\p{Lu}\p{Lt}"; // Unicode-aware equivalent of "[:upper:]" 00654 // Matches Unicode "word" characters: 00655 $word = "_\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}"; // Unicode-aware equivalent of "[:word:]" (or "[:alnum:]" plus "_") 00656 // Defines the PCRE pattern modifier(s) to be used in conjunction with the above variables: 00657 // More info: <http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php> 00658 $patternModifiers = "u"; // the "u" (PCRE_UTF8) pattern modifier causes PHP/PCRE to treat pattern strings as UTF-8 00659 return array($alnum, $alpha, $cntrl, $dash, $digit, $graph, $lower, 00660 $print, $punct, $space, $upper, $word, $patternModifiers); 00661 } 00662 00663 } 00664 00665 class csl_names extends csl_format { 00666 private $substitutes; 00667 00668 function init($dom_node, $citeproc) { 00669 00670 $tag = $dom_node->getElementsByTagName('substitute')->item(0); 00671 if ($tag) { 00672 $this->substitutes = csl_factory::create($tag, $citeproc); 00673 $dom_node->removeChild($tag); 00674 } 00675 00676 $var = $dom_node->getAttribute('variable'); 00677 foreach ($dom_node->childNodes as $node) { 00678 if ($node->nodeType == 1) { 00679 $element = csl_factory::create($node, $citeproc); 00680 if (($element instanceof csl_label)) $element->set_attribute('variable', $var); 00681 $this->add_element($element); 00682 } 00683 } 00684 } 00685 00686 function render($data, $mode) { 00687 $matches = 0; 00688 $variable_parts = array(); 00689 if (!isset($this->attributes['delimiter'])) { 00690 $style_delimiter = $this->citeproc->style->get_attributes('names-delimiter'); 00691 $mode_delimiter = $this->citeproc->{$mode}->get_attributes('names-delimiter'); 00692 $this->attributes['delimiter'] = (!empty($mode_delimiter)) ? $mode_delimiter : (!empty($style_delimiter)? $style_delimiter : ''); 00693 } 00694 00695 $variables = explode(' ', $this->get_attributes('variable')); 00696 foreach ($variables as $var) { 00697 if (isset($data->{$var}) && (!empty($data->{$var}))) { 00698 $matches++; 00699 break; 00700 } 00701 } 00702 00703 if (!$matches) { // we don't have any primary suspects, so lets check the substitutes... 00704 if (isset($this->substitutes)) { 00705 foreach ($this->substitutes->elements as $element) { 00706 if (($element instanceof csl_names)) { //test to see if any of the other names variables has content 00707 $variables = explode(' ', $element->get_attributes('variable')); 00708 foreach ($variables as $var) { 00709 //list($contributor, $type) = explode(':', $var); 00710 if (isset($data->{$var}) ) { 00711 $matches++; 00712 break; 00713 } 00714 } 00715 } 00716 else { // if it's not a "names" element, just render it 00717 return $element->render($data, $mode); 00718 } 00719 } 00720 } 00721 } 00722 00723 foreach ($variables as $var) { 00724 $text = ''; 00725 if (!empty($data->{$var})) { 00726 foreach ($this->elements as $element) { 00727 $text .= $element->render($data->{$var}, $mode); 00728 } 00729 } 00730 if (!empty($text)) $variable_parts[] = $text; 00731 } 00732 00733 if (!empty($variable_parts)) { 00734 $text = implode($this->attributes['delimiter'], $variable_parts); 00735 return $this->format($text); 00736 } 00737 00738 return ; 00739 } 00740 } 00741 00742 class csl_date extends csl_format { 00743 00744 function init($dom_node, $citeproc) { 00745 $locale_elements = array(); 00746 00747 if ($form = $this->get_attributes('form')) { 00748 $local_date = $this->citeproc->get_locale('date_options', $form); 00749 $dom_elem = dom_import_simplexml($local_date[0]); 00750 if ($dom_elem) { 00751 foreach ($dom_elem->childNodes as $node) { 00752 if ($node->nodeType == 1) { 00753 $locale_elements[] = csl_factory::create($node, $citeproc); 00754 } 00755 } 00756 } 00757 foreach ($dom_node->childNodes as $node) { 00758 if ($node->nodeType == 1) { 00759 $element = csl_factory::create($node, $citeproc); 00760 00761 foreach ($locale_elements as $key => $locale_element) { 00762 if ($locale_element->attributes['name'] == $element->attributes['name']) { 00763 $locale_elements[$key]->attributes = array_merge($locale_element->attributes, $element->attributes); 00764 $locale_elements[$key]->format = $element->format; 00765 break; 00766 } 00767 00768 else { 00769 $locale_elements[] = $element; 00770 } 00771 } 00772 } 00773 } 00774 if ($date_parts = $this->get_attributes("date-parts")) { 00775 $parts = explode('-', $date_parts); 00776 foreach ($locale_elements as $key => $element) { 00777 if (array_search($element->attributes['name'], $parts) === FALSE) { 00778 unset($locale_elements[$key]); 00779 } 00780 } 00781 if (count($locale_elements) != count($parts)) { 00782 foreach ($parts as $part) { 00783 $element = new csl_date_part(); 00784 $element->set_attribute('name', $part); 00785 $locale_elements[] = $element; 00786 } 00787 } 00788 // now re-order the elements 00789 foreach ($parts as $part) { 00790 foreach ($locale_elements as $key => $element) 00791 if ($element->attributes['name'] == $part) { 00792 $this->elements[] = $element; 00793 unset($locale_elements[$key]); 00794 } 00795 } 00796 00797 } 00798 else { 00799 $this->elements = $locale_elements; 00800 } 00801 } 00802 else { 00803 parent::init($dom_node, $citeproc); 00804 } 00805 00806 00807 } 00808 00809 function render($data, $mode) { 00810 $date_parts = array(); 00811 $date = ''; 00812 $text = ''; 00813 00814 if (($var = $this->get_attributes('variable')) && isset($data->{$var})) { 00815 $date = $data->{$var}->{'date-parts'}[0]; 00816 foreach ($this->elements as $element) { 00817 $date_parts[] = $element->render($date, $mode); 00818 } 00819 $text = implode('', $date_parts); 00820 }else { 00821 $text = $this->citeproc->get_locale('term', 'no date'); 00822 } 00823 00824 return $this->format($text); 00825 } 00826 } 00827 00828 class csl_date_part extends csl_format { 00829 00830 function render($date, $mode) { 00831 $text = ''; 00832 00833 switch ($this->get_attributes('name')) { 00834 case 'year': 00835 $text = (isset($date[0])) ? $date[0] : ''; 00836 if ($text > 0 && $text < 500) { 00837 $text = $text . $this->citeproc->get_locale('term', 'ad'); 00838 } 00839 elseif ($text < 0) { 00840 $text = $text * -1; 00841 $text = $text . $this->citeproc->get_locale('term', 'bc'); 00842 } 00843 //return ((isset($this->prefix))? $this->prefix : '') . $date[0] . ((isset($this->suffix))? $this->suffix : ''); 00844 break; 00845 case 'month': 00846 $text = (isset($date[1])) ? $date[1] : ''; 00847 if (empty($text) || $text < 1 || $text > 12) return; 00848 $form = $this->get_attributes('form'); 00849 switch ($form) { 00850 case 'numeric': break; 00851 case 'numeric-leading-zeros': 00852 if ($text < 10) { 00853 $text = '0' . $text; 00854 break; 00855 } 00856 break; 00857 case 'short': 00858 $month = 'month-' . sprintf('%02d', $text); 00859 $text = $this->citeproc->get_locale('term', $month, 'short'); 00860 break; 00861 default: 00862 $month = 'month-' . sprintf('%02d', $text); 00863 $text = $this->citeproc->get_locale('term', $month); 00864 break; 00865 } 00866 break; 00867 case 'day': 00868 $text = (isset($date[2])) ? $date[2] : ''; 00869 break; 00870 } 00871 00872 return $this->format($text); 00873 } 00874 } 00875 00876 class csl_number extends csl_format { 00877 00878 function render($data, $mode) { 00879 $var = $this->get_attributes('variable'); 00880 00881 if (!$var || empty($data->$var)) return; 00882 00883 $form = $this->get_attributes('form'); 00884 00885 switch ($form) { 00886 case 'ordinal': 00887 $text = $this->ordinal($data->$var); 00888 break; 00889 case 'long-ordinal': 00890 $text = $this->long_ordinal($data->$var); 00891 break; 00892 case 'roman': 00893 $text = $this->roman($data->$var); 00894 break; 00895 case 'numeric': 00896 default: 00897 $text = $data->$var; 00898 break; 00899 } 00900 return $this->format($text); 00901 } 00902 00903 function ordinal($num) { 00904 if ( ($num/10)%10 == 1) { 00905 $num .= $this->citeproc->get_locale('term', 'ordinal-04'); 00906 } 00907 elseif ( $num%10 == 1) { 00908 $num .= $this->citeproc->get_locale('term', 'ordinal-01'); 00909 } 00910 elseif ( $num%10 == 2) { 00911 $num .= $this->citeproc->get_locale('term', 'ordinal-02'); 00912 } 00913 elseif ( $num%10 == 3) { 00914 $num .= $this->citeproc->get_locale('term', 'ordinal-03'); 00915 } 00916 else { 00917 $num .= $this->citeproc->get_locale('term', 'ordinal-04'); 00918 } 00919 return $num; 00920 00921 } 00922 00923 function long_ordinal($num) { 00924 $num = sprintf("%02d", $num); 00925 $ret = $this->citeproc->get_locale('term', 'long-ordinal-' . $num); 00926 if (!$ret) { 00927 return $this->ordinal($num); 00928 } 00929 return $ret; 00930 } 00931 00932 function roman($num) { 00933 $ret = ""; 00934 if ($num < 6000) { 00935 $ROMAN_NUMERALS = array( 00936 array( "", "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix" ), 00937 array( "", "x", "xx", "xxx", "xl", "l", "lx", "lxx", "lxxx", "xc" ), 00938 array( "", "c", "cc", "ccc", "cd", "d", "dc", "dcc", "dccc", "cm" ), 00939 array( "", "m", "mm", "mmm", "mmmm", "mmmmm") 00940 ); 00941 $numstr = strrev($num); 00942 $len = strlen($numstr); 00943 for ($pos = 0; $pos < $len; $pos++) { 00944 $n = $numstr[$pos]; 00945 $ret = $ROMAN_NUMERALS[$pos][$n] . $ret; 00946 } 00947 } 00948 00949 return $ret; 00950 } 00951 00952 } 00953 00954 class csl_text extends csl_format { 00955 public $source; 00956 protected $var; 00957 00958 function init($dom_node, $citeproc) { 00959 foreach (array('variable', 'macro', 'term', 'value') as $attr) { 00960 if ($dom_node->hasAttribute($attr)) { 00961 $this->source = $attr; 00962 if ($this->source == 'macro') { 00963 $this->var = str_replace(' ', '_', $dom_node->getAttribute($attr)); 00964 } 00965 else { 00966 $this->var = $dom_node->getAttribute($attr); 00967 } 00968 } 00969 } 00970 } 00971 00972 function render($data, $mode) { 00973 $text = ''; 00974 00975 switch ($this->source) { 00976 case 'variable': 00977 if(!isset($data->{$this->attributes['variable']})) return; 00978 $text = $data->{$this->attributes['variable']}; //$this->data[$this->var]; // include the contents of a variable 00979 break; 00980 case 'macro': 00981 $macro = $this->var; 00982 $text = $this->citeproc->render_macro($macro, $data, $mode); //trigger the macro process 00983 break; 00984 case 'term': 00985 $form = (($form = $this->get_attributes('form'))) ? $form : ''; 00986 $text = $this->citeproc->get_locale('term', $this->var, $form); 00987 break; 00988 case 'value': 00989 $text = $this->var; //$this->var; // dump the text verbatim 00990 break; 00991 } 00992 00993 if (empty($text)) return; 00994 return $this->format($text); 00995 } 00996 } 00997 00998 class csl_label extends csl_format { 00999 private $plural; 01000 01001 function render($data, $mode) { 01002 $text = ''; 01003 01004 $variables = explode(' ', $this->get_attributes('variable')); 01005 $form = (($form = $this->get_attributes('form'))) ? $form : 'long'; 01006 $plural = (($plural = $this->get_attributes('plural'))) ? $plural : 'contextual'; 01007 switch ($this->get_attributes('plural')) { 01008 case 'never': 01009 $plural = 'single'; 01010 break; 01011 case 'always': 01012 $plural = 'multiple'; 01013 break; 01014 case 'contextual': 01015 default: 01016 if (count($data) == 1) { 01017 $plural = 'single'; 01018 } 01019 elseif (count($data) > 1) { 01020 $plural = 'multiple'; 01021 } 01022 } 01023 foreach ($variables as $variable) { 01024 if (($term = $this->citeproc->get_locale('term', $variable, $form, $plural))) { 01025 $text = $term; 01026 break; 01027 } 01028 } 01029 01030 if (empty($text)) return; 01031 if ($this->get_attributes('strip-periods')) $text = str_replace('.', '', $text); 01032 return $this->format($text); 01033 } 01034 } 01035 01036 class csl_macro extends csl_format{ 01037 01038 } 01039 01040 class csl_macros extends csl_collection{ 01041 01042 function __construct($macro_nodes, $citeproc) { 01043 foreach ($macro_nodes as $macro) { 01044 $macro = csl_factory::create($macro, $citeproc); 01045 $this->elements[$macro->name()] = $macro; 01046 } 01047 } 01048 01049 function render_macro($name, $data, $mode) { 01050 return $this->elements[$name]->render($data, $mode); 01051 } 01052 } 01053 01054 class csl_group extends csl_format{ 01055 01056 function render($data, $mode) { 01057 $text = ''; 01058 $text_parts = array(); 01059 01060 $terms=0; 01061 foreach ($this->elements as $element) { 01062 if (($element instanceof csl_text) && 01063 ($element->source == 'term' || 01064 $element->source == 'value' || 01065 $element->source == 'variable')) { 01066 $terms++; 01067 } 01068 $text = $element->render($data, $mode); 01069 if (!empty($text)) { 01070 $text_parts[] = $text; 01071 } 01072 } 01073 01074 if (empty($text_parts)) return; 01075 if ($terms && count($text_parts) <= $terms) return; // there has to be at least one other none empty value before the term is output 01076 01077 $delimiter = $this->get_attributes('delimiter'); 01078 $text = implode($delimiter, $text_parts); // insert the delimiter if supplied. 01079 01080 01081 return $this->format($text); 01082 } 01083 } 01084 01085 class csl_layout extends csl_format { 01086 01087 function render($data, $mode) { 01088 $text = ''; 01089 $parts = array(); 01090 $delimiter = $this->get_attributes('delimiter'); 01091 01092 foreach ($this->elements as $element) { 01093 $parts[] = $element->render($data, $mode); 01094 } 01095 01096 $text = implode($delimiter, $parts); 01097 01098 return $this->format($text); 01099 } 01100 01101 } 01102 01103 class csl_citation extends csl_element{ 01104 private $layout = NULL; 01105 01106 function init($dom_node, $citeproc) { 01107 $options = $dom_node->getElementsByTagName('option'); 01108 foreach ($options as $option) { 01109 $value = $option->getAttribute('value'); 01110 $name = $option->getAttribute('name'); 01111 $this->attributes[$name] = $value; 01112 } 01113 01114 $layouts = $dom_node->getElementsByTagName('layout'); 01115 foreach ($layouts as $layout) { 01116 $this->layout = new csl_layout($layout, $citeproc); 01117 } 01118 } 01119 01120 function render($data, $mode = NULL) { 01121 $text = $this->layout->render($data, 'citation'); 01122 01123 return $text; 01124 } 01125 01126 } 01127 class csl_bibliography extends csl_element { 01128 private $layout = NULL; 01129 01130 function init($dom_node, $citeproc) { 01131 $hier_name_attr = $this->get_hier_attributes(); 01132 $options = $dom_node->getElementsByTagName('option'); 01133 foreach ($options as $option) { 01134 $value = $option->getAttribute('value'); 01135 $name = $option->getAttribute('name'); 01136 $this->attributes[$name] = $value; 01137 } 01138 01139 $layouts = $dom_node->getElementsByTagName('layout'); 01140 foreach ($layouts as $layout) { 01141 $this->layout = new csl_layout($layout, $citeproc); 01142 } 01143 01144 } 01145 01146 function render($data, $mode = NULL) { 01147 $text = $this->layout->render($data, 'bibliography'); 01148 if ($this->get_attributes('hanging-indent') == 'true') { 01149 $text = '<div style=" text-indent: -25px; padding-left: 25px;">' . $text . '</div>'; 01150 } 01151 $text = str_replace('?.', '?', str_replace('..', '.', $text)); 01152 return $text; 01153 } 01154 } 01155 01156 class csl_option { 01157 private $name; 01158 private $value; 01159 01160 function get() { 01161 return array($this->name => $this->value); 01162 } 01163 } 01164 01165 class csl_options extends csl_element{ 01166 01167 } 01168 01169 class csl_sort extends csl_element{ 01170 01171 } 01172 class csl_style extends csl_element{ 01173 01174 function __construct($dom_node = NULL, $citeproc = NULL) { 01175 if ($dom_node) { 01176 $this->attributes = $this->set_attributes($dom_node); 01177 } 01178 } 01179 } 01180 01181 class csl_choose extends csl_element{ 01182 01183 function render($data, $mode) { 01184 foreach ($this->elements as $choice) { 01185 if ($choice->evaluate($data)) { 01186 return $choice->render($data, $mode); 01187 } 01188 } 01189 } 01190 } 01191 01192 class csl_if extends csl_rendering_element { 01193 01194 function evaluate($data) { 01195 $match = (($match = $this->get_attributes('match'))) ? $match : 'all'; 01196 if (($types = $this->get_attributes('type'))) { 01197 $types = explode(' ', $types); 01198 $matches = 0; 01199 foreach ($types as $type) { 01200 if (isset($data->type)) { 01201 if ($data->type == $type && $match == 'any') return TRUE; 01202 if ($data->type != $type && $match == 'all') return FALSE; 01203 if ($data->type == $type) $matches++; 01204 } 01205 } 01206 if ($match == 'all' && $matches = count($types)) return TRUE; 01207 if ($match == 'none' && $matches = 0) return TRUE; 01208 return FALSE; 01209 } 01210 if (($variables = $this->get_attributes('variable'))) { 01211 $variables = explode(' ', $variables); 01212 $matches = 0; 01213 foreach ($variables as $var) { 01214 if (isset($data->$var) && $match == 'any') return TRUE; 01215 if (!isset($data->$var) && $match == 'all') return FALSE; 01216 if (isset($data->$var)) $matches++; 01217 } 01218 if ($match == 'all' && $matches = count($variables)) return TRUE; 01219 if ($match == 'none' && $matches = 0) return TRUE; 01220 return FALSE; 01221 } 01222 if (($is_numeric = $this->get_attributes('is-numeric'))) { 01223 $variables = explode(' ', $is_numeric); 01224 $matches = 0; 01225 foreach ($variables as $var) { 01226 if (isset($data->$var)) { 01227 if (is_numeric($data->$var) && $match == 'any') return TRUE; 01228 if (!is_numeric($data->$var) && $match == 'all') return FALSE; 01229 if (is_numeric($data->$var)) $matches++; 01230 } 01231 } 01232 if ($match == 'all' && $matches == count($variables)) return TRUE; 01233 if ($match == 'none' && $matches == 0) return TRUE; 01234 return FALSE; 01235 } 01236 if (isset($this->locator)) $test = explode(' ', $this->type); 01237 01238 return FALSE; 01239 } 01240 } 01241 01242 class csl_else_if extends csl_if { 01243 01244 } 01245 01246 class csl_else extends csl_if { 01247 01248 function evaluate($data = NULL) { 01249 return TRUE; // the last else always returns TRUE 01250 } 01251 } 01252 01253 class csl_substitute extends csl_element{ 01254 01255 } 01256 01257 class csl_locale { 01258 protected $locale_xmlstring = NULL; 01259 protected $style_locale_xmlstring = NULL; 01260 protected $locale = NULL; 01261 protected $style_locale = NULL; 01262 private $module_path; 01263 01264 function __construct($lang = 'en') { 01265 $this->module_path = '.'; 01266 $this->locale = new SimpleXMLElement($this->get_locales_file_name($lang)); 01267 if ($this->locale) { 01268 $this->locale->registerXPathNamespace('cs', 'http://purl.org/net/xbiblio/csl'); 01269 } 01270 } 01271 01272 // SimpleXML objects cannot be serialized, so we must convert to an XML string prior to serialization 01273 function __sleep() { 01274 $this->locale_xmlstring = ($this->locale) ? $this->locale->asXML() : ''; 01275 $this->style_locale_xmlstring = ($this->style_locale) ? $this->style_locale->asXML() : ''; 01276 return array('locale_xmlstring', 'style_locale_xmlstring'); 01277 } 01278 01279 // SimpleXML objects cannot be serialized, so when un-serializing them, they must rebuild from the serialized XML string. 01280 function __wakeup() { 01281 $this->style_locale = (!empty($this->style_locale_xmlstring)) ? new SimpleXMLElement($this->style_locale_xmlstring) : NULL; 01282 $this->locale = (!empty($this->locale_xmlstring)) ? new SimpleXMLElement($this->locale_xmlstring) : NULL; 01283 if ($this->locale) { 01284 $this->locale->registerXPathNamespace('cs', 'http://purl.org/net/xbiblio/csl'); 01285 } 01286 } 01287 01288 function get_locales_file_name($lang) { 01289 $lang_bases = array( 01290 "af" => "af-ZA", 01291 "ar" => "ar-AR", 01292 "bg" => "bg-BG", 01293 "ca" => "ca-AD", 01294 "cs" => "cs-CZ", 01295 "da" => "da-DK", 01296 "de" => "de-DE", 01297 "el" => "el-GR", 01298 "en" => "en-US", 01299 "es" => "es-ES", 01300 "et" => "et-EE", 01301 "fr" => "fr-FR", 01302 "he" => "he-IL", 01303 "hu" => "hu-HU", 01304 "is" => "is-IS", 01305 "it" => "it-IT", 01306 "ja" => "ja-JP", 01307 "ko" => "ko-KR", 01308 "mn" => "mn-MN", 01309 "nb" => "nb-NO", 01310 "nl" => "nl-NL", 01311 "pl" => "pl-PL", 01312 "pt" => "pt-PT", 01313 "ro" => "ro-RO", 01314 "ru" => "ru-RU", 01315 "sk" => "sk-SK", 01316 "sl" => "sl-SI", 01317 "sr" => "sr-RS", 01318 "sv" => "sv-SE", 01319 "th" => "th-TH", 01320 "tr" => "tr-TR", 01321 "uk" => "uk-UA", 01322 "vi" => "vi-VN", 01323 "zh" => "zh-CN", 01324 ); 01325 return (isset($lang_bases[$lang])) ? file_get_contents($this->module_path . '/locale/locales-' . $lang_bases[$lang] . '.xml') : file_get_contents($this->module_path . '/locale/locales-en-US.xml'); 01326 } 01327 01328 function get_locale($type, $arg1, $arg2 = NULL, $arg3 = NULL) { 01329 switch ($type) { 01330 case 'term': 01331 $term = ''; 01332 $form = $arg2 ? " and @form='$arg2'" : ''; 01333 $plural = $arg3 ? "/cs:$arg3" : ''; 01334 if ($this->style_locale) { 01335 $term = $this->style_locale->xpath("//locale[@xml:lang='en']/terms/term[@name='$arg1'$form]$plural"); 01336 if (!$term) { 01337 $term = $this->style_locale->xpath("//locale/terms/term[@name='$arg1'$form]$plural"); 01338 } 01339 } 01340 if (!$term) { 01341 $term = $this->locale->xpath("//cs:term[@name='$arg1'$form]$plural"); 01342 } 01343 if (isset($term[0])) return (string)$term[0]; 01344 break; 01345 case 'date_option': 01346 $attribs = array(); 01347 if ($this->style_locale) { 01348 $date_part = $this->style_locale->xpath("//date[@form='$arg1']/date-part[@name='$arg2']"); 01349 } 01350 if (!isset($date_part)) { 01351 $date_part = $this->locale->xpath("//cs:date[@form='$arg1']/cs:date-part[@name='$arg2']"); 01352 } 01353 if (isset($date_part)) { 01354 foreach ($$date_part->attributes() as $name => $value) { 01355 $attribs[$name] = (string)$value; 01356 } 01357 } 01358 return $attribs; 01359 break; 01360 case 'date_options': 01361 if ($this->style_locale) { 01362 $options = $this->style_locale->xpath("//locale[@xml:lang='en']/date[@form='$arg1']"); 01363 if (!$options) { 01364 $options = $this->style_locale->xpath("//locale/date[@form='$arg1']"); 01365 } 01366 } 01367 if (!$options) { 01368 $options = $this->locale->xpath("//cs:date[@form='$arg1']"); 01369 } 01370 if (isset($options[0]))return $options[0]; 01371 break; 01372 case 'style_option': 01373 $attribs = array(); 01374 if ($this->style_locale) { 01375 $option = $this->style_locale->xpath("//locale[@xml:lang='en']/style-options[@$arg1]"); 01376 if (!$option) { 01377 $option = $this->style_locale->xpath("//locale/style-options[@$arg1]"); 01378 } 01379 } 01380 if (isset($option)) { 01381 $attribs = $option[0]->attributes(); 01382 } 01383 if (empty($attribs)) { 01384 $option = $this->locale->xpath("//cs:style-options[@$arg1]"); 01385 } 01386 foreach ($option[0]->attributes() as $name => $value) { 01387 if ($name == $arg1) return (string)$value; 01388 } 01389 break; 01390 } 01391 } 01392 01393 public function set_style_locale($csl_doc) { 01394 $xml = ''; 01395 $locale_nodes = $csl_doc->getElementsByTagName('locale'); 01396 if ($locale_nodes) { 01397 $xml_open = '<style-locale>'; 01398 $xml_close = '</style-locale>'; 01399 foreach ($locale_nodes as $key => $locale_node) { 01400 $xml .= $csl_doc->saveXML($locale_node); 01401 } 01402 if (!empty($xml)) { 01403 $this->style_locale = new SimpleXMLElement($xml_open . $xml . $xml_close); 01404 } 01405 } 01406 } 01407 01408 } 01409 01410 class csl_mapper { 01411 01412 function map_field($field) { 01413 if (!isset($this->field_map)) { 01414 $this->field_map = array('title' => 'title', 01415 'container-title' => 'biblio_secondary_title', 01416 'collection-title' => 'biblio_secondary_title', 01417 'original-title' => 'biblio_alternate_title', 01418 'publisher' => 'biblio_publisher', 01419 'publisher-place' => 'biblio_place_published', 01420 'original-publisher' => 'no_match', 01421 'original-publisher-place' => 'no_match', 01422 'archive' => 'no_match', 01423 'archive-place' => 'no_match', 01424 'authority' => 'no_match', 01425 'archive_location' => 'no_match', 01426 'event' => 'biblio_secondary_title', 01427 'event-place' => 'biblio_place_published', 01428 'page' => 'biblio_pages', 01429 'page-first' => 'no_match', 01430 'locator' => 'no_match', 01431 'version' => 'biblio_edition', 01432 'volume' => 'biblio_volume', 01433 'number-of-volumes' => 'biblio_number_of_volumes', 01434 'number-of-pages' => 'no_match', 01435 'issue' => 'biblio_issue', 01436 'chapter-number' => 'biblio_section', 01437 'medium' => 'no_match', 01438 'status' => 'no_match', 01439 'edition' => 'biblio_edition', 01440 'section' => 'biblio_section', 01441 'genre' => 'no_match', 01442 'note' => 'biblio_notes', 01443 'annote' => 'no_match', 01444 'abstract' => 'biblio_abst_e', 01445 'keyword' => 'biblio_keywords', 01446 'number' => 'biblio_number', 01447 'references' => 'no_match', 01448 'URL' => 'biblio_url', 01449 'DOI' => 'biblio_doi', 01450 'ISBN' => 'biblio_isbn', 01451 'call-number' => 'biblio_call_number', 01452 'citation-number' => 'no_match', 01453 'citation-label' => 'biblio_citekey', 01454 'first-reference-note-number' => 'no_match', 01455 'year-suffix' => 'no_match', 01456 'jurisdiction' => 'no_match', 01457 01458 //Date Variables' 01459 01460 'issued' => 'biblio_year', 01461 'event' => 'biblio_date', 01462 'accessed' => 'biblio_accessed', 01463 'container' => 'biblio_date', 01464 'original-date' => 'biblio_date', 01465 01466 //Name Variables' 01467 01468 'author' => 'biblio_contributors:1', 01469 'editor' => 'biblio_contributors:2', 01470 'translator' => 'biblio_contributors:3', 01471 'recipient' => 'no_match', 01472 'interviewer' => 'biblio_contributors:1', 01473 'publisher' => 'biblio_publisher', 01474 'composer' => 'biblio_contributors:1', 01475 'original-publisher' => '', 01476 'original-author' => '', 01477 'container-author' => '', 01478 'collection-editor' => '', 01479 ); 01480 } 01481 $vars = explode(' ', $field); 01482 foreach ($vars as $key => $value) { 01483 $vars[$key] = (!empty($this->field_map[$value])) ? $this->field_map[$value] : ''; 01484 } 01485 01486 return implode(' ', $vars); 01487 } 01488 01489 function map_type($types) { 01490 if (!isset($this->type_map)) { 01491 $this->type_map = array( 01492 'article' => '', 01493 'article-magazine' => 106, 01494 'article-newspaper' => 105, 01495 'article-journal' => 102, 01496 'bill' => 117, 01497 'book' => 100, 01498 'broadcast' => 111, 01499 'chapter' => 101, 01500 'entry' => '', 01501 'entry-dictionary' => '', 01502 'entry-encyclopedia' => '', 01503 'figure' => '', 01504 'graphic' => '', 01505 'interview' => '', 01506 'legislation' => 118, 01507 'legal_case' => 128, 01508 'manuscript' => 121, 01509 'map' => 122, 01510 'motion_picture' => 110, 01511 'musical_score' => '', 01512 'pamphlet' => '', 01513 'paper-conference' => 103, 01514 'patent' => 119, 01515 'post' => '', 01516 'post-weblog' => '', 01517 'personal\_communication' => 120, 01518 'report' => 109, 01519 'review' => '', 01520 'review-book' => '', 01521 'song' => '', 01522 'speech' => '', 01523 'thesis' => 108, 01524 'treaty' => '', 01525 'webpage' => 107, 01526 ); 01527 } 01528 $vars = explode(' ', $types); 01529 foreach ($vars as $key => $value) { 01530 $vars[$key] = (!empty($this->type_map[$value])) ? $this->type_map[$value] : ''; 01531 } 01532 01533 return implode(' ', $vars); 01534 01535 } 01536 01537 } 01538 //$csl_data = simplexml_load_file('./style/chicago-fullnote-bibliography.csl'); 01539 // $local_xml = simplexml_load_file('./locale/locales-en-US.xml'); 01540 $csl_data ='./style/chicago-fullnote-bibliography.csl'; 01541 $csl_data = file_get_contents($csl_data); 01542 $test_data = file_get_contents("./tests/fullstyles_ChicagoNoteWithBibliographyWithPublisher.json"); 01543 $test_data = json_decode($test_data); 01544 01545 $citeproc = new citeproc($csl_data); 01546 $input_data = (array)$test_data->input; 01547 $count = count($input_data); 01548 foreach($input_data as $data) { 01549 print $citeproc->render($data).'<br>'; 01550 } 01551 //print $text; 01552 //print($csl_parse);