packages feed

haskintex 0.1.0.1 → 0.2.0.0

raw patch · 2 files changed

+163/−29 lines, 2 files

Files

Main.hs view
@@ -4,7 +4,7 @@ module Main (main) where  -- System-import System.Process+import System.Process (readProcess) import System.Environment (getArgs) import System.FilePath import System.Directory@@ -19,13 +19,30 @@ import Control.Monad.Trans.Class import Control.Monad.Trans.Reader -- LaTeX-import Text.LaTeX+import Text.LaTeX hiding (version)+import Text.LaTeX.Base.Syntax -- Utils import Control.Applicative import Data.Foldable (foldMap)+-- Paths+import Paths_haskintex+import Data.Version (showVersion)+-- Lists+import Data.List (intersperse)  -- 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:+--+-- * writehaskell environments (WriteHaskell), either marked+--   visible or not.+--+-- * evalhaskell commands and environments (EvalHaskell).+--+-- * Anything else (WriteLaTeX).+-- data Syntax =     WriteLaTeX   Text   | WriteHaskell Bool Text -- False for Hidden, True for Visible@@ -102,16 +119,24 @@  -- PASS 2: Evaluate Haskell expressions from processed Syntax. -evalCode :: String -> Syntax -> Haskintex Text-evalCode modName = go+evalCode :: String -> Bool -> Bool -> Syntax -> Haskintex Text+evalCode modName mFlag lhsFlag = go   where     go (WriteLaTeX t) = return t     go (WriteHaskell b t) =-         return $ if b then render (verbatim t :: LaTeX)-                       else mempty-    go (EvalHaskell b t) =          let f :: Text -> LaTeX-             f = if b then verbatim . layout else verb+             f x | not b = mempty+                 | mFlag = raw x+                 | lhsFlag = TeXEnv "code" [] $ raw x+                 | otherwise = verbatim x+         in return $ render $ f t+    go (EvalHaskell env t) =+         let f :: Text -> LaTeX+             f x | mFlag = raw x -- Manual flag overrides lhs2tex flag behavior+                 | env && lhsFlag = TeXEnv "code" [] $ raw x+                 | lhsFlag = raw $ "|" <> x <> "|"+                 | env = verbatim $ layout x+                 | otherwise = verb x          in (render . f . pack) <$> ghc modName t     go (Sequence xs) = mconcat <$> mapM go xs @@ -138,22 +163,47 @@ -- Configuration  data Conf = Conf-  { keepFlag :: Bool-  , visibleFlag :: Bool-  , verboseFlag :: Bool-  , inputs :: [FilePath]+  { keepFlag     :: Bool+  , visibleFlag  :: Bool+  , verboseFlag  :: Bool+  , manualFlag   :: Bool+  , helpFlag     :: Bool+  , lhs2texFlag  :: Bool+  , stdoutFlag   :: Bool+  , unknownFlags :: [String]+  , inputs       :: [FilePath]     } -isArg :: String -> Bool-isArg [] = False-isArg (x:_) = x == '-'+supportedFlags :: [(String,Conf -> Bool)]+supportedFlags =+  [ ("keep", keepFlag)+  , ("visible", visibleFlag)+  , ("verbose", verboseFlag)+  , ("manual", manualFlag)+  , ("help", helpFlag)+  , ("lhs2tex", lhs2texFlag)+  , ("stdout", stdoutFlag)+    ]  readConf :: [String] -> Conf-readConf xs =-  Conf ("-keep" `elem` xs)-       ("-visible" `elem` xs)-       ("-verbose" `elem` xs)-       (filter (not . isArg) xs)+readConf = go $ Conf False False False False False False False [] []+  where+    go c [] = c+    go c (x:xs) =+       case x of+        -- 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+        -- Otherwise, an input file.+        _ -> go (c {inputs = inputs c ++ [x]}) xs  -- Haskintex @@ -170,18 +220,49 @@ main = (readConf <$> getArgs) >>= runReaderT haskintex  haskintex :: Haskintex ()-haskintex = ask >>= mapM_ haskintexFile . inputs+haskintex = do+  flags <- ask+  if helpFlag flags+     then lift $ putStr help+     else do let xs = inputs flags+             if null xs+                then lift $ putStr noFiles+                else mapM_ haskintexFile xs +commas :: [String] -> String+commas = concat . intersperse ", "++showEnabledFlags :: Haskintex ()+showEnabledFlags = do+  c <- ask+  outputStr $ "Enabled flags: "+           ++ commas (foldr (\(str,f) xs -> if f c then str : xs else xs) [] supportedFlags)+           ++ "."++reportWarnings :: Haskintex ()+reportWarnings = do+  -- Combination of manual and lhs2tex flags.+  manFlag <- manualFlag  <$> ask+  lhsFlag <- lhs2texFlag <$> ask+  when (manFlag && lhsFlag) $+    outputStr "Warning: lhs2tex flag is useless in presence of manual flag."+ haskintexFile :: FilePath -> Haskintex () haskintexFile fp_ = do   -- If the given file does not exist, try adding '.tex'.   b <- lift $ doesFileExist fp_   let fp = if b then fp_ else fp_ ++ ".tex"-  -- Read visible flag. It will be required in the file parsing.-  vFlag <- visibleFlag <$> ask-  outputStr $ "Visible flag: " ++ (if vFlag then "enabled" else "disabled") ++ "."+  -- Report enabled flags+  showEnabledFlags+  -- Warnings+  reportWarnings+  -- Other unknown flags passed.+  uFlags <- unknownFlags <$> ask+  unless (null uFlags) $+    outputStr $ "Unsupported flags: " ++ commas uFlags ++ "."   -- File parsing.   outputStr $ "Reading " ++ fp ++ "..."+  vFlag <- visibleFlag <$> ask   t <- lift $ T.readFile fp   case parseOnly (parseSyntax vFlag) t of     Left err -> outputStr $ "Reading of " ++ fp ++ " failed: " ++ err@@ -194,11 +275,17 @@       lift $ T.writeFile (modName ++ ".hs") $ moduleHeader <> hs       -- Second pass: Evaluate expressions using 'evalCode'.       outputStr $ "Evaluating expressions in " ++ fp ++ "..."-      l <- evalCode modName s-      let fp' = "haskintex_" ++ fp+      mFlag <- manualFlag <$> ask+      lhsFlag <- lhs2texFlag <$> ask+      l <- evalCode modName mFlag lhsFlag s       -- Write final output.-      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       -- If the keep flag is not set, remove the haskell source file.       kFlag <- keepFlag <$> ask       unless kFlag $ do@@ -207,3 +294,49 @@         lift $ removeFile $ modName ++ ".hs"       -- End.       outputStr $ "End of processing of file " ++ fp ++ "."++-- MESSAGES++help :: String+help = unlines [+    "You are using haskintex version " ++ showVersion version ++ "."+  , "http://daniel-diaz.github.io/projects/haskintex"+  , ""+  , "Usage and flags:"+  , "Any argument passed to haskintex that starts with '-' will be considered"+  , "a flag. Otherwise, it will be considered an input file. Every input file"+  , "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."+  , ""+  , "  -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."+  , ""+  , "  -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."+  , ""+  , "  -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."+  , ""+  , "Any unsupported flag will be ignored."+  ]++noFiles :: String+noFiles = "No input file given.\n"
haskintex.cabal view
@@ -1,5 +1,5 @@ name:                haskintex-version:             0.1.0.1+version:             0.2.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@@ -22,6 +22,7 @@  executable haskintex   main-is:             Main.hs+  other-modules:       Paths_haskintex   build-depends:       base >= 4.6 && < 4.7                ,       transformers == 0.3.*                ,       text >= 0.11.2.3 && < 0.12