Report abuse


			
#!/usr/bin/env 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'. 
#
#   John Gruber
#   http://daringfireball.net/
#   10 May 2008
#
#   Ruby version: Jeremy Ashkenas
#   http://ashkenas.com/
#   21 May 2008
#
#   License: http://www.opensource.org/licenses/mit-license.php

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

# Function to capitalize the first character.
def capit(word)
  word.sub(/./) { |l| l.upcase }
end

lines = STDIN.readlines

lines.each do |line|
  parts = line.split( /( [:.;?!][ ] | (?:[ ]|^)["“] )/x )
  parts.each do |part|
    part.gsub!(/\b([a-z.'’]+)\b/) do |s|
      s =~ /[a-z]\.[a-z]/i ? s : capit(s)
    end
    
    # Lowercase the small words
    part.gsub!(/\b(#{@small_regex})\b/i) { |w| w.downcase }

    # If the first word is a small word, capitalize it.
    part.gsub!(/^([^\w\s]*)(#{@small_regex})\b/) { $1 + capit($2) }

    # If the last word is a small word, capitalize it.
    part.gsub!(/\b(#{@small_regex})([^\w\s]*)$/) { capit($1) + $2 }
  end
  
  line = parts.join
  
  # Special cases:
  line.gsub!(/ V(s?)\. /, ' v\1. ')               # "v." and "vs."
  line.gsub!(/(['’])S\b/, '\1s')                  # 'S (otherwise you get "the SEC'S decision")
  line.gsub!(/\b(AT&T|Q&A)\b/i) { |w| w.upcase }  # "AT&T" and "Q&A", which get tripped up.
  
  puts line
end