From: Richard Heck Date: Mon, 20 Aug 2007 17:04:36 +0000 (+0000) Subject: Biblio.{h,cpp} --> BiblioInfo.{h,cpp} X-Git-Tag: 1.6.10~8794 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=cd772c60a58569034d9fa5aa5f7963e3c90241cf;p=features.git Biblio.{h,cpp} --> BiblioInfo.{h,cpp} git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19660 a592a061-630c-0410-9148-cb99ea01b6c8 --- diff --git a/development/qmake/src/src.pro b/development/qmake/src/src.pro index ced3a40562..2c44a0a2ff 100644 --- a/development/qmake/src/src.pro +++ b/development/qmake/src/src.pro @@ -12,7 +12,7 @@ INC += boost HPP += ASpell_local.h HPP += Author.h -HPP += Biblio.h +HPP += BiblioInfo.h HPP += Bidi.h HPP += Box.h HPP += BranchList.h @@ -122,7 +122,7 @@ HPP += version.h #CPP += ASpell.cpp CPP += Author.cpp -CPP += Biblio.cpp +CPP += BiblioInfo.cpp CPP += Bidi.cpp CPP += Box.cpp CPP += BranchList.cpp diff --git a/development/scons/scons_manifest.py b/development/scons/scons_manifest.py index 5ea690fe8c..0c05993126 100644 --- a/development/scons/scons_manifest.py +++ b/development/scons/scons_manifest.py @@ -33,7 +33,7 @@ TOP_extra_files = Split(''' src_header_files = Split(''' ASpell_local.h Author.h - Biblio.h + BiblioInfo.h Bidi.h Box.h BranchList.h @@ -144,7 +144,7 @@ src_header_files = Split(''' src_pre_files = Split(''' Author.cpp - Biblio.cpp + BiblioInfo.cpp Bidi.cpp BranchList.cpp Buffer.cpp diff --git a/src/Biblio.cpp b/src/Biblio.cpp deleted file mode 100644 index a295defa19..0000000000 --- a/src/Biblio.cpp +++ /dev/null @@ -1,551 +0,0 @@ -/** - * \file BiblioInfo.cpp - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author Angus Leeming - * \author Herbert Voß - * \author Richard Heck - * - * Full author contact details are available in file CREDITS. - */ - -#include - -#include "Biblio.h" -#include "Buffer.h" -#include "BufferParams.h" -#include "buffer_funcs.h" -#include "gettext.h" -#include "InsetIterator.h" -#include "Paragraph.h" - -#include "insets/Inset.h" -#include "insets/InsetBibitem.h" -#include "insets/InsetBibtex.h" -#include "insets/InsetInclude.h" - -#include "support/lstrings.h" - -#include "boost/regex.hpp" - -using std::string; -using std::vector; -using std::pair; -using std::endl; -using std::set; - -namespace lyx { -using support::bformat; -using support::compare_no_case; -using support::getVectorFromString; -using support::ltrim; -using support::rtrim; - -//////////////////////////////////////// -// -// BibTeXInfo -// -//////////////////////////////////////// - -BibTeXInfo::BibTeXInfo() : isBibTeX(true) -{} - - -bool BibTeXInfo::hasField(docstring const & field) const -{ - return count(field) == 1; -} - - -docstring const & BibTeXInfo::getValueForField(docstring const & field) const -{ - BibTeXInfo::const_iterator it = find(field); - if (it != end()) - return it->second; - static docstring const empty_value = docstring(); - return empty_value; -} - - -docstring const & BibTeXInfo::getValueForField(string const & field) const -{ - return getValueForField(from_ascii(field)); -} - - -namespace { - docstring const familyName(docstring const & name) - { - if (name.empty()) - return docstring(); - - // Very simple parser - docstring fname = name; - - // possible authorname combinations are: - // "Surname, FirstName" - // "Surname, F." - // "FirstName Surname" - // "F. Surname" - docstring::size_type idx = fname.find(','); - if (idx != docstring::npos) - return ltrim(fname.substr(0, idx)); - idx = fname.rfind('.'); - if (idx != docstring::npos && idx + 1 < fname.size()) - fname = ltrim(fname.substr(idx + 1)); - // test if we have a LaTeX Space in front - if (fname[0] == '\\') - return fname.substr(2); - return rtrim(fname); - } -} // namespace anon - - - -docstring const BibTeXInfo::getAbbreviatedAuthor() const -{ - if (!isBibTeX) - return docstring(); - - docstring author = getValueForField("author"); - - if (author.empty()) { - author = getValueForField("editor"); - if (author.empty()) - return bibKey; - } - - //OK, we've got some names. Let's format them. - //Try to split the author list on " and " - vector const authors = - getVectorFromString(author, from_ascii(" and ")); - - if (authors.size() == 2) - return bformat(_("%1$s and %2$s"), - familyName(authors[0]), familyName(authors[1])); - else if (authors.size() > 2) - return bformat(_("%1$s et al."), familyName(authors[0])); - else - return familyName(authors[0]); -} - -docstring const BibTeXInfo::getYear() const -{ - if (!isBibTeX) - return docstring(); - - docstring year = getValueForField("year"); - if (year.empty()) - year = _("No year"); - return year; -} - - -docstring const BibTeXInfo::getInfo() const -{ - if (!isBibTeX) { - BibTeXInfo::const_iterator it = find(from_ascii("ref")); - return it->second; - } - - //FIXME - //This could be made alot better using the entryType - //field to customize the output based upon entry type. - - //Search for all possible "required" fields - docstring author = getValueForField("author"); - if (author.empty()) - author = getValueForField("editor"); - - docstring year = getValueForField("year"); - docstring title = getValueForField("title"); - docstring docLoc = getValueForField("pages"); - if (docLoc.empty()) { - docLoc = getValueForField("chapter"); - if (!docLoc.empty()) - docLoc = from_ascii("Ch. ") + docLoc; - } else - docLoc = from_ascii("pp. ") + docLoc; - docstring media = getValueForField("journal"); - if (media.empty()) { - media = getValueForField("publisher"); - if (media.empty()) { - media = getValueForField("school"); - if (media.empty()) - media = getValueForField("institution"); - } - } - docstring volume = getValueForField("volume"); - - odocstringstream result; - if (!author.empty()) - result << author << ", "; - if (!title.empty()) - result << title; - if (!media.empty()) - result << ", " << media; - if (!year.empty()) - result << ", " << year; - if (!docLoc.empty()) - result << ", " << docLoc; - - docstring const result_str = rtrim(result.str()); - if (!result_str.empty()) - return result_str; - - // This should never happen (or at least be very unusual!) - return docstring(); -} - - -//////////////////////////////////////// -// -// BiblioInfo -// -//////////////////////////////////////// - -namespace { -// A functor for use with std::sort, leading to case insensitive sorting - class compareNoCase: public std::binary_function - { - public: - bool operator()(docstring const & s1, docstring const & s2) const { - return compare_no_case(s1, s2) < 0; - } - }; -} // namespace anon - - -vector const BiblioInfo::getKeys() const -{ - vector bibkeys; - BiblioInfo::const_iterator it = begin(); - for (; it != end(); ++it) - bibkeys.push_back(it->first); - std::sort(bibkeys.begin(), bibkeys.end(), compareNoCase()); - return bibkeys; -} - - -vector const BiblioInfo::getFields() const -{ - vector bibfields; - set::const_iterator it = fieldNames.begin(); - set::const_iterator end = fieldNames.end(); - for (; it != end; ++it) - bibfields.push_back(*it); - std::sort(bibfields.begin(), bibfields.end()); - return bibfields; -} - - -vector const BiblioInfo::getEntries() const -{ - vector bibentries; - set::const_iterator it = entryTypes.begin(); - set::const_iterator end = entryTypes.end(); - for (; it != end; ++it) - bibentries.push_back(*it); - std::sort(bibentries.begin(), bibentries.end()); - return bibentries; -} - - -docstring const BiblioInfo::getAbbreviatedAuthor(docstring const & key) const -{ - BiblioInfo::const_iterator it = find(key); - if (it == end()) - return docstring(); - BibTeXInfo const & data = it->second; - return data.getAbbreviatedAuthor(); -} - - -docstring const BiblioInfo::getYear(docstring const & key) const -{ - BiblioInfo::const_iterator it = find(key); - if (it == end()) - return docstring(); - BibTeXInfo const & data = it->second; - return data.getYear(); -} - - -docstring const BiblioInfo::getInfo(docstring const & key) const -{ - BiblioInfo::const_iterator it = find(key); - if (it == end()) - return docstring(); - BibTeXInfo const & data = it->second; - return data.getInfo(); -} - - -vector const BiblioInfo::getCiteStrings( - docstring const & key, Buffer const & buf) const -{ - biblio::CiteEngine const engine = buf.params().getEngine(); - if (engine == biblio::ENGINE_NATBIB_NUMERICAL) - return getNumericalStrings(key, buf); - else - return getAuthorYearStrings(key, buf); -} - - -vector const BiblioInfo::getNumericalStrings( - docstring const & key, Buffer const & buf) const -{ - if (empty()) - return vector(); - - docstring const author = getAbbreviatedAuthor(key); - docstring const year = getYear(key); - if (author.empty() || year.empty()) - return vector(); - - vector const & styles = - biblio::getCiteStyles(buf.params().getEngine()); - - vector vec(styles.size()); - for (vector::size_type i = 0; i != vec.size(); ++i) { - docstring str; - - switch (styles[i]) { - case biblio::CITE: - case biblio::CITEP: - str = from_ascii("[#ID]"); - break; - - case biblio::CITET: - str = author + " [#ID]"; - break; - - case biblio::CITEALT: - str = author + " #ID"; - break; - - case biblio::CITEALP: - str = from_ascii("#ID"); - break; - - case biblio::CITEAUTHOR: - str = author; - break; - - case biblio::CITEYEAR: - str = year; - break; - - case biblio::CITEYEARPAR: - str = '(' + year + ')'; - break; - } - - vec[i] = str; - } - - return vec; -} - - -vector const BiblioInfo::getAuthorYearStrings( - docstring const & key, Buffer const & buf) const -{ - if (empty()) - return vector(); - - docstring const author = getAbbreviatedAuthor(key); - docstring const year = getYear(key); - if (author.empty() || year.empty()) - return vector(); - - vector const & styles = - getCiteStyles(buf.params().getEngine()); - - vector vec(styles.size()); - for (vector::size_type i = 0; i != vec.size(); ++i) { - docstring str; - - switch (styles[i]) { - case biblio::CITE: - // jurabib only: Author/Annotator - // (i.e. the "before" field, 2nd opt arg) - str = author + "/<" + _("before") + '>'; - break; - - case biblio::CITET: - str = author + " (" + year + ')'; - break; - - case biblio::CITEP: - str = '(' + author + ", " + year + ')'; - break; - - case biblio::CITEALT: - str = author + ' ' + year ; - break; - - case biblio::CITEALP: - str = author + ", " + year ; - break; - - case biblio::CITEAUTHOR: - str = author; - break; - - case biblio::CITEYEAR: - str = year; - break; - - case biblio::CITEYEARPAR: - str = '(' + year + ')'; - break; - } - vec[i] = str; - } - return vec; -} - - -void BiblioInfo::fillWithBibKeys(Buffer const * const buf) -{ - /// if this is a child document and the parent is already loaded - /// use the parent's list instead [ale990412] - Buffer const * const tmp = buf->getMasterBuffer(); - BOOST_ASSERT(tmp); - if (tmp != buf) { - this->fillWithBibKeys(tmp); - return; - } - - // Pre-load all child documents. - loadChildDocuments(*buf); - - for (InsetIterator it = inset_iterator_begin(buf->inset()); it; ++it) - it->fillWithBibKeys(*buf, *this, it); -} - - -namespace biblio { - -//////////////////////////////////////// -// -// CitationStyle -// -//////////////////////////////////////// - -namespace { - - -char const * const citeCommands[] = { - "cite", "citet", "citep", "citealt", "citealp", "citeauthor", - "citeyear", "citeyearpar" }; - -unsigned int const nCiteCommands = - sizeof(citeCommands) / sizeof(char *); - -CiteStyle const citeStyles[] = { - CITE, CITET, CITEP, CITEALT, CITEALP, -CITEAUTHOR, CITEYEAR, CITEYEARPAR }; - -unsigned int const nCiteStyles = - sizeof(citeStyles) / sizeof(CiteStyle); - -CiteStyle const citeStylesFull[] = { - CITET, CITEP, CITEALT, CITEALP, CITEAUTHOR }; - -unsigned int const nCiteStylesFull = - sizeof(citeStylesFull) / sizeof(CiteStyle); - -CiteStyle const citeStylesUCase[] = { - CITET, CITEP, CITEALT, CITEALP, CITEAUTHOR }; - -unsigned int const nCiteStylesUCase = - sizeof(citeStylesUCase) / sizeof(CiteStyle); - -} // namespace anon - - -CitationStyle::CitationStyle(string const & command) - : style(CITE), full(false), forceUCase(false) -{ - if (command.empty()) - return; - - string cmd = command; - if (cmd[0] == 'C') { - forceUCase = true; - cmd[0] = 'c'; - } - - string::size_type const n = cmd.size() - 1; - if (cmd != "cite" && cmd[n] == '*') { - full = true; - cmd = cmd.substr(0,n); - } - - char const * const * const last = citeCommands + nCiteCommands; - char const * const * const ptr = std::find(citeCommands, last, cmd); - - if (ptr != last) { - size_t idx = ptr - citeCommands; - style = citeStyles[idx]; - } -} - - -string const CitationStyle::asLatexStr() const -{ - string cite = citeCommands[style]; - if (full) { - CiteStyle const * last = citeStylesFull + nCiteStylesFull; - if (std::find(citeStylesFull, last, style) != last) - cite += '*'; - } - - if (forceUCase) { - CiteStyle const * last = citeStylesUCase + nCiteStylesUCase; - if (std::find(citeStylesUCase, last, style) != last) - cite[0] = 'C'; - } - - return cite; -} - - -vector const getCiteStyles(CiteEngine const engine) -{ - unsigned int nStyles = 0; - unsigned int start = 0; - - switch (engine) { - case ENGINE_BASIC: - nStyles = 1; - start = 0; - break; - case ENGINE_NATBIB_AUTHORYEAR: - case ENGINE_NATBIB_NUMERICAL: - nStyles = nCiteStyles - 1; - start = 1; - break; - case ENGINE_JURABIB: - nStyles = nCiteStyles; - start = 0; - break; - } - - typedef vector cite_vec; - - cite_vec styles(nStyles); - cite_vec::size_type i = 0; - int j = start; - for (; i != styles.size(); ++i, ++j) - styles[i] = citeStyles[j]; - - return styles; -} - -} // namespace biblio -} // namespace lyx - diff --git a/src/Biblio.h b/src/Biblio.h deleted file mode 100644 index 7739f21856..0000000000 --- a/src/Biblio.h +++ /dev/null @@ -1,162 +0,0 @@ -// -*- C++ -*- -/** - * \file Biblio.h - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author Angus Leeming - * \author Herbert Voß - * \author Richard Heck - * - * Full author contact details are available in file CREDITS. - */ - -#ifndef BIBLIO_H -#define BIBLIO_H - -#include "support/docstring.h" - -#include -#include -#include - - -namespace lyx { - -class Buffer; - -namespace biblio { - -enum CiteEngine { - ENGINE_BASIC, - ENGINE_NATBIB_AUTHORYEAR, - ENGINE_NATBIB_NUMERICAL, - ENGINE_JURABIB -}; - -enum CiteStyle { - CITE, - CITET, - CITEP, - CITEALT, - CITEALP, - CITEAUTHOR, - CITEYEAR, - CITEYEARPAR -}; - - -class CitationStyle { -public: - /// - CitationStyle(CiteStyle s = CITE, bool f = false, bool force = false) - : style(s), full(f), forceUCase(force) {} - /// \param latex_str a LaTeX command, "cite", "Citep*", etc - CitationStyle(std::string const & latex_str); - /// - std::string const asLatexStr() const; - /// - CiteStyle style; - /// - bool full; - /// - bool forceUCase; -}; - -/// Returns a vector of available Citation styles. -std::vector const getCiteStyles(CiteEngine const ); - -} // namespace biblio - -/// Class to represent information about a BibTeX or -/// bibliography entry. -/// The keys are BibTeX fields (e.g., author, title, etc), -/// and the values are the associated field values. -class BibTeXInfo : public std::map { -public: - /// - BibTeXInfo(); - ///Search for the given field and return the associated info. - ///The point of this is that BibTeXInfo::operator[] has no const - ///form. - docstring const & getValueForField(docstring const & field) const; - /// - docstring const & getValueForField(std::string const & field) const; - /// - bool hasField(docstring const & field) const; - /// return the short form of an authorlist - docstring const getAbbreviatedAuthor() const; - /// - docstring const getYear() const; - /// Returns formatted BibTeX data suitable for framing. - docstring const getInfo() const; - /// the BibTeX key for this entry - docstring bibKey; - /// a single string containing all BibTeX data associated with this key - docstring allData; - /// the BibTeX entry type (article, book, incollection, ...) - docstring entryType; - /// true if from BibTeX; false if from bibliography environment - bool isBibTeX; -}; - - -/// Class to represent a collection of bibliographical data, whether -/// from BibTeX or from bibliography environments. -/// BiblioInfo.first is the bibliography key -/// BiblioInfo.second is the data for that key -class BiblioInfo : public std::map { -public: - /// Returns a sorted vector of bibliography keys - std::vector const getKeys() const; - /// Returns a sorted vector of present BibTeX fields - std::vector const getFields() const; - /// Returns a sorted vector of BibTeX entry types in use - std::vector const getEntries() const; - /// Fills keys with BibTeX information derived from the various insets - /// in a given buffer, in its master document. - void fillWithBibKeys(Buffer const * const buf); - /// return the short form of an authorlist - docstring const getAbbreviatedAuthor(docstring const & key) const; - /// return the year from the bibtex data record - docstring const getYear(docstring const & key) const; - /// Returns formatted BibTeX data associated with a given key. - /// Empty if no info exists. - docstring const getInfo(docstring const & key) const; - - /** - * "Translates the available Citation Styles into strings for a given key, - * either numerical or author-year depending upon the active engine. (See - * below for those methods.) - */ - std::vector const - getCiteStrings(docstring const & key, Buffer const & buf) const; - /** - * "Translates" the available Citation Styles into strings for a given key. - * The returned string is displayed by the GUI. - * [XX] is used in place of the actual reference - * Eg, the vector will contain: [XX], Jones et al. [XX], ... - * User supplies : - * the key, - * the buffer - */ - std::vector const - getNumericalStrings(docstring const & key, Buffer const & buf) const; - /** - * "Translates" the available Citation Styles into strings for a given key. - * The returned string is displayed by the GUI. - * Eg, the vector will contain: - * Jones et al. (1990), (Jones et al. 1990), Jones et al. 1990, ... - * User supplies : - * the key, - * the buffer - */ - std::vector const - getAuthorYearStrings(docstring const & key, Buffer const & buf) const; - - std::set fieldNames; - std::set entryTypes; -}; - -} // namespace lyx -#endif diff --git a/src/BiblioInfo.cpp b/src/BiblioInfo.cpp new file mode 100644 index 0000000000..fd74f0346f --- /dev/null +++ b/src/BiblioInfo.cpp @@ -0,0 +1,551 @@ +/** + * \file BiblioInfo.cpp + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Angus Leeming + * \author Herbert Voß + * \author Richard Heck + * + * Full author contact details are available in file CREDITS. + */ + +#include + +#include "BiblioInfo.h" +#include "Buffer.h" +#include "BufferParams.h" +#include "buffer_funcs.h" +#include "gettext.h" +#include "InsetIterator.h" +#include "Paragraph.h" + +#include "insets/Inset.h" +#include "insets/InsetBibitem.h" +#include "insets/InsetBibtex.h" +#include "insets/InsetInclude.h" + +#include "support/lstrings.h" + +#include "boost/regex.hpp" + +using std::string; +using std::vector; +using std::pair; +using std::endl; +using std::set; + +namespace lyx { +using support::bformat; +using support::compare_no_case; +using support::getVectorFromString; +using support::ltrim; +using support::rtrim; + +//////////////////////////////////////// +// +// BibTeXInfo +// +//////////////////////////////////////// + +BibTeXInfo::BibTeXInfo() : isBibTeX(true) +{} + + +bool BibTeXInfo::hasField(docstring const & field) const +{ + return count(field) == 1; +} + + +docstring const & BibTeXInfo::getValueForField(docstring const & field) const +{ + BibTeXInfo::const_iterator it = find(field); + if (it != end()) + return it->second; + static docstring const empty_value = docstring(); + return empty_value; +} + + +docstring const & BibTeXInfo::getValueForField(string const & field) const +{ + return getValueForField(from_ascii(field)); +} + + +namespace { + docstring const familyName(docstring const & name) + { + if (name.empty()) + return docstring(); + + // Very simple parser + docstring fname = name; + + // possible authorname combinations are: + // "Surname, FirstName" + // "Surname, F." + // "FirstName Surname" + // "F. Surname" + docstring::size_type idx = fname.find(','); + if (idx != docstring::npos) + return ltrim(fname.substr(0, idx)); + idx = fname.rfind('.'); + if (idx != docstring::npos && idx + 1 < fname.size()) + fname = ltrim(fname.substr(idx + 1)); + // test if we have a LaTeX Space in front + if (fname[0] == '\\') + return fname.substr(2); + return rtrim(fname); + } +} // namespace anon + + + +docstring const BibTeXInfo::getAbbreviatedAuthor() const +{ + if (!isBibTeX) + return docstring(); + + docstring author = getValueForField("author"); + + if (author.empty()) { + author = getValueForField("editor"); + if (author.empty()) + return bibKey; + } + + //OK, we've got some names. Let's format them. + //Try to split the author list on " and " + vector const authors = + getVectorFromString(author, from_ascii(" and ")); + + if (authors.size() == 2) + return bformat(_("%1$s and %2$s"), + familyName(authors[0]), familyName(authors[1])); + else if (authors.size() > 2) + return bformat(_("%1$s et al."), familyName(authors[0])); + else + return familyName(authors[0]); +} + +docstring const BibTeXInfo::getYear() const +{ + if (!isBibTeX) + return docstring(); + + docstring year = getValueForField("year"); + if (year.empty()) + year = _("No year"); + return year; +} + + +docstring const BibTeXInfo::getInfo() const +{ + if (!isBibTeX) { + BibTeXInfo::const_iterator it = find(from_ascii("ref")); + return it->second; + } + + //FIXME + //This could be made alot better using the entryType + //field to customize the output based upon entry type. + + //Search for all possible "required" fields + docstring author = getValueForField("author"); + if (author.empty()) + author = getValueForField("editor"); + + docstring year = getValueForField("year"); + docstring title = getValueForField("title"); + docstring docLoc = getValueForField("pages"); + if (docLoc.empty()) { + docLoc = getValueForField("chapter"); + if (!docLoc.empty()) + docLoc = from_ascii("Ch. ") + docLoc; + } else + docLoc = from_ascii("pp. ") + docLoc; + docstring media = getValueForField("journal"); + if (media.empty()) { + media = getValueForField("publisher"); + if (media.empty()) { + media = getValueForField("school"); + if (media.empty()) + media = getValueForField("institution"); + } + } + docstring volume = getValueForField("volume"); + + odocstringstream result; + if (!author.empty()) + result << author << ", "; + if (!title.empty()) + result << title; + if (!media.empty()) + result << ", " << media; + if (!year.empty()) + result << ", " << year; + if (!docLoc.empty()) + result << ", " << docLoc; + + docstring const result_str = rtrim(result.str()); + if (!result_str.empty()) + return result_str; + + // This should never happen (or at least be very unusual!) + return docstring(); +} + + +//////////////////////////////////////// +// +// BiblioInfo +// +//////////////////////////////////////// + +namespace { +// A functor for use with std::sort, leading to case insensitive sorting + class compareNoCase: public std::binary_function + { + public: + bool operator()(docstring const & s1, docstring const & s2) const { + return compare_no_case(s1, s2) < 0; + } + }; +} // namespace anon + + +vector const BiblioInfo::getKeys() const +{ + vector bibkeys; + BiblioInfo::const_iterator it = begin(); + for (; it != end(); ++it) + bibkeys.push_back(it->first); + std::sort(bibkeys.begin(), bibkeys.end(), compareNoCase()); + return bibkeys; +} + + +vector const BiblioInfo::getFields() const +{ + vector bibfields; + set::const_iterator it = fieldNames.begin(); + set::const_iterator end = fieldNames.end(); + for (; it != end; ++it) + bibfields.push_back(*it); + std::sort(bibfields.begin(), bibfields.end()); + return bibfields; +} + + +vector const BiblioInfo::getEntries() const +{ + vector bibentries; + set::const_iterator it = entryTypes.begin(); + set::const_iterator end = entryTypes.end(); + for (; it != end; ++it) + bibentries.push_back(*it); + std::sort(bibentries.begin(), bibentries.end()); + return bibentries; +} + + +docstring const BiblioInfo::getAbbreviatedAuthor(docstring const & key) const +{ + BiblioInfo::const_iterator it = find(key); + if (it == end()) + return docstring(); + BibTeXInfo const & data = it->second; + return data.getAbbreviatedAuthor(); +} + + +docstring const BiblioInfo::getYear(docstring const & key) const +{ + BiblioInfo::const_iterator it = find(key); + if (it == end()) + return docstring(); + BibTeXInfo const & data = it->second; + return data.getYear(); +} + + +docstring const BiblioInfo::getInfo(docstring const & key) const +{ + BiblioInfo::const_iterator it = find(key); + if (it == end()) + return docstring(); + BibTeXInfo const & data = it->second; + return data.getInfo(); +} + + +vector const BiblioInfo::getCiteStrings( + docstring const & key, Buffer const & buf) const +{ + biblio::CiteEngine const engine = buf.params().getEngine(); + if (engine == biblio::ENGINE_NATBIB_NUMERICAL) + return getNumericalStrings(key, buf); + else + return getAuthorYearStrings(key, buf); +} + + +vector const BiblioInfo::getNumericalStrings( + docstring const & key, Buffer const & buf) const +{ + if (empty()) + return vector(); + + docstring const author = getAbbreviatedAuthor(key); + docstring const year = getYear(key); + if (author.empty() || year.empty()) + return vector(); + + vector const & styles = + biblio::getCiteStyles(buf.params().getEngine()); + + vector vec(styles.size()); + for (vector::size_type i = 0; i != vec.size(); ++i) { + docstring str; + + switch (styles[i]) { + case biblio::CITE: + case biblio::CITEP: + str = from_ascii("[#ID]"); + break; + + case biblio::CITET: + str = author + " [#ID]"; + break; + + case biblio::CITEALT: + str = author + " #ID"; + break; + + case biblio::CITEALP: + str = from_ascii("#ID"); + break; + + case biblio::CITEAUTHOR: + str = author; + break; + + case biblio::CITEYEAR: + str = year; + break; + + case biblio::CITEYEARPAR: + str = '(' + year + ')'; + break; + } + + vec[i] = str; + } + + return vec; +} + + +vector const BiblioInfo::getAuthorYearStrings( + docstring const & key, Buffer const & buf) const +{ + if (empty()) + return vector(); + + docstring const author = getAbbreviatedAuthor(key); + docstring const year = getYear(key); + if (author.empty() || year.empty()) + return vector(); + + vector const & styles = + getCiteStyles(buf.params().getEngine()); + + vector vec(styles.size()); + for (vector::size_type i = 0; i != vec.size(); ++i) { + docstring str; + + switch (styles[i]) { + case biblio::CITE: + // jurabib only: Author/Annotator + // (i.e. the "before" field, 2nd opt arg) + str = author + "/<" + _("before") + '>'; + break; + + case biblio::CITET: + str = author + " (" + year + ')'; + break; + + case biblio::CITEP: + str = '(' + author + ", " + year + ')'; + break; + + case biblio::CITEALT: + str = author + ' ' + year ; + break; + + case biblio::CITEALP: + str = author + ", " + year ; + break; + + case biblio::CITEAUTHOR: + str = author; + break; + + case biblio::CITEYEAR: + str = year; + break; + + case biblio::CITEYEARPAR: + str = '(' + year + ')'; + break; + } + vec[i] = str; + } + return vec; +} + + +void BiblioInfo::fillWithBibKeys(Buffer const * const buf) +{ + /// if this is a child document and the parent is already loaded + /// use the parent's list instead [ale990412] + Buffer const * const tmp = buf->getMasterBuffer(); + BOOST_ASSERT(tmp); + if (tmp != buf) { + this->fillWithBibKeys(tmp); + return; + } + + // Pre-load all child documents. + loadChildDocuments(*buf); + + for (InsetIterator it = inset_iterator_begin(buf->inset()); it; ++it) + it->fillWithBibKeys(*buf, *this, it); +} + + +namespace biblio { + +//////////////////////////////////////// +// +// CitationStyle +// +//////////////////////////////////////// + +namespace { + + +char const * const citeCommands[] = { + "cite", "citet", "citep", "citealt", "citealp", "citeauthor", + "citeyear", "citeyearpar" }; + +unsigned int const nCiteCommands = + sizeof(citeCommands) / sizeof(char *); + +CiteStyle const citeStyles[] = { + CITE, CITET, CITEP, CITEALT, CITEALP, +CITEAUTHOR, CITEYEAR, CITEYEARPAR }; + +unsigned int const nCiteStyles = + sizeof(citeStyles) / sizeof(CiteStyle); + +CiteStyle const citeStylesFull[] = { + CITET, CITEP, CITEALT, CITEALP, CITEAUTHOR }; + +unsigned int const nCiteStylesFull = + sizeof(citeStylesFull) / sizeof(CiteStyle); + +CiteStyle const citeStylesUCase[] = { + CITET, CITEP, CITEALT, CITEALP, CITEAUTHOR }; + +unsigned int const nCiteStylesUCase = + sizeof(citeStylesUCase) / sizeof(CiteStyle); + +} // namespace anon + + +CitationStyle::CitationStyle(string const & command) + : style(CITE), full(false), forceUCase(false) +{ + if (command.empty()) + return; + + string cmd = command; + if (cmd[0] == 'C') { + forceUCase = true; + cmd[0] = 'c'; + } + + string::size_type const n = cmd.size() - 1; + if (cmd != "cite" && cmd[n] == '*') { + full = true; + cmd = cmd.substr(0,n); + } + + char const * const * const last = citeCommands + nCiteCommands; + char const * const * const ptr = std::find(citeCommands, last, cmd); + + if (ptr != last) { + size_t idx = ptr - citeCommands; + style = citeStyles[idx]; + } +} + + +string const CitationStyle::asLatexStr() const +{ + string cite = citeCommands[style]; + if (full) { + CiteStyle const * last = citeStylesFull + nCiteStylesFull; + if (std::find(citeStylesFull, last, style) != last) + cite += '*'; + } + + if (forceUCase) { + CiteStyle const * last = citeStylesUCase + nCiteStylesUCase; + if (std::find(citeStylesUCase, last, style) != last) + cite[0] = 'C'; + } + + return cite; +} + + +vector const getCiteStyles(CiteEngine const engine) +{ + unsigned int nStyles = 0; + unsigned int start = 0; + + switch (engine) { + case ENGINE_BASIC: + nStyles = 1; + start = 0; + break; + case ENGINE_NATBIB_AUTHORYEAR: + case ENGINE_NATBIB_NUMERICAL: + nStyles = nCiteStyles - 1; + start = 1; + break; + case ENGINE_JURABIB: + nStyles = nCiteStyles; + start = 0; + break; + } + + typedef vector cite_vec; + + cite_vec styles(nStyles); + cite_vec::size_type i = 0; + int j = start; + for (; i != styles.size(); ++i, ++j) + styles[i] = citeStyles[j]; + + return styles; +} + +} // namespace biblio +} // namespace lyx + diff --git a/src/BiblioInfo.h b/src/BiblioInfo.h new file mode 100644 index 0000000000..b6973e1ead --- /dev/null +++ b/src/BiblioInfo.h @@ -0,0 +1,162 @@ +// -*- C++ -*- +/** + * \file BiblioInfo.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Angus Leeming + * \author Herbert Voß + * \author Richard Heck + * + * Full author contact details are available in file CREDITS. + */ + +#ifndef BIBLIO_H +#define BIBLIO_H + +#include "support/docstring.h" + +#include +#include +#include + + +namespace lyx { + +class Buffer; + +namespace biblio { + +enum CiteEngine { + ENGINE_BASIC, + ENGINE_NATBIB_AUTHORYEAR, + ENGINE_NATBIB_NUMERICAL, + ENGINE_JURABIB +}; + +enum CiteStyle { + CITE, + CITET, + CITEP, + CITEALT, + CITEALP, + CITEAUTHOR, + CITEYEAR, + CITEYEARPAR +}; + + +class CitationStyle { +public: + /// + CitationStyle(CiteStyle s = CITE, bool f = false, bool force = false) + : style(s), full(f), forceUCase(force) {} + /// \param latex_str a LaTeX command, "cite", "Citep*", etc + CitationStyle(std::string const & latex_str); + /// + std::string const asLatexStr() const; + /// + CiteStyle style; + /// + bool full; + /// + bool forceUCase; +}; + +/// Returns a vector of available Citation styles. +std::vector const getCiteStyles(CiteEngine const ); + +} // namespace biblio + +/// Class to represent information about a BibTeX or +/// bibliography entry. +/// The keys are BibTeX fields (e.g., author, title, etc), +/// and the values are the associated field values. +class BibTeXInfo : public std::map { +public: + /// + BibTeXInfo(); + ///Search for the given field and return the associated info. + ///The point of this is that BibTeXInfo::operator[] has no const + ///form. + docstring const & getValueForField(docstring const & field) const; + /// + docstring const & getValueForField(std::string const & field) const; + /// + bool hasField(docstring const & field) const; + /// return the short form of an authorlist + docstring const getAbbreviatedAuthor() const; + /// + docstring const getYear() const; + /// Returns formatted BibTeX data suitable for framing. + docstring const getInfo() const; + /// the BibTeX key for this entry + docstring bibKey; + /// a single string containing all BibTeX data associated with this key + docstring allData; + /// the BibTeX entry type (article, book, incollection, ...) + docstring entryType; + /// true if from BibTeX; false if from bibliography environment + bool isBibTeX; +}; + + +/// Class to represent a collection of bibliographical data, whether +/// from BibTeX or from bibliography environments. +/// BiblioInfo.first is the bibliography key +/// BiblioInfo.second is the data for that key +class BiblioInfo : public std::map { +public: + /// Returns a sorted vector of bibliography keys + std::vector const getKeys() const; + /// Returns a sorted vector of present BibTeX fields + std::vector const getFields() const; + /// Returns a sorted vector of BibTeX entry types in use + std::vector const getEntries() const; + /// Fills keys with BibTeX information derived from the various insets + /// in a given buffer, in its master document. + void fillWithBibKeys(Buffer const * const buf); + /// return the short form of an authorlist + docstring const getAbbreviatedAuthor(docstring const & key) const; + /// return the year from the bibtex data record + docstring const getYear(docstring const & key) const; + /// Returns formatted BibTeX data associated with a given key. + /// Empty if no info exists. + docstring const getInfo(docstring const & key) const; + + /** + * "Translates the available Citation Styles into strings for a given key, + * either numerical or author-year depending upon the active engine. (See + * below for those methods.) + */ + std::vector const + getCiteStrings(docstring const & key, Buffer const & buf) const; + /** + * "Translates" the available Citation Styles into strings for a given key. + * The returned string is displayed by the GUI. + * [XX] is used in place of the actual reference + * Eg, the vector will contain: [XX], Jones et al. [XX], ... + * User supplies : + * the key, + * the buffer + */ + std::vector const + getNumericalStrings(docstring const & key, Buffer const & buf) const; + /** + * "Translates" the available Citation Styles into strings for a given key. + * The returned string is displayed by the GUI. + * Eg, the vector will contain: + * Jones et al. (1990), (Jones et al. 1990), Jones et al. 1990, ... + * User supplies : + * the key, + * the buffer + */ + std::vector const + getAuthorYearStrings(docstring const & key, Buffer const & buf) const; + + std::set fieldNames; + std::set entryTypes; +}; + +} // namespace lyx +#endif diff --git a/src/Buffer.cpp b/src/Buffer.cpp index 98cf4ebdb8..f9d11689bb 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -13,7 +13,7 @@ #include "Buffer.h" #include "Author.h" -#include "Biblio.h" +#include "BiblioInfo.h" #include "BranchList.h" #include "buffer_funcs.h" #include "BufferList.h" diff --git a/src/BufferParams.h b/src/BufferParams.h index d0de105f03..bf5926e823 100644 --- a/src/BufferParams.h +++ b/src/BufferParams.h @@ -15,7 +15,7 @@ #ifndef BUFFERPARAMS_H #define BUFFERPARAMS_H -#include "Biblio.h" +#include "BiblioInfo.h" #include "TextClass.h" #include "paper.h" diff --git a/src/Makefile.am b/src/Makefile.am index 7daedf1db3..d99921090b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -78,8 +78,8 @@ endif liblyxcore_la_SOURCES = \ Author.cpp \ Author.h \ - Biblio.h \ - Biblio.cpp \ + BiblioInfo.h \ + BiblioInfo.cpp \ Bidi.cpp \ Bidi.h \ boost.cpp \ diff --git a/src/frontends/controllers/ControlCitation.h b/src/frontends/controllers/ControlCitation.h index b3170c6267..94985eacc9 100644 --- a/src/frontends/controllers/ControlCitation.h +++ b/src/frontends/controllers/ControlCitation.h @@ -13,7 +13,7 @@ #ifndef CONTROLCITATION_H #define CONTROLCITATION_H -#include "Biblio.h" +#include "BiblioInfo.h" #include "ControlCommand.h" namespace lyx { diff --git a/src/insets/Inset.h b/src/insets/Inset.h index c5b2946144..25c343850d 100644 --- a/src/insets/Inset.h +++ b/src/insets/Inset.h @@ -15,7 +15,7 @@ #ifndef INSETBASE_H #define INSETBASE_H -#include "Biblio.h" +//#include "BiblioInfo.h" #include "Changes.h" #include "Dimension.h" @@ -26,6 +26,7 @@ namespace lyx { +class BiblioInfo; class Buffer; class BufferParams; class BufferView; diff --git a/src/insets/InsetBibitem.h b/src/insets/InsetBibitem.h index e497814111..d039eb04b0 100644 --- a/src/insets/InsetBibitem.h +++ b/src/insets/InsetBibitem.h @@ -14,7 +14,7 @@ #include "InsetCommand.h" -#include "Biblio.h" +#include "BiblioInfo.h" namespace lyx { diff --git a/src/insets/InsetBibtex.h b/src/insets/InsetBibtex.h index ea558ca5ff..a3ce2c6f28 100644 --- a/src/insets/InsetBibtex.h +++ b/src/insets/InsetBibtex.h @@ -14,7 +14,7 @@ #include #include "InsetCommand.h" -#include "Biblio.h" +#include "BiblioInfo.h" #include "support/FileName.h" diff --git a/src/insets/InsetCitation.cpp b/src/insets/InsetCitation.cpp index fafb585855..5a007cf46f 100644 --- a/src/insets/InsetCitation.cpp +++ b/src/insets/InsetCitation.cpp @@ -13,7 +13,6 @@ #include "InsetCitation.h" -#include "Biblio.h" #include "Buffer.h" #include "BufferParams.h" #include "debug.h" diff --git a/src/insets/InsetCitation.h b/src/insets/InsetCitation.h index 1d469c2e2c..2c89a5bd0f 100644 --- a/src/insets/InsetCitation.h +++ b/src/insets/InsetCitation.h @@ -16,7 +16,7 @@ #include "InsetCommand.h" -#include "Biblio.h" +#include "BiblioInfo.h" namespace lyx { diff --git a/src/insets/InsetInclude.h b/src/insets/InsetInclude.h index a2ef0d551a..9200fda6af 100644 --- a/src/insets/InsetInclude.h +++ b/src/insets/InsetInclude.h @@ -12,7 +12,7 @@ #ifndef INSET_INCLUDE_H #define INSET_INCLUDE_H -#include "Biblio.h" +#include "BiblioInfo.h" #include "Inset.h" #include "InsetCommandParams.h" #include "RenderButton.h"