Fork me on GitHub Lingo

Lingo

Linguistics module for Node providing inflection, transformations and more.

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;
};

lingo

lib/lingo.js

Module dependencies.

var fs = require('fs');

Library version.

  • type: String

exports.version = '0.0.3';

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 && 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;
};

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));
};

en

lib/languages/en.js

Module dependencies.

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

English.

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

Default pluralization rules.

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

Default singularization rules.

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

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');