Empirical
Author.h
Go to the documentation of this file.
1 // This file is part of Empirical, https://github.com/devosoft/Empirical
2 // Copyright (C) Michigan State University, 2016-2017.
3 // Released under the MIT Software license; see doc/LICENSE
4 //
5 //
6 // Basic information about an author.
7 //
8 //
9 // Developer notes:
10 // * Prefixs (Dr., Prof., etc) and Suffixes (Jr., Sr., III, etc.) should be allowed.
11 // * Most parts of names can be auto-detected.
12 // * GetName() (with formatting) needs to be implemented (notes below)
13 // * Consider using ce_string for inputs? And making other aspects const experession?
14 
15 #ifndef EMP_AUTHOR_H
16 #define EMP_AUTHOR_H
17 
18 #include <string>
19 
20 #include "../tools/Lexer.h"
21 
22 namespace emp {
23 
24  class Author {
25  private:
26  std::string prefix;
27  std::string first_name;
28  emp::vector<std::string> middle_names;
29  std::string last_name;
30  std::string suffix;
31 
32  static Lexer & GetFormatLexer() {
33  static Lexer lexer;
34  if (lexer.GetNumTokens() == 0) {
35  lexer.AddToken("type", "[FMLfmlPSx]");
36  lexer.AddToken("spacing", "[- ,.:]+");
37  }
38  return lexer;
39  }
40  public:
41  Author(const std::string & first, const std::string & middle, const std::string & last)
42  : first_name(first), last_name(last) { middle_names.push_back(middle); }
43  Author(const std::string & first, const std::string & last)
44  : first_name(first), last_name(last) { ; }
45  Author(const std::string & last)
46  : last_name(last) { ; }
47  Author(const Author &) = default;
48  ~Author() { ; }
49  Author & operator=(const Author &) = default;
50 
51  bool operator==(const Author & other) const {
52  return (prefix == other.prefix) && (first_name == other.first_name) &&
53  (middle_names == other.middle_names) &&
54  (last_name == other.last_name) && (suffix == other.suffix);
55  }
56  bool operator!=(const Author & other) const { return !(*this == other); }
57  bool operator<(const Author & other) const {
58  if (last_name != other.last_name) return (last_name < other.last_name);
59  if (first_name != other.first_name) return (first_name < other.first_name);
60  for (size_t i = 0; i < middle_names.size(); i++) {
61  if (other.middle_names.size() <= i) return false;
62  if (middle_names[i] != other.middle_names[i]) {
63  return (middle_names[i] < other.middle_names[i]);
64  }
65  }
66  if (middle_names.size() < other.middle_names.size()) return true;
67  if (suffix != other.suffix) return (suffix < other.suffix);
68  if (prefix != other.prefix) return (prefix < other.prefix);
69  return false; // Must be equal!
70  }
71  bool operator>(const Author & other) const { return other < *this; }
72  bool operator>=(const Author & other) const { return !(*this < other); }
73  bool operator<=(const Author & other) const { return !(*this > other); }
74 
75  bool HasPrefix() const { return prefix.size(); }
76  bool HasFirstName() const { return first_name.size(); }
77  bool HasMiddleName() const { return middle_names.size(); }
78  bool HasLastName() const { return last_name.size(); }
79  bool HasSuffix() const { return suffix.size(); }
80 
81  const std::string & GetPrefix() const { return prefix; }
82  const std::string & GetFirstName() const { return first_name; }
83  const std::string & GetMiddleName(size_t id=0) const {
84  if (middle_names.size() == 0) return emp::empty_string();
85  return middle_names[id];
86  }
87  const std::string & GetLastName() const { return last_name; }
88  const std::string & GetSuffix() const { return suffix; }
89 
90  std::string GetFullName() const {
91  std::string full_name(prefix);
92  if (full_name.size() && HasFirstName()) full_name += " ";
93  full_name += first_name;
94  for (const auto & middle_name : middle_names) {
95  if (full_name.size()) full_name += " ";
96  full_name += middle_name;
97  }
98  if (full_name.size() && HasLastName()) full_name += " ";
99  full_name += last_name;
100  if (full_name.size() && HasSuffix()) full_name += " ";
101  full_name += suffix;
102  return full_name;
103  }
104  std::string GetReverseName() const {
105  std::string full_name(last_name);
106  if (full_name.size() && HasFirstName()) full_name += ", ";
107  full_name += first_name;
108  for (const auto & middle_name : middle_names) {
109  if (full_name.size()) full_name += " ";
110  full_name += middle_name;
111  }
112  if (full_name.size() && HasSuffix()) full_name += ", ";
113  full_name += suffix;
114  return full_name;
115  }
116 
117  std::string GetFirstInitial() const {
118  return HasFirstName() ? to_string(first_name[0]) : emp::empty_string();
119  }
120  std::string GetMiddleInitials() const {
121  std::string out;
122  for (const auto & m : middle_names) out += m[0];
123  return out;
124  }
125  std::string GetLastInitial() const {
126  return HasLastName() ? to_string(last_name[0]) : emp::empty_string();
127  }
128  std::string GetInitials() const {
129  std::string inits;
130  inits += GetFirstInitial();
131  inits += GetMiddleInitials();
132  inits += GetLastInitial();
133  return inits;
134  }
135 
136  // A generic GetName() function that takes a string to produce the final format.
137  // F = first name f = first initial
138  // M = middle names m = middle initials
139  // L = last name l = last initial
140  // P = prefix S = suffix
141  // x = an empty breakpoint to ensure certain puctuation exists.
142  //
143  // Allowable punctuation = [ ,.-:] and is associated with the prior name key, so it will
144  // appear only if the name does (and in the case of the middle name, will appear with each).
145  //
146  // For example, if the person's name is "Abraham Bartholomew Carmine Davidson" then...
147  // GetName("FML") would return "Abraham Bartholomew Carmine Davidson"
148  // GetName("fml") would return "ABCD"
149  // GetName("L, fm") would return "Davidson, ABC"
150  // GetName("f.m.x L") would return "A.B.C. Davidson"
151  //
152  // Note that without the 'x', the space would be associated with all middle names:
153  //
154  // GetName("f.m. L") would return "A.B. C. Davidson"
155 
156  std::string GetName(std::string pattern="FML") {
157  std::string out_name;
158  Lexer & lexer = GetFormatLexer();
159  lexer.Process(pattern);
160  return out_name;
161  }
162 
163  Author & Clear() {
164  prefix=""; first_name=""; last_name=""; middle_names.resize(0); suffix="";
165  return *this;
166  }
167  Author & SetFirst(const std::string & str) { first_name = str; return *this; }
168  Author & SetLast(const std::string & str) { last_name = str; return *this; }
169  Author & AddMiddle(const std::string & str) { middle_names.push_back(str); return *this; }
170  };
171 
172 }
173 
174 #endif
static const std::string & empty_string()
Definition: string_utils.h:29
Author(const std::string &last)
Definition: Author.h:45
bool HasPrefix() const
Definition: Author.h:75
std::string GetInitials() const
Definition: Author.h:128
std::string GetName(std::string pattern="FML")
Definition: Author.h:156
std::string GetMiddleInitials() const
Definition: Author.h:120
std::string to_string(ALL_TYPES &&...all_values)
Definition: string_utils.h:511
size_t GetNumTokens() const
How many types of tokens can be identified in this Lexer?
Definition: Lexer.h:82
Author & SetFirst(const std::string &str)
Definition: Author.h:167
std::string GetLastInitial() const
Definition: Author.h:125
bool operator>=(const Author &other) const
Definition: Author.h:72
void push_back(PB_Ts &&...args)
Definition: vector.h:189
const std::string & GetPrefix() const
Definition: Author.h:81
A lexer with a set of token types (and associated regular expressions)
Definition: Lexer.h:64
Author & SetLast(const std::string &str)
Definition: Author.h:168
size_t size() const
Definition: vector.h:151
Author & AddMiddle(const std::string &str)
Definition: Author.h:169
Token Process(std::istream &is)
Get the next token found in an input stream.
Definition: Lexer.h:133
bool operator>(const Author &other) const
Definition: Author.h:71
Author(const std::string &first, const std::string &middle, const std::string &last)
Definition: Author.h:41
const std::string & GetMiddleName(size_t id=0) const
Definition: Author.h:83
const std::string & GetLastName() const
Definition: Author.h:87
std::string GetFullName() const
Definition: Author.h:90
bool HasSuffix() const
Definition: Author.h:79
bool operator<=(const Author &other) const
Definition: Author.h:73
Author & Clear()
Definition: Author.h:163
std::string GetFirstInitial() const
Definition: Author.h:117
void resize(size_t new_size)
Definition: vector.h:161
std::string GetReverseName() const
Definition: Author.h:104
Author(const std::string &first, const std::string &last)
Definition: Author.h:43
~Author()
Definition: Author.h:48
If we are in emscripten, make sure to include the header.
Definition: array.h:37
bool operator<(const Author &other) const
Definition: Author.h:57
bool operator==(const Author &other) const
Definition: Author.h:51
Definition: Author.h:24
Author & operator=(const Author &)=default
bool HasMiddleName() const
Definition: Author.h:77
bool HasFirstName() const
Definition: Author.h:76
const std::string & GetFirstName() const
Definition: Author.h:82
const std::string & GetSuffix() const
Definition: Author.h:88
bool operator!=(const Author &other) const
Definition: Author.h:56
bool HasLastName() const
Definition: Author.h:78
size_t AddToken(const std::string &in_name, const std::string &in_regex)
Add a new token, specified by a name and the regex used to identify it.
Definition: Lexer.h:85