Just rearranging and adding some comments.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@29158 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Richard Heck 2009-04-09 12:55:47 +00:00
parent df3cddcd37
commit 1b160bd82d
2 changed files with 148 additions and 143 deletions

View File

@ -39,49 +39,9 @@ using namespace lyx::support;
namespace lyx {
//////////////////////////////////////////////////////////////////////
//
// BibTeXInfo
//
//////////////////////////////////////////////////////////////////////
BibTeXInfo::BibTeXInfo(docstring const & key, docstring const & type)
: is_bibtex_(true), bib_key_(key), entry_type_(type), info_()
{}
bool BibTeXInfo::hasField(docstring const & field) const
{
return count(field) == 1;
}
docstring const & BibTeXInfo::operator[](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::operator[](string const & field) const
{
return operator[](from_ascii(field));
}
docstring BibTeXInfo::getValueForKey(string const & key,
BibTeXInfo const * const xref) const
{
docstring const ret = operator[](key);
if (!ret.empty() || !xref)
return ret;
return (*xref)[key];
}
namespace {
// gets the "family name" from an author-type string
docstring familyName(docstring const & name)
{
if (name.empty())
@ -128,6 +88,123 @@ docstring familyName(docstring const & name)
return retval;
}
// converts a string containing LaTeX commands into unicode
// for display.
docstring convertLaTeXCommands(docstring const & str)
{
docstring val = str;
docstring ret;
bool scanning_cmd = false;
bool scanning_math = false;
bool escaped = false; // used to catch \$, etc.
while (val.size()) {
char_type const ch = val[0];
// if we're scanning math, we output everything until we
// find an unescaped $, at which point we break out.
if (scanning_math) {
if (escaped)
escaped = false;
else if (ch == '\\')
escaped = true;
else if (ch == '$')
scanning_math = false;
ret += ch;
val = val.substr(1);
continue;
}
// if we're scanning a command name, then we just
// discard characters until we hit something that
// isn't alpha.
if (scanning_cmd) {
if (isAlphaASCII(ch)) {
val = val.substr(1);
escaped = false;
continue;
}
// so we're done with this command.
// now we fall through and check this character.
scanning_cmd = false;
}
// was the last character a \? If so, then this is something like: \\,
// or \$, so we'll just output it. That's probably not always right...
if (escaped) {
ret += ch;
val = val.substr(1);
escaped = false;
continue;
}
if (ch == '$') {
ret += ch;
val = val.substr(1);
scanning_math = true;
continue;
}
// we just ignore braces
if (ch == '{' || ch == '}') {
val = val.substr(1);
continue;
}
// we're going to check things that look like commands, so if
// this doesn't, just output it.
if (ch != '\\') {
ret += ch;
val = val.substr(1);
continue;
}
// ok, could be a command of some sort
// let's see if it corresponds to some unicode
// unicodesymbols has things in the form: \"{u},
// whereas we may see things like: \"u. So we'll
// look for that and change it, if necessary.
static boost::regex const reg("^\\\\\\W\\w");
if (boost::regex_search(to_utf8(val), reg)) {
val.insert(3, from_ascii("}"));
val.insert(2, from_ascii("{"));
}
docstring rem;
docstring const cnvtd = Encodings::fromLaTeXCommand(val, rem);
if (!cnvtd.empty()) {
// it did, so we'll take that bit and proceed with what's left
ret += cnvtd;
val = rem;
continue;
}
// it's a command of some sort
scanning_cmd = true;
escaped = true;
val = val.substr(1);
}
return ret;
}
} // anon namespace
//////////////////////////////////////////////////////////////////////
//
// BibTeXInfo
//
//////////////////////////////////////////////////////////////////////
BibTeXInfo::BibTeXInfo(docstring const & key, docstring const & type)
: is_bibtex_(true), bib_key_(key), entry_type_(type), info_()
{}
bool BibTeXInfo::hasField(docstring const & field) const
{
return count(field) == 1;
}
docstring const BibTeXInfo::getAbbreviatedAuthor() const
{
if (!is_bibtex_) {
@ -188,106 +265,6 @@ docstring const BibTeXInfo::getXRef() const
}
namespace {
docstring convertLaTeXCommands(docstring const & str)
{
docstring val = str;
docstring ret;
bool scanning_cmd = false;
bool scanning_math = false;
bool escaped = false; // used to catch \$, etc.
while (val.size()) {
char_type const ch = val[0];
// if we're scanning math, we output everything until we
// find an unescaped $, at which point we break out.
if (scanning_math) {
if (escaped)
escaped = false;
else if (ch == '\\')
escaped = true;
else if (ch == '$')
scanning_math = false;
ret += ch;
val = val.substr(1);
continue;
}
// if we're scanning a command name, then we just
// discard characters until we hit something that
// isn't alpha.
if (scanning_cmd) {
if (isAlphaASCII(ch)) {
val = val.substr(1);
escaped = false;
continue;
}
// so we're done with this command.
// now we fall through and check this character.
scanning_cmd = false;
}
// was the last character a \? If so, then this is something like: \\,
// or \$, so we'll just output it. That's probably not always right...
if (escaped) {
ret += ch;
val = val.substr(1);
escaped = false;
continue;
}
if (ch == '$') {
ret += ch;
val = val.substr(1);
scanning_math = true;
continue;
}
// we just ignore braces
if (ch == '{' || ch == '}') {
val = val.substr(1);
continue;
}
// we're going to check things that look like commands, so if
// this doesn't, just output it.
if (ch != '\\') {
ret += ch;
val = val.substr(1);
continue;
}
// ok, could be a command of some sort
// let's see if it corresponds to some unicode
// unicodesymbols has things in the form: \"{u},
// whereas we may see things like: \"u. So we'll
// look for that and change it, if necessary.
static boost::regex const reg("^\\\\\\W\\w");
if (boost::regex_search(to_utf8(val), reg)) {
val.insert(3, from_ascii("}"));
val.insert(2, from_ascii("{"));
}
docstring rem;
docstring const cnvtd = Encodings::fromLaTeXCommand(val, rem);
if (!cnvtd.empty()) {
// it did, so we'll take that bit and proceed with what's left
ret += cnvtd;
val = rem;
continue;
}
// it's a command of some sort
scanning_cmd = true;
escaped = true;
val = val.substr(1);
}
return ret;
}
} // anon namespace
docstring const & BibTeXInfo::getInfo(BibTeXInfo const * const xref) const
{
if (!info_.empty())
@ -354,6 +331,32 @@ docstring const & BibTeXInfo::getInfo(BibTeXInfo const * const xref) const
}
docstring const & BibTeXInfo::operator[](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::operator[](string const & field) const
{
return operator[](from_ascii(field));
}
docstring BibTeXInfo::getValueForKey(string const & key,
BibTeXInfo const * const xref) const
{
docstring const ret = operator[](key);
if (!ret.empty() || !xref)
return ret;
return (*xref)[key];
}
//////////////////////////////////////////////////////////////////////
//
// BiblioInfo

View File

@ -87,7 +87,9 @@ public:
///
docstring entryType() const { return entry_type_; }
private:
/// like operator[], except it will also check the given xref
/// like operator[], except, if the field is empty, it will attempt
/// to get the data from xref BibTeXInfo object, which would normally
/// be the one referenced in the crossref field.
docstring getValueForKey(std::string const & key,
BibTeXInfo const * const xref = 0) const;
/// true if from BibTeX; false if from bibliography environment