diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2011 Jeremy Hull
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
diff --git a/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,3 @@
+#!/usr/bin/env runhaskell
+> import Distribution.Simple
+> main = defaultMain
diff --git a/hyakko.cabal b/hyakko.cabal
new file mode 100644
--- /dev/null
+++ b/hyakko.cabal
@@ -0,0 +1,43 @@
+name:             hyakko
+version:          0.2.0
+cabal-version:    >= 1.6
+build-type:       Simple
+license:          MIT
+license-file:     LICENSE
+copyright:        (c) 2011 Jeremy Hull
+author:           Jeremy Hull <sourdrums@gmail.com>
+maintainer:       Jeremy Hull <sourdrums@gmail.com>
+bug-reports:      https://github.com/sourrust/hyakko/issues
+stability:        alpha
+homepage:         http://sourrust.github.com/hyakko/
+category:         Documentation
+tested-with:      GHC == 7.0.3
+synopsis:         Literate-style Documentation Generator
+description:      Hyakko is a Haskell port of Docco: the original quick-and-dirty,
+                  hundred-line-long, literate-programming-style documentation
+                  generator.
+data-files:
+                  -- HTML template and CSS sytle
+                  resources/hyakko.html
+                  resources/hyakko.css
+
+source-repository head
+  type:           git
+  location:       git://github.com/sourrust/hyakko.git
+
+Flag threaded
+  default:        True
+
+Executable hyakko
+  build-depends:  base >= 4 && < 5,
+                  ghc >= 7,
+                  process >= 1,
+                  filepath >= 1.2,
+                  regex-compat >= 0.9,
+                  regex-pcre >= 0.9,
+                  containers >= 0.4,
+                  directory >= 1,
+                  pandoc >= 1.8.2
+  hs-source-dirs: src
+  ghc-options:    -O2 -Wall
+  main-is:        Hyakko.hs
diff --git a/resources/hyakko.css b/resources/hyakko.css
new file mode 100644
--- /dev/null
+++ b/resources/hyakko.css
@@ -0,0 +1,186 @@
+/*--------------------- Layout and Typography ----------------------------*/
+body {
+  font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif;
+  font-size: 15px;
+  line-height: 22px;
+  color: #252519;
+  margin: 0; padding: 0;
+}
+a {
+  color: #261a3b;
+}
+  a:visited {
+    color: #261a3b;
+  }
+p {
+  margin: 0 0 15px 0;
+}
+h1, h2, h3, h4, h5, h6 {
+  margin: 0px 0 15px 0;
+}
+  h1 {
+    margin-top: 40px;
+  }
+#container {
+  position: relative;
+}
+#background {
+  position: fixed;
+  top: 0; left: 525px; right: 0; bottom: 0;
+  background: #f5f5ff;
+  border-left: 1px solid #e5e5ee;
+  z-index: -1;
+}
+#jump_to, #jump_page {
+  background: white;
+  -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777;
+  -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px;
+  font: 10px Arial;
+  text-transform: uppercase;
+  cursor: pointer;
+  text-align: right;
+}
+#jump_to, #jump_wrapper {
+  position: fixed;
+  right: 0; top: 0;
+  padding: 5px 10px;
+}
+  #jump_wrapper {
+    padding: 0;
+    display: none;
+  }
+    #jump_to:hover #jump_wrapper {
+      display: block;
+    }
+    #jump_page {
+      padding: 5px 0 3px;
+      margin: 0 0 25px 25px;
+    }
+      #jump_page .source {
+        display: block;
+        padding: 5px 10px;
+        text-decoration: none;
+        border-top: 1px solid #eee;
+      }
+        #jump_page .source:hover {
+          background: #f5f5ff;
+        }
+        #jump_page .source:first-child {
+        }
+table td {
+  border: 0;
+  outline: 0;
+}
+  td.docs, th.docs {
+    max-width: 450px;
+    min-width: 450px;
+    min-height: 5px;
+    padding: 10px 25px 1px 50px;
+    overflow-x: hidden;
+    vertical-align: top;
+    text-align: left;
+  }
+    .docs pre {
+      margin: 15px 0 15px;
+      padding-left: 15px;
+    }
+    .docs p tt, .docs p code {
+      background: #f8f8ff;
+      border: 1px solid #dedede;
+      font-size: 12px;
+      padding: 0 0.2em;
+    }
+    .pilwrap {
+      position: relative;
+    }
+      .pilcrow {
+        font: 12px Arial;
+        text-decoration: none;
+        color: #454545;
+        position: absolute;
+        top: 3px; left: -20px;
+        padding: 1px 2px;
+        opacity: 0;
+        -webkit-transition: opacity 0.2s linear;
+      }
+        td.docs:hover .pilcrow {
+          opacity: 1;
+        }
+  td.code, th.code {
+    padding: 14px 15px 16px 25px;
+    width: 100%;
+    vertical-align: top;
+    background: #f5f5ff;
+    border-left: 1px solid #e5e5ee;
+  }
+    pre, tt, code {
+      font-size: 12px; line-height: 18px;
+      font-family: Monaco, Consolas, "Lucida Console", monospace;
+      margin: 0; padding: 0;
+    }
+
+
+/*---------------------- Syntax Highlighting -----------------------------*/
+td.linenos { background-color: #f0f0f0; padding-right: 10px; }
+span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
+body .hll { background-color: #ffffcc }
+body .c { color: #408080; font-style: italic }  /* Comment */
+body .err { border: 1px solid #FF0000 }         /* Error */
+body .k { color: #954121 }                      /* Keyword */
+body .o { color: #666666 }                      /* Operator */
+body .cm { color: #408080; font-style: italic } /* Comment.Multiline */
+body .cp { color: #BC7A00 }                     /* Comment.Preproc */
+body .c1 { color: #408080; font-style: italic } /* Comment.Single */
+body .cs { color: #408080; font-style: italic } /* Comment.Special */
+body .gd { color: #A00000 }                     /* Generic.Deleted */
+body .ge { font-style: italic }                 /* Generic.Emph */
+body .gr { color: #FF0000 }                     /* Generic.Error */
+body .gh { color: #000080; font-weight: bold }  /* Generic.Heading */
+body .gi { color: #00A000 }                     /* Generic.Inserted */
+body .go { color: #808080 }                     /* Generic.Output */
+body .gp { color: #000080; font-weight: bold }  /* Generic.Prompt */
+body .gs { font-weight: bold }                  /* Generic.Strong */
+body .gu { color: #800080; font-weight: bold }  /* Generic.Subheading */
+body .gt { color: #0040D0 }                     /* Generic.Traceback */
+body .kc { color: #954121 }                     /* Keyword.Constant */
+body .kd { color: #954121; font-weight: bold }  /* Keyword.Declaration */
+body .kn { color: #954121; font-weight: bold }  /* Keyword.Namespace */
+body .kp { color: #954121 }                     /* Keyword.Pseudo */
+body .kr { color: #954121; font-weight: bold }  /* Keyword.Reserved */
+body .kt { color: #B00040 }                     /* Keyword.Type */
+body .m { color: #666666 }                      /* Literal.Number */
+body .s { color: #219161 }                      /* Literal.String */
+body .na { color: #7D9029 }                     /* Name.Attribute */
+body .nb { color: #954121 }                     /* Name.Builtin */
+body .nc { color: #0000FF; font-weight: bold }  /* Name.Class */
+body .no { color: #880000 }                     /* Name.Constant */
+body .nd { color: #AA22FF }                     /* Name.Decorator */
+body .ni { color: #999999; font-weight: bold }  /* Name.Entity */
+body .ne { color: #D2413A; font-weight: bold }  /* Name.Exception */
+body .nf { color: #0000FF }                     /* Name.Function */
+body .nl { color: #A0A000 }                     /* Name.Label */
+body .nn { color: #0000FF; font-weight: bold }  /* Name.Namespace */
+body .nt { color: #954121; font-weight: bold }  /* Name.Tag */
+body .nv { color: #19469D }                     /* Name.Variable */
+body .ow { color: #AA22FF; font-weight: bold }  /* Operator.Word */
+body .w { color: #bbbbbb }                      /* Text.Whitespace */
+body .mf { color: #666666 }                     /* Literal.Number.Float */
+body .mh { color: #666666 }                     /* Literal.Number.Hex */
+body .mi { color: #666666 }                     /* Literal.Number.Integer */
+body .mo { color: #666666 }                     /* Literal.Number.Oct */
+body .sb { color: #219161 }                     /* Literal.String.Backtick */
+body .sc { color: #219161 }                     /* Literal.String.Char */
+body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */
+body .s2 { color: #219161 }                     /* Literal.String.Double */
+body .se { color: #BB6622; font-weight: bold }  /* Literal.String.Escape */
+body .sh { color: #219161 }                     /* Literal.String.Heredoc */
+body .si { color: #BB6688; font-weight: bold }  /* Literal.String.Interpol */
+body .sx { color: #954121 }                     /* Literal.String.Other */
+body .sr { color: #BB6688 }                     /* Literal.String.Regex */
+body .s1 { color: #219161 }                     /* Literal.String.Single */
+body .ss { color: #19469D }                     /* Literal.String.Symbol */
+body .bp { color: #954121 }                     /* Name.Builtin.Pseudo */
+body .vc { color: #19469D }                     /* Name.Variable.Class */
+body .vg { color: #19469D }                     /* Name.Variable.Global */
+body .vi { color: #19469D }                     /* Name.Variable.Instance */
+body .il { color: #666666 }                     /* Literal.Number.Integer.Long */
diff --git a/resources/hyakko.html b/resources/hyakko.html
new file mode 100644
--- /dev/null
+++ b/resources/hyakko.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+  <title>$title$</title>
+  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+  <link rel="stylesheet" media="all" href="hyakko.css" />
+</head>
+<body>
+  <div id="container">
+    <div id="background"></div>
+    $if(multi)$
+      <div id="jump_to">
+        Jump To &hellip;
+        <div id="jump_wrapper">
+          <div id="jump_page">
+$for(source)$
+$source$
+$endfor$
+          </div>
+        </div>
+      </div>
+    $endif$
+    <table cellpadding="0" cellspacing="0">
+      <thead>
+        <tr>
+          <th class="docs">
+            <h1>
+              $title$
+            </h1>
+          </th>
+          <th class="code">
+          </th>
+        </tr>
+      </thead>
+      <tbody>
+$for(section)$
+$section$
+$endfor$
+      </tbody>
+    </table>
+  </div>
+</body>
+</html>
diff --git a/src/Hyakko.hs b/src/Hyakko.hs
new file mode 100644
--- /dev/null
+++ b/src/Hyakko.hs
@@ -0,0 +1,245 @@
+-- **Hyakko** is a Haskell port of [docco](http://jashkenas.github.com/docco/):
+-- the original quick-and-dirty, hundred-line-line, literate-programming-style
+-- documentation generator. It produces HTML that displays your comments
+-- alongside your code. Comments are passed through
+-- [Markdown](http://daringfireball.net/projects/markdown/syntax) and code is
+-- passed through [Pygments](http://pygments.org/) syntax highlighting.
+-- This page is the result of running Hyakko against its own source file.
+--
+-- If you install Hyakko, you can run it from the command-line:
+--
+--     hyakko src/*.hs
+--
+-- ...will generate linked HTML documentation for the named source files, saving
+-- it into a `docs` folder.
+-- The [source for Hyakko](https://github.com/sourrust/hyakko) available on GitHub.
+--
+-- To install Hyakko
+--
+--     git clone git://github.com/sourrust/hyakko.git
+--     cd hyakko
+--     cabal install
+module Main where
+
+import Text.Markdown
+
+import Data.Map (Map)
+import qualified Data.Map as M
+import Data.List (sort, groupBy)
+import Data.Maybe (fromJust)
+import Control.Monad (filterM)
+import Text.Pandoc.Templates
+import Text.Regex
+import Text.Regex.PCRE ((=~))
+import System.Directory (getDirectoryContents, doesDirectoryExist, doesFileExist)
+import System.Environment (getArgs)
+import System.FilePath (takeBaseName, takeExtension, takeFileName, (</>))
+import System.Process (system, readProcess)
+import Paths_hyakko (getDataFileName)
+
+-- ### Main Documentation Generation Functions
+
+-- Make type signature more readable with these two `Callback` types.
+type Callback  = IO ()
+type Callback' = [Map String String] -> IO ()
+
+-- Generate the documentation for a source file by reading it in, splitting it
+-- up into comment/code sections, highlighting them for the appropriate language,
+-- and merging them into an HTML template.
+generateDocumentation :: [FilePath] -> IO ()
+generateDocumentation [] = return ()
+generateDocumentation (x:xs) = do
+  code <- readFile x
+  let sections = parse (getLanguage x) code
+  if null sections then
+    putStrLn $ "hyakko doesn't support the language extension " ++ takeExtension x
+    else
+      highlight x sections $ \y -> do
+        generateHTML x y
+        generateDocumentation xs
+
+-- Given a string of source code, parse out each comment and the code that
+-- follows it, and create an individual **section** for it.
+-- Sections take the form:
+--
+--     [
+--       ("docsText", ...),
+--       ("docsHtml", ...),
+--       ("codeText", ...),
+--       ("codeHtml", ...)
+--     ]
+--
+inSections :: [String] -> String -> [Map String String]
+inSections xs r =
+  let mkRegex' = mkRegex . (=~ r)
+      -- Generalized function used to section off code and comments
+      groupBy' t t1 = groupBy $ \x y -> and $ map (t1 . (=~ r)) [t x, t y]
+      -- Replace the beggining comment symbol with nothing
+      replace = unlines . map (\y -> subRegex (mkRegex' y) y "")
+      -- Clump sectioned off lines into doc and code text.
+      clump [] = []
+      clump [x] = clump $ ensurePair [x]
+      clump (x:y:ys) = [("docsText", replace x),("codeText", unlines y)] : clump ys
+      -- Make sure the result is in the right pairing order
+      ensurePair ys = if even $ length ys then ys else
+        if (head . head) ys =~ r then ys ++ [[""]] else [""]:ys
+
+      -- Group comments into a list
+      s1 = groupBy' id id xs
+      -- Group code into a list
+      s2 = groupBy' head not s1
+      -- Bring the lists together into groups of comment and groups of code
+      -- pattern.
+      s3 = ensurePair $ map concat s2
+  in [M.fromList l | l <- clump s3]
+
+parse :: Maybe (Map String String) -> String -> [Map String String]
+parse Nothing _ = []
+parse (Just src) code =
+  let line = filter ((/=) "#!" . take 2) $ lines code
+  in inSections line $ src M.! "comment"
+
+-- Highlights a single chunk of Haskell code, using **Pygments** over stdio,
+-- and runs the text of its corresponding comment through **Markdown**, using the
+-- Markdown translator in **[Pandoc](http://johnmacfarlane.net/pandoc/)**.
+--
+-- We process the entire file in a single call to Pygments by inserting little
+-- marker comments between each section and then splitting the result string
+-- wherever our markers occur.
+highlight :: FilePath -> [Map String String] -> Callback' -> IO ()
+highlight src section cb = do
+  let language = fromJust $ getLanguage src
+      options  = ["-l", language M.! "name", "-f", "html", "-O", "encoding=utf-8"]
+      input = concatMap (\x -> x M.! "codeText"++(language M.! "dividerText")) section
+
+  output <- readProcess "pygmentize" options input
+
+  let output'   = subRegex (mkRegex highlightReplace) output ""
+      fragments = splitRegex (mkRegex $ language M.! "dividerHtml") output'
+
+  cb $ map (\x -> let s = section !! x
+    in M.insert "docsHtml" (toHTML $ s M.! "docsText") $
+       M.insert "codeHtml" (highlightStart ++ (fragments !! x) ++
+         highlightEnd) s) [0..(length section) - 1]
+
+-- Once all of the code is finished highlighting, we can generate the HTML file
+-- and write out the documentation. Pass the completed sections into the template
+-- found in `resources/hyakko.html`
+generateHTML :: FilePath -> [Map String String] -> IO ()
+generateHTML src section = do
+  let title = takeFileName src
+      dest  = destination src
+  source <- sources
+  html <- hyakkoTemplate $ concat [
+    [("title", title)],
+    if length source > 1 then [("multi","1")] else [],
+    map (\x -> ("source", unlines [
+      "<a class='source' href='"++(takeFileName $ destination x)++"'>",
+      "  "++takeFileName x,"</a>"])) source,
+    map (\x -> ("section", unlines [
+      "<tr id='section-"++show (x + 1)++"'>",
+      "  <td class='docs'>",
+      "    <div class='pilwrap'>",
+      "      <a class='pilcrow' href='#section-"++show (x + 1)++"'>&#955;</a>",
+      "    </div>",
+      (section !! x) M.! "docsHtml",
+      "  </td>",
+      "  <td class='code'>",
+      (section !! x) M.! "codeHtml",
+      "  </td>",
+      "</tr>" ])) [0..(length section) - 1]
+    ]
+  putStrLn $ "hyakko: " ++ src ++ " -> " ++ dest
+  writeFile dest html
+
+-- ### Helpers & Setup
+
+-- A list of the languages that Hyakko supports, mapping the file extension to
+-- the name of the Pygments lexer and the symbol that indicates a comment. To
+-- add another language to Hyakko's repertoire, add it here.
+languages :: Map String (Map String String)
+languages =
+  let hashSymbol = ("symbol", "#")
+      l = M.fromList [
+          (".hs", M.fromList [
+            ("name", "haskell"), ("symbol", "--")]),
+          (".coffee", M.fromList [
+            ("name", "coffee-script"), hashSymbol]),
+          (".js", M.fromList [
+            ("name", "javascript"), ("symbol", "//")]),
+          (".py", M.fromList [
+            ("name", "python"), hashSymbol]),
+          (".rb", M.fromList [
+            ("name", "ruby"), hashSymbol])
+          ]
+  -- Build out the appropriate matchers and delimiters for each language.
+  in M.map (\x -> let s = x M.! "symbol"
+    -- Does the line begin with a comment?
+    in M.insert "comment" ("^\\s*"++s++"\\s?") $
+       -- The dividing token we feed into Pygments, to delimit the boundaries
+       -- between sections.
+       M.insert "dividerText" ("\n"++s++"DIVIDER\n") $
+       -- The mirror of `divider_text` that we expect Pygments to return. We can
+       -- split on this to recover the original sections.
+       -- Note: the class is "c" for Python and "c1" for the other languages
+       M.insert "dividerHtml" ("\n*<span class=\"c1?\">"++s++"DIVIDER</span>\n") x) l
+
+-- Get the current language we're documenting, based on the extension.
+getLanguage :: FilePath -> Maybe (Map String String)
+getLanguage src = M.lookup (takeExtension src) languages
+
+-- Compute the destination HTML path for an input source file path. If the source
+-- is `lib/example.hs`, the HTML will be at docs/example.html
+destination :: FilePath -> FilePath
+destination fp = "docs" </> (takeBaseName fp) ++ ".html"
+
+-- Ensure that the destination directory exists.
+ensureDirectory :: Callback -> IO ()
+ensureDirectory cb = system "mkdir -p docs" >> cb
+
+-- Create the template that we will use to generate the Hyakko HTML page.
+hyakkoTemplate :: [(String, String)] -> IO String
+hyakkoTemplate var = readDataFile "resources/hyakko.html" >>=
+  return . renderTemplate var
+
+-- The CSS styles we'd like to apply to the documentation.
+hyakkoStyles :: IO String
+hyakkoStyles = readDataFile "resources/hyakko.css"
+
+-- The start and end of each Pygments highlight block.
+highlightStart, highlightEnd, highlightReplace :: String
+highlightStart   = "<div class=\"highlight\"><pre>"
+highlightEnd     = "</pre></div>"
+highlightReplace = highlightStart ++ "|" ++ highlightEnd
+
+-- Reads from resource path given in cabal package
+readDataFile :: FilePath -> IO String
+readDataFile f = getDataFileName f >>= readFile
+
+-- For each source file passed in as an argument, generate the documentation.
+sources :: IO [FilePath]
+sources = getArgs >>= unpack >>= return . sort . concat
+  where
+    unpack = mapM (\x -> do
+      isDir <- doesDirectoryExist x
+      if isDir then unpackDirectories x else return [x])
+
+-- Turns the directory give into a list of files including all of the files
+-- in sub-directories.
+unpackDirectories :: FilePath -> IO [FilePath]
+unpackDirectories d = do
+  content <- getDirectoryContents d >>= return . filter (=~ "[^\\.{1,2}]")
+  let content' = map (d </>) content
+  files <- filterM doesFileExist content'
+  subdir <- filterM doesDirectoryExist content'
+  subcontent <- mapM unpackDirectories subdir >>= return . concat
+  return (files ++ subcontent)
+
+-- Run the script.
+main :: IO ()
+main = do
+  style <- hyakkoStyles
+  source <- sources
+  ensureDirectory $ do
+    writeFile "docs/hyakko.css" style
+    generateDocumentation source
