Module: Titleize

Extended by:
Titleize
Included in:
Titleize
Defined in:
lib/titleize.rb,
lib/titleize/version.rb

Overview

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.

Constant Summary collapse

SMALL_WORDS =
%w{a an and as at but by en for if in of on or the to v v. via vs vs.}
VERSION =
"1.4.0"

Instance Method Summary collapse

Instance Method Details

#phrases(title) ⇒ Object

Splits a title into an array based on punctuation.

"simple title"              # => ["simple title"]
"more complicated: titling" # => ["more complicated:", "titling"]

58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/titleize.rb', line 58

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.slice!(index + 1)
      end
    end
  end

  phrases
end

#titleize(title) ⇒ Object

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"

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/titleize.rb', line 20

def titleize(title)
  title = title.dup
  title.downcase! unless title[/[[:lower:]]/]  # assume all-caps need fixing

  phrases(title).map do |phrase|
    words = phrase.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