Implement display of starred cite commands

This entails a change of getAbbrAuthor to getAuthorList (the default is
still abbreviated with respect to MaxCiteItems, but the list can be, at
explicit request, shortened or full notwithstanding MaxCiteItems.
This commit is contained in:
Juergen Spitzmueller 2017-01-07 17:32:45 +01:00
parent 6933051747
commit eba2f0479e
8 changed files with 113 additions and 44 deletions

View File

@ -43,6 +43,7 @@ CiteFormat default
# MACROS
#
# 1. Translatable bits (need to be marked by _ prefix)
# Note that preceding and trailing spaces matter.
#
_notcited not cited
_addtobib Add to bibliography only.

View File

@ -109,6 +109,7 @@ CiteFormat authoryear
# MACROS
#
# 1. Translatable bits (need to be marked by _ prefix)
# Note that preceding and trailing spaces matter.
#
_notcited not cited
_addtobib Add to bibliography only.
@ -116,6 +117,11 @@ CiteFormat authoryear
_bibentry Bibliography entry.
_before before
_shorttitle short title
# The following are handled by BiblioInfo
_etal et al.
_namesep /
_lastnamesep /
_pairnamesep /
#
# 2. Macros re-used in the style definitions

View File

@ -106,9 +106,15 @@ CiteFormat default
# MACROS
#
# 1. Translatable bits (need to be marked by _ prefix)
# Note that preceding and trailing spaces matter.
#
_notcited not cited
_addtobib Add to bibliography only.
# The following are handled by BiblioInfo
_etal et al.
_namesep , [[separate author names in citation, except for last name]]
_lastnamesep , and [[separate name of last author in citation]]
_pairnamesep and [[separate two authors in citation]]
#
# 2. Macros re-used in the style definitions
@ -120,6 +126,10 @@ CiteFormat default
# "Author et al." or "??"
!abbrvauthor {%abbrvauthor%[[%abbrvauthor%]][[??]]}
# "Author, ..." or "??"
!fullauthor {%fullauthor%[[%fullauthor%]][[??]]}
# Handle starred command: abbr. or full author list
!makeauthor {%ifstar%[[%!fullauthor%]][[%!abbrvauthor%]]}
# "prenote "
!textbefore {%textbefore%[[%textbefore% ]]}
# ", postnote"
@ -129,6 +139,8 @@ CiteFormat default
# "...; Author..."
!nextauthor {%next%[[%!sep% %!startlink%%!abbrvauthor%%!endlink%%!nextauthor%]]}
# Handle starred command: abbr. or full author list
!makenextauthor {%next%[[%!sep% %!startlink%%!makeauthor%%!endlink%%!makenextauthor%]]}
# "..., CiteKey..."
!nextkey {%next%[[%!sep% %key%%!nextkey%]]}
# "..., Year..."
@ -155,14 +167,14 @@ CiteFormat authoryear
!close )
# "Author et al. (cf. Year..."
!makecitet %!startlink%%!abbrvauthor%%!endlink% %!open%%!textbefore%%!year%%!nextcitet%
!makecitet %!startlink%%!makeauthor%%!endlink% %!open%%!textbefore%%!year%%!nextcitet%
# "Author et al. cf. Year..." [sic!]
!makecitealt %!startlink%%!abbrvauthor% %!textbefore%%!year%%!endlink%%!nextcitealt%
!makecitealt %!startlink%%!makeauthor% %!textbefore%%!year%%!endlink%%!nextcitealt%
# "Author et al., Year..."
!makecitealp %!startlink%%!abbrvauthor%, %!year%%!endlink%%!nextcitealp%
!makecitealp %!startlink%%!makeauthor%, %!year%%!endlink%%!nextcitealp%
# "...); Nextauthor (Year..."
!nextcitet {%next%[[%!close%%!sep% %!startlink%%!abbrvauthor%%!endlink% %!open%%!year%%!nextcitet%]]}
!nextcitet {%next%[[%!close%%!sep% %!startlink%%!makeauthor%%!endlink% %!open%%!year%%!nextcitet%]]}
# "...; NextAuthor et al. Year..."
!nextcitealt {%next%[[%!sep% %!makecitealt%]]}
# "...; NextAuthor et al., Year..."
@ -183,7 +195,7 @@ CiteFormat authoryear
# "Author cf. Year; NextAuthor Year, p. xx" [sic!]
citealt %!makecitealt%%!textafter%
# "Author; NextAuthor, p. xx"
citeauthor %!startlink%%!abbrvauthor%%!endlink%%!nextauthor%%!textafter%
citeauthor %!startlink%%!makeauthor%%!endlink%%!makenextauthor%%!textafter%
# "Year; NextYear, p. xx"
citeyear %!startlink%%!year%%!endlink%%!nextyear%%!textafter%
@ -200,16 +212,16 @@ CiteFormat numerical
!close ]
# "Author [cf. ID..."
!makecitet %!abbrvauthor% %!open%%!textbefore%{%dialog%[[#ID]][[%!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%]]}%!nextcitet%
!makecitet %!makeauthor% %!open%%!textbefore%{%dialog%[[#ID]][[%!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%]]}%!nextcitet%
# "Author cf. ID..."
!makecitealt %!abbrvauthor% %!textbefore%{%dialog%[[#ID]][[%!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%]]}%!nextcitealt%
!makecitealt %!makeauthor% %!textbefore%{%dialog%[[#ID]][[%!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%]]}%!nextcitealt%
# "ID..."
!hashkey {%dialog%[[#ID]][[%!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%%!nexthashkey%]]}
# "...], NextAuthor [ID..."
!nextcitet {%next%[[%!close%%!sep% %!abbrvauthor% %!open%%!textbefore%{%dialog%[[#ID]][[%!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%]]}%!nextcitet%]]}
!nextcitet {%next%[[%!close%%!sep% %!makeauthor% %!open%%!textbefore%{%dialog%[[#ID]][[%!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%]]}%!nextcitet%]]}
# "..., NextAuthor ID..."
!nextcitealt {%next%[[%!sep% %!abbrvauthor% {%dialog%[[#ID]][[%!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%]]}%!nextcitealt%]]}
!nextcitealt {%next%[[%!sep% %!makeauthor% {%dialog%[[#ID]][[%!startlink%{%numericallabel%[[%numericallabel%]][[#%key%]]}%!endlink%]]}%!nextcitealt%]]}
# FIXME: What is this?
!nexthashid {%next%[[%!sep% #ID%!nexthashid%]]}
# "..., NextID..."
@ -230,7 +242,7 @@ CiteFormat numerical
# "Author cf. ID, NextAuthor ID, p. xx"
citealt %!makecitealt%%!textafter%
# "Author, NextAuthor"
citeauthor %!startlink%%!abbrvauthor%%!endlink%%!nextauthor%
citeauthor %!startlink%%!makeauthor%%!endlink%%!makenextauthor%
# "Year, NextYear"
citeyear %!startlink%%!year%%!endlink%%!nextyear%

View File

@ -256,9 +256,13 @@ BibTeXInfo::BibTeXInfo(docstring const & key, docstring const & type)
{}
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())
@ -295,21 +299,51 @@ docstring const BibTeXInfo::getAbbreviatedAuthor(
shortauthor += "/" + familyName(authors[2]);
return convertLaTeXCommands(shortauthor);
}
docstring retval;
docstring retval = familyName(authors[0]);
CiteEngineType const engine_type = buf ? buf->params().citeEngineType()
: ENGINE_TYPE_DEFAULT;
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]));
// 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);
}
@ -717,6 +751,8 @@ docstring BibTeXInfo::getValueForKey(string const & oldkey, Buffer const & buf,
// 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 == "ifstar" && ci.Starred)
ret = from_ascii("x"); // any non-empty string will do
else if (key == "entrytype")
ret = entry_type_;
else if (key == "key")
@ -727,9 +763,6 @@ docstring BibTeXInfo::getValueForKey(string const & oldkey, Buffer const & buf,
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
@ -744,6 +777,21 @@ docstring BibTeXInfo::getValueForKey(string const & oldkey, Buffer const & buf,
+ " [" + 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") {
@ -866,13 +914,13 @@ vector<docstring> const BiblioInfo::getEntries() const
}
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);
}
@ -1038,8 +1086,8 @@ namespace {
// 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");
@ -1127,7 +1175,7 @@ void BiblioInfo::makeCitationLabels(Buffer const & buf)
// 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())) {
@ -1159,7 +1207,7 @@ void BiblioInfo::makeCitationLabels(Buffer const & buf)
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);

View File

@ -55,11 +55,12 @@ public:
BibTeXInfo(bool ib) : is_bibtex_(ib), modifier_(0) {}
/// constructor that sets the entryType
BibTeXInfo(docstring const & key, docstring const & type);
/// \return the short form of an authorlist, used for sorting
/// this will be translated to the UI language if buf is null
/// \return the an authorlist (short form by default),
/// used for sorting.
/// This will be translated to the UI language if buf is null
/// otherwise, it will be translated to the buffer language.
docstring const getAbbreviatedAuthor(
Buffer const * buf = 0, bool jurabib_style = false) const;
docstring const getAuthorList(Buffer const * buf = 0, bool full = false,
bool forceshort = false) const;
///
docstring const getYear() const;
/// \return formatted BibTeX data suitable for framing.
@ -178,8 +179,8 @@ public:
std::vector<docstring> const getFields() const;
/// \return a sorted vector of BibTeX entry types in use
std::vector<docstring> const getEntries() const;
/// \return the short form of an authorlist
docstring const getAbbreviatedAuthor(docstring const & key, Buffer const & buf) const;
/// \return authorlist (abbreviated form by default)
docstring const getAuthorList(docstring const & key, Buffer const & buf) const;
/// \return the year from the bibtex data record for \param key
/// if \param use_modifier is true, then we will also append any
/// modifier for this entry (e.g., 1998b).

View File

@ -125,7 +125,7 @@ GuiCitation::GuiCitation(GuiView & lv)
connect(citationStyleCO, SIGNAL(activated(int)),
this, SLOT(on_citationStyleCO_currentIndexChanged(int)));
connect(starredCB, SIGNAL(clicked()),
this, SLOT(changed()));
this, SLOT(updateStyles()));
connect(forceuppercaseCB, SIGNAL(clicked()),
this, SLOT(updateStyles()));
connect(textBeforeED, SIGNAL(textChanged(QString)),
@ -686,6 +686,7 @@ QStringList GuiCitation::citationStyles(BiblioInfo const & bi, size_t max_size)
ci.textBefore = qstring_to_ucs4(textBeforeED->text());
ci.textAfter = qstring_to_ucs4(textAfterED->text());
ci.forceUpperCase = forceuppercaseCB->isChecked();
ci.Starred = starredCB->isChecked();
ci.context = CiteItem::Dialog;
ci.max_size = max_size;
vector<docstring> ret = bi.getCiteStrings(keys, styles, documentBuffer(), ci);

View File

@ -1554,6 +1554,7 @@ void MenuDefinition::expandCiteStyles(BufferView const * bv)
ci.textBefore = citinset->getParam("before");
ci.textAfter = citinset->getParam("after");
ci.forceUpperCase = force;
ci.Starred = star;
ci.context = CiteItem::Dialog;
ci.max_size = 40;
vector<docstring> citeStrings =

View File

@ -177,7 +177,6 @@ docstring InsetCitation::toolTip(BufferView const & bv, int, int) const
namespace {
CitationStyle asValidLatexCommand(BufferParams const & bp, string const & input,
vector<CitationStyle> const & valid_styles)
{
@ -254,13 +253,12 @@ docstring InsetCitation::complexLabel(bool for_xhtml) const
if (key.empty())
return _("No citations selected!");
// We don't currently use the full or forceUCase fields.
string cite_type = getCmdName();
bool const uppercase = isUpperCase(cite_type[0]);
if (uppercase)
cite_type[0] = lowercase(cite_type[0]);
if (cite_type[cite_type.size() - 1] == '*')
// and this would mean FULL
bool const starred = (cite_type[cite_type.size() - 1] == '*');
if (starred)
cite_type = cite_type.substr(0, cite_type.size() - 1);
// handle alias
@ -279,6 +277,7 @@ docstring InsetCitation::complexLabel(bool for_xhtml) const
ci.textBefore = getParam("before");
ci.textAfter = getParam("after");
ci.forceUpperCase = uppercase;
ci.Starred = starred;
ci.max_size = UINT_MAX;
if (for_xhtml) {
ci.max_key_size = UINT_MAX;