diff --git a/HaTeX-meta.cabal b/HaTeX-meta.cabal
new file mode 100644
--- /dev/null
+++ b/HaTeX-meta.cabal
@@ -0,0 +1,30 @@
+Name: HaTeX-meta
+Version: 1.0.0
+Cabal-Version: >= 1.6
+Build-Type: Simple
+License: BSD3
+License-file: license
+Maintainer: Daniel Díaz {danieldiaz <at> dhelta <dot> net}
+Stability: Experimental
+Homepage: http://dhelta.net/hprojects/HaTeX-meta
+Bug-reports: danieldiaz <at> dhelta <dot> net
+Synopsis: HaTeX monad modules builder.
+Description: This packages belongs to the HaTeX project.
+             It builds the @.Monad@ modules.
+Category: Text
+Author: Daniel Díaz
+Tested-with: GHC == 7.0.3
+Extra-source-files: ReleaseNotes
+                  , ReadMe
+
+Executable metahatex
+  Build-depends: base == 4.*
+               , mtl  == 2.*
+               , haskell-src-exts == 1.11.*
+               , haddock == 2.9.*
+               , ghc  == 7.*
+               , parsec == 3.*
+               , containers == 0.4.*
+               , directory == 1.*
+               , filepath == 1.*
+  Main-is: MetaHaTeX.hs
diff --git a/MetaHaTeX.hs b/MetaHaTeX.hs
new file mode 100644
--- /dev/null
+++ b/MetaHaTeX.hs
@@ -0,0 +1,310 @@
+
+import Prelude hiding (lookup)
+import Language.Haskell.Exts hiding (ModuleName)
+import Documentation.Haddock hiding (Decl)
+import Control.Monad.State
+import Data.Maybe
+import Data.List (find,intercalate)
+import qualified Name as GHC
+import qualified Outputable as GHC
+import qualified Module as GHC
+import Text.Parsec
+import Text.Parsec.String
+import Data.Map hiding (filter)
+import System.FilePath (dropFileName)
+import System.Directory (createDirectoryIfMissing)
+import Data.Char (isAlpha)
+
+-- | Module names are written with 'String's.
+type ModuleName = String
+
+-- | The name of a monad version of one module is the
+--   the name of that module followed by @.Monad@.
+monadMName :: ModuleName -- Original module name
+           -> ModuleName -- New module name
+monadMName mn = mn ++ ".Monad"
+
+-- | The list of modules to be transformed by HaTeX-meta.
+moduleList :: [ModuleName]
+moduleList = [
+   "Text.LaTeX.Base.Commands"
+ , "Text.LaTeX.Packages.AMSFonts"
+ , "Text.LaTeX.Packages.AMSMath"
+ , "Text.LaTeX.Packages.Beamer"
+ , "Text.LaTeX.Packages.Hyperref"
+ , "Text.LaTeX.Packages.Inputenc"
+ , "Text.LaTeX.Packages.Color"
+   ]
+
+-- | Get the 'FilePath' of a 'ModuleName'.
+mNameToFilePath :: ModuleName -> FilePath
+mNameToFilePath = (++ ".hs") . fmap (\c -> if c == '.' then '/' else c)
+
+nameString :: Name -> String
+nameString = prettyPrint
+
+snd3 :: (a,b,c) -> b
+snd3 (_,x,_) = x
+
+unlines2 :: [String] -> String
+unlines2 = intercalate "\n\n"
+
+ghcName :: GHC.Name -> String
+ghcName = GHC.occNameString . GHC.nameOccName
+
+loc0 :: SrcLoc
+loc0 = SrcLoc [] 0 0
+
+symbolParens :: String -> String
+symbolParens [] = []
+symbolParens str@(x:_) =
+ if isAlpha x then str
+              else "(" ++ str ++ ")"
+
+--------------
+
+data FunDoc = FD
+ { funName    :: String
+ , funDoc     :: Maybe (Doc GHC.Name)
+ , funArgsDoc :: FnArgsDoc GHC.Name
+   }
+
+data HSInfo = HSI
+ { hsModuleName :: ModuleName
+ , hsPragma     :: String
+ , hsModuleInfo :: Maybe (Doc GHC.Name)
+ , hsExportList :: String
+ , hsTypeNames  :: [String]
+ , hsFunInfo    :: [(FunDoc,Type)]
+   }
+
+getHSInfo :: ModuleName -> Interface -> IO HSInfo
+getHSInfo mn i = do
+ let fp = mNameToFilePath mn
+ -- Parsing module
+ pr <- parseFile fp
+ (Module _ _ pragmas _ _ imports decls)
+   <- case pr of
+       ParseOk x -> return x
+       ParseFailed loc err -> fail $ show loc ++ ":" ++ err
+ -- Getting export list
+ let exportListParser :: Parser String
+     exportListParser = do
+       manyTill anyChar (try $ string $ "module " ++ mn)
+       str <- manyTill anyChar (try $ string $ "where")
+       return $ "module " ++ monadMName mn ++ str ++ "where"
+     getExportList :: IO String
+     getExportList = do
+       pr <- parseFromFile exportListParser fp
+       case pr of
+         Left err -> fail $ "getExportList: parse error: " ++ show err
+         Right str -> return str
+ expList <- getExportList
+ -- Exported names
+ let exportedNames = fmap (symbolParens . ghcName) $ ifaceExports i
+ -- Getting type names
+ let getTypeName :: Decl -> Maybe String
+     getTypeName (TypeDecl _ n _ _) = Just $ nameString n
+     getTypeName (DataDecl _ _ _ n _ _ _) = Just $ nameString n
+     getTypeName _ = Nothing
+ -- Getting functions info
+ let getFunInfo :: Decl -> [(FunDoc,Type)]
+     getFunInfo (TypeSig _ ns_ t) =
+      let ns = filter (`elem` exportedNames) $ fmap nameString ns_
+          funmap = ifaceDeclMap i
+          strfunmap = mapKeys ghcName funmap
+      in  fmap (\n -> let dinfo = lookup n strfunmap
+                          (fd,fad) = maybe (Nothing,Data.Map.empty) snd3 dinfo
+                      in ( FD n fd fad , t )) ns
+     getFunInfo _ = []
+ -- Final result
+ return $
+  HSI { hsModuleName = mn
+      , hsPragma     = unlines $ fmap prettyPrint pragmas
+      , hsModuleInfo = ifaceDoc i
+      , hsExportList = expList
+      , hsTypeNames  = catMaybes $ fmap getTypeName decls
+      , hsFunInfo    = concat $ fmap getFunInfo decls
+       }
+
+-- Rendering Doc
+
+renderDoc :: Doc GHC.Name -> String
+renderDoc DocEmpty = []
+renderDoc (DocAppend d1 d2) = renderDoc d1 ++ renderDoc d2
+renderDoc (DocString str) = str
+renderDoc (DocParagraph d) = renderDoc d
+renderDoc (DocIdentifier xs) = "'" ++ ghcName (last xs) ++ "'"
+renderDoc (DocModule str) = "\"" ++ str ++ "\""
+renderDoc (DocEmphasis d) = "/" ++ renderDoc d ++ "/"
+renderDoc (DocMonospaced d) = "@" ++ renderDoc d ++ "@"
+renderDoc (DocUnorderedList xs) = unlines2 $ fmap renderDoc xs
+renderDoc (DocOrderedList xs) = unlines2
+                                  $ zipWith (++) (fmap (\n -> show n ++ ". ") [1 .. ])
+                                  $ fmap renderDoc xs
+renderDoc (DocCodeBlock d) = "\n> " ++ renderDoc d ++ "\n"
+renderDoc (DocURL str) = "<" ++ str ++ ">"
+
+docCommenting :: String -> String
+docCommenting str =
+ let lns = length $ lines str
+ in  if lns > 1 then "{-|\n" ++ str ++ "-}"
+                else "-- | " ++ str
+
+docString :: Doc GHC.Name -> String
+docString = docCommenting . renderDoc
+
+-- Type synonyms
+
+typeSynonym :: String -> String
+typeSynonym t = unwords [ "type" , t , "=" , "App." ++ t ]
+
+-- Monadic functions
+
+namesInType :: Type -> [String]
+namesInType (TyForall _ _ t) = namesInType t
+namesInType (TyFun t1 t2) = namesInType t1 ++ namesInType t2
+namesInType (TyTuple _ ts) = concat $ fmap namesInType ts
+namesInType (TyList t) = namesInType t
+namesInType (TyApp t1 t2) = namesInType t1 ++ namesInType t2
+namesInType (TyVar _) = []
+namesInType (TyCon qn) = [prettyPrint qn]
+namesInType (TyParen t) = namesInType t
+
+latexType :: Type -> Type
+latexType (TyForall m c t) = TyForall m c $ latexType t
+latexType (TyFun t1 t2) = latexType t1 `TyFun` latexType t2
+latexType (TyTuple b ts) = TyTuple b $ fmap latexType ts
+latexType (TyList t) = TyList $ latexType t
+latexType (TyApp t1 t2) = TyApp (latexType t1) (latexType t2)
+latexType (TyVar v) = TyVar v
+latexType (TyCon (UnQual (Ident "LaTeX"))) = TyApp (TyCon $ UnQual $ Ident "LaTeXT_")
+                                                   (TyVar $ Ident "m")
+latexType (TyCon qn) = TyCon qn
+latexType (TyParen t) = TyParen $ latexType t
+
+argNumber :: Type -> Int
+argNumber (TyForall _ _ t) = argNumber t
+argNumber (TyFun t1 t2) = argNumber t1 + argNumber t2
+argNumber _ = 1
+
+typeList :: Type -> [Type]
+typeList (TyForall _ _ t) = typeList t
+typeList (TyFun t1 t2) = typeList t1 ++ typeList t2
+typeList t = [t]
+
+doStatement :: Pat -> Type -> Maybe Stmt
+doStatement v@(PVar n) (TyCon (UnQual (Ident "LaTeX"))) = Just $
+  Generator loc0 v $ App (Var $ UnQual $ Ident "extractLaTeX_")
+                   $ Var $ UnQual n
+doStatement v@(PVar n) (TyList (TyCon (UnQual (Ident "LaTeX")))) = Just $
+ Generator loc0 v $ foldl1 App
+       [ Var $ UnQual $ Ident "mapM"
+       , Var $ UnQual $ Ident "extractLaTeX_"
+       , Var $ UnQual n ]
+doStatement v@(PVar n) (TyApp (TyCon (UnQual (Ident "Maybe")))
+                              (TyCon (UnQual (Ident "LaTeX")))) = Just $
+ Generator loc0 v $ foldl1 App
+   [ Var $ UnQual $ Ident "maybe"
+   , App (Var $ UnQual $ Ident "return") (Con $ UnQual $ Ident "Nothing")
+   , InfixApp (RightSection (QVarOp $ UnQual $ Symbol ">>=")
+                            (InfixApp (Var $ UnQual $ Ident "return")
+                                      (QVarOp $ UnQual $ Symbol ".")
+                                      (Con $ UnQual $ Ident "Just") ) )
+              (QVarOp $ UnQual $ Symbol ".")
+              (Var $ UnQual $ Ident "extractLaTeX_")
+   , Var $ UnQual n
+     ]
+doStatement _ _ = Nothing
+
+qualify :: String -> String
+qualify [] = []
+qualify str@(x:_) = if isAlpha x then "App." ++ str
+                                 else "(App." ++ (tail $ init $ str) ++ ")"
+
+monadicFunction :: (FunDoc,Type) -> String
+monadicFunction (fd,t) =
+ let n :: String
+     n = funName fd
+     varsn :: [Name]
+     varsn = fmap (Ident . ('a':) . show) [1 .. argNumber t - 1]
+     vars :: [Pat]
+     vars  = fmap PVar varsn
+     varse :: [Exp]
+     varse = fmap (Var . UnQual) varsn
+     lastStmt = Qualifier $ App (Var $ UnQual $ Ident "textell")
+                          $ foldl App (Var $ UnQual $ Ident [])
+                          $ (Var $ UnQual $ Ident $ qualify n) : varse
+ in
+ if elem "LaTeX" (namesInType t)
+    then unlines [ maybe [] docString $ funDoc fd
+                 , unwords [n , "::" , prettyPrint
+                                        $ TyForall Nothing
+                                                   [ClassA (UnQual $ Ident "Monad")
+                                                     [TyVar $ Ident "m"]]
+                                        $ latexType t]
+                 , prettyPrint
+                   $ FunBind [Match loc0
+                                  (Ident n)
+                                  vars
+                                  Nothing
+                                  (UnGuardedRhs $ Do $ (++[lastStmt]) $ catMaybes
+                                    $ zipWith doStatement vars $ init $ typeList t )
+                                  (BDecls []) ]
+                   ]
+    else unlines [ maybe [] docString $ funDoc fd
+                 , unwords [n , "::" , prettyPrint t]
+                 , unwords [n , "=" , qualify n] ]
+
+-- Import list string
+
+importString :: HSInfo -> String
+importString hsi =
+ let mn = hsModuleName hsi
+ in
+     unlines [
+   "import Text.LaTeX.Base.Writer"
+ , "import Text.LaTeX.Base.Render"
+ , "import Text.LaTeX.Base.Types"
+ , "import qualified " ++ mn ++ " as App"
+ , "import " ++ mn ++ "(" ++ intercalate "," (hsTypeNames hsi) ++ ")"
+   ]
+
+-- HaTeX-meta warning
+
+hatexmetawarn :: ModuleName -> String
+hatexmetawarn mn = unlines $ fmap ("-- "++) $ [
+   ""
+ , "/For contributors: This module was automatically generated by HaTeX-meta./"
+ , "/So, please, don't make any change here directly, because/"
+ , "/this is intended to be generated from/"
+ , "\"" ++ mn ++ "\" /module via HaTeX-meta,/"
+ , "/and therefore, changes must to be done in these places./"
+   ]
+
+-- Building the monad module
+
+buildMonadModule :: HSInfo -> String
+buildMonadModule hsi = unlines [
+   hsPragma hsi
+ , concat [ maybe "-- |\n" docString $ hsModuleInfo hsi
+          , hatexmetawarn $ hsModuleName hsi ]
+ , hsExportList hsi ++ "\n"
+ , importString hsi
+ -- , unlines2 $ fmap typeSynonym $ hsTypeNames hsi
+ , unlines $ fmap monadicFunction $ hsFunInfo hsi
+   ]
+
+-- Main function
+
+main :: IO ()
+main = do
+ is <- createInterfaces [] moduleList
+ mapM_ (\m -> do let fp  = mNameToFilePath m
+                     fp' = mNameToFilePath $ monadMName m
+                     i = fromJust $ find (\x -> (GHC.moduleNameString
+                                                   $ GHC.moduleName
+                                                   $ ifaceMod x) == m) is
+                 createDirectoryIfMissing True $ dropFileName fp'
+                 getHSInfo m i >>= writeFile fp' . buildMonadModule
+                  ) moduleList
diff --git a/ReadMe b/ReadMe
new file mode 100644
--- /dev/null
+++ b/ReadMe
@@ -0,0 +1,5 @@
+HaTeX-meta
+
+If you want to use HaTeX-meta to generate HaTeX .Monad modules:
+1) Compile HaTeX-meta.
+2) Run it in a directory that contains the source of HaTeX, being the Text folder a subdirectory.
diff --git a/ReleaseNotes b/ReleaseNotes
new file mode 100644
--- /dev/null
+++ b/ReleaseNotes
@@ -0,0 +1,6 @@
+HaTeX-meta Release Notes
+-- From version 1.0.0
+
+>>> 1.0.0
+
+* First release of HaTeX-meta.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,3 @@
+import Distribution.Simple
+
+main = defaultMain
diff --git a/license b/license
new file mode 100644
--- /dev/null
+++ b/license
@@ -0,0 +1,30 @@
+Copyright (c)2011, Daniel Díaz
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Daniel Díaz nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
