module Titleize

Adds String#titleize for creating properly capitalized titles. It can be called as Titleize.titleize or “a string”.titleize.

titlecase is included as an alias for titleize.

If loaded in a Rails environment, it modifies Inflector.titleize.

Constants

SMALL_WORDS

Public Instance Methods

phrases(title) click to toggle source

Splits a title into an array based on punctuation.

"simple title"              # => ["simple title"]
"more complicated: titling" # => ["more complicated:", "titling"]
# File lib/wedge/utilis/titleize.rb, line 57
def phrases(title)
  phrases = title.scan(/.+?(?:[:.;?!] |$)/).map {|phrase| phrase.strip }

  # rejoin phrases that were split on the '.' from a small word
  if phrases.size > 1
    phrases[0..-2].each_with_index do |phrase, index|
      if SMALL_WORDS.include?(phrase.split.last.downcase)
        # phrases[index] = "#{phrases[index]} #{phrases.slice!(index + 1)}"
        phrases[index] << " " + phrases.slice!(index + 1)
      end
    end
  end

  phrases
end
titleize(title) click to toggle source

Capitalizes most words to create a nicer looking title string.

The list of “small words” which are not capped comes from the New York Times Manual of Style, plus 'vs' and 'v'.

"notes on a scandal" # => "Notes on a Scandal"
"the good german"    # => "The Good German"
# File lib/wedge/utilis/titleize.rb, line 19
def titleize(title)
  title = title.dup
  title = title.downcase unless title[/[[:lower:]]/]  # assume all-caps need fixing

  phrases(title).map do |phrase|
    words = phrase.gsub(/_/, ' ').split
    words.map do |word|
      def word.capitalize
        # like String#capitalize, but it starts with the first letter
        self.sub(/[[:alpha:]].*/) {|subword| subword.capitalize}
      end

      case word
      when /[[:alpha:]]\.[[:alpha:]]/  # words with dots in, like "example.com"
        word
      when /[-‑]/  # hyphenated word (regular and non-breaking)
        word.split(/([-‑])/).map do |part|
          SMALL_WORDS.include?(part) ? part : part.capitalize
        end.join
      when /^[[:alpha:]].*[[:upper:]]/ # non-first letter capitalized already
        word
      when /^[[:digit:]]/  # first character is a number
        word
      when words.first, words.last
        word.capitalize
      when *(SMALL_WORDS + SMALL_WORDS.map {|small| small.capitalize })
        word.downcase
      else
        word.capitalize
      end
    end.join(" ")
  end.join(" ")
end