diff --git a/CompileRanges.hs b/CompileRanges.hs
new file mode 100644
--- /dev/null
+++ b/CompileRanges.hs
@@ -0,0 +1,84 @@
+#!/usr/bin/env runhaskell
+
+
+module CompileRanges where
+
+import Prelude hiding (lines, unlines)
+import Data.List (foldl')
+import Data.Char
+import Data.Maybe
+import Data.Either
+import Control.Applicative hiding (empty)
+import System.IO (stdin, stdout, stderr)
+import Data.ByteString.Lazy.Char8 hiding (count, foldl', reverse)
+
+import Data.ParserCombinators.Attoparsec.Char8
+
+
+
+
+main                         =  compile_ranges stdin stdout
+
+
+compile_ranges i o           =  do
+  ranges                    <-  rights . parse' . lines <$> hGetContents i
+  --sequence_ . (hPut o . display <$>) $ collate ranges
+  hPut o preamble
+  (sequence_ . (hPut o . compile <$>) . collate) ranges
+  hPut o postamble
+ where
+  parse'                     =  (snd . parse range <$>)
+  display ((a,z),w)          =  a `append` pack ".." `append` z `snoc` '\n'
+  compile ((a,z),w)          =  guard `append` eq `append` w `snoc` '\n'
+   where
+    guard                    =  pack "  | i <= " `append` z
+    eq                       =  pack "              =  "
+  preamble                   =  (unlines . fmap pack) [warning, mod, sig, f]
+   where
+    warning                  =  "\n\n--  This file was autogenerated.\n"
+    mod                      =  "\nmodule Data.Char.Cols.Generated where\n\n"
+    sig                      =  "cols                        ::  Char -> Int\n"
+    f                        =  "cols c\n"
+  postamble                  =  otherwise_clause `append` where_clause
+   where
+    otherwise_clause         =  pack "  | otherwise                =  -1\n"
+    where_clause             =  pack " where\n" `append` pack i `snoc` '\n'
+     where
+      i                      =  "  i                          =  fromEnum c\n"
+
+
+
+
+range                        =  do
+  start                     <-  short_hex
+  string ".."
+  end                       <-  short_hex
+  some (char ' ')
+  columns                   <-  little_int
+  return ((start, end), columns)
+
+short_hex                   ::  Parser ByteString
+short_hex                    =  do
+  ox                        <-  match (string "0x")
+  count 4 (char '0')
+  append ox <$> match (count 4 (satisfy isHexDigit))
+
+little_int                  ::  Parser ByteString
+little_int                   =  do
+  sign                      <-  maybe empty id <$> optional minus
+  digits                    <-  match (satisfy isDigit)
+  return (append sign digits)
+ where
+  minus                      =  match (char '-')
+
+
+
+
+collate                      =  reverse . foldl' collate' []
+ where
+  collate' [] range          =  [range]
+  collate' (((a,z),w):t) ((a',z'),w')
+    | w == w'                =  ((a,z'),w) : t
+    | otherwise              =  ((a',z'),w') : ((a,z),w) : t
+
+
diff --git a/wcwidth.cabal b/wcwidth.cabal
--- a/wcwidth.cabal
+++ b/wcwidth.cabal
@@ -1,11 +1,11 @@
 name                          : wcwidth
-version                       : 0.0.0
+version                       : 0.0.1
 category                      : Text
 license                       : BSD3
 license-file                  : LICENSE
 author                        : Jason Dusek
 maintainer                    : wcwidth@solidsnack.be 
-homepage                      : http://github.com/solidsnack/width/
+homepage                      : http://github.com/solidsnack/wcwidth/
 synopsis                      : Native wcwidth.
 description                   :
   Bindings for your system's native wcwidth and a command line tool to examine
@@ -15,6 +15,7 @@
 
 cabal-version                 : >= 1.6.0
 build-type                    : Simple
+extra-source-files            : CompileRanges.hs
 
 
 library
