2003-02-08 19:18:01 +00:00
|
|
|
/**
|
2007-04-26 04:41:58 +00:00
|
|
|
* \file Author.cpp
|
2003-02-08 19:18:01 +00:00
|
|
|
* This file is part of LyX, the document processor.
|
|
|
|
* Licence details can be found in the file COPYING.
|
|
|
|
*
|
|
|
|
* \author John Levon
|
|
|
|
*
|
2003-08-23 00:17:00 +00:00
|
|
|
* Full author contact details are available in file CREDITS.
|
2003-02-08 19:18:01 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
2007-04-26 04:41:58 +00:00
|
|
|
#include "Author.h"
|
2003-02-08 19:18:01 +00:00
|
|
|
|
2015-11-11 21:31:05 +00:00
|
|
|
#include "support/convert.h"
|
2016-05-03 19:40:28 +00:00
|
|
|
#include "support/gettext.h"
|
2008-04-30 08:26:40 +00:00
|
|
|
#include "support/lassert.h"
|
2010-11-05 18:25:29 +00:00
|
|
|
#include "support/lstrings.h"
|
2003-09-09 17:25:35 +00:00
|
|
|
|
2009-07-23 20:08:05 +00:00
|
|
|
#include <algorithm>
|
2007-11-06 21:45:24 +00:00
|
|
|
#include <istream>
|
2003-09-09 22:13:45 +00:00
|
|
|
|
2007-12-12 10:16:00 +00:00
|
|
|
using namespace std;
|
2007-12-12 18:57:56 +00:00
|
|
|
using namespace lyx::support;
|
2006-10-21 00:16:43 +00:00
|
|
|
|
|
|
|
namespace lyx {
|
|
|
|
|
2010-11-05 18:25:29 +00:00
|
|
|
static int computeHash(docstring const & name,
|
|
|
|
docstring const & email)
|
|
|
|
{
|
2010-11-12 09:41:41 +00:00
|
|
|
string const full_author_string = to_utf8(name + email);
|
2010-11-05 18:25:29 +00:00
|
|
|
// Bernstein's hash function
|
|
|
|
unsigned int hash = 5381;
|
|
|
|
for (unsigned int i = 0; i < full_author_string.length(); ++i)
|
2010-11-06 00:04:21 +00:00
|
|
|
hash = ((hash << 5) + hash) + (unsigned int)(full_author_string[i]);
|
2010-11-05 18:25:29 +00:00
|
|
|
return int(hash);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-12-24 13:31:08 +00:00
|
|
|
Author::Author(docstring const & name, docstring const & email, docstring const & initials)
|
|
|
|
: name_(name), email_(email), initials_(initials), used_(true),
|
2015-11-11 21:31:05 +00:00
|
|
|
buffer_id_(computeHash(name, email))
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
|
|
Author::Author(int buffer_id)
|
2019-12-24 13:31:08 +00:00
|
|
|
: name_(convert<docstring>(buffer_id)), email_(docstring()), initials_(docstring()), used_(false),
|
2015-11-11 21:31:05 +00:00
|
|
|
buffer_id_(buffer_id)
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
2016-05-03 19:40:28 +00:00
|
|
|
docstring Author::nameAndEmail() const
|
|
|
|
{
|
|
|
|
if (email().empty())
|
|
|
|
return name();
|
|
|
|
else
|
|
|
|
return bformat(_("%1$s[[name]] (%2$s[[email]])"), name(), email());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-11-11 21:31:05 +00:00
|
|
|
bool Author::valid() const
|
2010-11-05 18:25:29 +00:00
|
|
|
{
|
2015-11-11 21:31:05 +00:00
|
|
|
//this cannot be equal if the buffer_id was produced by the hash function.
|
|
|
|
return name_ != convert<docstring>(buffer_id_);
|
2010-11-05 18:25:29 +00:00
|
|
|
}
|
|
|
|
|
2003-06-30 23:56:22 +00:00
|
|
|
|
2003-02-08 19:18:01 +00:00
|
|
|
bool operator==(Author const & l, Author const & r)
|
|
|
|
{
|
2019-12-24 13:31:08 +00:00
|
|
|
return l.name() == r.name() && l.email() == r.email() && l.initials() == r.initials();
|
2003-02-08 19:18:01 +00:00
|
|
|
}
|
2003-03-02 12:16:00 +00:00
|
|
|
|
2003-02-08 19:18:01 +00:00
|
|
|
|
2007-12-12 19:28:07 +00:00
|
|
|
ostream & operator<<(ostream & os, Author const & a)
|
2003-02-08 19:18:01 +00:00
|
|
|
{
|
2006-12-21 13:58:28 +00:00
|
|
|
// FIXME UNICODE
|
2015-11-13 18:40:10 +00:00
|
|
|
os << a.buffer_id_ << " \"" << to_utf8(a.name_) << "\"";
|
|
|
|
if (!a.email_.empty())
|
|
|
|
os << " " << to_utf8(a.email_);
|
2012-05-28 20:41:32 +00:00
|
|
|
|
2003-02-08 19:18:01 +00:00
|
|
|
return os;
|
|
|
|
}
|
2003-03-02 12:16:00 +00:00
|
|
|
|
2012-10-27 13:45:27 +00:00
|
|
|
|
2007-12-12 19:28:07 +00:00
|
|
|
istream & operator>>(istream & is, Author & a)
|
2003-02-08 19:18:01 +00:00
|
|
|
{
|
|
|
|
string s;
|
2009-07-23 20:08:05 +00:00
|
|
|
is >> a.buffer_id_;
|
2003-02-08 19:18:01 +00:00
|
|
|
getline(is, s);
|
2006-12-21 13:58:28 +00:00
|
|
|
// FIXME UNICODE
|
|
|
|
a.name_ = from_utf8(trim(token(s, '\"', 1)));
|
|
|
|
a.email_ = from_utf8(trim(token(s, '\"', 2)));
|
2003-02-08 19:18:01 +00:00
|
|
|
return is;
|
|
|
|
}
|
2003-03-02 12:16:00 +00:00
|
|
|
|
|
|
|
|
2012-10-27 13:45:27 +00:00
|
|
|
bool author_smaller(Author const & lhs, Author const & rhs)
|
|
|
|
{
|
2010-11-17 16:12:43 +00:00
|
|
|
return lhs.bufferId() < rhs.bufferId();
|
2009-07-23 20:08:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-03-12 23:25:59 +00:00
|
|
|
AuthorList::AuthorList()
|
2012-10-27 13:45:27 +00:00
|
|
|
{}
|
2003-03-12 23:25:59 +00:00
|
|
|
|
|
|
|
|
2003-02-08 19:18:01 +00:00
|
|
|
int AuthorList::record(Author const & a)
|
|
|
|
{
|
2015-11-11 21:31:05 +00:00
|
|
|
bool const valid = a.valid();
|
2010-11-05 18:25:29 +00:00
|
|
|
// If we record an author which equals the current
|
|
|
|
// author, we copy the buffer_id, so that it will
|
|
|
|
// keep the same id in the file.
|
2015-11-11 21:31:05 +00:00
|
|
|
if (valid && !authors_.empty() && a == authors_[0])
|
2010-11-17 16:12:43 +00:00
|
|
|
authors_[0].setBufferId(a.bufferId());
|
2010-11-05 18:25:29 +00:00
|
|
|
|
2015-11-11 21:31:05 +00:00
|
|
|
Authors::const_iterator it = authors_.begin();
|
|
|
|
Authors::const_iterator const beg = it;
|
|
|
|
Authors::const_iterator const end = authors_.end();
|
|
|
|
for (; it != end; ++it) {
|
|
|
|
if (valid && *it == a)
|
|
|
|
return it - beg;
|
|
|
|
if (it->bufferId() == a.bufferId()) {
|
|
|
|
int id = it - beg;
|
|
|
|
if (!it->valid())
|
|
|
|
// we need to handle the case of a valid author being registred
|
|
|
|
// after an invalid one. For instance, because "buffer-reload"
|
|
|
|
// does not clear the buffer's author list.
|
|
|
|
record(id, a);
|
|
|
|
return id;
|
|
|
|
}
|
2003-03-02 12:16:00 +00:00
|
|
|
}
|
2009-07-23 20:08:05 +00:00
|
|
|
authors_.push_back(a);
|
2015-11-11 21:31:05 +00:00
|
|
|
return authors_.size() - 1;
|
2003-02-08 19:18:01 +00:00
|
|
|
}
|
2003-03-02 12:16:00 +00:00
|
|
|
|
2003-02-08 19:18:01 +00:00
|
|
|
|
|
|
|
void AuthorList::record(int id, Author const & a)
|
|
|
|
{
|
2014-03-10 19:39:43 +00:00
|
|
|
LBUFERR(unsigned(id) < authors_.size());
|
2003-02-08 19:18:01 +00:00
|
|
|
authors_[id] = a;
|
|
|
|
}
|
|
|
|
|
2003-03-02 12:16:00 +00:00
|
|
|
|
2010-10-29 19:27:55 +00:00
|
|
|
void AuthorList::recordCurrentAuthor(Author const & a)
|
|
|
|
{
|
|
|
|
// current author has id 0
|
|
|
|
record(0, a);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-03-04 09:37:32 +00:00
|
|
|
Author const & AuthorList::get(int id) const
|
2003-02-08 19:18:01 +00:00
|
|
|
{
|
2014-03-10 21:02:17 +00:00
|
|
|
LASSERT(id < (int)authors_.size() , return authors_[0]);
|
2009-07-23 20:08:05 +00:00
|
|
|
return authors_[id];
|
2003-02-08 19:18:01 +00:00
|
|
|
}
|
|
|
|
|
2003-03-02 12:16:00 +00:00
|
|
|
|
2003-02-08 19:18:01 +00:00
|
|
|
AuthorList::Authors::const_iterator AuthorList::begin() const
|
|
|
|
{
|
|
|
|
return authors_.begin();
|
|
|
|
}
|
2003-03-02 12:16:00 +00:00
|
|
|
|
2003-02-08 19:18:01 +00:00
|
|
|
|
|
|
|
AuthorList::Authors::const_iterator AuthorList::end() const
|
|
|
|
{
|
|
|
|
return authors_.end();
|
|
|
|
}
|
2006-10-21 00:16:43 +00:00
|
|
|
|
|
|
|
|
2012-10-27 13:45:27 +00:00
|
|
|
void AuthorList::sort()
|
|
|
|
{
|
2009-07-23 20:08:05 +00:00
|
|
|
std::sort(authors_.begin(), authors_.end(), author_smaller);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-10-27 13:45:27 +00:00
|
|
|
ostream & operator<<(ostream & os, AuthorList const & a)
|
|
|
|
{
|
2009-07-23 20:08:05 +00:00
|
|
|
// Copy the authorlist, because we don't want to sort the original
|
|
|
|
AuthorList sorted = a;
|
|
|
|
sorted.sort();
|
2020-02-28 06:06:22 +00:00
|
|
|
for (auto const & aut : sorted) {
|
|
|
|
if (aut.used() && aut.valid())
|
|
|
|
os << "\\author " << aut << "\n";
|
2009-07-23 20:08:05 +00:00
|
|
|
}
|
|
|
|
return os;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-10-21 00:16:43 +00:00
|
|
|
} // namespace lyx
|