#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
This is a Python port of John Gruber's TitleCase Perl script:
http://daringfireball.net/projects/titlecase/TitleCase.pl

David Lindquist (http://www.stringify.com/
21 May 2008

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'.

License: http://www.opensource.org/licenses/mit-license.php
"""

import re
from string import punctuation

small_words = 'a an and as at but by en for if in of on or the to v[.]? via vs[.]?'.split()
pattern_dict = {
    'small': '|'.join(small_words),
    # Python does not support POSIX-style character classes,
    # so we have to fake it. These are not as robust as their,
    # POSIX equivalents (e.g. they only match ASCII)
    'punct': punctuation,
    'alpha': 'A-Za-z',
    'lower': 'a-z',
}

inline_dots_re = re.compile(r'[%(alpha)s][.][%(alpha)s]' % pattern_dict)
split_re = re.compile(r'([:.;?!][ ]|(?:[ ]|^)["Ò])')

def _wordrepl(m):
    w = m.group(1)
    # Skip words with inline dots, e.g.
    # "del.icio.us" or "example.com"
    if inline_dots_re.search(w):
        return w
    return w.capitalize()

general_replacements = (
    (re.compile(r"\b([[%(alpha)s][%(lower)s.']*)\b" % pattern_dict),
     _wordrepl
     ),

    # Lowercase our list of small words:
    (re.compile(r'\b(%(small)s)\b' % pattern_dict, re.I),
     lambda m: m.group(1).lower()
     ),

    # If the first word in the title is a small word, then capitalize it:
    (re.compile(r'^([%(punct)s]*)(%(small)s)\b' % pattern_dict, re.I),
     lambda m: m.group(1) + m.group(2).capitalize()
     ),

    # If the last word in the title is a small word, then capitalize it:
    (re.compile(r'\b(%(small)s)([%(punct)s]*)$' % pattern_dict, re.I),
     lambda m: m.group(1).capitalize() + m.group(2)
     ),
)

special_replacements = (
    # "v." and "vs.":
    (re.compile(r' V(s?)\. '),
     lambda m: ' v%s. ' % m.group(1)
     ),

    # 'S (otherwise you get "the SEC'S decision")
    (re.compile(r"(['Õ])S\b"),
     lambda m: m.group(1) + 's'
     ),

    # "AT&T" and "Q&A", which get tripped up by
    # self-contained small words "at" and "a"
    (re.compile(r'\b(AT&T|Q&A)\b', re.I),
     lambda m: m.group(1).upper()
     ),
)

def titlecase(title):
    tokens = []
    for t in split_re.split(title):
        for regex, repl in general_replacements:
            t = regex.sub(repl, t)
        tokens.append(t)
    title = ''.join(tokens)
    for regex, repl in special_replacements:
        title = regex.sub(repl, title)
    return title

if __name__ == '__main__':
    import sys
    for line in sys.stdin:
        sys.stdout.write(titlecase(line))
