UNPKG

poserver

Version:
203 lines (168 loc) 7.35 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); */ var ParsedName = function (nameObject) { nameObject = nameObject || {}; if (typeof nameObject === "string") nameObject = this.parseName(nameObject); var _this = this; _this.__type = "ParsedName"; 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; if (nameObject.hasOwnProperty("userString")) _this.userString = nameObject.userString; }; ParsedName.prototype.fullNameWithTitle = function () { var _this = this; var fullname = _this.fullName(); if (_this.hasOwnProperty("courtesyTitle")) fullname = _this.courtesyTitle + ". " + fullname; return fullname; }; ParsedName.prototype.fullName = function () { var _this = this; 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; }; ParsedName.prototype.parsedName = function () { var _this = this; var pname = {}; pname.className = _this.__type; 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; }; ParsedName.prototype.toDocument = function () { return this.parsedName; }; ParsedName.prototype.toString = function () { return this.fullNameWithTitle; }; ParsedName.prototype.inferredGender = function () { 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" */ ParsedName.prototype.parseName = function (fullName, nameFromChannel) { var pName = 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 (pName.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" pName.courtesyTitle = nameParts[0]; pName.lastName = nameParts[1]; pName.salutation = nameParts[0] + ". " + nameParts[1]; return pName; } else { //We have a courtesy title and at least two other words, so assume second word is first name. //E.G. "Mr. Tom Daley" pName.courtesyTitle = nameParts[0]; pName.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. pName.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) { pName.suffix = nameParts[idx--]; pName.lastName = nameParts[idx--]; } else { pName.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] + " "; pName.middleName = mname.trim(); } //What is a polite way to address our user? if (pName.hasOwnProperty("courtesyTitle") && pName.hasOwnProperty("lastName")) pName.salutation = pName.courtesyTitle + ". " + pName.lastName; else if (pName.hasOwnProperty("firstName")) pName.salutation = pName.firstName; else pName.salutation = nameFromChannel; return pName; }; module.exports = ParsedName;