# Lingo

Linguistics module for Node providing inflection, transformations and more.

## inflection

lib/inflection.js

Module dependencies.

    var Language = require('./language');

Check if a `word` is uncountable.

##

- param: String word

- return: Boolean

- api: public

    Language.prototype.isUncountable = function(word){
      return !!this.rules.uncountable[word];
    };

Add an uncountable `word`.

##

- param: String word

- return: Language for chaining

- api: public

    Language.prototype.uncountable = function(word){
      this.rules.uncountable[word] = word;
      return this;
    };

Add an irreglar `singular` / `plural` map.

##

- param: String singular

- param: String plural

- return: Language for chaining

- api: public

    Language.prototype.irregular = function(singular, plural){
      this.rules.irregular.plural[singular] = plural;
      this.rules.irregular.singular[plural] = singular;
      return this;
    };

Add a pluralization `rule` with the given `substitution`.

##

- param: RegExp rule

- param: String substitution

- return: Language for chaining

- api: public

    Language.prototype.plural = function(rule, substitution){
      this.rules.plural.unshift([rule, substitution]);
      return this;
    };

Add a singularization `rule` with the given `substitution`.

##

- param: RegExp rule

- param: String substitution

- return: Language for chaining

- api: public

    Language.prototype.singular = function(rule, substitution){
      this.rules.singular.unshift([rule, substitution]);
      return this;
    };

Pluralize the given `word`.

##

- param: String word

- return: String

- api: public

    Language.prototype.pluralize = function(word){
      return this.inflect(word, 'plural');
    };

Check if `word` is plural.

##

- param: String word

- return: Boolean

- api: public

    Language.prototype.isPlural = function(word){
      return word == this.pluralize(this.singularize(word));
    };

Singularize the given `word`.

##

- param: String word

- return: String

- api: public

    Language.prototype.singularize = function(word){
      return this.inflect(word, 'singular');
    };

Check if `word` is singular.

##

- param: String word

- return: Boolean

- api: public

    Language.prototype.isSingular = function(word){
      return word == this.singularize(this.pluralize(word));
    };

## language

lib/language.js

Module dependencies.

    var lingo = require('./lingo');

Initialize a new `Language` with the given `code`.

##

- param: String code

- api: public

    var Language = module.exports = function Language(code) {
      this.code = code;
      this.translations = {};
      this.rules = {
          plural: []
        , singular: []
        , uncountable: {}
        , irregular: { plural: {}, singular: {}}
      };
      lingo[code] = this;
    };

Translate the given `str` with optional `params`.

##

- param: String str

- param: Object params

- return: String

- api: public

    Language.prototype.translate = function(str, params){
      str = this.translations[str] || str;
      if (params) {
        str = str.replace(/\{([^}]+)\}/g, function(_, key){
          return params[key];
        });
      }
      return str;
    };

## en

lib/languages/en.js

Module dependencies.

    var Language = require('../language');

English.

    var en = module.exports = new Language('en');

Default pluralization rules.

    en.plural(/$/, &quot;s&quot;)
      .plural(/(s|ss|sh|ch|x|o)$/i, &quot;$es&quot;)
      .plural(/y$/i, &quot;ies&quot;)
      .plural(/(o|e)y$/i, &quot;$ys&quot;)
      .plural(/(octop|vir)us$/i, &quot;$i&quot;)
      .plural(/(alias|status)$/i, &quot;$es&quot;)
      .plural(/(bu)s$/i, &quot;$ses&quot;)
      .plural(/([ti])um$/i, &quot;$a&quot;)
      .plural(/sis$/i, &quot;ses&quot;)
      .plural(/(?:([^f])fe|([lr])f)$/i, &quot;$1$ves&quot;)
      .plural(/([^aeiouy]|qu)y$/i, &quot;$ies&quot;)
      .plural(/(matr|vert|ind)(?:ix|ex)$/i, &quot;$ices&quot;)
      .plural(/([m|l])ouse$/i, &quot;$ice&quot;)
      .plural(/^(ox)$/i, &quot;$en&quot;)
      .plural(/(quiz)$/i, &quot;$zes&quot;);

Default singularization rules.

    en.singular(/s$/i, &quot;&quot;)
      .singular(/(bu|mis|kis)s$/i, &quot;$s&quot;)
      .singular(/([ti])a$/i, &quot;$um&quot;)
      .singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, &quot;$1$sis&quot;)
      .singular(/(^analy)ses$/i, &quot;$sis&quot;)
      .singular(/([^f])ves$/i, &quot;$fe&quot;)
      .singular(/([lr])ves$/i, &quot;$f&quot;)
      .singular(/([^aeiouy]|qu)ies$/i, &quot;$y&quot;)
      .singular(/ies$/i, &quot;ie&quot;)
      .singular(/(x|ch|ss|sh)es$/i, &quot;$1&quot;)
      .singular(/([m|l])ice$/i, &quot;$ouse&quot;)
      .singular(/(bus)es$/i, &quot;$1&quot;)
      .singular(/(o)es$/i, &quot;$1&quot;)
      .singular(/(shoe)s$/i, &quot;$1&quot;)
      .singular(/(cris|ax|test)es$/i, &quot;$is&quot;)
      .singular(/(octop|vir)i$/i, &quot;$us&quot;)
      .singular(/(alias|status)es$/i, &quot;$1&quot;)
      .singular(/^(ox)en/i, &quot;$1&quot;)
      .singular(/(vert|ind)ices$/i, &quot;$ex&quot;)
      .singular(/(matr)ices$/i, &quot;$ix&quot;)
      .singular(/(quiz)zes$/i, &quot;$1&quot;);

Default irregular word mappings.

    en.irregular('i', 'we')
      .irregular('person', 'people')
      .irregular('man', 'men')
      .irregular('child', 'children')
      .irregular('move', 'moves')
      .irregular('she', 'they')
      .irregular('he', 'they')
      .irregular('myself', 'ourselves')
      .irregular('yourself', 'ourselves')
      .irregular('himself', 'themselves')
      .irregular('herself', 'themselves')
      .irregular('themself', 'themselves')
      .irregular('mine', 'ours')
      .irregular('hers', 'theirs')
      .irregular('his', 'theirs')
      .irregular('its', 'theirs')
      .irregular('theirs', 'theirs')
      .irregular('sex', 'sexes');

Default uncountables.

    en.uncountable('advice')
      .uncountable('enegery')
      .uncountable('excretion')
      .uncountable('digestion')
      .uncountable('cooperation')
      .uncountable('health')
      .uncountable('justice')
      .uncountable('jeans')
      .uncountable('labour')
      .uncountable('machinery')
      .uncountable('equipment')
      .uncountable('information')
      .uncountable('pollution')
      .uncountable('sewage')
      .uncountable('paper')
      .uncountable('money')
      .uncountable('species')
      .uncountable('series')
      .uncountable('rain')
      .uncountable('rice')
      .uncountable('fish')
      .uncountable('sheep')
      .uncountable('moose')
      .uncountable('deer')
      .uncountable('bison')
      .uncountable('proceedings')
      .uncountable('shears')
      .uncountable('pincers')
      .uncountable('breeches')
      .uncountable('hijinks')
      .uncountable('clippers')
      .uncountable('chassis')
      .uncountable('innings')
      .uncountable('elk')
      .uncountable('rhinoceros')
      .uncountable('swine')
      .uncountable('you')
      .uncountable('news');

## lingo

lib/lingo.js

Module dependencies.

    var fs = require('fs');

Library version.

- type: String

    exports.version = '0.0.2';

Expose `Language`.

- type: Function

    exports.Language = require('./language');

Extend `Language` with inflection rules.

    require('./inflection');

Auto-require languages.

    require('./languages/en');

Capitalize the first word of `str` or optionally `allWords`.

## Examples

lingo.capitalize('hello there'); // => "Hello there"

lingo.capitalize('hello there', true); // => "Hello There"

##

- param: String str

- param: Boolean allWords

- return: String

- api: public

    exports.capitalize = function(str, allWords){
      if (allWords) {
        return str.split(' ').map(function(word){
          return exports.capitalize(word);
        }).join(' ');
      }
      return str.charAt(0).toUpperCase() + str.substr(1);
    };

Camel-case the given `str`.

## Examples

lingo.camelcase('foo bar'); // => "fooBar"

lingo.camelcase('foo bar baz', true); // => "FooBarBaz"

##

- param: String str

- param: Boolean uppercaseFirst

- return: String

- api: public

    exports.camelcase = function(str, uppercaseFirst){
      return str.replace(/[^\w\d ]+/g, '').split(' ').map(function(word, i){
        if (i || (0 == i &amp;&amp; uppercaseFirst)) {
          word = exports.capitalize(word);
        }
        return word;
      }).join('');
    };

Join an array with the given `last` string which defaults to "and".

## Examples

lingo.join(['fruits', 'veggies', 'sugar']); // => "fruits, veggies and sugar"

lingo.join(['fruits', 'veggies', 'sugar'], 'or'); // => "fruits, veggies or sugar"

##

- param: Array arr

- param: String last

- return: String

- api: public

    exports.join = function(arr, last){
      var str = arr.pop()
        , last = last || 'and';
      if (arr.length) {
        str = arr.join(', ') + ' ' + last + ' ' + str;
      }
      return str;
    };