Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 51 additions & 7 deletions lib/titleize.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,25 @@ module Titleize
#
# "notes on a scandal" # => "Notes on a Scandal"
# "the good german" # => "The Good German"
def titleize(title)
#
# Pass additional small words in opts[:small_words]
#
# titleize("coffee w cream", small_words: ['w']) # => "Coffee w Cream"
#
# For strings in ALL CAPS, specify acronyms to be preserved in opts[:acronyms]
#
# titleize("SMITH TO HEAD SEC", acronyms: ['SEC']) # => "Smith to Head SEC"
#
def titleize(title, opts={})
title = title.dup
title.downcase! unless title[/[[:lower:]]/] # assume all-caps need fixing

small_words = SMALL_WORDS + (opts[:small_words] || [])
small_words = small_words + small_words.map { |small| small.capitalize }

acronyms = opts[:acronyms] || []
acronyms = acronyms + acronyms.map { |acronym| acronym.downcase }

phrases(title).map do |phrase|
words = phrase.split
words.map.with_index do |word, index|
Expand All @@ -40,12 +55,14 @@ def word.capitalize
word
when /^[[:digit:]]/ # first character is a number
word
when *(SMALL_WORDS + SMALL_WORDS.map {|small| small.capitalize })
when *small_words
if index == 0 || index == words.size - 1
word.capitalize
else
word.downcase
end
when *acronyms
word.upcase
else
word.capitalize
end
Expand Down Expand Up @@ -87,17 +104,26 @@ class String
#
# "notes on a scandal" # => "Notes on a Scandal"
# "the good german" # => "The Good German"
#
# Pass additional small words in opts[:small_words]
#
# titleize("coffee w cream", small_words: ['w']) # => "Coffee w Cream"
#
# For strings in ALL CAPS, specify acronyms to be preserved in opts[:acronyms]
#
# titleize("SMITH TO HEAD SEC", acronyms: ['SEC']) # => "Smith to Head SEC"
#
def titleize(opts={})
if defined? ActiveSupport::Inflector
ActiveSupport::Inflector.titleize(self, opts)
else
Titleize.titleize(self)
Titleize.titleize(self, opts)
end
end
alias_method :titlecase, :titleize

def titleize!
replace(titleize)
def titleize!(opts={})

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surrounding space missing in default value assignment.

replace(titleize(opts))
end
alias_method :titlecase!, :titleize!
end
Expand All @@ -114,19 +140,37 @@ module ActiveSupport::Inflector
# This replaces the default Rails titleize. Like the default, it uses
# Inflector.underscore and Inflector.humanize to convert
# underscored_names and CamelCaseNames to a more human form. However, you can change
# this behavior by passing :humanize => false or :underscore => false as options.
# this behavior by passing :humanize => false or :underscore => false as options.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [85/80]

# This can be useful when dealing with words like "iPod" and "GPS".
#
# titleize is also aliased as titlecase.
#
# "notes on an active_record" # => "Notes on an Active Record"
# "the GoodGerman" # => "The Good German"
#
# Pass additional small words in opts[:small_words]
#
# titleize("coffee w cream", small_words: ['w']) # => "Coffee w Cream"
#
# For strings in ALL CAPS, acronyms specified in
# ActiveSupport::Inflector.inflections.acronyms will be properly
# capitalized. To override the set of acronyms used, pass in
# opts[:acronyms]
#
# titleize("SMITH TO HEAD SEC", acronyms: ['SEC']) # => "Smith to Head SEC"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [81/80]

#
def titleize(title, opts={})
opts = {:humanize => true, :underscore => true}.merge(opts)
title = ActiveSupport::Inflector.underscore(title) if opts[:underscore]
title = ActiveSupport::Inflector.humanize(title) if opts[:humanize]

Titleize.titleize(title)
# prioritize passed-in acronyms, fall back to those configured
# for ActiveSupport::Inflector
opts[:acronyms] ||= ActiveSupport::Inflector.inflections.acronyms.values

passthru_opts = opts.select { |k, _| [:acronyms, :small_words].include?(k) }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [82/80]


Titleize.titleize(title, passthru_opts)
end
alias_method :titlecase, :titleize
end
Expand Down
38 changes: 33 additions & 5 deletions spec/titleize_spec.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# -*- coding: utf-8 -*-

module ActiveSupport
module Inflector
require 'ostruct'

#stub
def underscore(string) string; end
def humanize(string) string; end
def inflections

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use empty lines between method definitions.

OpenStruct.new(acronyms: [])
end
end
end

Expand Down Expand Up @@ -102,11 +106,29 @@ def humanize(string) string; end
end
end

it "should not capitalize custom small words specified in opts[:small_words]" do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer single-quoted strings when you don't need string interpolation or special symbols.
Line is too long. [84/80]

titleize("first w last", small_words: ['w']).should == "First w Last"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer single-quoted strings when you don't need string interpolation or special symbols.

end

it "should not screw up acronyms" do
titleize("the SEC's decision").should == "The SEC's Decision"
end

it "should not capitalize words with dots" do
context "handling acronyms" do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer single-quoted strings when you don't need string interpolation or special symbols.

context "in a mixed-case string" do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer single-quoted strings when you don't need string interpolation or special symbols.

it "should not screw up acronyms" do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer single-quoted strings when you don't need string interpolation or special symbols.

titleize("the SEC's decision").should == "The SEC's Decision"
end
end

context "in an uppercase string with the acronyms option specified" do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer single-quoted strings when you don't need string interpolation or special symbols.

it 'keeps the acronyms in upper case' do
titleize("SMITH TO HEAD SEC", acronyms: ['SEC']).should == "Smith to Head SEC"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer single-quoted strings when you don't need string interpolation or special symbols.
Line is too long. [88/80]

end
end
end

it "should not capitalize words with dots" do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer single-quoted strings when you don't need string interpolation or special symbols.

titleize("del.icio.us web site").should == "del.icio.us Web Site"
end

Expand All @@ -115,7 +137,7 @@ def humanize(string) string; end
titleize("ends with 'quotation.'").should == "Ends With 'Quotation.'"
end

it "should not capitalize words that have a lowercase first letter" do
it "should not capitalize words that have a lowercase first letter" do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer single-quoted strings when you don't need string interpolation or special symbols.

titleize("iTunes").should == "iTunes"
end

Expand Down Expand Up @@ -263,7 +285,7 @@ def humanize(string) string; end
end

it "should replace Inflector.titleize" do
Titleize.should_receive(:titleize).with(@title)
Titleize.should_receive(:titleize).with(@title, acronyms: [])
ActiveSupport::Inflector.stub!(:underscore).and_return(@title)
ActiveSupport::Inflector.stub!(:humanize).and_return(@title)
ActiveSupport::Inflector.titleize(@title)
Expand Down Expand Up @@ -326,6 +348,12 @@ def humanize(string) string; end
ActiveSupport::Inflector.should_not_receive(:humanize)
"title".titleize(:humanize => false)
end

it "should properly capitalize acronyms configured in Inflector.inflections.acronyms" do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer single-quoted strings when you don't need string interpolation or special symbols.
Line is too long. [92/80]

inflections = double(acronyms: ['SEC'])
ActiveSupport::Inflector.stub!(:inflections).and_return(inflections)
"SMITH TO HEAD SEC".titleize.should == 'Smith to Head SEC'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer single-quoted strings when you don't need string interpolation or special symbols.

end
end

context "when ActiveSupport is not loaded" do
Expand All @@ -338,7 +366,7 @@ def humanize(string) string; end
end

it "should call Titleize#titleize" do
Titleize.should_receive(:titleize).with("title")
Titleize.should_receive(:titleize).with("title", {})

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer single-quoted strings when you don't need string interpolation or special symbols.

"title".titleize
end
end
Expand Down