UNPKG

hexo

Version:

A fast, simple & powerful blog framework, powered by Node.js.

402 lines (342 loc) 8.5 kB
/** * Inflector. * * @class inflector * @namespace util * @since 2.4.0 * @module hexo */ var plurals = [], singulars = [], uncountables = []; var words = [ 'a', 'an', 'and', 'as', 'at', 'but', 'by', 'en', 'for', 'if', 'in', 'of', 'on', 'or', 'the', 'to', 'v', 'v.', 'via', 'vs', 'vs.' ]; var plural = function(key, value){ plurals.push([key, value]); }; var singular = function(key, value){ singulars.push([key, value]); }; var irregular = function(key, value){ plural(new RegExp('(' + key + ')$', 'i'), value); singular(new RegExp('(' + value + ')$', 'i'), key); }; var uncountable = function(word){ uncountables.push(new RegExp('(' + word + ')$', 'i')); }; plural(/$/, 's'); plural(/s$/i, 's'); plural(/(ax|test)is$/i, '$1es'); plural(/(octop|vir)us$/i, '$1i'); plural(/(alias|status)$/i, '$1es'); plural(/(bu)s$/i, '$1ses'); plural(/(buffal|tomat)o$/i, '$1oes'); plural(/([ti])um$/i, '$1a'); plural(/sis$/i, 'ses'); plural(/(?:([^f])fe|([lr])f)$/i, '$1$2ves'); plural(/(hive)$/i, '$1s'); plural(/([^aeiouy]|qu)y$/i, '$1ies'); plural(/(x|ch|ss|sh)$/i, '$1es'); plural(/(matr|vert|ind)(?:ix|ex)$/i, '$1ices'); plural(/([m|l])ouse$/i, '$1ice'); plural(/^(ox)$/i, '$1en'); plural(/(quiz)$/i, '$1zes'); singular(/s$/i, ''); singular(/(n)ews$/i, '$1ews'); singular(/([ti])a$/i, '$1um'); singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, '$1$2sis'); singular(/(analy)ses$/i, '$1sis'); singular(/([^f])ves$/i, '$1fe'); singular(/(hive)s$/i, '$1'); singular(/(tive)s$/i, '$1'); singular(/([lr])ves$/i, '$1f'); singular(/([^aeiouy]|qu)ies$/i, '$1y'); singular(/(s)eries$/i, '$1eries'); singular(/(m)ovies$/i, '$1ovie'); singular(/(x|ch|ss|sh)es$/i, '$1'); singular(/([m|l])ice$/i, '$1ouse'); singular(/(bus)es$/i, '$1'); singular(/(o)es$/i, '$1'); singular(/(shoe)s$/i, '$1'); singular(/(cris|ax|test)es$/i, '$1is'); singular(/(octop|vir)i$/i, '$1us'); singular(/(alias|status)es$/i, '$1'); singular(/^(ox)en/i, '$1'); singular(/(vert|ind)ices$/i, '$1ex'); singular(/(matr)ices$/i, '$1ix'); singular(/(quiz)zes$/i, '$1'); singular(/(database)s$/i, '$1'); irregular('person', 'people'); irregular('man', 'men'); irregular('child', 'children'); irregular('sex', 'sexes'); irregular('move', 'moves'); irregular('cow', 'kine'); irregular('zombie', 'zombies'); irregular('genus', 'genera'); uncountable('equipment'); uncountable('information'); uncountable('rice'); uncountable('money'); uncountable('species'); uncountable('series'); uncountable('fish'); uncountable('sheep'); uncountable('jeans'); uncountable('police'); uncountable('status'); /** * Returns the plural form of the string. * * @method pluralize * @param {String} str * @return {String} * @static */ var pluralize = exports.pluralize = function(str){ str = str.toLowerCase(); var i; for (i = uncountables.length - 1; i >= 0; i--){ if (uncountables[i].test(str)){ return str; } } for (i = plurals.length - 1; i >= 0; i--){ var item = plurals[i], rule = item[0]; if (item[1] === str) return str; if (rule.test(str)){ return str.replace(rule, item[1]); } } return str; }; /** * Returns the singular form of the string. * * @method singularize * @param {String} str * @return {String} * @static */ var singularize = exports.singularize = function(str){ str = str.toLowerCase(); var i; for (i = uncountables.length - 1; i >= 0; i--){ if (uncountables[i].test(str)){ return str; } } for (i = singulars.length - 1; i >= 0; i--){ var item = singulars[i], rule = item[0]; if (rule.test(str)){ return str.replace(rule, item[1]); } } return str; }; /** * Converts the string to CamelCase. * * @method singularize * @param {String} str * @param {Boolean} uppercase * @return {String} * @static */ var camelize = exports.camelize = function(str, uppercase){ if (typeof uppercase === 'undefined') uppercase = true; str = str.replace(/(?:_|(\/))([a-z\d]*)/g, function(){ var word = arguments[2]; return word[0].toUpperCase() + word.substring(1); }); if (uppercase) str = str[0].toUpperCase() + str.substring(1); return str; }; /** * Returns an underscored, lowercased form of the string. * * @method underscore * @param {String} str * @return {String} * @static */ var underscore = exports.underscore = function(str){ return str .replace(/([A-Z\d]+)([A-Z][a-z])/g, function(){ return arguments[1] + '_' + arguments[2].toLowerCase(); }) .replace(/([a-z\d])([A-Z])/g, function(){ return arguments[1] + '_' + arguments[2].toLowerCase(); }) .replace(/-/g, '_') .toLowerCase(); }; /** * Capitalizes the first word, turns underscores into spaces and strip a trailing "_id". * * @method humanize * @param {String} str * @return {String} * @static */ var humanize = exports.humanize = function(str){ str = str .replace(/_id$/, '') .replace(/_/g, ' ') .toLowerCase(); return str[0].toUpperCase() + str.substring(1); }; /** * Capitalizes all the words. * * @method startcase * @param {String} str * @return {String} * @static */ var startcase = exports.startcase = function(str){ return humanize(underscore(str)) .replace(/\b(['’`])?([a-z])/g, function(match){ if (arguments[1]){ return match; } else { return arguments[2].toUpperCase(); } }); }; /** * Capitalizes all the words, except for articles, prepositions, and conjunctions. * * `titleize` is also aliased as `titlecase`. * * @method titleize * @param {String} str * @return {String} * @static */ var titleize = exports.titleize = exports.titlecase = function(str){ return startcase(str) .replace(/(['’`])?(\w+)/g, function(match, mark, str){ if (mark){ return match; } else { str = str.toLowerCase(); if (words.indexOf(str) == -1){ return str[0].toUpperCase() + str.substring(1); } else { return str; } } }); }; /** * Creates a name of a table. * * @method tableize * @param {String} str * @return {String} * @static */ var tableize = exports.tableize = function(str){ return pluralize(underscore(str)); }; /** * Creates a class name. * * @method classify * @param {String} str * @return {String} * @static */ var classify = exports.classify = function(str){ return camelize(singularize(str.replace(/.*\./g, ''))); }; /** * Replaces underscores with dashes in the string. * * @method dasherize * @param {String} str * @return {String} * @static */ var dasherize = exports.dasherize = function(str){ return str.replace(/_/g, '-'); }; /** * Replaces special characters in a string so that it may be used as part of a ‘pretty’ URL. * * @method parameterize * @param {String} str * @return {String} * @static */ var parameterize = exports.parameterize = function(str, sep){ if (typeof sep === 'undefined') sep = '-'; str = str .toLowerCase() .replace(/[^a-z0-9\-_]+/g, sep); if (sep){ str = str // Remove repeated separators .replace(new RegExp(sep + '{2,}', 'g'), sep) // Remove leading/trailing separators .replace(new RegExp('^' + sep + '|' + sep + '$'), ''); } return str; }; /** * Creates a foreign key name from a class name. `separate_class_name_and_id_with_underscore` sets * whether the method should put '_' between the name and 'id'. * * @method foreignKey * @param {String} str * @param {Boolean} sep * @return {String} * @static */ var foreignKey = exports.foreignKey = exports.foreign_key = function(str, sep){ if (typeof sep === 'undefined') sep = true; return underscore(singularize(str) + (sep ? '_id' : 'id')); }; /** * Returns the suffix that should be added to a number to denote the position in * an ordered sequence such as 1st, 2nd, 3rd, 4th. * * @method ordinal * @param {Number} num * @return {String} * @static */ var ordinal = exports.ordinal = function(num){ num = Math.abs(+num) % 100; if (num >= 11 && num <= 13){ return 'th'; } else { switch (num % 10){ case 1: return 'st'; case 2: return 'nd'; case 3: return 'rd'; default: return 'th'; } } }; /** * Turns a number into an ordinal string used to denote the position in an ordered sequence * such as 1st, 2nd, 3rd, 4th. * * @method ordinalize * @param {Number} num * @return {String} * @static */ var ordinalize = exports.ordinalize = function(num){ return num + ordinal(num); };