Skip to content

Commit

Permalink
Merge pull request #148 from xopoc14/145-citeproc-ignores-et-al-attri…
Browse files Browse the repository at this point in the history
…butes

#145 Cite-proc ignores et-al attributes if they set on bibliography/citation level.
  • Loading branch information
seboettg authored Feb 8, 2023
2 parents 676029f + 01bf1c2 commit bd92689
Show file tree
Hide file tree
Showing 4 changed files with 1,394 additions and 51 deletions.
25 changes: 17 additions & 8 deletions src/Rendering/Name/Name.php
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ public function render($data, $var, $citationNumber = null)
possible when the original name list has at least two more names than the truncated name list (for this
the value of et-al-use-first/et-al-subsequent-min must be at least 2 less than the value of
et-al-min/et-al-subsequent-use-first). */
if ($this->etAlUseLast) {
if ($this->etAlUseLast && $this->isEtAl($name, $resultNames)) {
$this->and = ""; // set "and"
$this->etAl = null; //reset $etAl;
}
Expand Down Expand Up @@ -244,6 +244,21 @@ private function cloneNamePOSC($name)
return $nameObj;
}

/**
* @param $data
* @param $resultNames
* @return bool
*/
protected function isEtAl($data, $resultNames): bool
{
return count($data) > 1
&& !empty($resultNames)
&& !empty($this->etAl)
&& !empty($this->etAlMin)
&& !empty($this->etAlUseFirst)
&& count($data) != count($resultNames);
}

/**
* @param $data
* @param $text
Expand All @@ -253,13 +268,7 @@ private function cloneNamePOSC($name)
protected function appendEtAl($data, $text, $resultNames)
{
//append et al abbreviation
if (count($data) > 1
&& !empty($resultNames)
&& !empty($this->etAl)
&& !empty($this->etAlMin)
&& !empty($this->etAlUseFirst)
&& count($data) != count($resultNames)
) {
if ($this->isEtAl($data, $resultNames)) {
/* By default, when a name list is truncated to a single name, the name and the “et-al” (or “and others”)
term are separated by a space (e.g. “Doe et al.”). When a name list is truncated to two or more names, the
name delimiter is used (e.g. “Doe, Smith, et al.”). This behavior can be changed with the
Expand Down
114 changes: 71 additions & 43 deletions src/Style/InheritableNameAttributesTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -232,105 +232,127 @@ public function initInheritableNameAttributes(SimpleXMLElement $node)
{
$context = CiteProc::getContext();
$parentStyleElement = null;
$root = $context->getRoot();
if ($this instanceof Name || $this instanceof Names) {
if ($context->getMode() === "bibliography") {
if ($this->isDescendantOfMacro()) {
$parentStyleElement = $context->getRoot();
} else {
$parentStyleElement = $context->getBibliography();
}
$parentStyleElement = $context->getBibliography();
} else {
$parentStyleElement = $context->getCitation();
}
} elseif ($this instanceof StyleElement) {
$parentStyleElement = $context->getRoot();
$parentStyleElement = $root;
}

foreach (self::$attributes as $nameAttribute) {
$attribute = $node[$nameAttribute];
switch ($nameAttribute) {
case 'and':
if (!empty($attribute)) {
$this->and = (string) $attribute;
} elseif (!empty($parentStyleElement)) { //inherit from parent style
$this->and = $parentStyleElement->getAnd();
$this->setAnd((string) $attribute);
} elseif (!empty($parentStyleElement) && !empty($parentStyleElement->getAnd())) {
$this->setAnd($parentStyleElement->getAnd());
} elseif (!empty($root) && !empty($root->getAnd())) {
$this->setAnd($root->getAnd());
}
break;
case 'delimiter-precedes-et-al':
if (!empty($attribute)) {
$this->delimiterPrecedesEtAl = (string) $attribute;
} elseif (!empty($parentStyleElement)) { //inherit from parent style
$this->delimiterPrecedesEtAl = $parentStyleElement->getDelimiterPrecedesEtAl();
$this->setDelimiterPrecedesEtAl((string) $attribute);
} elseif (!empty($parentStyleElement) && !empty($parentStyleElement->getDelimiterPrecedesEtAl())) {
$this->setDelimiterPrecedesEtAl($parentStyleElement->getDelimiterPrecedesEtAl());
} elseif (!empty($root)) {
$this->setDelimiterPrecedesEtAl($root->getDelimiterPrecedesEtAl());
}
break;
case 'delimiter-precedes-last':
if (!empty($attribute)) {
$this->delimiterPrecedesLast = (string) $attribute;
} elseif (!empty($parentStyleElement)) { //inherit from parent style
$this->delimiterPrecedesLast = $parentStyleElement->getDelimiterPrecedesLast();
$this->setDelimiterPrecedesLast((string) $attribute);
} elseif (!empty($parentStyleElement) && !empty($parentStyleElement->getDelimiterPrecedesLast())) {
$this->setDelimiterPrecedesLast($parentStyleElement->getDelimiterPrecedesLast());
} elseif (!empty($root)) {
$this->setDelimiterPrecedesLast($root->getDelimiterPrecedesLast());
}
break;
case 'et-al-min':
if (!empty($attribute)) {
$this->etAlMin = intval((string) $attribute);
} elseif (!empty($parentStyleElement)) {
$this->etAlMin = $parentStyleElement->getEtAlMin();
$this->setEtAlMin(intval((string) $attribute));
} elseif (!empty($parentStyleElement) && !empty($parentStyleElement->getEtAlMin())) {
$this->setEtAlMin($parentStyleElement->getEtAlMin());
} elseif (!empty($root)) {
$this->setEtAlMin($root->getEtAlMin());
}
break;
case 'et-al-use-first':
if (!empty($attribute)) {
$this->etAlUseFirst = intval((string) $attribute);
} elseif (!empty($parentStyleElement)) {
$this->etAlUseFirst = $parentStyleElement->getEtAlUseFirst();
$this->setEtAlUseFirst(intval((string) $attribute));
} elseif (!empty($parentStyleElement) && !empty($parentStyleElement->getEtAlUseFirst())) {
$this->setEtAlUseFirst($parentStyleElement->getEtAlUseFirst());
} elseif (!empty($root)) {
$this->setEtAlUseFirst($root->getEtAlUseFirst());
}
break;
case 'et-al-subsequent-min':
if (!empty($attribute)) {
$this->etAlSubsequentMin = intval((string) $attribute);
} elseif (!empty($parentStyleElement)) {
$this->etAlSubsequentMin = $parentStyleElement->getEtAlSubsequentMin();
$this->setEtAlSubsequentMin(intval((string) $attribute));
} elseif (!empty($parentStyleElement) && !empty($parentStyleElement->getEtAlSubsequentMin())) {
$this->setEtAlSubsequentMin($parentStyleElement->getEtAlSubsequentMin());
} elseif (!empty($root)) {
$this->setEtAlSubsequentMin($root->getEtAlSubsequentMin());
}
break;
case 'et-al-subsequent-use-first':
if (!empty($attribute)) {
$this->etAlSubsequentUseFirst = intval((string) $attribute);
} elseif (!empty($parentStyleElement)) {
$this->etAlSubsequentUseFirst = $parentStyleElement->getEtAlSubsequentUseFirst();
$this->setEtAlSubsequentUseFirst(intval((string) $attribute));
} elseif (!empty($parentStyleElement) && !empty($parentStyleElement->getEtAlSubsequentUseFirst())) {
$this->setEtAlSubsequentUseFirst($parentStyleElement->getEtAlSubsequentUseFirst());
} elseif (!empty($root)) {
$this->setEtAlSubsequentUseFirst($root->getEtAlSubsequentUseFirst());
}
break;
case 'et-al-use-last':
if (!empty($attribute)) {
$this->etAlUseLast = ((string) $attribute) === "true";
} elseif (!empty($parentStyleElement)) {
$this->etAlUseLast = $parentStyleElement->getEtAlUseLast();
$this->setEtAlUseLast(((string) $attribute) === "true");
} elseif (!empty($parentStyleElement) && !empty($parentStyleElement->getEtAlUseLast())) {
$this->setEtAlUseLast($parentStyleElement->getEtAlUseLast());
} elseif (!empty($root)) {
$this->setEtAlUseLast($root->getEtAlUseLast());
}
break;
case 'initialize':
if (!empty($attribute)) {
$this->initialize = ((string) $attribute) === "true";
} elseif (!empty($parentStyleElement)) {
$this->initialize = $parentStyleElement->getInitialize();
$this->setInitialize(((string) $attribute) === "true");
} elseif (!empty($parentStyleElement) && !empty($parentStyleElement->getInitialize())) {
$this->setInitialize($parentStyleElement->getInitialize());
} elseif (!empty($root)) {
$this->setInitialize($root->getInitialize());
}
break;
case 'initialize-with':
if (!empty($attribute)) {
$this->initializeWith = (string) $attribute;
} elseif (!empty($parentStyleElement)) {
$this->initializeWith = $parentStyleElement->getInitializeWith();
$this->setInitializeWith((string) $attribute);
} elseif (!empty($parentStyleElement) && !empty($parentStyleElement->getInitializeWith())) {
$this->setInitializeWith($parentStyleElement->getInitializeWith());
} elseif (!empty($root)) {
$this->setInitializeWith($root->getInitializeWith());
}
break;
case 'name-as-sort-order':
if (!empty($attribute)) {
$this->nameAsSortOrder = (string) $attribute;
} elseif (!empty($parentStyleElement)) {
$this->nameAsSortOrder = $parentStyleElement->getNameAsSortOrder();
$this->setNameAsSortOrder((string) $attribute);
} elseif (!empty($parentStyleElement) && !empty($parentStyleElement->getNameAsSortOrder())) {
$this->setNameAsSortOrder($parentStyleElement->getNameAsSortOrder());
} elseif (!empty($root)) {
$this->setNameAsSortOrder($root->getNameAsSortOrder());
}
break;
case 'sort-separator':
if (!empty($attribute)) {
$this->sortSeparator = (string) $attribute;
} elseif (!empty($parentStyleElement)) {
$this->sortSeparator = $parentStyleElement->getSortSeparator();
$this->setSortSeparator((string) $attribute);
} elseif (!empty($parentStyleElement) && !empty($parentStyleElement->getSortSeparator())) {
$this->setSortSeparator($parentStyleElement->getSortSeparator());
} elseif (!empty($root)) {
$this->setSortSeparator($root->getSortSeparator());
}
break;
case 'name-form':
Expand All @@ -346,8 +368,10 @@ public function initInheritableNameAttributes(SimpleXMLElement $node)
if ($this instanceof Name) {
if (!empty($attribute)) {
$this->setForm((string) $attribute);
} elseif (!empty($parentStyleElement)) {
} elseif (!empty($parentStyleElement) && !empty($parentStyleElement->getNameForm())) {
$this->setForm($parentStyleElement->getNameForm());
} elseif (!empty($root)) {
$this->setForm($root->getNameForm());
}
}
break;
Expand All @@ -363,8 +387,10 @@ public function initInheritableNameAttributes(SimpleXMLElement $node)
on cs:name. Similarly, names-delimiter corresponds to the delimiter attribute on cs:names. */
if (!empty($attribute)) {
$this->nameDelimiter = $this->delimiter = (string) $attribute;
} elseif (!empty($parentStyleElement)) {
} elseif (!empty($parentStyleElement) && !empty($parentStyleElement->getNameDelimiter())) {
$this->nameDelimiter = $this->delimiter = $parentStyleElement->getNameDelimiter();
} elseif (!empty($root)) {
$this->nameDelimiter = $this->delimiter = $root->getNameDelimiter();
}
}
break;
Expand All @@ -374,6 +400,8 @@ public function initInheritableNameAttributes(SimpleXMLElement $node)
$this->setDelimiter((string) $attribute);
} elseif (!empty($parentStyleElement)) {
$this->setDelimiter($parentStyleElement->getNameDelimiter());
} elseif (!empty($root)) {
$this->setDelimiter($root->getNameDelimiter());
}
}
}
Expand Down
Loading

0 comments on commit bd92689

Please sign in to comment.