Overview

Namespaces

  • academicpuma
    • citeproc

Classes

  • Bibliography
  • Choose
  • Citation
  • CiteProc
  • Collection
  • CSLUtils
  • Date
  • DatePart
  • Element
  • EtAl
  • Factory
  • Format
  • Group
  • Info
  • Label
  • Layout
  • Locale
  • Macro
  • Macros
  • Mapper
  • Name
  • Names
  • Number
  • Option
  • Options
  • PElse
  • PElseIf
  • PIf
  • RenderingElement
  • Sort
  • Style
  • Substitute
  • Terms
  • Text
  • Overview
  • Namespace
  • Class
  1: <?php
  2: 
  3: /*
  4:  * To change this license header, choose License Headers in Project Properties.
  5:  * To change this template file, choose Tools | Templates
  6:  * and open the template in the editor.
  7:  */
  8: 
  9: namespace academicpuma\citeproc;
 10: 
 11: /**
 12:  * Description of csl_name
 13:  *
 14:  * @author sebastian
 15:  */
 16: 
 17: class Name extends Format {
 18: 
 19:     private $name_parts = array();
 20:     private $attr_init = FALSE;
 21: 
 22:     function __construct($dom_node, $citeproc = NULL) {
 23: 
 24:         $tags = $dom_node->getElementsByTagName('name-part');
 25:         if ($tags) {
 26:             foreach ($tags as $tag) {
 27:                 $name_part = $tag->getAttribute('name');
 28:                 $tag->removeAttribute('name');
 29:                 for ($i = 0; $i < $tag->attributes->length; $i++) {
 30:                     $value = $tag->attributes->item($i)->value;
 31:                     $name = str_replace(' ', '_', $tag->attributes->item($i)->name);
 32:                     $this->name_parts[$name_part][$name] = $value;
 33:                 }
 34:             }
 35:         }
 36: 
 37:         parent::__construct($dom_node, $citeproc);
 38:     }
 39: 
 40:     function init_formatting() {
 41:         $this->no_op = array();
 42:         $this->format = array();
 43:         $this->base = $this->get_attributes();
 44:         $this->format['base'] = '';
 45:         $this->format['family'] = '';
 46:         $this->format['given'] = '';
 47:         $this->no_op['base'] = TRUE;
 48:         $this->no_op['family'] = TRUE;
 49:         $this->no_op['given'] = TRUE;
 50: 
 51:         if (isset($this->prefix)) {
 52:             $this->no_op['base'] = FALSE;
 53:         }
 54:         if (isset($this->suffix)) {
 55:             $this->no_op['base'] = FALSE;
 56:         }
 57:         $this->init_format($this->base);
 58: 
 59: 
 60:         if (!empty($this->name_parts)) {
 61:             foreach ($this->name_parts as $name => $formatting) {
 62:                 $this->init_format($formatting, $name);
 63:             }
 64:         }
 65:     }
 66: 
 67:     function init_attrs($mode) {
 68:         //   $and = $this->get_attributes('and');
 69:         if (isset($this->citeproc)) {
 70:             $style_attrs = $this->citeproc->style->get_hier_attributes();
 71:             $mode_attrs = $this->citeproc->{$mode}->get_hier_attributes();
 72:             $this->attributes = array_merge($style_attrs, $mode_attrs, $this->attributes);
 73:         }
 74:         if (isset($this->and)) {
 75:             if ($this->and == 'text') {
 76:                 $this->and = $this->citeproc->get_locale('term', 'and');
 77:             } elseif ($this->and == 'symbol') {
 78:                 $this->and = '&';
 79:             }
 80:         }
 81:         if (!isset($this->delimiter)) {
 82:             $this->delimiter = $this->{'name-delimiter'};
 83:         }
 84:         if (!isset($this->alnum)) {
 85:             list($this->alnum, $this->alpha, $this->cntrl, $this->dash,
 86:                     $this->digit, $this->graph, $this->lower, $this->print,
 87:                     $this->punct, $this->space, $this->upper, $this->word,
 88:                     $this->patternModifiers) = $this->get_regex_patterns();
 89:         }
 90:         $this->dpl = $this->{'delimiter-precedes-last'};
 91:         $this->sort_separator = isset($this->{'sort-separator'}) ? $this->{'sort-separator'} : ', ';
 92: 
 93:         $this->delimiter = isset($this->{'name-delimiter'}) ? $this->{'name-delimiter'} : (isset($this->delimiter) ? $this->delimiter : ', ');
 94: 
 95:         $this->form = isset($this->{'name-form'}) ? $this->{'name-form'} : (isset($this->form) ? $this->form : 'long');
 96: 
 97:         $this->attr_init = $mode;
 98:     }
 99: 
100:     function init_format($attribs, $part = 'base') {
101:         if (!isset($this->{$part})) {
102:             $this->{$part} = array();
103:         }
104:         if (isset($attribs['quotes']) && strtolower($attribs['quotes']) == 'true') {
105:             $this->{$part}['open-quote'] = $this->citeproc->get_locale('term', 'open-quote');
106:             $this->{$part}['close-quote'] = $this->citeproc->get_locale('term', 'close-quote');
107:             $this->{$part}['open-inner-quote'] = $this->citeproc->get_locale('term', 'open-inner-quote');
108:             $this->{$part}['close-inner-quote'] = $this->citeproc->get_locale('term', 'close-inner-quote');
109:             $this->no_op[$part] = FALSE;
110:         }
111: 
112:         if (isset($attribs['prefix']))
113:             $this->{$part}['prefix'] = $attribs['prefix'];
114:         if (isset($attribs['suffix']))
115:             $this->{$part}['suffix'] = $attribs['suffix'];
116: 
117:         $this->format[$part] .= (isset($attribs['font-style'])) ? 'font-style: ' . $attribs['font-style'] . ';' : '';
118:         $this->format[$part] .= (isset($attribs['font-family'])) ? 'font-family: ' . $attribs['font-family'] . ';' : '';
119:         $this->format[$part] .= (isset($attribs['font-weight'])) ? 'font-weight: ' . $attribs['font-weight'] . ';' : '';
120:         $this->format[$part] .= (isset($attribs['font-variant'])) ? 'font-variant: ' . $attribs['font-variant'] . ';' : '';
121:         $this->format[$part] .= (isset($attribs['text-decoration'])) ? 'text-decoration: ' . $attribs['text-decoration'] . ';' : '';
122:         $this->format[$part] .= (isset($attribs['vertical-align'])) ? 'vertical-align: ' . $attribs['vertical-align'] . ';' : '';
123: 
124:         if (isset($attribs['text-case'])) {
125:             $this->no_op[$part] = FALSE;
126:             $this->{$part}['text-case'] = $attribs['text-case'];
127:         }
128:         if (!empty($this->format[$part]))
129:             $this->no_op[$part] = FALSE;
130:     }
131: 
132:     function format($text, $part = 'base') {
133: 
134:         if (empty($text) || $this->no_op[$part])
135:             return $text;
136:         if (isset($this->{$part}['text-case'])) {
137:             switch ($this->{$part}['text-case']) {
138:                 case 'uppercase':
139:                     $text = mb_strtoupper($text);
140:                     break;
141:                 case 'lowercase':
142:                     $text = mb_strtolower($text);
143:                     break;
144:                 case 'capitalize-all':
145:                     $text = mb_convert_case($text, MB_CASE_TITLE);
146:                     break;
147:                 case 'capitalize-first':
148:                     $chr1 = mb_strtoupper(mb_substr($text, 0, 1));
149:                     $text = $chr1 . mb_substr($text, 1);
150:                     break;
151:             }
152:         }
153:         $open_quote = isset($this->{$part}['open-quote']) ? $this->{$part}['open-quote'] : '';
154:         $close_quote = isset($this->{$part}['close-quote']) ? $this->{$part}['close-quote'] : '';
155:         $prefix = isset($this->{$part}['prefix']) ? $this->{$part}['prefix'] : '';
156:         $suffix = isset($this->{$part}['suffix']) ? $this->{$part}['suffix'] : '';
157:         if ($text[(strlen($text) - 1)] == $suffix)
158:             unset($suffix);
159:         if (!empty($this->format[$part])) {
160:             $text = '<span style="' . $this->format[$part] . '">' . $text . '</span>';
161:         }
162:         return $prefix . $open_quote . $text . $close_quote . $suffix;
163:     }
164: 
165:     function render($names, $mode = NULL) {
166:         $text = '';
167:         $authors = array();
168:         $count = 0;
169:         $auth_count = 0;
170:         $et_al_triggered = FALSE;
171: 
172:         if (!$this->attr_init || $this->attr_init != $mode)
173:             $this->init_attrs($mode);
174: 
175:         $initialize_with = $this->{'initialize-with'};
176: 
177:         foreach ($names as $rank => $name) {
178:             $count++;
179:             //$given = (!empty($name->firstname)) ? $name->firstname : '';
180:             if (!empty($name->given) && isset($initialize_with)) {
181:                 $name->given = preg_replace("/([$this->upper])[$this->lower]+/$this->patternModifiers", '\\1', $name->given);
182:                 $name->given = preg_replace("/(?<=[-$this->upper]) +(?=[-$this->upper])/$this->patternModifiers", "", $name->given);
183:                 if (isset($name->initials)) {
184:                     $name->initials = $name->given . $name->initials;
185:                 }
186:                 $name->initials = $name->given;
187:             }
188:             if (isset($name->initials)) {
189:                 // within initials, remove any dots:
190:                 $name->initials = preg_replace("/([$this->upper])\.+/$this->patternModifiers", "\\1", $name->initials);
191:                 // within initials, remove any spaces *between* initials:
192:                 $name->initials = preg_replace("/(?<=[-$this->upper]) +(?=[-$this->upper])/$this->patternModifiers", "", $name->initials);
193:                 if ($this->citeproc->style->{'initialize-with-hyphen'} == 'false') {
194:                     $name->initials = preg_replace("/-/", '', $name->initials);
195:                 }
196:                 // within initials, add a space after a hyphen, but only if ...
197:                 if (preg_match("/ $/", $initialize_with)) {// ... the delimiter that separates initials ends with a space
198:                     // $name->initials = preg_replace("/-(?=[$this->upper])/$this->patternModifiers", " -", $name->initials);
199:                 }
200:                 // then, separate initials with the specified delimiter:
201:                 $name->initials = preg_replace("/([$this->upper])(?=[^$this->lower]+|$)/$this->patternModifiers", "\\1$initialize_with", $name->initials);
202: 
203:                 //      $shortenInitials = (isset($options['numberOfInitialsToKeep'])) ? $options['numberOfInitialsToKeep'] : FALSE;
204:                 //      if ($shortenInitials) $given = drupal_substr($given, 0, $shortenInitials);
205: 
206:                 if (isset($initialize_with)) {
207:                     $name->given = $name->initials;
208:                 } elseif (!empty($name->given)) {
209:                     $name->given = $name->given . ' ' . $name->initials;
210:                 } elseif (empty($name->given)) {
211:                     $name->given = $name->initials;
212:                 }
213:             }
214: 
215:             $ndp = (isset($name->{'non-dropping-particle'})) ? $name->{'non-dropping-particle'} . ' ' : '';
216:             $suffix = (isset($name->{'suffix'})) ? ' ' . $name->{'suffix'} : '';
217: 
218:             if (isset($name->given)) {
219:                 $given = $this->format($name->given, 'given');
220:             } else {
221:                 $given = '';
222:             }
223:             if (isset($name->family)) {
224:                 $name->family = $this->format($name->family, 'family');
225:                 if ($this->form == 'short') {
226:                     $text = $ndp . $name->family;
227:                 } else {
228:                     switch ($this->{'name-as-sort-order'}) {
229:                         case 'first' && $rank == 0:
230:                         case 'all':
231:                             $text = $ndp . $name->family . $this->sort_separator . $given;
232:                             break;
233:                         default:
234:                             $text = $given . ' ' . $ndp . $name->family . $suffix;
235:                     }
236:                 }
237:                 $authors[] = trim($this->format($text));
238:             }
239:             if (isset($this->{'et-al-min'}) && $count >= $this->{'et-al-min'})
240:                 break;
241:         }
242:         if (isset($this->{'et-al-min'}) &&
243:                 $count >= $this->{'et-al-min'} &&
244:                 isset($this->{'et-al-use-first'}) &&
245:                 $count >= $this->{'et-al-use-first'} &&
246:                 count($names) > $this->{'et-al-use-first'}) {
247:             if ($this->{'et-al-use-first'} < $this->{'et-al-min'}) {
248:                 for ($i = $this->{'et-al-use-first'}; $i < $count; $i++) {
249:                     unset($authors[$i]);
250:                 }
251:             }
252:             if ($this->etal) {
253:                 $etal = $this->etal->render();
254:             } else {
255:                 $etal = $this->citeproc->get_locale('term', 'et-al');
256:             }
257:             $et_al_triggered = TRUE;
258:         }
259: 
260:         if (!empty($authors) && !$et_al_triggered) {
261:             $auth_count = count($authors);
262:             if (isset($this->and) && $auth_count > 1) {
263:                 $authors[$auth_count - 1] = $this->and . ' ' . $authors[$auth_count - 1]; //stick an "and" in front of the last author if "and" is defined
264:             }
265:         }
266: 
267:         $text = implode($this->delimiter, $authors);
268: 
269:         if (!empty($authors) && $et_al_triggered) {
270:             switch ($this->{'delimiter-precedes-et-al'}) {
271:                 case 'never':
272:                     $text = $text . " $etal";
273:                     break;
274:                 case 'always':
275:                     $text = $text . "$this->delimiter$etal";
276:                     break;
277:                 default:
278:                     $text = count($authors) == 1 ? $text . " $etal" : $text . "$this->delimiter$etal";
279:             }
280:         }
281: 
282:         if ($this->form == 'count') {
283:             if (!$et_al_triggered) {
284:                 return (int) count($authors);
285:             } else {
286:                 return (int) (count($authors) - 1);
287:             }
288:         }
289:         // strip out the last delimiter if not required
290:         if (isset($this->and) && $auth_count > 1) {
291:             $last_delim = strrpos($text, $this->delimiter . $this->and);
292:             switch ($this->dpl) { //dpl == delimiter proceeds last
293:                 case 'always':
294:                     return $text;
295:                     break;
296:                 case 'never':
297:                     return substr_replace($text, ' ', $last_delim, strlen($this->delimiter));
298:                     break;
299:                 case 'contextual':
300:                 default:
301:                     if ($auth_count < 3) {
302:                         return substr_replace($text, ' ', $last_delim, strlen($this->delimiter));
303:                     }
304:             }
305:         }
306:         return $text;
307:     }
308: 
309:     function get_regex_patterns() {
310:         // Checks if PCRE is compiled with UTF-8 and Unicode support
311:         if (!@preg_match('/\pL/u', 'a')) {
312:             // probably a broken PCRE library
313:             return $this->get_latin1_regex();
314:         } else {
315:             // Unicode safe filter for the value
316:             return $this->get_utf8_regex();
317:         }
318:     }
319: 
320:     function get_latin1_regex() {
321:         $alnum = "[:alnum:]ÄÅÁÀÂÃÇÉÈÊËÑÖØÓÒÔÕÜÚÙÛÍÌÎÏÆäåáàâãçéèêëñöøóòôõüúùûíìîïæÿß";
322:         // Matches ISO-8859-1 letters:
323:         $alpha = "[:alpha:]ÄÅÁÀÂÃÇÉÈÊËÑÖØÓÒÔÕÜÚÙÛÍÌÎÏÆäåáàâãçéèêëñöøóòôõüúùûíìîïæÿß";
324:         // Matches ISO-8859-1 control characters:
325:         $cntrl = "[:cntrl:]";
326:         // Matches ISO-8859-1 dashes & hyphens:
327:         $dash = "-–";
328:         // Matches ISO-8859-1 digits:
329:         $digit = "[\d]";
330:         // Matches ISO-8859-1 printing characters (excluding space):
331:         $graph = "[:graph:]ÄÅÁÀÂÃÇÉÈÊËÑÖØÓÒÔÕÜÚÙÛÍÌÎÏÆäåáàâãçéèêëñöøóòôõüúùûíìîïæÿß";
332:         // Matches ISO-8859-1 lower case letters:
333:         $lower = "[:lower:]äåáàâãçéèêëñöøóòôõüúùûíìîïæÿß";
334:         // Matches ISO-8859-1 printing characters (including space):
335:         $print = "[:print:]ÄÅÁÀÂÃÇÉÈÊËÑÖØÓÒÔÕÜÚÙÛÍÌÎÏÆäåáàâãçéèêëñöøóòôõüúùûíìîïæÿß";
336:         // Matches ISO-8859-1 punctuation:
337:         $punct = "[:punct:]";
338:         // Matches ISO-8859-1 whitespace (separating characters with no visual representation):
339:         $space = "[\s]";
340:         // Matches ISO-8859-1 upper case letters:
341:         $upper = "[:upper:]ÄÅÁÀÂÃÇÉÈÊËÑÖØÓÒÔÕÜÚÙÛÍÌÎÏÆ";
342:         // Matches ISO-8859-1 "word" characters:
343:         $word = "_[:alnum:]ÄÅÁÀÂÃÇÉÈÊËÑÖØÓÒÔÕÜÚÙÛÍÌÎÏÆäåáàâãçéèêëñöøóòôõüúùûíìîïæÿß";
344:         // Defines the PCRE pattern modifier(s) to be used in conjunction with the above variables:
345:         // More info: <http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php>
346:         $patternModifiers = "";
347: 
348:         return array($alnum, $alpha, $cntrl, $dash, $digit, $graph, $lower,
349:             $print, $punct, $space, $upper, $word, $patternModifiers);
350:     }
351: 
352:     function get_utf8_regex() {
353:         // Matches Unicode letters & digits:
354:         $alnum = "\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}"; // Unicode-aware equivalent of "[:alnum:]"
355:         // Matches Unicode letters:
356:         $alpha = "\p{Ll}\p{Lu}\p{Lt}\p{Lo}"; // Unicode-aware equivalent of "[:alpha:]"
357:         // Matches Unicode control codes & characters not in other categories:
358:         $cntrl = "\p{C}"; // Unicode-aware equivalent of "[:cntrl:]"
359:         // Matches Unicode dashes & hyphens:
360:         $dash = "\p{Pd}";
361:         // Matches Unicode digits:
362:         $digit = "\p{Nd}"; // Unicode-aware equivalent of "[:digit:]"
363:         // Matches Unicode printing characters (excluding space):
364:         $graph = "^\p{C}\t\n\f\r\p{Z}"; // Unicode-aware equivalent of "[:graph:]"
365:         // Matches Unicode lower case letters:
366:         $lower = "\p{Ll}\p{M}"; // Unicode-aware equivalent of "[:lower:]"
367:         // Matches Unicode printing characters (including space):
368:         $print = "\P{C}"; // same as "^\p{C}", Unicode-aware equivalent of "[:print:]"
369:         // Matches Unicode punctuation (printing characters excluding letters & digits):
370:         $punct = "\p{P}"; // Unicode-aware equivalent of "[:punct:]"
371:         // Matches Unicode whitespace (separating characters with no visual representation):
372:         $space = "\t\n\f\r\p{Z}"; // Unicode-aware equivalent of "[:space:]"
373:         // Matches Unicode upper case letters:
374:         $upper = "\p{Lu}\p{Lt}"; // Unicode-aware equivalent of "[:upper:]"
375:         // Matches Unicode "word" characters:
376:         $word = "_\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}"; // Unicode-aware equivalent of "[:word:]" (or "[:alnum:]" plus "_")
377:         // Defines the PCRE pattern modifier(s) to be used in conjunction with the above variables:
378:         // More info: <http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php>
379:         $patternModifiers = "u"; // the "u" (PCRE_UTF8) pattern modifier causes PHP/PCRE to treat pattern strings as UTF-8
380:         return array($alnum, $alpha, $cntrl, $dash, $digit, $graph, $lower,
381:             $print, $punct, $space, $upper, $word, $patternModifiers);
382:     }
383: 
384: }
API documentation generated by ApiGen