public
Description: A Ruby implementation of John Gruber's Title Case
Homepage: http://mucur.name/posts/ruby-title-case
Clone URL: git://github.com/mudge/title_case.git
title_case / title_case.rb
100755 97 lines (75 sloc) 2.859 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#!/usr/bin/env ruby
 
# Ruby Title Case
# A Ruby implementation of John Gruber's Title Case
# http://daringfireball.net/2008/05/title_case
#
# Copyright (c) Paul Mucur (http://mucur.name), 2008.
# Dual-licensed under the BSD (BSD-LICENSE.txt) and GPL (GPL-LICENSE.txt)
# licenses.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
 
module TitleCase
 
  # A regular expression to match small words that should not be
  # titleized.
  SMALL_WORDS_RE = /^(a|an|and|as|at|but|by|en|for|if|in|of|on|or|the|to|v\.?|via|vs\.?)$/
  
  def titleize_if_appropriate
 
    # If a word does not contain a full-stop within itself and it doesn't
    # contain any capital letters apart from its first letter, titleize it.
    if !self[/\w\.\w/] && !self[/^.+[A-Z]/]
      
      # Capitalise the first *word* character (therefore avoiding problems
      # where the first character is some punctuation).
      self[/^\W*\w/] = self[/^\W*\w/].upcase
    end
    self
  end
 
  def title_case
 
    # Keep track when a colon has been used at the end of a word.
    colon_preceding = false
    
    # Split the string by any whitespace and then inspect each word
    # at a time.
    words = split(/\s+/).map do |word|
      title_cased_word = if colon_preceding
        
        # If there was a colon preceding this word then titleize
        # it even if it is a small word.
        colon_preceding = false
        word.titleize_if_appropriate
      elsif word.downcase[SMALL_WORDS_RE]
        
        # If this is a small word, make it lowercase.
        word.downcase
      else
        
        # In all other cases, titleize the word.
        word.titleize_if_appropriate
      end
 
      # If this word ends in a colon, set the flag so that the
      # following word can be titleized.
      colon_preceding = true if word[/:$/]
 
      title_cased_word
    end
 
    # Always capitalise the first and last words.
    words[0] = words[0].titleize_if_appropriate
    words[-1] = words[-1].titleize_if_appropriate
    
    words.join(" ")
  end
end
 
if $0 == __FILE__
  
  # If this file is being executed, read in from the command line
  # and STDIN.
  input = ARGV.first || STDIN.read
  
  if input.empty?
    
    # If no input was given, print simple usage instructions
    puts "usage: ruby title_case.rb [TEXT_TO_TITLE_CASE]"
  else
    
    class String
      include TitleCase
    end
  
    puts input.title_case
  end
end