/** * @covers Geissler\CSL\Style\Style::readFile * @covers Geissler\CSL\Style\Style::setDir * @covers Geissler\CSL\Style\Style::readXml */ public function testReadFile2() { $this->assertInstanceOf($this->class, $this->object->setDir($this->dir)); $this->assertInstanceOf($this->class, $this->object->readFile('american-journal-of-archaeology')); $this->assertInstanceOf('\\Geissler\\CSL\\Style\\Citation', \Geissler\CSL\Container::getCitation()); $this->assertInstanceOf('\\Geissler\\CSL\\Style\\Bibliography', \Geissler\CSL\Container::getBibliography()); $this->assertInstanceOf('\\Geissler\\CSL\\Locale\\Locale', \Geissler\CSL\Container::getLocale()); }
/** * Renders a long-ordinal, with fallback to ordinal for numbers greater ten. * * @param string $variable * @return string */ public static function renderLong($variable) { $ordinal = 'long-ordinal-'; if ((int) $variable <= 10) { $ordinal .= '0' . (int) $variable; } else { $ordinal .= $variable; } $long = Container::getLocale()->getTerms($ordinal); if ($long !== null) { return $long; } return self::render($variable); }
/** * 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'); $this->tmpDisambiguate = $this->getDisambiguate(); $this->tmpAmbiguous = $this->getAmbiguous(); $firstDifferent = false; // disambiguate years and missing years $this->regExp = '/([0-9]{2,4}'; if (Container::getLocale()->getTerms('do date', 'short') !== null) { $this->regExp .= '|' . Container::getLocale()->getTerms('do date', 'short'); } elseif (Container::getLocale()->getTerms('do date', 'short') !== null) { $this->regExp .= '|' . Container::getLocale()->getTerms('do date'); } $this->regExp .= ')/'; // disambiguate only where names and year are identical foreach ($this->tmpAmbiguous as $id => $name) { if (preg_match($this->regExp, $name) == 0) { $citation = Container::getRendered()->getFirstById($id); if (preg_match($this->regExp, $citation) == 1 && preg_match('/^' . preg_quote($this->tmpAmbiguous[$id], '/') . '/', $citation) == 1) { $this->tmpAmbiguous[$id] = $citation; } } } $ambiguous = ArrayData::ambiguous($this->tmpAmbiguous); if (count($ambiguous) > 0) { $this->tmpAmbiguous = $ambiguous; $this->addYearSuffix(); } elseif ($firstDifferent == true) { // test if second citation is ambiguous $this->tmpAmbiguous = $this->getAmbiguous(); $this->addYearSuffix(); } elseif (is_array($this->tmpDisambiguate) == true) { $this->tmpDisambiguate = array_merge($this->tmpDisambiguate, $this->getAmbiguous()); } else { $this->tmpDisambiguate = $this->getAmbiguous(); } if (count($ambiguous) > 0) { // store already disambiguated values $succeedAmbiguous = array(); if ($this->getAmbiguous() == $ambiguous) { $succeedAmbiguous = $ambiguous; } $this->succeed($this->getDisambiguate(), $succeedAmbiguous); } }
/** * Adds the quotes. * * @param string $data * @return string */ public function render($data) { if ($this->quote == true) { if (strpos($data, Container::getLocale()->getTerms('open-quote')) !== false && strpos($data, Container::getLocale()->getTerms('close-quote')) !== false) { $masked = false; if (strpos($data, Container::getLocale()->getTerms('open-inner-quote')) !== false && strpos($data, Container::getLocale()->getTerms('close-inner-quote')) !== false) { // masc inner quotes $data = str_replace(Container::getLocale()->getTerms('open-inner-quote'), '##', $data); $data = str_replace(Container::getLocale()->getTerms('close-inner-quote'), '#', $data); $masked = true; } $data = str_replace(Container::getLocale()->getTerms('open-quote'), Container::getLocale()->getTerms('open-inner-quote'), $data); $data = str_replace(Container::getLocale()->getTerms('close-quote'), Container::getLocale()->getTerms('close-inner-quote'), $data); if ($masked == true) { $data = str_replace('##', Container::getLocale()->getTerms('open-quote'), $data); $data = str_replace('#', Container::getLocale()->getTerms('close-quote'), $data); } } return Container::getLocale()->getTerms('open-quote') . $data . Container::getLocale()->getTerms('close-quote'); } return $data; }
/** * 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); }
/** * Render title cases. * * @param string $data * @return string */ private function renderTitle($data) { if (Container::getLocale()->getLanguage() == 'en' && Container::getData()->getVariable('language') == null || Container::getData()->getVariable('language') == 'en') { // In both cases, stop words are lowercased, unless they are the first or last word in the string, // or follow a colon. $stopWords = array('a', 'an', 'and', 'as', 'at', 'but', 'by', 'down', 'for', 'from', 'in', 'into', 'nor', 'of', 'on', 'onto', 'or', 'over', 'so', 'the', 'till', 'to', 'up', 'via', 'with', 'yet'); $values = explode(' ', $data); $length = count($values); if (preg_match('/^[A-Z| |\\.|,]+$/', $data) == 1) { // For uppercase strings, the first character of each word remains capitalized. // All other letters are lowercase. for ($i = 0; $i < $length; $i++) { if ($i > 0 && $i < $length - 1 && in_array(mb_strtolower($values[$i]), $stopWords) == true) { $values[$i] = mb_strtolower($values[$i]); } else { $values[$i] = mb_substr($values[$i], 0, 1) . mb_strtolower(mb_substr($values[$i], 1)); } } } else { // For lower or mixed case strings, the first character of each lowercase word is capitalized. // The case of words in mixed or uppercase stays the same. for ($i = 0; $i < $length; $i++) { if ($i > 0 && $i < $length - 1 && in_array(mb_strtolower($values[$i]), $stopWords) == true) { $values[$i] = mb_strtolower($values[$i]); } else { $values[$i] = mb_strtoupper(mb_substr($values[$i], 0, 1)) . mb_substr($values[$i], 1); } } } return implode(' ', $values); } return $data; }
/** * Retrieve the and term delimiter. * * @return string */ private function getAndDelimiter() { if ($this->and == 'text') { return Container::getLocale()->getTerms('and'); } elseif (Container::getLocale()->getTerms('symbol') !== null) { return Container::getLocale()->getTerms('symbol'); } elseif ($this->and == 'symbol') { return '&'; } return ''; }
/** * @covers Geissler\CSL\Rendering\Group::__construct * @covers Geissler\CSL\Rendering\Group::render * @covers Geissler\CSL\Rendering\Group::hasAccessEmptyVariable */ public function testRenderNumber() { $layout = '<group delimiter=": "> <text variable="title"/> <number variable="edition" form="ordinal"/> <label variable="edition"/> </group>'; $json = '[ { "title": "Book A", "edition": "1" } ]'; $this->initElement($layout, $json); Container::getLocale()->readFile(); $this->assertEquals('Book A: 1st: edition', $this->object->render('')); }
/** * Actually reads the locale value from the Locale-Object. * * @param integer $number * @param string $form Short or empty * @return string */ private function getLocale($number, $form = '') { $name = 'month-'; if ($number < 10) { $name .= '0'; } return $this->format(Container::getLocale()->getTerms($name . (int) $number, $form)); }
/** * @covers Geissler\CSL\Rendering\Text::__construct * @covers Geissler\CSL\Rendering\Text::render * @covers Geissler\CSL\Rendering\Text::hasAccessEmptyVariable */ public function testRenderGermanTerm() { Container::getLocale()->readFile('de'); $layout = '<text term="book" plural="false" prefix="(" suffix=")" text-decoration="underline"></text>'; $this->initElement($layout); $this->assertEquals('(<font style="text-decoration:underline">Buch</font>)', $this->object->render('blue')); }
/** * Creates a Year object containing the locale year configuration and the given form the xml. * * @param string $form text or numeric * @param \SimpleXMLElement $xml * @return \Geissler\CSL\Date\Year */ public static function year($form, \SimpleXMLElement $xml) { $standard = Container::getLocale()->getDateAsXml($form, 'year'); if ($standard !== null) { $year = new Year(new \SimpleXMLElement($standard)); return $year->modify($xml); } return new Year($xml); }
/** * When et-al abbreviation occurs, the "et-al" and "and others" terms are excluded from the sort key values. * * @param string $value * @return string */ private function removeEtAl($value) { $value = str_replace(Container::getLocale()->getTerms('et-al'), '', $value); return str_replace(Container::getLocale()->getTerms('and others'), '', $value); }
/** * Et-La rendering. * * @param string|array $data * @return string */ public function render($data) { $data = str_replace(' ' . Container::getLocale()->getTerms('et-al'), '', $data); $data .= ' ' . $this->formatting->render(Container::getLocale()->getTerms($this->term)); return $data; }
/** * 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; }
/** * Renders the label. * * @param string|array $data * @return string * @throws \ErrorException If the variable parameter is not set */ public function render($data) { if (isset($this->variable) == false) { throw new \ErrorException('variable is not set!'); } $content = Container::getData()->getVariable($this->variable); $variable = $this->variable; if ($this->variable == 'locator') { // Must be accompanied in the input data by a label indicating the locator type, which determines which // term is rendered by cs:label when the "locator" variable is selected if (is_object(Container::getCitationItem()) == true && Container::getCitationItem()->get('label') !== null) { $variable = Container::getCitationItem()->get('label'); $content = Container::getCitationItem()->get('locator'); } else { return ''; } } // The term is only rendered if the selected variable is non-empty. if ($content == '' && $variable !== 'editortranslator') { return ''; } $plural = 'single'; switch ($this->plural) { case 'contextual': if (is_array($content) == true) { if (count($content) > 1) { $plural = 'multiple'; } } elseif (($this->variable == 'number-of-pages' || $this->variable == 'number-of-volumes') && preg_match_all('/([0-9])/', $content) > 1) { $plural = 'multiple'; } elseif (preg_match('/^[0-9]+$/', $content, $match) == 0) { $plural = 'multiple'; } break; case 'always': case 'multiple': $plural = 'multiple'; break; } $form = ''; if ($this->form !== 'long') { $form = $this->form; } $return = Container::getLocale()->getTerms($variable, $form, $plural); if ($return !== '') { $return = $this->formatting->render($return); $return = $this->textCase->render($return); $return = $this->stripPeriods->render($return); $return = $this->affix->render($return, true); } 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; }
/** * Return locale season name. * * @param integer $date * @return null|string */ private function extractSeason($date) { return Container::getLocale()->getTerms('season-0' . $date); }
/** * Renders, if no previous data has been renderd and a month is required a given season instead. * * @return string */ private function renderSeason() { $data = Container::getData()->getVariable($this->variable); if (isset($data['season']) == true) { $month = false; foreach ($this->dateParts as $datePart) { if ($datePart['name'] == 'month') { $month = true; break; } } if ($month == true) { return Container::getLocale()->getTerms('season-0' . (int) $data['season']); } } return ''; }