packages feed

haskintex 0.2.0.0 → 0.3.0.0

raw patch · 6 files changed

+195/−83 lines, 6 filesdep +hintdep ~HaTeX

Dependencies added: hint

Dependency ranges changed: HaTeX

Files

Main.hs view
@@ -8,6 +8,7 @@ import System.Environment (getArgs) import System.FilePath import System.Directory+import System.IO (hFlush,stdout) -- Text import Data.Text (pack,unpack) import qualified Data.Text as T@@ -29,16 +30,21 @@ import Data.Version (showVersion) -- Lists import Data.List (intersperse)+-- GHC+import Language.Haskell.Interpreter  -- Syntax  -- | The 'Syntax' datatype describes how haskintex see a LaTeX --   file. When haskintex processes an input file, it parsers---   to this structure. It differentiates three things:+--   to this structure. It differentiates between these parts: -- -- * writehaskell environments (WriteHaskell), either marked --   visible or not. --+-- * Haskell expression of type 'LaTeX' (InsertHaTeX).+--   See the HaTeX package for details about this type.+-- -- * evalhaskell commands and environments (EvalHaskell). -- -- * Anything else (WriteLaTeX).@@ -46,6 +52,7 @@ data Syntax =     WriteLaTeX   Text   | WriteHaskell Bool Text -- False for Hidden, True for Visible+  | InsertHaTeX  Text   | EvalHaskell  Bool Text -- False for Command, True for Environment   | Sequence     [Syntax]     deriving Show -- Show instance for debugging.@@ -53,7 +60,7 @@ -- Parsing  parseSyntax :: Bool -> Parser Syntax-parseSyntax v = fmap Sequence $ many $ choice [ p_writehaskell v, p_evalhaskell, p_writelatex ]+parseSyntax v = fmap Sequence $ many $ choice [ p_writehaskell v, p_inserthatex, p_evalhaskell, p_writelatex ]  p_writehaskell :: Bool -> Parser Syntax p_writehaskell v = do@@ -64,6 +71,12 @@   h <- manyTill anyChar $ string "\\end{writehaskell}"   return $ WriteHaskell b $ pack h +p_inserthatex :: Parser Syntax+p_inserthatex = do+  _ <- string "\\hatex{"+  h <- p_haskell 0+  return $ InsertHaTeX $ pack h+ p_evalhaskell :: Parser Syntax p_evalhaskell = choice [ p_evalhaskellenv, p_evalhaskellcomm ] @@ -89,6 +102,8 @@           else ('}':) <$> p_haskell (n-1)   , do _ <- char '\"'        liftA2 (++) (('\"':) <$> p_string) (p_haskell n)+  , string "'{'" >> return "'{'"+  , string "'}'" >> return "'}'"   , liftA2 (:) anyChar (p_haskell n)     ] @@ -97,7 +112,7 @@     liftA2 (++) (char '\\' >> char '\"' >> return "\\\"") p_string   , liftA2 (:) (char '\"') (return [])   , liftA2 (:) anyChar p_string-    ]  +    ]  p_writelatex :: Parser Syntax p_writelatex = (WriteLaTeX . pack) <$>@@ -105,6 +120,7 @@   where     p_other =       choice [ string "\\begin{writehaskell}" >> return False -- starts p_writehaskell+             , string "\\hatex"               >> return False -- starts p_inserthatex              , string "\\begin{evalhaskell}"  >> return False -- starts p_evalhaskellenv              , string "\\evalhaskell"         >> return False -- starts p_evalhaskellcomm              , return True@@ -119,7 +135,10 @@  -- PASS 2: Evaluate Haskell expressions from processed Syntax. -evalCode :: String -> Bool -> Bool -> Syntax -> Haskintex Text+evalCode :: String -- ^ Auxiliary module name+         -> Bool   -- ^ Is manual flag on?+         -> Bool   -- ^ Is lhs2tex flag on?+         -> Syntax -> Haskintex Text evalCode modName mFlag lhsFlag = go   where     go (WriteLaTeX t) = return t@@ -130,6 +149,21 @@                  | lhsFlag = TeXEnv "code" [] $ raw x                  | otherwise = verbatim x          in return $ render $ f t+    go (InsertHaTeX t) = do+         let e = unpack $ T.strip t+             int = do+               loadModules [modName]+               setTopLevelModules [modName]+               setImports ["Prelude"]+               interpret e (as :: LaTeX)+         outputStr $ "Evaluation (LaTeX): " ++ e+         r <- runInterpreter int+         case r of+           Left err -> do+             outputStr $ "Warning: Error while evaluating the expression.\n"+               ++ errorString err+             return mempty+           Right l -> return $ render l     go (EvalHaskell env t) =          let f :: Text -> LaTeX              f x | mFlag = raw x -- Manual flag overrides lhs2tex flag behavior@@ -160,33 +194,43 @@               in  l : go (r:ts)          else t : go ts +-- Errors++errorString :: InterpreterError -> String+errorString (UnknownError e) = "Unknown error: " ++ e+errorString (WontCompile es) = "Compiler error:\n" ++ init (unlines $ fmap errMsg es)+errorString (NotAllowed e) = "Not allowed:" ++ e+errorString (GhcException e) = "GHC exception: " ++ e+ -- Configuration  data Conf = Conf-  { keepFlag     :: Bool-  , visibleFlag  :: Bool-  , verboseFlag  :: Bool-  , manualFlag   :: Bool-  , helpFlag     :: Bool-  , lhs2texFlag  :: Bool-  , stdoutFlag   :: Bool-  , unknownFlags :: [String]-  , inputs       :: [FilePath]+  { keepFlag      :: Bool+  , visibleFlag   :: Bool+  , verboseFlag   :: Bool+  , manualFlag    :: Bool+  , helpFlag      :: Bool+  , lhs2texFlag   :: Bool+  , stdoutFlag    :: Bool+  , overwriteFlag :: Bool+  , unknownFlags  :: [String]+  , inputs        :: [FilePath]     }  supportedFlags :: [(String,Conf -> Bool)] supportedFlags =-  [ ("keep", keepFlag)-  , ("visible", visibleFlag)-  , ("verbose", verboseFlag)-  , ("manual", manualFlag)-  , ("help", helpFlag)-  , ("lhs2tex", lhs2texFlag)-  , ("stdout", stdoutFlag)+  [ ("keep"      , keepFlag)+  , ("visible"   , visibleFlag)+  , ("verbose"   , verboseFlag)+  , ("manual"    , manualFlag)+  , ("help"      , helpFlag)+  , ("lhs2tex"   , lhs2texFlag)+  , ("stdout"    , stdoutFlag)+  , ("overwrite" , overwriteFlag)     ]  readConf :: [String] -> Conf-readConf = go $ Conf False False False False False False False [] []+readConf = go $ Conf False False False False False False False False [] []   where     go c [] = c     go c (x:xs) =@@ -194,14 +238,15 @@         -- Arguments starting with '-' are considered a flag.         ('-':flag) ->            case flag of-             "keep"    -> go (c {keepFlag    = True}) xs-             "visible" -> go (c {visibleFlag = True}) xs-             "verbose" -> go (c {verboseFlag = True}) xs-             "manual"  -> go (c {manualFlag  = True}) xs-             "help"    -> go (c {helpFlag    = True}) xs-             "lhs2tex" -> go (c {lhs2texFlag = True}) xs-             "stdout"  -> go (c {stdoutFlag  = True}) xs-             _         -> go (c {unknownFlags = unknownFlags c ++ [flag]}) xs+             "keep"      -> go (c {keepFlag      = True}) xs+             "visible"   -> go (c {visibleFlag   = True}) xs+             "verbose"   -> go (c {verboseFlag   = True}) xs+             "manual"    -> go (c {manualFlag    = True}) xs+             "help"      -> go (c {helpFlag      = True}) xs+             "lhs2tex"   -> go (c {lhs2texFlag   = True}) xs+             "stdout"    -> go (c {stdoutFlag    = True}) xs+             "overwrite" -> go (c {overwriteFlag = True}) xs+             _           -> go (c {unknownFlags = unknownFlags c ++ [flag]}) xs         -- Otherwise, an input file.         _ -> go (c {inputs = inputs c ++ [x]}) xs @@ -222,12 +267,14 @@ haskintex :: Haskintex () haskintex = do   flags <- ask-  if helpFlag flags+  if -- If the help flag is passed, ignore everything else+     -- and just print the help.+     helpFlag flags      then lift $ putStr help-     else do let xs = inputs flags-             if null xs-                then lift $ putStr noFiles-                else mapM_ haskintexFile xs+     else let xs = inputs flags+          in  if null xs+                 then lift $ putStr noFiles+                 else mapM_ haskintexFile xs  commas :: [String] -> String commas = concat . intersperse ", "@@ -249,9 +296,9 @@  haskintexFile :: FilePath -> Haskintex () haskintexFile fp_ = do-  -- If the given file does not exist, try adding '.tex'.+  -- If the given file does not exist, try adding '.htex'.   b <- lift $ doesFileExist fp_-  let fp = if b then fp_ else fp_ ++ ".tex"+  let fp = if b then fp_ else fp_ ++ ".htex"   -- Report enabled flags   showEnabledFlags   -- Warnings@@ -279,13 +326,25 @@       lhsFlag <- lhs2texFlag <$> ask       l <- evalCode modName mFlag lhsFlag s       -- Write final output.+      let fp' = dropExtension (takeFileName fp) ++ ".tex"+          writeit = do outputStr $ "Writing final file at " ++ fp' ++ "..."+                       lift $ T.writeFile fp' l       outFlag <- stdoutFlag <$> ask-      if outFlag-         then do outputStr "Sending final output to stdout..."-                 lift $ T.putStr l-         else do let fp' = "haskintex_" ++ fp-                 outputStr $ "Writing final file at " ++ fp' ++ "..."-                 lift $ T.writeFile fp' l+      overFlag <- overwriteFlag <$> ask+      nonew <- lift $ doesFileExist fp'+      let finalOutput+           | outFlag = do outputStr "Sending final output to stdout..."+                          lift $ T.putStr l+           | overFlag = writeit+           | nonew = do lift $ putStr $ "File " ++ fp' ++ " already exists. Overwrite?"+                                     ++ " (use -overwrite to overwrite by default) "+                        lift $ hFlush stdout -- To immediately show the text on Windows systems.+                        resp <- lift getLine+                        if resp `elem` ["","y","yes"]+                           then writeit+                           else outputStr "No file was written."+           | otherwise = writeit+      finalOutput       -- If the keep flag is not set, remove the haskell source file.       kFlag <- keepFlag <$> ask       unless kFlag $ do@@ -308,32 +367,35 @@   , "will be processed with the same set of flags, which will include all the"   , "flags passed in the call. This is the list of flags supported by haskintex:"   , ""-  , "  -keep     haskintex creates an intermmediate Haskell file before"-  , "            evaluating any expressions. By default, this file is "-  , "            eliminated after processing the file. Pass this flag to"-  , "            keep the file."+  , "  -keep       haskintex creates an intermmediate Haskell file before"+  , "              evaluating any expressions. By default, this file is "+  , "              eliminated after processing the file. Pass this flag to"+  , "              keep the file."   , ""-  , "  -visible  By default, code written inside a writehaskell environment"-  , "            is not shown in the LaTeX output. This flag changes the"-  , "            default."+  , "  -visible    By default, code written inside a writehaskell environment"+  , "              is not shown in the LaTeX output. This flag changes the"+  , "              default."   , ""-  , "  -verbose  If this flag is enabled, haskintex will print information"-  , "            about its own execution while running."+  , "  -verbose    If this flag is enabled, haskintex will print information"+  , "              about its own execution while running."   , ""-  , "  -manual   By default, Haskell expressions, either from writehaskell "-  , "            or evalhaskell, appear in the LaTeX output inside verb or"-  , "            verbatim declarations. If this flag is passed, neither verb"-  , "            nor verbatim will be used. The code will be written as text "-  , "            as it is. The user will decide how to handle it."+  , "  -manual     By default, Haskell expressions, either from writehaskell "+  , "              or evalhaskell, appear in the LaTeX output inside verb or"+  , "              verbatim declarations. If this flag is passed, neither verb"+  , "              nor verbatim will be used. The code will be written as text "+  , "              as it is. The user will decide how to handle it."   , ""-  , "  -help     This flags cancels any other flag or input file and makes"-  , "            the program simply show this help message."+  , "  -help       This flags cancels any other flag or input file and makes"+  , "              the program simply show this help message."   , ""-  , "  -stdout   Instead of writing the output to a file, send it to the"-  , "            standard output stream (stdout)."+  , "  -stdout     Instead of writing the output to a file, send it to the"+  , "              standard output stream (stdout)."   , ""-  , "  -lhs2tex  Instead of using verb or verbatim declarations, format the"-  , "            output using the syntax accepted by lhs2TeX."+  , "  -lhs2tex    Instead of using verb or verbatim declarations, format the"+  , "              output using the syntax accepted by lhs2TeX."+  , ""+  , "  -overwrite  Overwrite the output file if it already exists. If this flag"+  , "              is not set, the program will ask before overwriting."   , ""   , "Any unsupported flag will be ignored."   ]
+ examples/fact.htex view
@@ -0,0 +1,14 @@+\documentclass{article}+\begin{document}++Recursive definition of the factorial function in Haskell.++\begin{writehaskell}[visible]+fact :: Int -> Int+fact 0 = 1+fact n = n * fact (n-1)+\end{writehaskell}++The factorial function grows really fast. While 5 factorial is+\evalhaskell{fact 5}, 10 factorial is \evalhaskell{fact 10}.+\end{document}
− examples/fact.tex
@@ -1,14 +0,0 @@-\documentclass{article}-\begin{document}--Recursive definition of the factorial function in Haskell.--\begin{writehaskell}[visible]-fact :: Int -> Int-fact 0 = 1-fact n = n * fact (n-1)-\end{writehaskell}--The factorial function grows really fast. While 5 factorial is-\evalhaskell{fact 5}, 10 factorial is \evalhaskell{fact 10}.-\end{document}
+ examples/hatex.htex view
@@ -0,0 +1,24 @@+\documentclass{article}+\usepackage{tikz}+\usepackage[utf8]{inputenc}+\author{Daniel Díaz}+\title{Embedding HaTeX in \emph{haskintex}}+\begin{document}+\maketitle+Below is the \emph{Spira Mirabilis} inserted using the HaTeX+package.+\begin{writehaskell}+import Text.LaTeX+import Text.LaTeX.Packages.TikZ.Simple++spiral :: Figure+spiral = LineWidth (Pt 2) $+    pathImage 0.01 (0,4) $+      \t -> ( a * exp t * cos (b*t)+            , a * exp t * sin (b*t)+              )+  where+    a = 0.1 ; b = 4+\end{writehaskell}+\hatex{center $ tikzpicture $ figuretikz spiral}+\end{document}
+ examples/sine.htex view
@@ -0,0 +1,22 @@+\documentclass{article}+\author{Mr. Trigonometric}+\title{The sine function}+\usepackage{tikz}+\begin{document}+\maketitle+\begin{writehaskell}+import Text.LaTeX+import Text.LaTeX.Packages.TikZ.Simple++graphLength :: Double+graphLength = 3*pi++sineGraph :: Figure+sineGraph = Figures [+    Colored (BasicColor Red) $ Line [ (-1,0) , (graphLength,0) ]+  , Colored (BasicColor Red) $ Line [ (0,-1) , (0,1) ]+  , LineWidth (Pt 2) $ pathImage 0.01 (0,graphLength) $ \x -> (x,sin x)+    ]+\end{writehaskell}+\hatex{tikzpicture $ figuretikz sineGraph}+\end{document}
haskintex.cabal view
@@ -1,12 +1,13 @@ name:                haskintex-version:             0.2.0.0+version:             0.3.0.0 synopsis:            Haskell Evaluation inside of LaTeX code. description:-  The /haskintex/ program is a tool that reads a LaTeX file and evaluates Haskell expressions contained+  The /haskintex/ (Haskell in LaTeX) program is a tool that reads a LaTeX file and evaluates Haskell expressions contained   in some specific commands and environments. It allows you to define your own functions, use any GHC Haskell language-  extension and, in brief, anything you can do within Haskell. You can freely add any Haskell code you need, and make-  this code appear /optionally/ in the LaTeX output. It is a tiny program, and therefore, easy to understand, use and-  predict.+  extension and, in brief, anything you can do within Haskell.+  Additionally, it is possible to include expressions of 'LaTeX' type (see /HaTeX/ package) and render them as LaTeX code.+  You can freely add any Haskell code you need, and make this code appear /optionally/ in the LaTeX output. It is a tiny program,+  and therefore, easy to understand, use and predict. homepage:            http://daniel-diaz.github.io/projects/haskintex bug-reports:         https://github.com/Daniel-Diaz/haskintex/issues license:             BSD3@@ -17,7 +18,9 @@ build-type:          Simple extra-source-files:  README.md                      -- examples-                     examples/fact.tex+                     examples/fact.htex+                     examples/hatex.htex+                     examples/sine.htex cabal-version:       >=1.10  executable haskintex@@ -29,7 +32,8 @@                ,       directory >= 1.2.0.0 && < 1.3                ,       filepath >= 1.1.0.0 && < 1.4                ,       process >= 1.1.0.2 && < 1.2-               ,       HaTeX >= 3.6 && < 3.9+               ,       HaTeX >= 3.9 && < 3.10                ,       attoparsec >= 0.10.2.0 && < 0.11+               ,       hint   default-language:    Haskell2010   ghc-options: -Wall