Skip to content

Commit 8503b98

Browse files
author
Sean Santry
committed
Adds ability to specify custom small words and acronyms
1 parent 185a433 commit 8503b98

File tree

2 files changed

+54
-12
lines changed

2 files changed

+54
-12
lines changed

lib/titleize.rb

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,16 @@ module Titleize
1717
#
1818
# "notes on a scandal" # => "Notes on a Scandal"
1919
# "the good german" # => "The Good German"
20-
def titleize(title)
20+
def titleize(title, opts={})
2121
title = title.dup
2222
title.downcase! unless title[/[[:lower:]]/] # assume all-caps need fixing
2323

24+
small_words = SMALL_WORDS + (opts[:small_words] || [])
25+
small_words = small_words + small_words.map { |small| small.capitalize }
26+
27+
acronyms = opts[:acronyms] || []
28+
acronyms = acronyms + acronyms.map { |acronym| acronym.downcase }
29+
2430
phrases(title).map do |phrase|
2531
words = phrase.split
2632
words.map.with_index do |word, index|
@@ -40,12 +46,14 @@ def word.capitalize
4046
word
4147
when /^[[:digit:]]/ # first character is a number
4248
word
43-
when *(SMALL_WORDS + SMALL_WORDS.map {|small| small.capitalize })
49+
when *small_words
4450
if index == 0 || index == words.size - 1
4551
word.capitalize
4652
else
4753
word.downcase
4854
end
55+
when *acronyms
56+
word.upcase
4957
else
5058
word.capitalize
5159
end
@@ -91,13 +99,13 @@ def titleize(opts={})
9199
if defined? ActiveSupport::Inflector
92100
ActiveSupport::Inflector.titleize(self, opts)
93101
else
94-
Titleize.titleize(self)
102+
Titleize.titleize(self, opts)
95103
end
96104
end
97105
alias_method :titlecase, :titleize
98106

99-
def titleize!
100-
replace(titleize)
107+
def titleize!(opts={})
108+
replace(titleize(opts))
101109
end
102110
alias_method :titlecase!, :titleize!
103111
end
@@ -114,7 +122,7 @@ module ActiveSupport::Inflector
114122
# This replaces the default Rails titleize. Like the default, it uses
115123
# Inflector.underscore and Inflector.humanize to convert
116124
# underscored_names and CamelCaseNames to a more human form. However, you can change
117-
# this behavior by passing :humanize => false or :underscore => false as options.
125+
# this behavior by passing :humanize => false or :underscore => false as options.
118126
# This can be useful when dealing with words like "iPod" and "GPS".
119127
#
120128
# titleize is also aliased as titlecase.
@@ -126,7 +134,13 @@ def titleize(title, opts={})
126134
title = ActiveSupport::Inflector.underscore(title) if opts[:underscore]
127135
title = ActiveSupport::Inflector.humanize(title) if opts[:humanize]
128136

129-
Titleize.titleize(title)
137+
# prioritize passed-in acronyms, fall back to those configured
138+
# for ActiveSupport::Inflector
139+
opts[:acronyms] ||= ActiveSupport::Inflector.inflections.acronyms
140+
141+
passthru_opts = opts.select { |k, _| [:acronyms, :small_words].include?(k) }
142+
143+
Titleize.titleize(title, passthru_opts)
130144
end
131145
alias_method :titlecase, :titleize
132146
end

spec/titleize_spec.rb

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
# -*- coding: utf-8 -*-
2-
32
module ActiveSupport
43
module Inflector
4+
require 'ostruct'
5+
56
#stub
67
def underscore(string) string; end
78
def humanize(string) string; end
9+
def inflections
10+
OpenStruct.new(acronyms: [])
11+
end
812
end
913
end
1014

@@ -102,11 +106,29 @@ def humanize(string) string; end
102106
end
103107
end
104108

109+
it "should not capitalize custom small words specified in opts[:small_words]" do
110+
titleize("first w last", small_words: ['w']).should == "First w Last"
111+
end
112+
105113
it "should not screw up acronyms" do
106114
titleize("the SEC's decision").should == "The SEC's Decision"
107115
end
108116

109-
it "should not capitalize words with dots" do
117+
context "handling acronyms" do
118+
context "in a mixed-case string" do
119+
it "should not screw up acronyms" do
120+
titleize("the SEC's decision").should == "The SEC's Decision"
121+
end
122+
end
123+
124+
context "in an uppercase string with the acronyms option specified" do
125+
it 'keeps the acronyms in upper case' do
126+
titleize("SMITH TO HEAD SEC", acronyms: ['SEC']).should == "Smith to Head SEC"
127+
end
128+
end
129+
end
130+
131+
it "should not capitalize words with dots" do
110132
titleize("del.icio.us web site").should == "del.icio.us Web Site"
111133
end
112134

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

118-
it "should not capitalize words that have a lowercase first letter" do
140+
it "should not capitalize words that have a lowercase first letter" do
119141
titleize("iTunes").should == "iTunes"
120142
end
121143

@@ -263,7 +285,7 @@ def humanize(string) string; end
263285
end
264286

265287
it "should replace Inflector.titleize" do
266-
Titleize.should_receive(:titleize).with(@title)
288+
Titleize.should_receive(:titleize).with(@title, acronyms: [])
267289
ActiveSupport::Inflector.stub!(:underscore).and_return(@title)
268290
ActiveSupport::Inflector.stub!(:humanize).and_return(@title)
269291
ActiveSupport::Inflector.titleize(@title)
@@ -326,6 +348,12 @@ def humanize(string) string; end
326348
ActiveSupport::Inflector.should_not_receive(:humanize)
327349
"title".titleize(:humanize => false)
328350
end
351+
352+
it "should properly capitalize acronyms configured in Inflector.inflections.acronyms" do
353+
inflections = double(acronyms: ['SEC'])
354+
ActiveSupport::Inflector.stub!(:inflections).and_return(inflections)
355+
"SMITH TO HEAD SEC".titleize.should == 'Smith to Head SEC'
356+
end
329357
end
330358

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

340368
it "should call Titleize#titleize" do
341-
Titleize.should_receive(:titleize).with("title")
369+
Titleize.should_receive(:titleize).with("title", {})
342370
"title".titleize
343371
end
344372
end

0 commit comments

Comments
 (0)