diff --git a/hyakko.cabal b/hyakko.cabal
--- a/hyakko.cabal
+++ b/hyakko.cabal
@@ -1,5 +1,5 @@
 name:             hyakko
-version:          0.4.0
+version:          0.5.0
 cabal-version:    >= 1.6
 build-type:       Simple
 license:          MIT
@@ -8,8 +8,8 @@
 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/
+stability:        beta
+homepage:         http://sourrust.github.io/hyakko/
 category:         Documentation
 tested-with:      GHC == 7.4.2
 synopsis:         Literate-style Documentation Generator
@@ -33,15 +33,15 @@
 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.10,
                   bytestring >= 0.9,
-                  text >= 0.11
+                  text >= 0.11,
+                  highlighting-kate >= 0.5,
+                  blaze-html >= 0.5
   hs-source-dirs: src
   ghc-options:    -O2 -Wall
-  main-is:        Hyakko.hs
+  main-is:        Hyakko.lhs
diff --git a/resources/hyakko.css b/resources/hyakko.css
--- a/resources/hyakko.css
+++ b/resources/hyakko.css
@@ -124,13 +124,12 @@
 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 .co { color: #408080; font-style: italic }  /* Comment */
+body .er { 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 .ot { 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 */
@@ -146,10 +145,10 @@
 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 .kw { 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 .st { color: #219161 }                      /* Literal. */
 body .na { color: #7D9029 }                     /* Name.Attribute */
 body .nb { color: #954121 }                     /* Name.Builtin */
 body .nc { color: #0000FF; font-weight: bold }  /* Name.Class */
@@ -157,19 +156,19 @@
 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 .fu { color: #0000FF }                     /* Name.Function */
 body .nl { color: #A0A000 }                     /* Name.Label */
-body .nn { color: #0000FF; font-weight: bold }  /* Name.Namespace */
+body .dt { 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 .fl { color: #666666 }                     /* Literal.Number.Float */
 body .mh { color: #666666 }                     /* Literal.Number.Hex */
-body .mi { color: #666666 }                     /* Literal.Number.Integer */
+body .dv { 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 .ch { 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 */
diff --git a/src/Hyakko.hs b/src/Hyakko.hs
deleted file mode 100644
--- a/src/Hyakko.hs
+++ /dev/null
@@ -1,358 +0,0 @@
-{-# LANGUAGE OverloadedStrings #-}
--- **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
---
---  or
---
---     cabal update
---     cabal install hyakko
-module Main where
-
-import Text.Markdown
-
-import Data.Map (Map)
-import qualified Data.Map as M
-import Data.ByteString.Lazy.Char8 (ByteString)
-import qualified Data.ByteString.Lazy.Char8 as L
-import Data.Text (Text)
-import qualified Data.Text as T
-import qualified Data.Text.IO as T
-import Data.List (sort, groupBy, genericIndex)
-import Data.Maybe (fromJust)
-import Control.Monad (filterM, (>=>), forM)
-import Text.Pandoc.Templates
-import Text.Regex
-import Text.Regex.PCRE ((=~))
-import System.Directory ( getDirectoryContents
-                        , doesDirectoryExist
-                        , doesFileExist
-                        , createDirectoryIfMissing
-                        )
-import System.Environment (getArgs)
-import System.FilePath ( takeBaseName
-                       , takeExtension
-                       , takeFileName
-                       , (</>)
-                       )
-import System.Process (readProcess)
-import Paths_hyakko (getDataFileName)
-
--- ### Main Documentation Generation Functions
-
-(++.) :: Text -> Text -> Text
-(++.) = T.append
-{-# INLINE (++.) #-}
-
-(++*) :: ByteString -> ByteString -> ByteString
-(++*) = L.append
-{-# INLINE (++*) #-}
-
--- 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 <- T.readFile x
-  let sections = parse (getLanguage x) code
-  if null sections then
-    putStrLn $ "hyakko doesn't support the language extension " ++ takeExtension x
-    else do
-      (output, language) <- highlight x sections
-      let y = mapSections sections output language
-      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 :: [Text] -> ByteString -> [Map String Text]
-inSections xs r = [M.fromList l | l <- clump sections]
-  where
-    -- Bring the lists together into groups of comment and groups of code
-    -- pattern.
-    sections :: [[Text]]
-    sections = ensurePair . map concat
-                          -- Group code into a list
-                          . groupBy' head not
-                          -- Group comments into a list
-                          $ groupBy' id id xs
-
-    -- Clump sectioned off lines into doc and code text.
-    clump :: [[Text]] -> [[(String, Text)]]
-    clump [x] = clump $ ensurePair [x]
-    clump (x:y:ys) = [ ("docsText", replace x)
-                     , ("codeText", T.unlines y)
-                     ] : clump ys
-    clump _ = []
-
-    -- Generalized function used to section off code and comments
-    groupBy' t t1 = groupBy $ \x y ->
-      and $ map (t1 . (=~ r) . T.unpack) [t x, t y]
-
-    -- Replace the beggining comment symbol with nothing
-    replace :: [Text] -> Text
-    replace = T.unlines . map (\x ->
-      let y = T.unpack x
-          mkReg = mkRegex . (=~ r)
-      in T.pack $ subRegex (mkReg y) y "")
-
-    -- Make sure the result is in the right pairing order
-    ensurePair :: [[Text]] -> [[Text]]
-    ensurePair ys | even (length ys) = ys
-                  | otherwise = appendList [[""]]
-      where appendList | toBytes ys =~ r = (ys ++)
-                       | otherwise       = (++ ys)
-
-    toBytes :: [[Text]] -> ByteString
-    toBytes = L.pack . T.unpack . head . head
-
-parse :: Maybe (Map String ByteString) -> Text -> [Map String Text]
-parse Nothing _       = []
-parse (Just src) code = inSections line $ src M.! "comment"
-  where line = filter ((/=) "#!" . T.take 2) $ T.lines code
-
--- 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 Text]
-          -> IO (String, Map String ByteString)
-highlight src section = do
-  let language = fromJust $ getLanguage src
-      options  = ["-l", L.unpack $ language M.! "name", "-f",
-                  "html", "-O", "encoding=utf-8"]
-      input = concatMap (\x ->
-        let codeText = T.unpack $ x M.! "codeText"
-            divider  = L.unpack $ language M.! "dividerText"
-        in codeText ++ divider) section
-
-  output <- readProcess "pygmentize" options input
-
-  return (output, language)
-
--- After `highlight` is called, there are divider inside to show when the
--- hightlighed stop and code begins. `mapSections` is used to take out the
--- dividers and put them into `docsHtml` and `codeHtml` sections.
-mapSections :: [Map String Text]
-            -> String
-            -> Map String ByteString
-            -> [Map String Text]
-mapSections section highlighted language =
-  let output     = subRegex (mkRegex highlightReplace) highlighted ""
-      divider    = mkRegex . L.unpack $ language M.! "dividerHtml"
-      fragments  = splitRegex divider output
-      packFrag   = T.pack . genericIndex fragments
-      docText s  = toHTML . T.unpack $ s M.! "docsText"
-      codeText i = highlightStart ++. packFrag i ++. highlightEnd
-      sectLength = (length section) - 1
-      intoMap x  = let sect = section !! x
-                   in M.insert "docsHtml" (docText sect) $
-                      M.insert "codeHtml" (codeText x) sect
-  in map intoMap [0 .. sectLength]
-
--- Determine whether or not there is a `Jump to` section
-multiTemplate :: Int -> [(String, String)]
-multiTemplate 1 = []
-multiTemplate _ = [("multi", "1")]
-
--- Produces a list of anchor tags to different files in docs
---
---     <a class="source" href="$href-link$">$file-name$</a>
-sourceTemplate :: [FilePath] -> [(String, String)]
-sourceTemplate = map source
-  where source x = ("source", concat
-          [ "<a class=\"source\" href=\""
-          , takeFileName $ destination x
-          , "\">"
-          , takeFileName x
-          , "</a>"
-          ])
-
--- Produces a list of table rows that split up code and documentation
---
---     <tr id="section-$number$">
---       <td class="docs">
---         <div class="pilwrap">
---           <a class="pilcrow" href="#section-$number$">λ</a>
---         </div>
---         $doc-html$
---       </td>
---       <td class="code">
---         $code-html$
---       </td>
---     </tr>
-sectionTemplate :: [Map String Text]
-                -> [Int]
-                -> [(String, String)]
-sectionTemplate section = map sections
-  where sections x =
-          let x'   = x + 1
-              sect = section !! x
-          in ("section", concat
-             [ "<tr id=\"section-"
-             ,  show x'
-             ,  "\"><td class=\"docs\">"
-             , "<div class=\"pilwrap\">"
-             , "<a class=\"pilcrow\" href=\"#section-"
-             , show x'
-             , "\">&#955;</a></div>"
-             , T.unpack $ sect M.! "docsHtml"
-             , "</td><td class=\"code\">"
-             , T.unpack $ sect M.! "codeHtml"
-             , "</td></tr>"
-             ])
-
--- 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 Text] -> IO ()
-generateHTML src section = do
-  let title = takeFileName src
-      dest  = destination src
-  source <- sources
-  html <- hyakkoTemplate $ concat
-    [ [("title", title)]
-    , multiTemplate $ length source
-    , sourceTemplate source
-    , sectionTemplate section [0 .. (length section) - 1]
-    ]
-  putStrLn $ "hyakko: " ++ src ++ " -> " ++ dest
-  T.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 ByteString)
-languages =
-  let hashSymbol = ("symbol", "#")
-      language   = 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])
-          ]
-      -- Does the line begin with a comment?
-      hasComments symbol = "^\\s*" ++* symbol ++*  "\\s?"
-      -- The dividing token we feed into Pygments, to delimit the boundaries
-      -- between sections.
-      tokenDivider symbol = "\n" ++* symbol ++* "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
-      htmlDivider symbol = L.concat [ "\n*<span class=\"c1?\">"
-                                    , symbol
-                                    , "DIVIDER</span>"
-                                    ]
-      intoMap lang = let symbol = lang M.! "symbol"
-                  in M.insert "comment" (hasComments symbol)
-                   . M.insert "dividerText" (tokenDivider symbol)
-                   $ M.insert "dividerHtml" (htmlDivider symbol) lang
-
-  -- Build out the appropriate matchers and delimiters for each language.
-  in M.map intoMap language
-
--- Get the current language we're documenting, based on the extension.
-getLanguage :: FilePath -> Maybe (Map String ByteString)
-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"
-
--- Create the template that we will use to generate the Hyakko HTML page.
-hyakkoTemplate :: [(String, String)] -> IO Text
-hyakkoTemplate var = readDataFile "resources/hyakko.html" >>=
-  return . T.pack . renderTemplate var . T.unpack
-
--- The CSS styles we'd like to apply to the documentation.
-hyakkoStyles :: IO Text
-hyakkoStyles = readDataFile "resources/hyakko.css"
-
--- The start and end of each Pygments highlight block.
-highlightStart, highlightEnd :: Text
-highlightStart   = "<div class=\"highlight\"><pre>"
-highlightEnd     = "</pre></div>"
-
-highlightReplace :: String
-highlightReplace = T.unpack highlightStart ++ "|" ++ T.unpack highlightEnd
-
--- Reads from resource path given in cabal package
-readDataFile :: FilePath -> IO Text
-readDataFile = getDataFileName >=> T.readFile
-
--- For each source file passed in as an argument, generate the
--- documentation.
-sources :: IO [FilePath]
-sources = do
-  args <- getArgs
-  files <- forM args $ \x -> do
-    isDir <- doesDirectoryExist x
-    if isDir then
-      unpackDirectories x
-      else
-        return [x]
-  return . sort $ concat files
-
--- Turns the directory give into a list of files including all of the files
--- in sub-directories.
-unpackDirectories :: FilePath -> IO [FilePath]
-unpackDirectories d = do
-  let reg = "[^(^\\.{1,2}$)]" :: ByteString
-  content <- getDirectoryContents d >>= return . filter (=~ reg)
-  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
-  createDirectoryIfMissing False "docs"
-  T.writeFile "docs/hyakko.css" style
-  generateDocumentation source
diff --git a/src/Hyakko.lhs b/src/Hyakko.lhs
new file mode 100644
--- /dev/null
+++ b/src/Hyakko.lhs
@@ -0,0 +1,368 @@
+**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 [Kate](http://johnmacfarlane.net/highlighting-kate/) 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
+
+or just specify a directory and Hyakko will search for supported files
+inside the directory recursively.
+
+Then it 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
+
+or
+
+    cabal update
+    cabal install hyakko
+
+> {-# LANGUAGE OverloadedStrings #-}
+
+> module Main where
+
+> import Text.Markdown
+
+> import Data.Map (Map)
+> import qualified Data.Map as M
+> import Data.ByteString.Lazy.Char8 (ByteString)
+> import qualified Data.ByteString.Lazy.Char8 as L
+> import Data.Text (Text)
+> import qualified Data.Text as T
+> import qualified Data.Text.IO as T
+> import Data.List (sort)
+> import Data.Maybe (fromJust)
+> import Control.Monad (filterM, (>=>), forM)
+> import qualified Text.Blaze.Html as B
+> import Text.Blaze.Html.Renderer.Utf8 (renderHtml)
+> import qualified Text.Highlighting.Kate as K
+> import Text.Pandoc.Templates
+> import Text.Regex.PCRE ((=~))
+> import System.Directory ( getDirectoryContents
+>                         , doesDirectoryExist
+>                         , doesFileExist
+>                         , createDirectoryIfMissing
+>                         )
+> import System.Environment (getArgs)
+> import System.FilePath ( takeBaseName
+>                        , takeExtension
+>                        , takeFileName
+>                        , (</>)
+>                        )
+> import Paths_hyakko (getDataFileName)
+
+Main Documentation Generation Functions
+---------------------------------------
+
+Infix functions for easier concatenation with Text and ByteString.
+
+> (++.) :: Text -> Text -> Text
+> (++.) = T.append
+> {-# INLINE (++.) #-}
+
+> (++*) :: ByteString -> ByteString -> ByteString
+> (++*) = L.append
+> {-# INLINE (++*) #-}
+
+Simpler type signatuted regex replace function.
+
+> replace :: ByteString -> Text -> Text -> Text
+> replace reg x y =
+>   let str  = T.unpack x
+>       (_, _, rp) = str =~ reg :: (String, String, String)
+>   in y ++. (T.pack rp)
+
+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 <- T.readFile x
+>   let sections = parse (getLanguage x) code
+>   if null sections then
+>     putStrLn $ "hyakko doesn't support the language extension "
+>              ++ takeExtension x
+>     else do
+>       let output = highlight x sections
+>           y      = mapSections sections output
+>       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 :: [Text]
+>            -> ByteString
+>            -> [Map String Text]
+> inSections xs r =
+>   let sections = sectionOff "" "" xs
+>   in map M.fromList sections
+
+>   where sectionOff :: Text -> Text -> [Text] -> [[(String, Text)]]
+>         sectionOff code docs [] = [ ("codeText", code)
+>                                   , ("docsText", docs)
+>                                   ] : []
+>         sectionOff code docs (y:ys) =
+>           if T.unpack y =~ r then
+>             handleDocs
+>             else
+>               sectionOff (code ++. y ++. "\n") docs ys
+>           where handleDocs =
+>                   if T.null code then
+>                     sectionOff code (newdocs docs) ys
+>                   else
+>                     [ ("codeText", code)
+>                     , ("docsText", docs)
+>                     ] : sectionOff "" (newdocs "") ys
+
+>                 newdocs d = d ++. (replace r y "") ++. "\n"
+
+> parse :: Maybe (Map String ByteString) -> Text -> [Map String Text]
+> parse Nothing _       = []
+> parse (Just src) code =
+>   inSections (newlines line (M.lookup "literate" src) True)
+>              (src M.! "comment")
+>   where line :: [Text]
+>         line = filter ((/=) "#!" . T.take 2) $ T.lines code
+
+>         newlines :: [Text] -> Maybe ByteString -> Bool -> [Text]
+>         newlines [] _ _            = []
+>         newlines xs Nothing _      = xs
+>         newlines (x:xs) lit isText =
+>           let s       = src M.! "symbol"
+>               r       = "^" ++* (src M.! "symbol2") ++* "\\s?"
+>               r1      = L.pack "^\\s*$"
+>               (x', y) = if T.unpack x =~ r then
+>                      (replace r x "", False)
+>                      else
+>                        insert (T.unpack x =~ r1) isText
+>                          ((T.pack $ L.unpack s)  ++. " " ++. x)
+>           in x': newlines xs lit y
+
+>           where insert :: Bool -> Bool -> Text -> (Text, Bool)
+>                 insert True True _  = (T.pack . L.unpack
+>                                         $ src M.! "symbol", True)
+>                 insert True False _ = ("", False)
+>                 insert False _ y    = (y, True)
+
+Highlights a single chunk of Haskell code, using **Kate**, and runs the text
+of its corresponding comment through **Markdown**, using the Markdown
+translator in **[Pandoc](http://johnmacfarlane.net/pandoc/)**.
+
+> highlight :: FilePath -> [Map String Text] -> [Text]
+> highlight src section =
+>   let language = fromJust $ getLanguage src
+>       langName = L.unpack $ language M.! "name"
+>       input    = map (\x -> T.unpack $ x M.! "codeText") section
+>       html     = B.toHtml . K.formatHtmlBlock K.defaultFormatOpts
+>                           . K.highlightAs langName
+>       htmlText = T.pack . L.unpack . renderHtml . html
+>   in map htmlText input
+
+`mapSections` is used to insert the html parts of the mapped sections of
+text into the corresponding keys of `docsHtml` and `codeHtml`.
+
+> mapSections :: [Map String Text] -> [Text] -> [Map String Text]
+> mapSections section highlighted =
+>   let docText s  = toHTML . T.unpack $ s M.! "docsText"
+>       codeText i = highlighted !! i
+>       sectLength = (length section) - 1
+>       intoMap x  = let sect = section !! x
+>                    in M.insert "docsHtml" (docText sect) $
+>                       M.insert "codeHtml" (codeText x) sect
+>   in map intoMap [0 .. sectLength]
+
+Determine whether or not there is a `Jump to` section
+
+> multiTemplate :: Int -> [(String, String)]
+> multiTemplate 1 = []
+> multiTemplate _ = [("multi", "1")]
+
+Produces a list of anchor tags to different files in docs
+
+    <a class="source" href="$href-link$">$file-name$</a>
+
+> sourceTemplate :: [FilePath] -> [(String, String)]
+> sourceTemplate = map source
+>   where source x = ("source", concat
+>           [ "<a class=\"source\" href=\""
+>           , takeFileName $ destination x
+>           , "\">"
+>           , takeFileName x
+>           , "</a>"
+>           ])
+
+Produces a list of table rows that split up code and documentation
+
+    <tr id="section-$number$">
+      <td class="docs">
+        <div class="pilwrap">
+          <a class="pilcrow" href="#section-$number$">λ</a>
+        </div>
+        $doc-html$
+      </td>
+      <td class="code">
+        $code-html$
+      </td>
+    </tr>
+
+> sectionTemplate :: [Map String Text]
+>                 -> [Int]
+>                 -> [(String, String)]
+> sectionTemplate section = map sections
+>   where sections x =
+>           let x'   = x + 1
+>               sect = section !! x
+>           in ("section", concat
+>              [ "<tr id=\"section-"
+>              ,  show x'
+>              ,  "\"><td class=\"docs\">"
+>              , "<div class=\"pilwrap\">"
+>              , "<a class=\"pilcrow\" href=\"#section-"
+>              , show x'
+>              , "\">&#955;</a></div>"
+>              , T.unpack $ sect M.! "docsHtml"
+>              , "</td><td class=\"code\">"
+>              , T.unpack $ sect M.! "codeHtml"
+>              , "</td></tr>"
+>              ])
+
+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 Text] -> IO ()
+> generateHTML src section = do
+>   let title = takeFileName src
+>       dest  = destination src
+>   source <- sources
+>   html <- hyakkoTemplate $ concat
+>     [ [("title", title)]
+>     , multiTemplate $ length source
+>     , sourceTemplate source
+>     , sectionTemplate section [0 .. (length section) - 1]
+>     ]
+>   putStrLn $ "hyakko: " ++ src ++ " -> " ++ dest
+>   T.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 ByteString)
+> languages =
+>   let hashSymbol = ("symbol", "#")
+>       language   = M.fromList [
+>           (".hs", M.fromList [
+>             ("name", "haskell"), ("symbol", "--")]),
+>           (".lhs", M.fromList [
+>             ("name", "haskell"), ("symbol", "--"),
+>             ("literate", "True"), ("symbol2", ">")]),
+>           (".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])
+>           ]
+
+Does the line begin with a comment?
+
+>       hasComments symbol = "^\\s*" ++* symbol ++*  "\\s?"
+>       intoMap lang = M.insert "comment"
+>                               (hasComments $ lang M.! "symbol")
+>                               lang
+
+Build out the appropriate matchers and delimiters for each language.
+
+>  in M.map intoMap language
+
+Get the current language we're documenting, based on the extension.
+
+> getLanguage :: FilePath -> Maybe (Map String ByteString)
+> 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"
+
+Create the template that we will use to generate the Hyakko HTML page.
+
+> hyakkoTemplate :: [(String, String)] -> IO Text
+> hyakkoTemplate var = readDataFile "resources/hyakko.html" >>=
+>   return . T.pack . renderTemplate var . T.unpack
+
+The CSS styles we'd like to apply to the documentation.
+
+> hyakkoStyles :: IO Text
+> hyakkoStyles = readDataFile "resources/hyakko.css"
+
+Reads from resource path given in cabal package
+
+> readDataFile :: FilePath -> IO Text
+> readDataFile = getDataFileName >=> T.readFile
+
+For each source file passed in as an argument, generate the documentation.
+
+> sources :: IO [FilePath]
+> sources = do
+>   args <- getArgs
+>   files <- forM args $ \x -> do
+>     isDir <- doesDirectoryExist x
+>     if isDir then
+>       unpackDirectories x
+>       else
+>         return [x]
+>   return . sort $ concat files
+
+Turns the directory give into a list of files including all of the files in
+sub-directories.
+
+> unpackDirectories :: FilePath -> IO [FilePath]
+> unpackDirectories d = do
+>   let reg = "[^(^\\.{1,2}$)]" :: ByteString
+>   content <- getDirectoryContents d >>= return . filter (=~ reg)
+>   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
+>   createDirectoryIfMissing False "docs"
+>   T.writeFile "docs/hyakko.css" style
+>   generateDocumentation source
