Title Case

This is a Ruby script adapted from John Gruber’s TitleCase Perl Script:

#!/usr/bin/ruby

#   This filter changes all words to Title Caps, and attempts to be clever
#   about *un*capitalizing small words like a/an/the in the input.
#
#   The list of "small words" which are not capped comes from
#   the New York Times Manual of Style, plus 'vs' and 'v'.
#
#   Ruby version by Frank Schmitt
#   http://frankschmitt.org/
#   21 May 2008
#
#   Adapted from perl version by John Gruber
#   http://daringfireball.net/
#   10 May 2008
#
#   License: http://www.opensource.org/licenses/mit-license.php
#

small_re = %w( a an and as at but by en for if in of on or the to via v[.]? vs[.]? ).join('|');

ARGF.each do |line|
	# split line into phrases
	line = line.split(/( [:.;?!][ ] | (?:[ ]|^)["”] )/x).collect do |s|
		# Uppercase all non-dotted (e.g. del.icio.us) words for now
		s.gsub(/\b([[:alpha:]][[:lower:].'’]*)\b/ex) do |w|
			w.match(/[[:alpha:]] [.] [[:alpha:]] /x) ? w : w.capitalize
		end.

		# Lowercase our list of small words:
		gsub(/\b(#{small_re})\b/i) {|w| w.downcase }.

		# If the first word in the title is a small word, then capitalize it:
		gsub(/\A([[:punct:]]*)(#{small_re})\b/io) { $1 + $2.capitalize}.

		# If the last word in the title is a small word, then capitalize it:
		gsub(/\b(#{small_re})([[:punct:]]*)\Z/io) { $1.capitalize + $2}
	end.join.

	# Special Cases
	gsub(/ V(s?)[.] /, ' v\1. ').               # "v." and "vs.":
	gsub(/(['’])S\b/, '\1s').                   # 'S (otherwise you get "the SEC'S decision")
	gsub(/\b(AT&T|Q&A)\b/i) {|s| s.upcase}      # "AT&T" and "Q&A", which get tripped up by

	puts line;
end

Someone could probably clean this up by going back and re-thinking the problem. The above is just a quick port of Gruber’s script.