#include "Author.h"
+#include "support/convert.h"
+#include "support/gettext.h"
#include "support/lassert.h"
#include "support/lstrings.h"
string const full_author_string = to_utf8(name + email);
// Bernstein's hash function
unsigned int hash = 5381;
- for (unsigned int i = 0; i < full_author_string.length(); ++i)
- hash = ((hash << 5) + hash) + (unsigned int)(full_author_string[i]);
+ for (char c : full_author_string)
+ hash = ((hash << 5) + hash) + (unsigned int)c;
return int(hash);
}
-Author::Author(docstring const & name, docstring const & email)
- : name_(name), email_(email), used_(true)
+Author::Author(docstring const & name, docstring const & email, docstring const & initials)
+ : name_(name), email_(email), initials_(initials), used_(true),
+ buffer_id_(computeHash(name, email))
+{}
+
+
+Author::Author(int buffer_id)
+ : name_(convert<docstring>(buffer_id)), email_(docstring()), initials_(docstring()), used_(false),
+ buffer_id_(buffer_id)
+{}
+
+
+docstring Author::nameAndEmail() const
{
- buffer_id_ = computeHash(name_, email_);
+ if (email().empty())
+ return name();
+ return bformat(_("%1$s[[name]] (%2$s[[email]])"), name(), email());
+}
+
+
+bool Author::valid() const
+{
+ //this cannot be equal if the buffer_id was produced by the hash function.
+ return name_ != convert<docstring>(buffer_id_);
}
bool operator==(Author const & l, Author const & r)
{
- return l.name() == r.name() && l.email() == r.email();
+ return l.name() == r.name() && l.email() == r.email() && l.initials() == r.initials();
}
ostream & operator<<(ostream & os, Author const & a)
{
// FIXME UNICODE
- os << a.buffer_id_ << " \"" << to_utf8(a.name_)
- << "\" " << to_utf8(a.email_);
-
+ os << a.buffer_id_ << " \"" << to_utf8(a.name_) << "\"";
+ if (!a.email_.empty())
+ os << " " << to_utf8(a.email_);
+
return os;
}
+
istream & operator>>(istream & is, Author & a)
{
string s;
}
-bool author_smaller(Author const & lhs, Author const & rhs) {
+bool author_smaller(Author const & lhs, Author const & rhs)
+{
return lhs.bufferId() < rhs.bufferId();
}
AuthorList::AuthorList()
- : last_id_(0)
-{
-}
+{}
int AuthorList::record(Author const & a)
{
+ bool const valid = a.valid();
// 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.
- if (authors_.size() > 0 && a == authors_[0])
+ if (valid && !authors_.empty() && a == authors_[0])
authors_[0].setBufferId(a.bufferId());
- Authors::const_iterator it(authors_.begin());
- Authors::const_iterator itend(authors_.end());
- for (int i = 0; it != itend; ++it, ++i) {
- if (*it == a)
- return i;
+ 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 const id = it - beg;
+ if (!it->valid()) {
+ // we need to handle the case of a valid author being registered
+ // after an invalid one. For instance, because "buffer-reload"
+ // does not clear the buffer's author list.
+ record(id, a);
+ }
+ return id;
+ }
}
authors_.push_back(a);
- return last_id_++;
+ return authors_.size() - 1;
}
void AuthorList::record(int id, Author const & a)
{
- LASSERT(unsigned(id) < authors_.size(), /**/);
-
+ LBUFERR(unsigned(id) < authors_.size());
authors_[id] = a;
}
Author const & AuthorList::get(int id) const
{
- LASSERT(id < (int)authors_.size() , /**/);
+ LASSERT(id < (int)authors_.size() , return authors_[0]);
return authors_[id];
}
}
-void AuthorList::sort() {
+void AuthorList::sort()
+{
std::sort(authors_.begin(), authors_.end(), author_smaller);
}
-ostream & operator<<(ostream & os, AuthorList const & a) {
+ostream & operator<<(ostream & os, AuthorList const & a)
+{
// Copy the authorlist, because we don't want to sort the original
AuthorList sorted = a;
sorted.sort();
-
- AuthorList::Authors::const_iterator a_it = sorted.begin();
- AuthorList::Authors::const_iterator a_end = sorted.end();
-
- for (a_it = sorted.begin(); a_it != a_end; ++a_it) {
- if (a_it->used())
- os << "\\author " << *a_it << "\n";
+ for (auto const & aut : sorted) {
+ if (aut.used() && aut.valid())
+ os << "\\author " << aut << "\n";
}
return os;
}