/** * With cite grouping, cites in in-text citations with identical rendered names are grouped together. * * @param array $data * @return array */ public function apply(array $data) { $names = Container::getContext()->get('layout', 'layout')->getChildElement('\\Geissler\\CSL\\Names\\Names'); if ($this->active == false || is_object($names) == false || Container::getCitationItem() === false) { return $data; } Container::getCitationItem()->moveToFirst(); $delimiter = Container::getContext()->get('delimiter', 'layout'); if (isset($this->citeGroupDelimiter) == false) { $this->citeGroupDelimiter = $delimiter; $this->citeGroupDelimiter = ', '; } $length = count($data); $newData = array(); for ($i = 0; $i < $length; $i++) { // get all names in citation group $namesAsArray = array(); $namesFull = array(); do { Container::getData()->moveToId(Container::getActualId()); $namesAsArray[] = $names->renderAsArray(''); $namesFull[] = $names->render(''); } while (Container::getCitationItem()->nextInGroup() == true); $newData[$i] = array(); $citeLength = count($namesAsArray); for ($j = 0; $j < $citeLength; $j++) { $actualName = $namesAsArray[$j][0]; // check if name already used if ($actualName !== '' && isset($data[$i][$j]) == true) { $actualGroup = array($data[$i][$j]); $groupPosition = 0; for ($k = $j + 1; $k < $citeLength; $k++) { if ($actualName == $namesAsArray[$k][0] && $namesFull[$j] == $namesFull[$k] && isset($data[$i][$k]) == true) { // replace delimiter in previous group entry with cite group delimiter $actualGroup[$groupPosition]['delimiter'] = $this->citeGroupDelimiter; $actualGroup[] = $data[$i][$k]; $namesAsArray[$k][0] = ''; $groupPosition++; // Add delimiter to values without one if ($actualGroup[$groupPosition]['delimiter'] == '') { $actualGroup[$groupPosition]['delimiter'] = $delimiter; } } } $newData[$i] = array_merge($newData[$i], $actualGroup); } } // remove delimiter from last entry in group $newData[$i][count($newData[$i]) - 1]['delimiter'] = ''; Container::getCitationItem()->next(); } return $newData; }
/** * Render citations with citations or citation-items data. * * @param string|array $data * @return array */ private function citation($data) { Container::getContext()->addOption('layout', 'delimiter', $this->delimiter); Container::getCitationItem()->moveToFirst(); $result = array(); do { $group = array(); do { $id = Container::getActualId(); $citationId = Container::getActualCitationId(); if ($id !== null && $citationId !== null) { Container::getData()->moveToId($id); // store rendered citation Container::getRendered()->set($id, $citationId, $this->renderJustActualEntry($data)); $group[] = $id . '#' . $citationId; } } while (Container::getCitationItem()->nextInGroup() == true); $result[] = $group; } while (Container::getCitationItem()->next() == true); return explode("\n", $this->applyCitationOptions($result, "\n")); }
/** * Renders the names. * * @param array $data * @return string */ public function render($data) { $this->apply(); $names = array(); $length = count($data); if ($length == 0) { return ''; } for ($i = 0; $i < $length; $i++) { $names[] = $this->formatName($data[$i], $i); } $etAl = false; $etAlUseFirst = $this->etAlUseFirst; $etAlMin = $this->etAlMin; // If used, the values of these attributes replace those of respectively et-al-min and et-al-use-first // for subsequent cites (cites referencing earlier cited items) if (Container::getRendered()->get(Container::getActualId(), Container::getActualCitationId()) !== false) { if ($this->etAlSubsequentMin > 0) { $etAlMin = $this->etAlSubsequentMin; } if ($this->etAlSubsequentUseFirst !== '') { $etAlUseFirst = $this->etAlSubsequentUseFirst; } } if ($etAlMin > 0 && $length > 1 && $etAlMin <= $length && $etAlUseFirst < $length) { $etAl = true; } $namesAndSplitter = array(); $and = $this->getAndDelimiter(); $countNames = 0; for ($i = 0; $i < $length; $i++) { $namesAndSplitter[] = $names[$i]; $countNames++; if ($etAl == true && $i == $etAlUseFirst - 1) { switch ($this->delimiterPrecedesEtAl) { case 'contextual': if ($etAlUseFirst >= 2) { $namesAndSplitter[] = $this->delimiter; } break; case 'after-inverted-name': if ($this->nameAsSortOrder == 'first') { $namesAndSplitter[] = $this->delimiter; } break; case 'always': $namesAndSplitter[] = $this->delimiter; break; } // et-al Term $namesAndSplitter[] = ' '; $namesAndSplitter[] = Container::getLocale()->getTerms('et-al'); break; } // The delimiter between the second to last and last name of the names in a name variable if ($i == $length - 2 && $and !== '' && in_array($names[$i], $this->literals) == false) { switch ($this->delimiterPrecedesLast) { case 'contextual': if ($length >= 3) { $namesAndSplitter[] = $this->delimiter; } break; case 'after-inverted-name': if ($this->nameAsSortOrder == 'first') { $namesAndSplitter[] = $this->delimiter; } break; case 'always': $namesAndSplitter[] = $this->delimiter; break; case 'never': break; } if ($this->and !== '') { $namesAndSplitter[] = ' '; $namesAndSplitter[] = $and; $namesAndSplitter[] = ' '; } } elseif ($i < $length - 1) { $namesAndSplitter[] = $this->delimiter; } } // returns the total number of names that would otherwise be rendered if ($this->form == 'count') { return (int) $countNames; } $return = str_replace(' ', ' ', implode('', $namesAndSplitter)); // do not connect literals with an and if (count($this->literals) > 0) { $and = $and . ' '; foreach ($this->literals as $literal) { $return = str_replace($and . $literal, $literal, $return); } } // name lists truncated by et-al abbreviation are followed by the name delimiter, the ellipsis character, // and the last name of the original name list. if ($this->etAlUseLast == true && count($names) + 2 >= $countNames) { $return = str_replace(Container::getLocale()->getTerms('et-al'), ' … ' . end($names), $return); } // no formatting while sorting if (Container::getContext()->in('sort') == true) { return $return; } // no formatting while author-only is set for actual cite if (Container::getCitationItem() !== false && Container::getCitationItem()->get('author-only') == 1) { return $this->affix->render($return, true); } $return = $this->formatting->render($return); return $this->affix->render($return, true); }
/** * Renders the variable. * * @param string $data * @return string */ public function render($data) { if ($this->form !== '') { $return = Container::getData()->getVariable($this->name . '-' . $this->form); if ($return !== null) { return $return; } if (is_object(Container::getAbbreviation()) == true) { $return = Container::getAbbreviation()->get($this->name, $this->form); } if ($return !== null) { return $return; } } // special cases switch ($this->name) { case 'title-short': $return = Container::getData()->getVariable('shortTitle'); if ($return !== null) { return $return; } break; case 'title': if ($this->form == 'short') { $return = Container::getData()->getVariable('shortTitle'); if ($return !== null) { return $return; } } break; case 'citation-label': $return = Container::getData()->getVariable($this->name); if ($return !== null) { return $return; } // first 4 letters from the first two author family names and last to year digits $authors = Container::getData()->getVariable('author'); $format = new Format(); if (isset($authors[0]['family']) == true && $format->format('issued') == true) { $year = $format->getData(); if (isset($year[0]['year']) == true) { switch (count($authors)) { case 1: $author = substr($authors[0]['family'], 0, 4); break; case 2: $author = substr($authors[0]['family'], 0, 2) . substr($authors[1]['family'], 0, 2); break; default: $author = ''; for ($i = 0; $i < 4; $i++) { if (preg_match('/[A-Z]/', $authors[$i]['family'], $match) == 1) { $author .= $match[0]; } } break; } $length = strlen($year[0]['year']); return $author . substr($year[0]['year'], $length - 2, $length); } } break; case 'page': $format = Container::getContext()->getValue('pageRangeFormat'); if (is_object($format) == true) { return $format->format(Container::getData()->getVariable($this->name)); } break; case 'first-reference-note-number': // number of a preceding note containing the first reference to the item if (Container::getCitationItem()->get('noteIndex') !== null || Container::getCitationItem()->get('index') !== null) { $first = Container::getRendered()->getPositionOfFirstId(Container::getActualId()); if ($first !== null && $first < Container::getRendered()->getLength()) { return $first; } } break; } $return = Container::getData()->getVariable($this->name); if ($return !== null) { return $return; } // retrieve variables form citations if (Container::getContext()->getName() == 'citation' && Container::getCitationItem() !== false) { $return = Container::getCitationItem()->get($this->name); if ($return !== null) { return $return; } } return ''; }