BiblioInfo: Ability to distinguish '&' and 'and' author separation

Finicky styles such as APA use both in different context, and we need
to represent this to make style choice differentiatable
This commit is contained in:
Juergen Spitzmueller 2024-07-11 09:13:43 +02:00
parent a1e57a8fe5
commit 5c2652fa12
3 changed files with 49 additions and 24 deletions

View File

@ -29,6 +29,8 @@ CiteFormat default
B_namesep , [[separate author names in citation, except for last name]] B_namesep , [[separate author names in citation, except for last name]]
B_lastnamesep , and [[separate name of last author in citation]] B_lastnamesep , and [[separate name of last author in citation]]
B_pairnamesep and [[separate two authors in citation]] B_pairnamesep and [[separate two authors in citation]]
B_lastampnamesep , & [[separate name of last author in citation w/ ampersand]]
B_amppairnamesep & [[separate two authors in citation w/ ampersand]]
# #
# Macros # Macros

View File

@ -524,19 +524,19 @@ BibTeXInfo::BibTeXInfo(docstring const & key, docstring const & type)
docstring const BibTeXInfo::getAuthorOrEditorList(Buffer const * buf, docstring const BibTeXInfo::getAuthorOrEditorList(Buffer const * buf,
size_t const max_key_size, size_t const max_key_size,
bool full, bool forceshort) const bool amp, bool full, bool forceshort) const
{ {
docstring author = operator[]("author"); docstring author = operator[]("author");
if (author.empty()) if (author.empty())
author = operator[]("editor"); author = operator[]("editor");
return getAuthorList(buf, author, max_key_size, full, forceshort); return getAuthorList(buf, author, max_key_size, amp, full, forceshort);
} }
docstring const BibTeXInfo::getAuthorList(Buffer const * buf, docstring const BibTeXInfo::getAuthorList(Buffer const * buf,
docstring const & author, size_t const max_key_size, docstring const & author, size_t const max_key_size,
bool const full, bool const forceshort, bool const amp, bool const full, bool const forceshort,
bool const allnames, bool const beginning) const bool const allnames, bool const beginning) const
{ {
// Maxnames treshold depend on engine // Maxnames treshold depend on engine
@ -582,12 +582,14 @@ docstring const BibTeXInfo::getAuthorList(Buffer const * buf,
string const namesep = string const namesep =
buf ? buf->params().documentClass().getCiteMacro(engine_type, "B_namesep") buf ? buf->params().documentClass().getCiteMacro(engine_type, "B_namesep")
: ", "; : ", ";
string const lastnamesep = string lastnamesep = ", and ";
buf ? buf->params().documentClass().getCiteMacro(engine_type, "B_lastnamesep") if (buf)
: ", and "; lastnamesep = amp ? buf->params().documentClass().getCiteMacro(engine_type, "B_lastampnamesep")
string const pairnamesep = : buf->params().documentClass().getCiteMacro(engine_type, "B_lastnamesep");
buf ? buf->params().documentClass().getCiteMacro(engine_type, "B_pairnamesep") string pairnamesep = " and ";
: " and "; if (buf)
pairnamesep = amp ? buf->params().documentClass().getCiteMacro(engine_type, "B_amppairnamesep")
: buf->params().documentClass().getCiteMacro(engine_type, "B_pairnamesep");
string firstnameform = string firstnameform =
buf ? buf->params().documentClass().getCiteMacro(engine_type, "!firstnameform") buf ? buf->params().documentClass().getCiteMacro(engine_type, "!firstnameform")
: "{%prefix%[[%prefix% ]]}%surname%{%suffix%[[, %suffix%]]}{%prename%[[, %prename%]]}"; : "{%prefix%[[%prefix% ]]}%surname%{%suffix%[[, %suffix%]]}{%prename%[[, %prename%]]}";
@ -1192,65 +1194,86 @@ docstring BibTeXInfo::getValueForKey(string const & oldkey, Buffer const & buf,
// Special key to provide abbreviated name list, // Special key to provide abbreviated name list,
// with respect to maxcitenames. Suitable for Bibliography // with respect to maxcitenames. Suitable for Bibliography
// beginnings. // beginnings.
bool const amp = prefixIs(subtype, '&');
if (amp)
subtype = subtype.substr(1);
docstring const kind = operator[](subtype); docstring const kind = operator[](subtype);
ret = getAuthorList(&buf, kind, ci.max_key_size, false, false, true); ret = getAuthorList(&buf, kind, ci.max_key_size, amp, false, false, true);
if (ci.forceUpperCase && isLowerCase(ret[0])) if (ci.forceUpperCase && isLowerCase(ret[0]))
ret[0] = uppercase(ret[0]); ret[0] = uppercase(ret[0]);
} else if (prefixIs(key, "fullnames:")) { } else if (prefixIs(key, "fullnames:")) {
// Return a full name list. Suitable for Bibliography // Return a full name list. Suitable for Bibliography
// beginnings. // beginnings.
bool const amp = prefixIs(subtype, '&');
if (amp)
subtype = subtype.substr(1);
docstring const kind = operator[](subtype); docstring const kind = operator[](subtype);
ret = getAuthorList(&buf, kind, ci.max_key_size, true, false, true); ret = getAuthorList(&buf, kind, ci.max_key_size, amp, true, false, true);
if (ci.forceUpperCase && isLowerCase(ret[0])) if (ci.forceUpperCase && isLowerCase(ret[0]))
ret[0] = uppercase(ret[0]); ret[0] = uppercase(ret[0]);
} else if (prefixIs(key, "forceabbrvnames:")) { } else if (prefixIs(key, "forceabbrvnames:")) {
// Special key to provide abbreviated name lists, // Special key to provide abbreviated name lists,
// irrespective of maxcitenames. Suitable for Bibliography // irrespective of maxcitenames. Suitable for Bibliography
// beginnings. // beginnings.
bool const amp = prefixIs(subtype, '&');
if (amp)
subtype = subtype.substr(1);
docstring const kind = operator[](subtype); docstring const kind = operator[](subtype);
ret = getAuthorList(&buf, kind, ci.max_key_size, false, true, true); ret = getAuthorList(&buf, kind, ci.max_key_size, amp, false, true, true);
if (ci.forceUpperCase && isLowerCase(ret[0])) if (ci.forceUpperCase && isLowerCase(ret[0]))
ret[0] = uppercase(ret[0]); ret[0] = uppercase(ret[0]);
} else if (prefixIs(key, "abbrvbynames:")) { } else if (prefixIs(key, "abbrvbynames:")) {
// Special key to provide abbreviated name list, // Special key to provide abbreviated name list,
// with respect to maxcitenames. Suitable for further names inside a // with respect to maxcitenames. Suitable for further names inside a
// bibliography item // (such as "ed. by ...") // bibliography item // (such as "ed. by ...")
bool const amp = prefixIs(subtype, '&');
if (amp)
subtype = subtype.substr(1);
docstring const kind = operator[](subtype); docstring const kind = operator[](subtype);
ret = getAuthorList(&buf, kind, ci.max_key_size, false, false, true, false); ret = getAuthorList(&buf, kind, ci.max_key_size, amp, false, false, true, false);
if (ci.forceUpperCase && isLowerCase(ret[0])) if (ci.forceUpperCase && isLowerCase(ret[0]))
ret[0] = uppercase(ret[0]); ret[0] = uppercase(ret[0]);
} else if (prefixIs(key, "fullbynames:")) { } else if (prefixIs(key, "fullbynames:")) {
// Return a full name list. Suitable for further names inside a // Return a full name list. Suitable for further names inside a
// bibliography item // (such as "ed. by ...") // bibliography item // (such as "ed. by ...")
bool const amp = prefixIs(subtype, '&');
if (amp)
subtype = subtype.substr(1);
docstring const kind = operator[](subtype); docstring const kind = operator[](subtype);
ret = getAuthorList(&buf, kind, ci.max_key_size, true, false, true, false); ret = getAuthorList(&buf, kind, ci.max_key_size, amp, true, false, true, false);
if (ci.forceUpperCase && isLowerCase(ret[0])) if (ci.forceUpperCase && isLowerCase(ret[0]))
ret[0] = uppercase(ret[0]); ret[0] = uppercase(ret[0]);
} else if (prefixIs(key, "forceabbrvbynames:")) { } else if (prefixIs(key, "forceabbrvbynames:")) {
// Special key to provide abbreviated name lists, // Special key to provide abbreviated name lists,
// irrespective of maxcitenames. Suitable for further names inside a // irrespective of maxcitenames. Suitable for further names inside a
// bibliography item // (such as "ed. by ...") // bibliography item // (such as "ed. by ...")
bool const amp = prefixIs(subtype, '&');
if (amp)
subtype = subtype.substr(1);
docstring const kind = operator[](subtype); docstring const kind = operator[](subtype);
ret = getAuthorList(&buf, kind, ci.max_key_size, false, true, true, false); ret = getAuthorList(&buf, kind, ci.max_key_size, amp, false, true, true, false);
if (ci.forceUpperCase && isLowerCase(ret[0])) if (ci.forceUpperCase && isLowerCase(ret[0]))
ret[0] = uppercase(ret[0]); ret[0] = uppercase(ret[0]);
} else if (key == "abbrvciteauthor") { } else if (prefixIs(key, "abbrvciteauthor")) {
// Special key to provide abbreviated author or // Special key to provide abbreviated author or
// editor names (suitable for citation labels), // editor names (suitable for citation labels),
// with respect to maxcitenames. // with respect to maxcitenames.
ret = getAuthorOrEditorList(&buf, ci.max_key_size, false, false); bool const amp = suffixIs(key, "&");
ret = getAuthorOrEditorList(&buf, ci.max_key_size, amp, false, false);
if (ci.forceUpperCase && isLowerCase(ret[0])) if (ci.forceUpperCase && isLowerCase(ret[0]))
ret[0] = uppercase(ret[0]); ret[0] = uppercase(ret[0]);
} else if (key == "fullciteauthor") { } else if (prefixIs(key, "fullciteauthor")) {
// Return a full author or editor list (for citation labels) // Return a full author or editor list (for citation labels)
ret = getAuthorOrEditorList(&buf, ci.max_key_size, true, false); bool const amp = suffixIs(key, "&");
ret = getAuthorOrEditorList(&buf, ci.max_key_size, amp, true, false);
if (ci.forceUpperCase && isLowerCase(ret[0])) if (ci.forceUpperCase && isLowerCase(ret[0]))
ret[0] = uppercase(ret[0]); ret[0] = uppercase(ret[0]);
} else if (key == "forceabbrvciteauthor") { } else if (prefixIs(key, "forceabbrvciteauthor")) {
// Special key to provide abbreviated author or // Special key to provide abbreviated author or
// editor names (suitable for citation labels), // editor names (suitable for citation labels),
// irrespective of maxcitenames. // irrespective of maxcitenames.
ret = getAuthorOrEditorList(&buf, ci.max_key_size, false, true); bool const amp = suffixIs(key, "&");
ret = getAuthorOrEditorList(&buf, ci.max_key_size, amp, false, true);
if (ci.forceUpperCase && isLowerCase(ret[0])) if (ci.forceUpperCase && isLowerCase(ret[0]))
ret[0] = uppercase(ret[0]); ret[0] = uppercase(ret[0]);
} else if (key == "bibentry") { } else if (key == "bibentry") {
@ -1425,7 +1448,7 @@ docstring const BiblioInfo::getAuthorOrEditorList(docstring const & key, Buffer
if (it == end()) if (it == end())
return docstring(); return docstring();
BibTeXInfo const & data = it->second; BibTeXInfo const & data = it->second;
return data.getAuthorOrEditorList(&buf, max_key_size, false); return data.getAuthorOrEditorList(&buf, max_key_size, false, false);
} }

View File

@ -68,10 +68,10 @@ public:
/// otherwise, it will be translated to the buffer language. /// otherwise, it will be translated to the buffer language.
docstring const getAuthorOrEditorList(Buffer const * buf = nullptr, docstring const getAuthorOrEditorList(Buffer const * buf = nullptr,
size_t const max_key_size = 128, size_t const max_key_size = 128,
bool full = false, bool forceshort = false) const; bool amp = false, bool full = false, bool forceshort = false) const;
/// Same for a specific author role (editor, author etc.) /// Same for a specific author role (editor, author etc.)
docstring const getAuthorList(Buffer const * buf, docstring const & author, size_t const max_key_size, docstring const getAuthorList(Buffer const * buf, docstring const & author, size_t const max_key_size,
bool const full = false, bool const forceshort = false, bool const amp = false, bool const full = false, bool const forceshort = false,
bool const allnames = false, bool const beginning = true) const; bool const allnames = false, bool const beginning = true) const;
/// ///
docstring const getYear() const; docstring const getYear() const;