Skip to content

Instantly share code, notes, and snippets.

@silentmatt
Created June 17, 2009 18:20
Show Gist options
  • Save silentmatt/131402 to your computer and use it in GitHub Desktop.
Save silentmatt/131402 to your computer and use it in GitHub Desktop.

Revisions

  1. silentmatt created this gist Jun 17, 2009.
    247 changes: 247 additions & 0 deletions name.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,247 @@
    var Name = (function() {
    function Name(prefix, first, middle, last, suffix, called) {
    this.prefix = prefix || "";
    this.first = first || "";
    this.middle = middle || "";
    this.last = last || "";
    this.suffix = suffix || "";
    this.called = called || "";
    }

    function capitalize(s) {
    return s.charAt(0).toUpperCase() + s.substring(1);
    }

    function addSetter(cls, name, fn) {
    cls.prototype["set" + capitalize(name)] = fn || function(value) {
    this[name] = value;
    return this;
    };

    // Define a JS setter if it's supported and needed
    if (fn && cls.prototype.__defineGetter__) {
    cls.prototype.__defineGetter__(name, fn);
    }
    }

    function addGetter(cls, name, fn) {
    cls.prototype["get" + capitalize(name)] = fn;
    if (cls.prototype.__defineGetter__) {
    cls.prototype.__defineGetter__(name, fn);
    }
    }

    // Chainable setters
    addSetter(Name, "prefix");
    addSetter(Name, "prefix");
    addSetter(Name, "first");
    addSetter(Name, "middle");
    addSetter(Name, "last");
    addSetter(Name, "suffix");
    addSetter(Name, "called");

    // Common name formats
    addGetter(Name, "fullName", function() {
    return this.toString("PFMLS");
    });

    addGetter(Name, "lastFirst", function() {
    return this.toString("L,F");
    //return (this.last + ", " + this.first).replace(/(^, )|(, $)/, "");
    });

    addGetter(Name, "lastFirstMiddle", function() {
    return this.toString("L,FM");
    });

    addGetter(Name, "firstLast", function() {
    return this.toString("FL");
    });

    addGetter(Name, "firstMiddleLast", function() {
    return this.toString("FML");
    });

    addGetter(Name, "informal", function() {
    return this.toString("CL");
    });


    // Initials
    addGetter(Name, "firstInitial", function() {
    return (this.first || "").substring(0, 1);
    });

    addGetter(Name, "middleInitial", function() {
    return (this.middle || "").substring(0, 1);
    });

    addGetter(Name, "lastInitial", function() {
    return (this.last || "").substring(0, 1);
    });

    addGetter(Name, "monogram", function() {
    return this.getFirstInitial() + this.getMiddleInitial() + this.getLastInitial();
    });

    // Names match if all the common parts match
    Name.prototype.matches = function(other) {
    if (this.prefix && other.prefix) {
    if (this.prefix != other.prefix) {
    return false;
    }
    }
    if (this.first && other.first) {
    if (this.first != other.first) {
    return false;
    }
    }
    if (this.middle && other.middle) {
    if (this.middle != other.middle) {
    return false;
    }
    }
    if (this.last && other.last) {
    if (this.last != other.last) {
    return false;
    }
    }
    if (this.suffix && other.suffix) {
    if (this.suffix != other.suffix) {
    return false;
    }
    }

    return true;
    }

    // Spaces are automatically inserted between parts where it (hopefully) makes sense
    // Leading and trailing spaces and commas, as well as empty quotes, braces, etc. are stripped.
    // Multiple spaces are squeezed into a single space.
    //
    // Default format is "PFMLS" - the same as getFullName()
    //
    // Format characters:
    // P - Prefix
    // N - Nickname (called)
    // C - Called By (called or first)
    // F,f - First / first initial
    // M,m - Middle / middle initial
    // L,l - Last / last initial
    // S - Suffix
    // (,[,{," - Literal (no implied space after)
    // ),],} - Literal
    // .,comma - Literal (skipped if the last part was missing)
    // space - Force a space (useful after an end quote)
    Name.prototype.toString = function(fmt) {
    fmt = fmt || "PFMLS";
    var parts = [];
    var sep = "";
    var hadLast = false;

    function pushPart(value) {
    hadLast = false;
    if (value) {
    parts.push(sep + value);
    sep = " ";
    hadLast = true;
    }
    }

    for (var i = 0; i < fmt.length; i++) {
    var c = fmt.charAt(i);

    switch (c) {
    case ',':
    case '.':
    if (hadLast) {
    parts.push(c);
    sep = " ";
    }
    break;
    case ' ':
    parts.push(" ");
    sep = "";
    break;
    case 'P':
    pushPart(this.prefix);
    break;
    case 'N':
    pushPart(this.called);
    break;
    case 'C':
    pushPart(this.called || this.first);
    break;
    case 'F':
    pushPart(this.first);
    break;
    case 'f':
    pushPart(this.getFirstInitial());
    break;
    case 'M':
    pushPart(this.middle);
    break;
    case 'm':
    pushPart(this.getMiddleInitial());
    break;
    case 'L':
    pushPart(this.last);
    break;
    case 'l':
    pushPart(this.getLastInitial());
    break;
    case 'S':
    pushPart(this.suffix);
    break;
    case '"':
    parts.push('"');
    sep = "";
    break;
    case '{':
    case '[':
    case '(':
    parts.push(sep + c);
    sep = "";
    break;
    case '}':
    case ']':
    case ')':
    parts.push(c);
    sep = " ";
    break;
    default:
    throw new Error("Invalid format character: '" + c + "'");
    }
    }

    return parts.join("").replace(/(^[, ]+)|([, ]+$)|(\(\))|("")|(\[\])|({})/g, "").replace(/ +/g, " ");
    }

    Name.test = function() {
    function expect(actual, expected) {
    if (expected !== actual) {
    print("Expected <" + expected + "> but got <" + actual + ">");
    return false;
    }
    return true;
    }

    var me = new Name();
    me.setFirst("Matthew").setLast("Crumley").setCalled("M@");
    expect(me.first, "Matthew");
    expect(me.last, "Crumley");
    expect(me.middle, "");
    expect(me.firstInitial, "M");
    expect(me.lastInitial, "C");
    expect(me.monogram, "MC");
    expect(me.toString(), "Matthew Crumley");
    expect(me.toString('F "N" L'), 'Matthew "M@" Crumley');
    expect(me.toString('L,F'), 'Crumley, Matthew');

    me.called = "";
    expect(me.toString('L,N'), 'Crumley');
    expect(me.toString('L,C'), 'Crumley, Matthew');
    }

    return Name;
    })();