#include "Buffer.h"
#include "BufferParams.h"
#include "buffer_funcs.h"
+#include "Citation.h"
#include "Encoding.h"
#include "InsetIterator.h"
#include "Language.h"
{}
-docstring const BibTeXInfo::getAbbreviatedAuthor(
- Buffer const * buf, bool jurabib_style) const
+docstring const BibTeXInfo::getAuthorList(
+ Buffer const * buf, bool full, bool forceshort) const
{
+ // Maxnames treshold depend on engine
+ size_t maxnames = buf ?
+ buf->params().documentClass().max_citenames() : 2;
+
if (!is_bibtex_) {
docstring const opt = label();
if (opt.empty())
shortauthor += "/" + familyName(authors[2]);
return convertLaTeXCommands(shortauthor);
}
+ docstring retval;
- docstring retval = familyName(authors[0]);
-
- if (authors.size() == 2 && authors[1] != "others") {
- docstring const dformat = buf ?
- buf->B_("%1$s and %2$s") : from_ascii("%1$s and %2$s");
- retval = bformat(dformat, familyName(authors[0]), familyName(authors[1]));
- } else if (authors.size() >= 2) {
- // we get here either if the author list is longer than two names
- // or if the second 'name' is "others". we do the same thing either
- // way.
- docstring const dformat = buf ?
- buf->B_("%1$s et al.") : from_ascii("%1$s et al.");
- retval = bformat(dformat, familyName(authors[0]));
+ CiteEngineType const engine_type = buf ? buf->params().citeEngineType()
+ : ENGINE_TYPE_DEFAULT;
+
+ // These are defined in the styles
+ string const etal =
+ buf ? buf->params().documentClass().getCiteMacro(engine_type, "_etal")
+ : " et al.";
+ string const namesep =
+ buf ? buf->params().documentClass().getCiteMacro(engine_type, "_namesep")
+ : ", ";
+ string const lastnamesep =
+ buf ? buf->params().documentClass().getCiteMacro(engine_type, "_lastnamesep")
+ : ", and ";
+ string const pairnamesep =
+ buf ? buf->params().documentClass().getCiteMacro(engine_type, "_pairnamesep")
+ : " and ";
+
+ // Shorten the list (with et al.) if forceshort is set
+ // and the list can actually be shorten, else if maxcitenames
+ // is passed and full is not set.
+ bool shorten = forceshort && authors.size() > 1;
+ vector<docstring>::const_iterator it = authors.begin();
+ vector<docstring>::const_iterator en = authors.end();
+ for (size_t i = 0; it != en; ++it, ++i) {
+ if (i >= maxnames && !full) {
+ shorten = true;
+ break;
+ }
+ if (*it == "others") {
+ retval += buf ? buf->B_(etal) : from_ascii(etal);
+ break;
+ }
+ if (i > 0 && i == authors.size() - 1) {
+ if (authors.size() == 2)
+ retval += buf ? buf->B_(pairnamesep) : from_ascii(pairnamesep);
+ else
+ retval += buf ? buf->B_(lastnamesep) : from_ascii(lastnamesep);
+ } else if (i > 0)
+ retval += buf ? buf->B_(namesep) : from_ascii(namesep);
+ retval += familyName(*it);
}
+ if (shorten)
+ retval = familyName(authors[0]) + (buf ? buf->B_(etal) : from_ascii(etal));
return convertLaTeXCommands(retval);
}
*/
docstring BibTeXInfo::expandFormat(docstring const & format,
BibTeXInfoList const xrefs, int & counter, Buffer const & buf,
- docstring before, docstring after, docstring dialog, bool next) const
+ CiteItem const & ci, bool next, bool second) const
{
// incorrect use of macros could put us in an infinite loop
static int const max_passes = 5000;
ret << trans;
} else {
docstring const val =
- getValueForKey(key, buf, before, after, dialog, xrefs, max_keysize);
+ getValueForKey(key, buf, ci, xrefs, max_keysize);
if (!scanning_rich)
ret << from_ascii("{!<span class=\"bib-" + key + "\">!}");
ret << val;
return _("ERROR!");
fmt = newfmt;
docstring const val =
- getValueForKey(optkey, buf, before, after, dialog, xrefs);
+ getValueForKey(optkey, buf, ci, xrefs);
if (optkey == "next" && next)
ret << ifpart; // without expansion
else if (!val.empty()) {
int newcounter = 0;
ret << expandFormat(ifpart, xrefs, newcounter, buf,
- before, after, dialog, next);
+ ci, next);
} else if (!elsepart.empty()) {
int newcounter = 0;
ret << expandFormat(elsepart, xrefs, newcounter, buf,
- before, after, dialog, next);
+ ci, next);
}
// fmt will have been shortened for us already
continue;
docstring const & BibTeXInfo::getInfo(BibTeXInfoList const xrefs,
- Buffer const & buf, bool richtext) const
+ Buffer const & buf, CiteItem const & ci) const
{
+ bool const richtext = ci.richtext;
+
if (!richtext && !info_.empty())
return info_;
if (richtext && !info_richtext_.empty())
from_utf8(dc.getCiteFormat(engine_type, to_utf8(entry_type_)));
int counter = 0;
info_ = expandFormat(format, xrefs, counter, buf,
- docstring(), docstring(), docstring(), false);
+ ci, false, false);
if (info_.empty()) {
// this probably shouldn't happen
docstring const BibTeXInfo::getLabel(BibTeXInfoList const xrefs,
- Buffer const & buf, docstring const & format, bool richtext,
- docstring const & before, docstring const & after,
- docstring const & dialog, bool next) const
+ Buffer const & buf, docstring const & format,
+ CiteItem const & ci, bool next, bool second) const
{
docstring loclabel;
int counter = 0;
- loclabel = expandFormat(format, xrefs, counter, buf,
- before, after, dialog, next);
+ loclabel = expandFormat(format, xrefs, counter, buf, ci, next, second);
if (!loclabel.empty() && !next) {
- loclabel = processRichtext(loclabel, richtext);
+ loclabel = processRichtext(loclabel, ci.richtext);
loclabel = convertLaTeXCommands(loclabel);
}
docstring BibTeXInfo::getValueForKey(string const & oldkey, Buffer const & buf,
- docstring const & before, docstring const & after, docstring const & dialog,
- BibTeXInfoList const xrefs, size_t maxsize) const
+ CiteItem const & ci, BibTeXInfoList const xrefs, size_t maxsize) const
{
// anything less is pointless
LASSERT(maxsize >= 16, maxsize = 16);
if (ret.empty()) {
// some special keys
// FIXME: dialog, textbefore and textafter have nothing to do with this
- if (key == "dialog")
- ret = dialog;
+ if (key == "dialog" && ci.context == CiteItem::Dialog)
+ ret = from_ascii("x"); // any non-empty string will do
+ else if (key == "ifstar" && ci.Starred)
+ ret = from_ascii("x"); // any non-empty string will do
else if (key == "entrytype")
ret = entry_type_;
else if (key == "key")
ret = modifier_;
else if (key == "numericallabel")
ret = cite_number_;
- else if (key == "abbrvauthor")
- // Special key to provide abbreviated author names.
- ret = getAbbreviatedAuthor(&buf, false);
else if (key == "shortauthor")
// When shortauthor is not defined, jurabib automatically
// provides jurabib-style abbreviated author names. We do
+ " [" + operator[]("year") + "]";
else
ret = operator[]("title");
+ else if (key == "abbrvauthor") {
+ // Special key to provide abbreviated author names,
+ // with respect to maxcitenames.
+ ret = getAuthorList(&buf, false, false);
+ if (ci.forceUpperCase && isLowerCase(ret[0]))
+ ret[0] = uppercase(ret[0]);
+ } else if (key == "fullauthor") {
+ // Return a full author list
+ ret = getAuthorList(&buf, true, false);
+ if (ci.forceUpperCase && isLowerCase(ret[0]))
+ ret[0] = uppercase(ret[0]);
+ } else if (key == "forceabbrvauthor") {
+ // Special key to provide abbreviated author names,
+ // irrespective of maxcitenames.
+ ret = getAuthorList(&buf, false, true);
+ if (ci.forceUpperCase && isLowerCase(ret[0]))
+ ret[0] = uppercase(ret[0]);
} else if (key == "bibentry") {
// Special key to provide the full bibliography entry: see getInfo()
CiteEngineType const engine_type = buf.params().citeEngineType();
docstring const & format =
from_utf8(dc.getCiteFormat(engine_type, to_utf8(entry_type_)));
int counter = 0;
- ret = expandFormat(format, xrefs, counter, buf,
- docstring(), docstring(), docstring(), false);
+ ret = expandFormat(format, xrefs, counter, buf, ci, false, false);
} else if (key == "textbefore")
- ret = before;
+ ret = ci.textBefore;
else if (key == "textafter")
- ret = after;
+ ret = ci.textAfter;
else if (key == "year")
ret = getYear();
}
}
-docstring const BiblioInfo::getAbbreviatedAuthor(docstring const & key, Buffer const & buf) const
+docstring const BiblioInfo::getAuthorList(docstring const & key, Buffer const & buf) const
{
BiblioInfo::const_iterator it = find(key);
if (it == end())
return docstring();
BibTeXInfo const & data = it->second;
- return data.getAbbreviatedAuthor(&buf, false);
+ return data.getAuthorList(&buf, false);
}
docstring const BiblioInfo::getInfo(docstring const & key,
- Buffer const & buf, bool richtext) const
+ Buffer const & buf, CiteItem const & ci) const
{
BiblioInfo::const_iterator it = find(key);
if (it == end())
xrefptrs.push_back(&(xrefit->second));
}
}
- return data.getInfo(xrefptrs, buf, richtext);
+ return data.getInfo(xrefptrs, buf, ci);
}
docstring const BiblioInfo::getLabel(vector<docstring> keys,
- Buffer const & buf, string const & style, bool for_xhtml,
- size_t max_size, docstring const & before, docstring const & after,
- docstring const & dialog) const
+ Buffer const & buf, string const & style, CiteItem const & ci) const
{
+ size_t max_size = ci.max_size;
// shorter makes no sense
LASSERT(max_size >= 16, max_size = 16);
}
}
}
- ret = data.getLabel(xrefptrs, buf, ret, for_xhtml,
- before, after, dialog, key + 1 != ken);
+ ret = data.getLabel(xrefptrs, buf, ret, ci, key + 1 != ken, i == 1);
}
if (too_many_keys)
vector<docstring> const BiblioInfo::getCiteStrings(
vector<docstring> const & keys, vector<CitationStyle> const & styles,
- Buffer const & buf, docstring const & before,
- docstring const & after, docstring const & dialog, size_t max_size) const
+ Buffer const & buf, CiteItem const & ci) const
{
if (empty())
return vector<docstring>();
vector<docstring> vec(styles.size());
for (size_t i = 0; i != vec.size(); ++i) {
style = styles[i].name;
- vec[i] = getLabel(keys, buf, style, false, max_size, before, after, dialog);
+ vec[i] = getLabel(keys, buf, style, ci);
}
return vec;
// used in xhtml to sort a list of BibTeXInfo objects
bool lSorter(BibTeXInfo const * lhs, BibTeXInfo const * rhs)
{
- docstring const lauth = lhs->getAbbreviatedAuthor();
- docstring const rauth = rhs->getAbbreviatedAuthor();
+ docstring const lauth = lhs->getAuthorList();
+ docstring const rauth = rhs->getAuthorList();
docstring const lyear = lhs->getYear();
docstring const ryear = rhs->getYear();
docstring const ltitl = lhs->operator[]("title");
// the first test.
// coverity[FORWARD_NULL]
if (it != cited_entries_.begin()
- && entry.getAbbreviatedAuthor() == last->second.getAbbreviatedAuthor()
+ && entry.getAuthorList() == last->second.getAuthorList()
// we access the year via getYear() so as to get it from the xref,
// if we need to do so
&& getYear(entry.key()) == getYear(last->second.key())) {
if (numbers) {
entry.label(entry.citeNumber());
} else {
- docstring const auth = entry.getAbbreviatedAuthor(&buf, false);
+ docstring const auth = entry.getAuthorList(&buf, false);
// we do it this way so as to access the xref, if necessary
// note that this also gives us the modifier
docstring const year = getYear(*it, buf, true);