UNPKG

poserver

Version:
201 lines (169 loc) 8.03 kB
/** * Created by tomdaley on 10/8/16. */ "use strict"; /** * ParsedName - Class containing name fields for a person * * var myName = "Mr. Thomas J. Daley, Esq."; * var myParsedName = ParsedName.parse(myName); */ class ParsedName { constructor(nameObject) { if (nameObject.hasOwnProperty("courtesyTitle")) this.courtesyTitle = nameObject.courtesyTitle; if (nameObject.hasOwnProperty("firstName")) this.firstName = nameObject.firstName; if (nameObject.hasOwnProperty("middleName")) this.middleName = nameObject.middleName; if (nameObject.hasOwnProperty("lastName")) this.lastName = nameObject.lastName; if (nameObject.hasOwnProperty("suffix")) this.suffix = nameObject.suffix; if (nameObject.hasOwnProperty("salutation")) this.salutation = nameObject.salutation; } get fullNameWithTitle() { var fullname = this.fullName; if (this.hasOwnProperty("courtesyTitle")) fullname = this.courtesyTitle + ". " + fullname; return fullname; } get fullName() { var fullname = ""; if (this.hasOwnProperty("firstName")) fullname += this.firstName; if (this.hasOwnProperty("middleName")) { if (this.middleName.length === 1) fullname += " " + this.middleName + ". "; else fullname += " " + this.middleName; } if (this.hasOwnProperty("lastName")) fullname += " " + this.lastName; if (this.hasOwnProperty("suffix")) fullname += ", " + this.suffix; fullname = fullname.replace(/\s+/, ' ').trim(); return fullname; } get parsedName() { var pname = {}; if (this.suffix) pname.suffix = this.suffix; if (this.firstName) pname.firstName = this.firstName; if (this.middleName) pname.middleName = this.middleName; if (this.lastName) pname.lastName = this.lastName; if (this.suffix) pname.suffix = this.suffix; return pname; } toDocument() { return this.parsedName; } toString() { return this.fullNameWithTitle; } get inferredGender() { var maleTitles = ["MR"]; var femaleTitles = ["MS", "MX", "MRS"]; if (this.courtesyTitle === false) return -1; if (maleTitles.indexOf(this.courtesyTitle.toUpperCase()) != -1) return 0; if (femaleTitles.indexOf(this.courtesyTitle.toUpperCase()) != -1) return 1; return -1; } /** * Here to break a string apart into various name parts. I will probably use LUIS for this purpose * in the future. For now, I'm just doing a dumb parse. Here's a trick that no user will ever figure out * so I don't know what it's worth. For now, an equal sign between words causes them to be parsed as a single * entity, but then the equal is replaced by a space so that we get the visual appearance of a two-word name. * * For example, if the person's last name were "St. Laurent", the user could enter it as "St.=Laurent" and * it would parse as expected and look nice. Otherwise, with THIS version of the algorithm, the "St." potion * will parse out as part of the person's middle name. * * Input -> First Name Middle Name Last Name * Tom Daley Tom Daley * Ludwig Van Beethove Ludwig Van Beethoven * Ludwig Van=Beethoven Ludwig Van Beethoven * Ms. C. K. Rowling, PhD C. K. Rowling * * TODO: Does not work for multi-word last names, such as "St. Laurent" or "Van Beethoven" */ static parseName(fullName, nameFromChannel) { var parsedName = new ParsedName({"userString": fullName}); nameFromChannel = nameFromChannel || fullName; var suffixes = ["JR", "SR", "II", "III", "IV", "V", "PHD", "JD", "ESQ", "MD", "LPC", "RN"]; var courtesyTitles = ["MR", "MS", "MRS", "DR", "HON", "REV", "FR", "GURU", "PANDIT", "ELDER", "WITCH", "LAMANE", "MOBAD", "SEID"]; //Remove commas, periods. Convert all white space to spaces. Compress out consecutive spaces. var nameParts = fullName.replace(/[.,]/g, '').replace(/\s/g, ' ').replace(/\s+/g, ' ').split(' '); //For now, if the user puts an equal-sign ("=") in the name, convert it to a space to accommodate multi-word //names or multiple middle names. This is ugly, but it provides some relief for the "to do" above. for (var i = 0; i < nameParts.length; i++) nameParts[i] = (nameParts[i].replace(/=/g, ' ').replace(/\s+/g, ' ')).trim(); //no double space trickery! //Remember where we found the person's first name var firstNameIndex; if (courtesyTitles.indexOf(nameParts[0].toUpperCase()) != -1) { if (parsedName.length === 2) { //Strange use case where user provides a courtesy title and a last name, e.g. "Mr. Daley" //Of course, I can't tell the difference between that and someone saying "Mr. Tom" parsedName.courtesyTitle = nameParts[0]; parsedName.lastName = nameParts[1]; parsedName.salutation = nameParts[0] + ". " + nameParts[1]; return parsedName; } else { //We have a courtesy title and at least two other words, so assume second word is first name. //E.G. "Mr. Tom Daley" parsedName.courtesyTitle = nameParts[0]; parsedName.firstName = nameParts[1]; firstNameIndex = 1; } } else { //No courtesy title. Assume first word is first name. //E.G. "Tom Daley" //Note, we have a provincial list of courtesy titles: Common titles from non-Western traditions //will be missed, e.g. "Guru", "Pandit", as well as less common Western titles, e.g. "Elder". //OK, I just added those, but you get the picture. parsedName.firstName = nameParts[0]; firstNameIndex = 0; } //See if we have a suffix. If not, last element is last name var idx = nameParts.length - 1; if (suffixes.indexOf(nameParts[idx].toUpperCase()) != -1) { parsedName.suffix = nameParts[idx--]; parsedName.lastName = nameParts[idx--]; } else { parsedName.lastName = nameParts[idx--]; } //Anything left over is the middle name. if (idx != firstNameIndex) { var mname = ""; for (i = firstNameIndex + 1; i <= idx; i++) mname += nameParts[i] + " "; parsedName.middleName = mname.trim(); } //What is a polite way to address our user? if (parsedName.hasOwnProperty("courtesyTitle") && parsedName.hasOwnProperty("lastName")) parsedName.salutation = parsedName.courtesyTitle + ". " + parsedName.lastName; else if (parsedName.hasOwnProperty("firstName")) parsedName.salutation = parsedName.firstName; else parsedName.salutation = nameFromChannel; /* if (parsedName.hasOwnProperty("courtesyTitle")) this.courtesyTitle = parsedName.courtesyTitle; if (parsedName.hasOwnProperty("firstName")) this.firstName = parsedName.firstName; if (parsedName.hasOwnProperty("middleName")) this.middleName = parsedName.middleName; if (parsedName.hasOwnProperty("lastName")) this.lastName = parsedName.lastName; if (parsedName.hasOwnProperty("suffix")) this.suffix = parsedName.suffix; if (parsedName.hasOwnProperty("salutation")) this.salutation = parsedName.salutation; */ return parsedName; } } module.exports = ParsedName;