+ if (ret.empty() && !xrefs.empty()) {
+ vector<BibTeXInfo const *>::const_iterator it = xrefs.begin();
+ vector<BibTeXInfo const *>::const_iterator en = xrefs.end();
+ for (; it != en; ++it) {
+ if (*it && !(**it)[key].empty()) {
+ ret = (**it)[key];
+ break;
+ }
+ }
+ }
+ if (ret.empty()) {
+ // some special keys
+ // FIXME: dialog, textbefore and textafter have nothing to do with this
+ if (key == "dialog" && ci.context == CiteItem::Dialog)
+ ret = from_ascii("x"); // any non-empty string will do
+ else if (key == "export" && ci.context == CiteItem::Export)
+ 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 == "ifqualified" && ci.isQualified)
+ ret = from_ascii("x"); // any non-empty string will do
+ else if (key == "entrytype")
+ ret = entry_type_;
+ else if (prefixIs(key, "ifentrytype:")
+ && from_ascii(key.substr(12)) == entry_type_)
+ ret = from_ascii("x"); // any non-empty string will do
+ else if (key == "key")
+ ret = bib_key_;
+ else if (key == "label")
+ ret = label_;
+ else if (key == "modifier" && modifier_ != 0)
+ ret = modifier_;
+ else if (key == "numericallabel")
+ ret = cite_number_;
+ else if (prefixIs(key, "ifmultiple:")) {
+ // Return whether we have multiple authors
+ docstring const kind = operator[](from_ascii(key.substr(11)));
+ if (multipleAuthors(kind))
+ ret = from_ascii("x"); // any non-empty string will do
+ }
+ else if (prefixIs(key, "abbrvnames:")) {
+ // Special key to provide abbreviated name list,
+ // with respect to maxcitenames. Suitable for Bibliography
+ // beginnings.
+ docstring const kind = operator[](from_ascii(key.substr(11)));
+ ret = getAuthorList(&buf, kind, false, false, true);
+ if (ci.forceUpperCase && isLowerCase(ret[0]))
+ ret[0] = uppercase(ret[0]);
+ } else if (prefixIs(key, "fullnames:")) {
+ // Return a full name list. Suitable for Bibliography
+ // beginnings.
+ docstring const kind = operator[](from_ascii(key.substr(10)));
+ ret = getAuthorList(&buf, kind, true, false, true);
+ if (ci.forceUpperCase && isLowerCase(ret[0]))
+ ret[0] = uppercase(ret[0]);
+ } else if (prefixIs(key, "forceabbrvnames:")) {
+ // Special key to provide abbreviated name lists,
+ // irrespective of maxcitenames. Suitable for Bibliography
+ // beginnings.
+ docstring const kind = operator[](from_ascii(key.substr(15)));
+ ret = getAuthorList(&buf, kind, false, true, true);
+ if (ci.forceUpperCase && isLowerCase(ret[0]))
+ ret[0] = uppercase(ret[0]);
+ } else if (prefixIs(key, "abbrvbynames:")) {
+ // Special key to provide abbreviated name list,
+ // with respect to maxcitenames. Suitable for further names inside a
+ // bibliography item // (such as "ed. by ...")
+ docstring const kind = operator[](from_ascii(key.substr(11)));
+ ret = getAuthorList(&buf, kind, false, false, true, false);
+ if (ci.forceUpperCase && isLowerCase(ret[0]))
+ ret[0] = uppercase(ret[0]);
+ } else if (prefixIs(key, "fullbynames:")) {
+ // Return a full name list. Suitable for further names inside a
+ // bibliography item // (such as "ed. by ...")
+ docstring const kind = operator[](from_ascii(key.substr(10)));
+ ret = getAuthorList(&buf, kind, true, false, true, false);
+ if (ci.forceUpperCase && isLowerCase(ret[0]))
+ ret[0] = uppercase(ret[0]);
+ } else if (prefixIs(key, "forceabbrvbynames:")) {
+ // Special key to provide abbreviated name lists,
+ // irrespective of maxcitenames. Suitable for further names inside a
+ // bibliography item // (such as "ed. by ...")
+ docstring const kind = operator[](from_ascii(key.substr(15)));
+ ret = getAuthorList(&buf, kind, false, true, true, false);
+ if (ci.forceUpperCase && isLowerCase(ret[0]))
+ ret[0] = uppercase(ret[0]);
+ } else if (key == "abbrvciteauthor") {
+ // Special key to provide abbreviated author or
+ // editor names (suitable for citation labels),
+ // with respect to maxcitenames.
+ ret = getAuthorOrEditorList(&buf, false, false);
+ if (ci.forceUpperCase && isLowerCase(ret[0]))
+ ret[0] = uppercase(ret[0]);
+ } else if (key == "fullciteauthor") {
+ // Return a full author or editor list (for citation labels)
+ ret = getAuthorOrEditorList(&buf, true, false);
+ if (ci.forceUpperCase && isLowerCase(ret[0]))
+ ret[0] = uppercase(ret[0]);
+ } else if (key == "forceabbrvciteauthor") {
+ // Special key to provide abbreviated author or
+ // editor names (suitable for citation labels),
+ // irrespective of maxcitenames.
+ ret = getAuthorOrEditorList(&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();
+ DocumentClass const & dc = buf.params().documentClass();
+ docstring const & format =
+ from_utf8(dc.getCiteFormat(engine_type, to_utf8(entry_type_), false));
+ int counter = 0;
+ ret = expandFormat(format, xrefs, counter, buf, ci, false, false);
+ } else if (key == "textbefore")
+ ret = ci.textBefore;
+ else if (key == "textafter")
+ ret = ci.textAfter;
+ else if (key == "curpretext")
+ ret = ci.getPretexts()[bib_key_];
+ else if (key == "curposttext")
+ ret = ci.getPosttexts()[bib_key_];
+ else if (key == "year")
+ ret = getYear();
+ }
+
+ if (cleanit)
+ ret = html::cleanAttr(ret);
+
+ // make sure it is not too big
+ support::truncateWithEllipsis(ret, maxsize);