/** * Use only some child elements for rendering if author-only or suppress-author is used. * * @param array $children * @return array */ public function getRenderClasses(array $children) { // render just child elements of a given class (@see Macro) if (Container::getContext()->in('sort') == true && Container::getContext()->get('renderJust', 'sort') !== null) { $toRender = Container::getContext()->get('renderJust', 'sort'); $render = array(); foreach ($children as $child) { if (in_array(get_class($child), $toRender) == true || $child instanceof \Geissler\CSL\Interfaces\Parental) { $render[] = $child; } } return $render; } elseif (Container::getCitationItem() !== false) { if (Container::getCitationItem()->get('author-only') == 1) { $render = array(); foreach ($children as $child) { if (in_array('Geissler\\CSL\\Interfaces\\Variable', class_implements($child)) == true && $child->isAccessingVariable('author') == true) { $render[] = $child; } } if (count($render) == 0) { foreach ($children as $child) { if (in_array('Geissler\\CSL\\Interfaces\\Variable', class_implements($child)) == true && $child->isAccessingVariable('citation-number') == true) { $render[] = new Value(new \SimpleXMLElement('<value value="Reference " />')); $render[] = $child; } } } return $render; } elseif (Container::getCitationItem()->get('suppress-author') == 1) { return $this->suppressAuthor($children); } } return $children; }
/** * Render a day. * * @param string|integer $data * @return string */ public function render($data) { // use always numeric value for sorting if (Container::getContext()->in('sort') == true) { if ($data !== '') { $data = (int) $data; if ($data < 10) { return '0' . $data; } return $data; } return 00; } switch ($this->form) { case 'numeric-leading-zeros': if ((int) $data < 10) { return '0' . (int) $data; } return $this->format($data); break; case 'ordinal': return $this->format(Ordinal::render($data, true)); break; case 'numeric': default: return $this->format((int) $data); break; } }
/** * Apply the reference grouping rule, if activated by setting a replace value. * * @param array $data * @return array */ public function apply(array $data) { Container::getData()->moveToFirst(); $this->names = Container::getContext()->get('layout', 'layout')->getChildElement('\\Geissler\\CSL\\Names\\Names'); if (isset($this->value) == false || is_object($this->names) == false) { return $data; } switch ($this->rule) { case 'complete-all': return $this->completeAll($data); break; case 'complete-each': return $this->completeEach($data); break; case 'partial-each': return $this->partialEach($data); break; case 'partial-first': return $this->partialFirst($data); break; default: return $data; break; } }
/** * Replacing the id's by the rendered and disambiguated values and add the delimiter. * * @param array $data * @return array|string */ public function apply(array $data) { $delimiter = Container::getContext()->get('delimiter', 'layout'); $layout = Container::getContext()->get('layout', 'layout'); // move to starting position for citations and citations items $citationData = false; if (Container::getCitationItem() !== false) { $citationData = true; Container::getCitationItem()->moveToFirst(); } // remove all additional temporary disambiguation options Container::getContext()->clearDisambiguationOptions(); // replace item ids by disambiguate cite $length = count($data); for ($i = 0; $i < $length; $i++) { if (is_array($data[$i]) == true) { $innerLength = count($data[$i]); for ($j = 0; $j < $innerLength; $j++) { // add existing prefix and/or suffixes to the rendered value $actualCitation = Container::getRendered()->get($data[$i][$j]); // re-render citation if missing if ($actualCitation == false) { Container::getContext()->enter('disambiguation'); $data[$i][$j] = array('value' => $layout->renderJustActualEntry(''), 'delimiter' => ''); Container::getContext()->leave(); } else { $data[$i][$j] = array('value' => $actualCitation, 'delimiter' => ''); } // Add delimiter at end if not ending with a dot // (see affix_SuppressDelimiterCharsWhenFullStopInSuffix.txt) if ($j < $innerLength - 1) { if (preg_match('/\\.$/', $data[$i][$j]['value']) == 0) { $data[$i][$j]['delimiter'] = $delimiter; } else { $data[$i][$j]['delimiter'] = ' '; } } // move to next in group if ($citationData == true) { Container::getCitationItem()->nextInGroup(); } } } else { // re-render citation if missing $actualCitation = Container::getRendered()->get($data[$i]); if ($actualCitation == false) { Container::getContext()->enter('disambiguation'); $data[$i] = array('value' => $layout->renderJustActualEntry(''), 'delimiter' => ''); Container::getContext()->leave(); } else { $data[$i] = array('value' => $actualCitation, 'delimiter' => ''); } } if ($citationData == true) { Container::getCitationItem()->next(); } } return $data; }
/** * @covers Geissler\CSL\Context\Options::set */ public function testSet() { $layout = '<citation delimiter-precedes-last="always"> </citation>'; $this->assertInstanceOf('\\Geissler\\CSL\\Context\\Options', $this->object->set('style', new \SimpleXMLElement($layout))); $this->assertEquals('always', Container::getContext()->getValue('delimiterPrecedesLast')); }
/** * Apply the formatting options on a date/date-part element. * * @param string $value * @return string */ protected function format($value) { $value = $this->formatting->render($value); $value = $this->textCase->render($value); // Attributes for affixes are allowed, unless cs:date calls a localized date format if (Container::getContext()->get('form', 'date') !== '') { return $value; } return $this->affix->render($value); }
/** * Create a chain of objects to disambiguate the ambiguous values. The first element tries to disambiguate the * values. If it fails, the ambiguous values are passed to the next element in the chain. The chain stops, if all * ambiguous values are disambiguated or if no succeeding chain element exists. * * @param array $ambiguous */ public function __construct(array $ambiguous) { $store = new Store(); $store->setAmbiguous($ambiguous); $chain = false; // last step if (Container::getContext()->isChooseDisambiguationActive() == true) { Container::getContext()->setChooseDisambiguateValue(false); $chain = new ChooseDisambiguate(); $chain->setStore($store); } // step 3 if (Container::getContext()->getValue('disambiguateAddYearSuffix', 'citation') == true) { $addYear = new AddYearSuffix(); $addYear->setStore($store); if ($chain !== false) { $addYear->setSuccessor($chain); } $chain = $addYear; } // step 2, a // if disambiguate-add-names is set to "true", then the names still hidden as a result of // et-al abbreviation after the disambiguation attempt of disambiguate-add-names are // added one by one to all members of a set of ambiguous cites if (Container::getContext()->getValue('disambiguateAddNames', 'citation') === true && Container::getContext()->getValue('disambiguateAddGivenname', 'citation') == true) { Container::getContext()->removeDisambiguationOptions('Geissler\\CSL\\Names\\Name'); $addHidden = new AddHiddenGivenName(); $addHidden->setStore($store); if ($chain !== false) { $addHidden->setSuccessor($chain); } $chain = $addHidden; } // step 2 if (Container::getContext()->getValue('disambiguateAddGivenname', 'citation') == true) { $addGiveName = new AddGivenName(); $addGiveName->setStore($store); if ($chain !== false) { $addGiveName->setSuccessor($chain); } $chain = $addGiveName; } // step 1 if (Container::getContext()->getValue('disambiguateAddNames', 'citation') === true) { $addNames = new AddNames(); $addNames->setStore($store); if ($chain !== false) { $addNames->setSuccessor($chain); } $chain = $addNames; } if ($chain !== false) { $chain->setAmbiguous($ambiguous)->setDisambiguate(array())->disambiguate(); } }
/** * Add an alphabetic year-suffix to ambiguous cites. * * @return void */ private function addYearSuffix() { // test if year is rendered, if not try if year is rendered through choose disambiguate $layout = Container::getContext()->get('layout', 'layout'); if (preg_match($this->regExp, current($this->tmpAmbiguous)) == 0 && Container::getContext()->isChooseDisambiguationActive() == true) { Container::getContext()->setChooseDisambiguateValue(true); foreach (array_keys($this->tmpAmbiguous) as $id) { $reRendered = $layout->renderById($id, ''); if (isset($this->tmpAmbiguous[$id]) == true && $reRendered !== $this->tmpAmbiguous[$id]) { $this->tmpAmbiguous[$id] = $reRendered; } } } if (array_values($this->tmpAmbiguous) > array_unique(array_values($this->tmpAmbiguous))) { $useYearSuffix = $layout->isAccessingVariable('year-suffix'); $suffix = 'a'; foreach (array_keys($this->tmpAmbiguous) as $id) { Container::getData()->moveToId($id); $actualSuffix = Container::getData()->getVariable('year-suffix'); if ($actualSuffix === null) { // store year-suffix variable Container::getData()->setVariable('year-suffix', $suffix); $actualSuffix = $suffix; } if (Container::getCitationItem() !== false) { $cites = Container::getCitationItem()->getWithIds(array($id)); foreach ($cites as $entry) { Container::getCitationItem()->moveTo($id, $entry['citationID']); if ($useYearSuffix == true) { Container::getRendered()->clearById($id); Container::getRendered()->set($id, $entry['citationID'], $layout->renderById($id, '')); } else { Container::getRendered()->set($id, $entry['citationID'], $this->addYearSuffixToValue($this->tmpAmbiguous[$id], $actualSuffix)); } } } else { $cites = Container::getRendered()->getAllById(); foreach ($cites as $itemId => $value) { if ($itemId == $id) { if ($useYearSuffix == true) { Container::getRendered()->clearById($id); Container::getRendered()->set($id, 0, $layout->renderById($id, '')); } else { $newValue = $this->addYearSuffixToValue($value, $actualSuffix); Container::getRendered()->set($id, 0, $newValue); $this->tmpDisambiguate[$id] = $newValue; } } } } unset($this->tmpAmbiguous[$id]); $suffix++; } } }
/** * Try to disambiguate the ambiguous values. If not possible, pass the values to the successor and try to * disambiguate with the successor. If possible, store ambiguous and disambiguated values. */ public function disambiguate() { Container::getContext()->removeDisambiguationOptions('Geissler\\CSL\\Names\\Name'); Container::getContext()->setChooseDisambiguateValue(true); $layout = Container::getContext()->get('layout', 'layout'); $secondary = Container::getCitationItem()->getWithIds(array_keys($this->getAmbiguous())); foreach ($secondary as $entry) { Container::getCitationItem()->moveTo($entry['id'], $entry['citationID']); Container::getData()->moveToId($entry['id']); Container::getRendered()->set($entry['id'], $entry['citationID'], $layout->renderById($entry['id'], '')); } }
/** * 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; }
/** * Returns the result of the first rendering element which returns a non-empty value. * * @param string|array $data * @return string */ public function render($data) { foreach ($this->renderingElements as $rendering) { $return = $rendering->render($data); if ($return != '') { Container::getContext()->getSubstitute()->setValue($return); if ($rendering instanceof Names == true) { $variables = $rendering->getVariables(); Container::getContext()->getSubstitute()->setVariable($variables[0]); } return $return; } } return ''; }
/** * Parses the style configuration from the SimpleXMLElement object. * * @param \SimpleXMLElement $xml * @return \Geissler\CSL\Style\Style */ public function readXml(\SimpleXMLElement $xml) { // store "global" configuration options in the context object Container::getContext()->addStyle('initializeWithHyphen', true); Container::getContext()->addStyle('demoteNonDroppingParticle', 'display-and-sort'); foreach ($xml->attributes() as $name => $value) { switch ($name) { case 'class': Container::getContext()->addStyle('class', (string) $value); break; case 'default-locale': $locale = Factory::locale(); $locale->readFile((string) $value); Container::setLocale($locale); break; } } // set global options and inheritable name options $options = new Options(); $options->set('style', $xml); foreach ($xml->children() as $child) { switch ($child->getName()) { case 'citation': Container::setCitation(new Citation($child)); break; case 'bibliography': Container::setBibliography(new Bibliography($child)); break; case 'macro': $macroName = ''; foreach ($child->attributes() as $name => $value) { if ($name == 'name') { $macroName = (string) $value; break; } } if ($macroName !== '') { Container::addMacro($macroName, new Macro($child)); } break; case 'locale': Container::getLocale()->addXml($child); break; } } return $this; }
/** * Create the objects for the additional options. * * @param \SimpleXMLElement $xml */ public function __construct(\SimpleXMLElement $xml) { $this->disambiguation = new Disambiguation(); $this->renderFromIds = new RenderFromIds(); $this->citeGrouping = new CiteGrouping(); $this->citeCollapsing = new CiteCollapsing(); // set standard values for citationItems-specific options Container::getContext()->addCitation('disambiguateAddNames', false); Container::getContext()->addCitation('disambiguateAddGivenname', false); Container::getContext()->addCitation('givennameDisambiguationRule', 'by-cite'); Container::getContext()->addCitation('disambiguateAddYearSuffix', false); Container::getContext()->addCitation('nearNoteDistance', 5); foreach ($xml->attributes() as $name => $value) { switch ($name) { case 'disambiguate-add-names': Container::getContext()->addCitation('disambiguateAddNames', isBoolean($value)); break; case 'disambiguate-add-givenname': Container::getContext()->addCitation('disambiguateAddGivenname', isBoolean($value)); break; case 'givenname-disambiguation-rule': Container::getContext()->addCitation('givennameDisambiguationRule', (string) $value); break; case 'disambiguate-add-year-suffix': Container::getContext()->addCitation('disambiguateAddYearSuffix', isBoolean($value)); break; case 'cite-group-delimiter': $this->citeGrouping->setCiteGroupDelimiter((string) $value); $this->citeGrouping->setActive(true); break; case 'collapse': $this->citeCollapsing->setCollapse((string) $value); $this->citeGrouping->setActive(true); break; case 'year-suffix-delimiter': $this->citeCollapsing->setYearSuffixDelimiter((string) $value); break; case 'after-collapse-delimiter': $this->citeCollapsing->setAfterCollapseDelimiter((string) $value); break; case 'near-note-distance': Container::getContext()->addCitation('nearNoteDistance', (int) $value); break; } } }
/** * Render all child elements. * * @param string|array $data * @return string|array */ public function render($data) { // render just child elements of a given class (@see Macro) $renderJustSelectedClass = false; $renderJustClass = array(); if (Container::getContext()->in('sort') == true && Container::getContext()->get('renderJust', 'sort') !== null) { $renderJustClass = Container::getContext()->get('renderJust', 'sort'); $renderJustSelectedClass = true; } $result = array(); foreach ($this->children as $child) { $rendered = $child->render(''); if ($renderJustSelectedClass == false || in_array(get_class($child), $renderJustClass) == true) { $result[] = $rendered; } } return implode('', $result); }
/** * Sort the data in the given context. * * @param string $context * @return Sort */ public function sort($context) { if (count($this->keys) == 0) { return false; } try { Container::getContext()->enter('sort', array('sort' => $this->keys[0]['sort'])); if ($context == 'citation') { $this->citation(); } else { $this->bibliography(); } Container::getContext()->leave(); return true; } catch (\ErrorException $error) { // ignore exceptions, because they are mainly thrown by incomplete tests } return false; }
/** * Renders the month. * * @param string|integer $data * @return string * @todo strip periods implementation */ public function render($data) { if (preg_match('/^([1-9]|0[1-9]|1[0-2])$/', $data) == 0) { $data = $this->getMonthNumber($data); } // return season name, if set as month name if (preg_match('/^([1-9]|0[1-9]|1[0-2])$/', $data) == 0) { return $this->format($data); } // use always numeric value for sorting if (Container::getContext()->in('sort') == true) { if ($data !== '') { $data = (int) $data; if ($data < 10) { return '0' . $data; } return $data; } return 00; } if ($data !== '') { switch ($this->form) { case 'long': return $this->getLocale($data); break; case 'short': return $this->getLocale($data, 'short'); break; case 'numeric': return $this->format((int) $data); break; case 'numeric-leading-zeros': $data = (int) $data; if ($data < 10) { return $this->format('0' . $data); } return $this->format($data); break; } } return $data; }
/** * Try to disambiguate the ambiguous values. If not possible, pass the values to the successor and try to * disambiguate with the successor. If possible, store ambiguous and disambiguated values. */ public function disambiguate() { $etAl = Container::getContext()->getValue('etAlUseFirst', 'citation'); $maxNames = Container::getContext()->get('layout', 'layout')->getChildElement('\\Geissler\\CSL\\Names\\Names')->getMaxNumberOfNames(); $disambiguated = false; $this->tmpDisambiguate = $this->getDisambiguate(); $this->tmpAmbiguous = $this->getAmbiguous(); if (is_array($this->getAmbiguous()) == true) { do { Container::getContext()->removeDisambiguationOptions('Geissler\\CSL\\Names\\Name'); $etAl++; Container::getContext()->setDisambiguationOptions('Geissler\\CSL\\Names\\Name', array('etAlUseFirst' => $etAl)); $disambiguated = $this->addGivenName($this->tmpAmbiguous); } while ($disambiguated == false && $etAl <= $maxNames); } if ($disambiguated == true) { $this->store($this->tmpDisambiguate, $this->tmpAmbiguous); } else { $this->succeed($this->tmpDisambiguate, $this->tmpAmbiguous); } }
/** * Adds the affixes. * * @param string $data * @return string */ public function render($data) { $return = Container::getLocale()->getTerms($this->name, $this->form, $this->plural, $this->additional); if ($return == null) { if ($this->name == 'year-suffix' && (Container::getContext()->in('sort') == true || Container::getContext()->in('disambiguation') == true)) { return ''; } switch ($this->form) { case 'verb-short': $return = Container::getLocale()->getTerms($this->name, 'verb', $this->plural, $this->additional); break; case 'symbol': $return = Container::getLocale()->getTerms($this->name, 'short', $this->plural, $this->additional); break; case 'verb': $return = Container::getLocale()->getTerms($this->name, 'verb', $this->plural); break; case 'symbol': $return = Container::getLocale()->getTerms($this->name, 'symbol', $this->plural); break; } if ($return == null) { switch ($this->form) { case 'verb-short': case 'symbol': case 'verb': case 'short': $return = Container::getLocale()->getTerms($this->name, 'long'); break; } } if ($return == null) { $return = Container::getLocale()->getTerms($this->name); } if ($return == null) { $return = ''; } } return $return; }
/** * Displays a year. * * @param string|integer $data * @return string */ public function render($data) { if ($data === '') { return $data; } $data = (int) $data; if (Container::getContext()->in('sort') == true) { return $data; } if ($data < 0) { // The "bc" term (Before Christ) is automatically appended to negative years return $this->format(-1 * $data . Container::getLocale()->getTerms('bc')); } if ($data < 1000) { // The "ad" term (Anno Domini) is automatically appended to positive years of less than four digits return $this->format($data . Container::getLocale()->getTerms('ad')); } if ($this->form == 'short') { return $this->format(mb_substr($data, 2)); } return $this->format($data); }
/** * Tests whether the cite position matches the given positions * * @param string $variable * @return boolean */ protected function validateVariable($variable) { if (Container::getContext()->getName() == 'bibliography' || Container::getContext()->in('bibliography') == true) { return false; } if (Container::getCitationItem() === false) { if ($variable == 'first') { if (Container::getData()->getPosition() == 0) { return true; } else { return false; } } else { return false; } } switch ($variable) { // position of cites that are the first to reference an item case 'first': $length = Container::getCitationItem()->getPosition(); $actual = Container::getCitationItem()->get('id'); for ($i = 0; $i < $length; $i++) { if (Container::getCitationItem()->getAtPosition('id', $i) == $actual) { return false; } } return true; break; case 'subsequent': $length = Container::getCitationItem()->getPosition(); $actual = Container::getCitationItem()->get('id'); for ($i = 0; $i < $length; $i++) { if (Container::getCitationItem()->getAtPosition('id', $i) == $actual) { return true; } } break; case 'ibid': if ($this->isIbid() == true && (Container::getCitationItem()->get('locator') == $this->getVariableForPrevious('locator') || $this->isIbidWithLocator() == true)) { return true; } return false; break; case 'ibid-with-locator': return $this->isIbidWithLocator(); break; case 'near-note': $nearNote = Container::getCitationItem()->get('near-note'); if ($nearNote !== null) { return $nearNote; } $maxDistance = Container::getContext()->getValue('nearNoteDistance', 'citation'); $position = Container::getCitationItem()->getPosition(); $id = Container::getCitationItem()->get('id'); $start = 0; if ($position > $maxDistance) { $start = $position - $maxDistance; } for ($i = $start; $i < $position; $i++) { $groupPosition = 0; $inGroup = true; while ($inGroup == true) { $actual = Container::getCitationItem()->getAtPosition('id', $i, $groupPosition); if ($actual == null) { $inGroup = false; } elseif ($actual == $id) { return true; } else { $groupPosition++; } } } break; } return false; }
/** * Renders the date part, if a value is set. * * @param array $data Array with the keys: month, day, year * @return string */ public function render($data) { if (isset($data[$this->name]) == false || $data[$this->name] == '') { return ''; } $value = $this->render->render($data[$this->name]); $value = $this->formatting->render($value); $value = $this->textCase->render($value); // Attributes for affixes are allowed, unless cs:date calls a localized date format if (Container::getContext()->get('form', 'date') !== '') { $value = $this->affix->render($value); } return $value; }
/** * Renders the names for the given ids as array or string. * * @param array $data * @param bool $asArray * @return array */ protected function renderNames($data, $asArray = false) { $names = Container::getContext()->get('layout', 'layout')->getChildElement('\\Geissler\\CSL\\Names\\Names'); if (is_object($names) == false) { return array(); } $ids = array_keys($data); $length = count($ids); $values = array(); for ($i = 0; $i < $length; $i++) { $id = $ids[$i]; Container::getData()->moveToId($id); if ($asArray == false) { $values[$id] = $names->render(''); } else { $values[$id] = $names->renderAsArray(''); } } return $values; }
/** * Move to first entry in citation group. * * @return CitationAbstract */ public function moveToFirstInGroup() { Container::getContext()->getSubstitute()->clear(); $this->groupPosition = 0; return $this; }
/** * Disambiguate citations by the name properties. * * @param array $citations */ private function disambiguateByName($citations) { $identical = array(); $last = false; $lastNames = false; foreach ($citations as $id => $citation) { Container::getData()->moveToId($id); $actualNames = $this->names->render(''); if ($last === false) { $identical = array(); $lastNames = $actualNames; $last = $citation; $identical[] = array('id' => $id, 'citation' => $citation, 'position' => $this->getSortedPosition($id), 'names' => $actualNames); } elseif ($last == $citation || $lastNames == $actualNames) { $identical[] = array('id' => $id, 'citation' => $citation, 'position' => $this->getSortedPosition($id), 'names' => $actualNames); } else { if (count($identical) > 1) { $this->disambiguateIdentical($identical); } $last = $citation; $lastNames = $actualNames; $identical = array(); $identical[] = array('id' => $id, 'citation' => $citation, 'position' => $this->getSortedPosition($id), 'names' => $actualNames); } } if (count($identical) > 1) { $this->disambiguateIdentical($identical); } Container::getContext()->leave(); }
/** * Render a bibliography. * * @param string $data * @return string */ public function render($data) { // sort $this->sort(); // render citation to create year-suffix if necessary if (Container::getContext()->getValue('disambiguateAddYearSuffix', 'citation') == true) { Container::getContext()->setName('citation'); Container::getData()->moveToFirst(); Container::getCitation()->render($data); Container::getContext()->setName('bibliography'); // re-sort with bibliography keys $this->sort(); } // render Container::getContext()->enter('bibliography'); $result = $this->layout->render($data); Container::getContext()->leave(); // format return $return = '<div class="csl-bib-body"><div class="csl-entry">'; if (is_array($result) == true && count($result) > 0) { $return .= implode('</div><div class="csl-entry">', $result); } else { $return .= $result; } return $return . '</div></div>'; }
/** * Render all child elements of the group. * * @return string */ private function renderGroup() { $toRender = $this->discretionary->getRenderClasses($this->children); $result = array(); foreach ($toRender as $element) { $rendered = $element->render(''); if ($rendered !== '') { $result[] = $rendered; } } $this->renderedGroup = implode($this->delimiter, $result); $this->renderedGroup = preg_replace('/[' . preg_quote($this->delimiter, '/') . '][' . preg_quote($this->delimiter, '/') . ']+/', $this->delimiter, $this->renderedGroup); if (Container::getContext()->in('sort') == true) { return $this->renderedGroup; } $this->renderedGroup = $this->display->render($this->renderedGroup); $this->renderedGroup = $this->formatting->render($this->renderedGroup); $this->renderedGroup = $this->affix->render($this->renderedGroup); return $this->renderedGroup; }
/** * Defines the order of the names. * * @param array $data * @param integer $position * @return array Array containing the order for displaying (display) and sorting (sort) name elements. */ private function getDisplayAndSortOrder($data, $position) { $return = array('display' => array(), 'sort' => array(), 'switched' => false); if (isset($data['family']) == false) { return $return; } if (preg_match('/\\p{Cyrillic}+|\\p{Latin}|\\p{Greek}+/u', $data['family']) == 1) { // Display order of latin/Cyrillic names $demoteNonDroppingParticle = Container::getContext()->getValue('demoteNonDroppingParticle'); if ($this->form == 'long') { if ($this->nameAsSortOrder == 'first' && $position == 0 || $this->nameAsSortOrder == 'all') { $return['switched'] = true; if ($demoteNonDroppingParticle == 'sort-only' && Container::getContext()->in('sort') == true) { $return['display'][] = 'family'; $return['display'][] = 'non-dropping-particle'; $return['display'][] = 'given'; $return['display'][] = 'dropping-particle'; $return['display'][] = 'suffix'; } elseif ($demoteNonDroppingParticle == 'never' || $demoteNonDroppingParticle == 'sort-only') { $return['display'][] = 'non-dropping-particle'; $return['display'][] = 'family'; $return['display'][] = 'given'; $return['display'][] = 'dropping-particle'; $return['display'][] = 'suffix'; } else { $return['display'][] = 'family'; $return['display'][] = 'given'; $return['display'][] = 'dropping-particle'; $return['display'][] = 'non-dropping-particle'; $return['display'][] = 'suffix'; } } else { $return['display'][] = 'given'; $return['display'][] = 'dropping-particle'; $return['display'][] = 'non-dropping-particle'; $return['display'][] = 'family'; $return['display'][] = 'suffix'; } } else { $return['display'][] = 'non-dropping-particles'; $return['display'][] = 'family'; } // Sorting order of latin/Cyrillic names if ($demoteNonDroppingParticle == 'never') { $return['sort'][] = 'non-dropping-particle'; $return['sort'][] = 'family'; $return['sort'][] = 'dropping-particle'; $return['sort'][] = 'given'; $return['sort'][] = 'suffix'; } else { $return['sort'][] = 'family'; $return['sort'][] = 'dropping-particle'; $return['sort'][] = 'non-dropping-particle'; $return['sort'][] = 'given'; $return['sort'][] = 'suffix'; } } else { // Display and sorting order of non-latin/Cyrillic names if ($this->form == 'long') { $return['display'][] = 'family'; $return['display'][] = 'given'; $return['sort'][] = 'family'; $return['sort'][] = 'given'; } else { $return['display'][] = 'family'; $return['sort'][] = 'family'; } } return $return; }
/** * @covers Geissler\CSL\Rendering\Group::__construct * @covers Geissler\CSL\Rendering\Group::render * @covers Geissler\CSL\Rendering\Group::hasAccessEmptyVariable */ public function testRenderNames() { $layout = '<group delimiter=", "> <names variable="author"> <name and="symbol" delimiter=", " form="short" /> </names> </group>'; $json = '[ { "author": [ { "family": "Doe", "given": "John", "static-ordering": false }, { "family": "Roe", "given": "Jane", "static-ordering": false } ], "id": "ITEM-1", "issued": { "date-parts": [ [ "2000" ] ] }, "title": "Book A", "type": "book" }, { "author": [ { "family": "Doe", "given": "John", "static-ordering": false }, { "family": "Roe", "given": "Jane", "static-ordering": false } ], "id": "ITEM-2", "issued": { "date-parts": [ [ "2000" ] ] }, "title": "Book B", "type": "book" } ]'; $this->initElement($layout, $json); Container::getLocale()->readFile(); $citation = '<citation disambiguate-add-givenname="true" disambiguate-add-names="true" disambiguate-add-year-suffix="true" et-al-min="2" et-al-use-first="1" givenname-disambiguation-rule="by-cite"> <layout></layout> </citation>'; Container::setCitation(new Citation(new \SimpleXMLElement($citation))); Container::getContext()->setName('citation'); $this->assertEquals('Doe et al.', $this->object->render('')); }
/** * Set the display mode (citation or bibliography). * * @param string $context * @return \Geissler\CSL\CSL */ private function registerContext($context) { Container::clear(); Container::getContext()->setName($context); return $this; }
/** * Render the macro. * * @param string $data * @return string */ public function render($data) { $result = array(); $sort = Container::getContext()->in('sort'); $hasDate = false; // drop all non-date values if macro is used in sorting context and macro access one date entry if (Container::getContext()->in('sort') == true) { foreach ($this->children as $child) { if ($child instanceof \Geissler\CSL\Date\Date == true || $child instanceof \Geissler\CSL\Date\DatePart == true) { Container::getContext()->addOption('sort', 'renderJust', array('Geissler\\CSL\\Date\\Date', 'Geissler\\CSL\\Date\\DatePart')); $hasDate = true; break; } elseif ($child instanceof Parental == true && ($child->getChildElement('\\Geissler\\CSL\\Date\\Date') !== false || $child->getChildElement('\\Geissler\\CSL\\Date\\DatePart') !== false)) { Container::getContext()->addOption('sort', 'renderJust', array('Geissler\\CSL\\Date\\Date', 'Geissler\\CSL\\Date\\DatePart')); $hasDate = true; break; } } } foreach ($this->children as $child) { if ($hasDate == false) { $result[] = $child->render($data); } elseif ($child instanceof \Geissler\CSL\Date\Date == true || $child instanceof \Geissler\CSL\Date\DatePart == true || $child instanceof Parental == true) { $result[] = $child->render($data); } } if ($sort == true) { Container::getContext()->removeOption('sort', 'renderJust'); } return implode('', $result); }