haskintex 0.1.0.1 → 0.2.0.0
raw patch · 2 files changed
+163/−29 lines, 2 files
Files
- Main.hs +161/−28
- haskintex.cabal +2/−1
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