Gruber-style Title Case in Ruby
Posted by Ben Jackson Wed, 21 May 2008 16:11:00 GMT
module TitleCase
SMALL_WORDS = %w(a an and as at but by en for if in of on or the to v[.]? via vs[.]?)
def self.convert input
# downcase everything first, then capitalize
input.gsub!(/\b(\w)/) { $1.capitalize }
input.gsub!(/(\b)(#{SMALL_WORDS.join("|")})(\b)/i) { "#{$1}#{$2.downcase}#{$3}" }
# If the first/last word in the title is a small word, then capitalize it:
input.sub!(/^(#{SMALL_WORDS.join("|")})\b/i) { $1.capitalize }
input.sub!(/\b(#{SMALL_WORDS.join("|")})$/i) { $1.capitalize }
# "v." and "vs.":
input.gsub!(/ V(s?). /i){ "v#{$1}." }
# 'S (otherwise you get "the SEC'S decision")
input.gsub!(/(['’])S\b/i){"#{$1}s"}
# "AT&T" and "Q&A", which get tripped up by
# self-contained small words "at" and "a"
input.gsub!(/\b(AT&T|Q&A)\b/i){ $1.upcase }
input
end
end
# some brief tests
puts TitleCase.convert("The book is On the table")
puts TitleCase.convert("the book is on the table")
# and the edge cases
puts TitleCase.convert("at&t u-verse marks one-year anniversary of giving los angeles")
puts TitleCase.convert("the SEC'S decision")
Let me know of any bugs in the comments. Enjoy.
