~ 5 min read

String to Title Case in Javascript

Based on the title case project. Which I discovered through this jekyll fix titlecase an npm package while switching to jekyll (in fact there are numerous npm packages that wrap this same library)

The author of the npm package adds 3 more exceptions to the original source code

function toTitleCase(str) {
    var smallWords = /^(a|an|and|as|at|but|by|en|for|if|in|nor|of|on|or|per|the|to|vs?\.?|via)$/i;

    return (str + '').replace(/[A-Za-z0-9\u00C0-\u00FF]+[^\s-]*/g, function (match, index, title) {

        if (index > 0 && index + match.length !== title.length &&
            match.search(smallWords) > -1 && title.charAt(index - 2) !== ":" &&
            (title.charAt(index + match.length) !== '-' || title.charAt(index - 1) === '-') &&
            title.charAt(index - 1).search(/[^\s-]/) < 0) {
            return match.toLowerCase();
        }

        if (match.substr(1).search(/[A-Z]|\../) > -1) {
            return match;
        }
        // Avoid uppercasing 'mod_deflate', apt-file - kvz
        if (match.match(/.[\_\-\/\d]./)) {
            return match;
        }
        // Avoid uppercasing '`frame`', '/sftp/import' - kvz
        if (match.match(/(^[`\/]|[`]$)/)) {
            return match;
        }
        // Avoid uppercasing: 'tmpfs' or anything that doesn't have a vowel - kvz
        if (!match.match(/[aeiou]/)) {
            return match;
        }
        return match.charAt(0).toUpperCase() + match.substr(1);
    });
};

The original source code:

/* 
* To Title Case 2.1 – http://individed.com/code/to-title-case/
* Copyright © 2008–2013 David Gouch. Licensed under the MIT License.
* 
* https://github.com/gouch/to-title-case/blob/master/to-title-case.js
*/

String.prototype.toTitleCase = function(){
  var smallWords = /^(a|an|and|as|at|but|by|en|for|if|in|nor|of|on|or|per|the|to|vs?\.?|via)$/i;

  return this.replace(/[A-Za-z0-9\u00C0-\u00FF]+[^\s-]*/g, function(match, index, title){
    if (index > 0 && index + match.length !== title.length &&
      match.search(smallWords) > -1 && title.charAt(index - 2) !== ":" &&
      (title.charAt(index + match.length) !== '-' || title.charAt(index - 1) === '-') &&
      title.charAt(index - 1).search(/[^\s-]/) < 0) {
      return match.toLowerCase();
    }

    if (match.substr(1).search(/[A-Z]|\../) > -1) {
      return match;
    }

    return match.charAt(0).toUpperCase() + match.substr(1);
  });
};