-- | Module containing functions for working with the
-- [illiterate](http://github.com/vmchale/illiterate) preprocessor for literate
-- programs.
module Development.Shake.Literate ( -- * Action
                                    illiterateA
                                  -- * Rules
                                  , literateHaskell
                                  , literateIdris
                                  , literateAlex
                                  , literateHappy
                                  ) where

import           Development.Shake
import           Development.Shake.FilePath

illiterateA :: FilePath -- ^ Literate source file
            -> FilePath -- ^ Generated source
            -> Action ()
illiterateA :: FilePath -> FilePath -> Action ()
illiterateA FilePath
inF FilePath
outF = do
    (Stdout FilePath
o) <- ([FilePath] -> Action (Stdout FilePath)) :-> Action Any
forall args r. (Partial, CmdArguments args) => args
cmd [FilePath
"lit", FilePath
inF]
    IO () -> Action ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Action ()) -> IO () -> Action ()
forall a b. (a -> b) -> a -> b
$ FilePath -> FilePath -> IO ()
writeFile FilePath
outF FilePath
o

literateRules :: String -- ^ File extension
              -> Rules ()
literateRules :: FilePath -> Rules ()
literateRules FilePath
ext = FilePath
pat Partial => FilePath -> (FilePath -> Action ()) -> Rules ()
FilePath -> (FilePath -> Action ()) -> Rules ()
%> FilePath -> Action ()
g
    where pat :: FilePath
pat = FilePath
"//*." FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> (Char
'l' Char -> FilePath -> FilePath
forall a. a -> [a] -> [a]
: FilePath
ext)
          g :: FilePath -> Action ()
g FilePath
out = let new :: FilePath
new = (FilePath, FilePath) -> FilePath
forall a b. (a, b) -> a
fst (FilePath -> (FilePath, FilePath)
splitExtension FilePath
out) FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> (Char
'.' Char -> FilePath -> FilePath
forall a. a -> [a] -> [a]
: FilePath
ext)
            in FilePath -> FilePath -> Action ()
illiterateA FilePath
out FilePath
new

-- | Rules for building @.lhs@ files.
literateHaskell :: Rules ()
literateHaskell :: Rules ()
literateHaskell = FilePath -> Rules ()
literateRules FilePath
"hs"

-- | Rules for building @.lidr@ files.
literateIdris :: Rules ()
literateIdris :: Rules ()
literateIdris = FilePath -> Rules ()
literateRules FilePath
"idr"

-- | Rules for building @.lx@ files
literateAlex :: Rules ()
literateAlex :: Rules ()
literateAlex = FilePath -> Rules ()
literateRules FilePath
"x"

-- | Rules for building @.ly@ files
literateHappy :: Rules ()
literateHappy :: Rules ()
literateHappy = FilePath -> Rules ()
literateRules FilePath
"y"