module Cake.Rules where
import Cake.Core
import Cake.Process
import System.Directory
import System.FilePath
import Control.Applicative
import Control.Monad (when)
import Control.Monad.RWS (liftIO)
import qualified Parsek
import Parsek (completeResults, parse, Parser)
import Data.List
import Data.List.Split
extension :: String -> P (String,String)
extension s = do
base <- Parsek.many Parsek.anyChar
Parsek.string s
return (base++s,base)
anyExtension :: [String] -> P (String,String)
anyExtension ss = foldr (<|>) empty (map extension ss)
copy :: FilePath -> FilePath -> Act()
copy from to = produce to $ needing [from] $ do
mkdir $ takeDirectory to
liftIO $ copyFile from to
mkdir :: FilePath -> Act ()
mkdir d = liftIO $ createDirectoryIfMissing True d
touch :: FilePath -> Act ()
touch x = produce x $ do
system ["touch",x]
readFile :: FilePath -> Act String
readFile x = do
need x
liftIO $ Prelude.readFile x
_pdflatex x = system ["pdflatex",x]
_bibtex x = system ["bibtex",x]
pandoc inp typ options = produce out $ do
need inp
cut $ system $ ["pandoc",inp,"-t",typ,"-o",out] ++ options
where out = replaceExtension inp typ
graphviz program inp typ options = produce out $ needing [inp] $ do
system $ [program, "-T"++typ, "-o"++out, inp] ++ options
where out = replaceExtension inp typ
needing :: [FilePath] -> Act () -> Act ()
needing xs act = do
mapM_ need xs
cut act
simple outExt inExt f = extension outExt ==> \(output,base) ->
let input = base ++ inExt
in produce output $ needing [input] $ f output input
tex_markdown_standalone = simple ".tex" ".markdown" $ \o i ->
pandoc i o ["--standalone"]
pdf_tex = simple ".pdf" ".tex" $ \o i ->
system ["latexmk","-pdf",i]
getBibFiles input = distill (Custom ["bibfiles",input]) $ do
ls <- map (drop 14) . filter ("\\bibliography{" `isPrefixOf`) . lines <$> Cake.Rules.readFile input
let bibs = map (++".bib") $ case ls of
[] -> []
(l:_) -> splitOn "," $ reverse . dropWhile (== '}') . reverse $ l
return $ Text bibs
includedTex input = do
ls <- map (drop 7) . filter ("\\input{" `isPrefixOf`) . lines <$> Cake.Rules.readFile input
let inputs = map (++".tex") $ case ls of
[] -> []
(l:_) -> splitOn "," $ reverse . dropWhile (== '}') . reverse $ l
return $ inputs
chaseDeps i = do
is <- includedTex i
mapM_ chaseDeps is
pdflatexBibtex c = do
let input = c ++ ".tex"
aux = c ++ ".aux"
pdf = c ++ ".pdf"
bbl = c ++ ".bbl"
produce pdf $ do
produce' aux $ do
produce bbl $ do
produce' aux $ do
chaseDeps input
cut $ _pdflatex c
Text bibs <- getBibFiles input
mapM_ need bibs
when (not $ null bibs) $
cut $ _bibtex c
cut $ _pdflatex c
cut $ do _pdflatex c
overwrote aux
return ()
pdf_tex_bibtex = extension ".pdf" ==> \(_,c) -> pdflatexBibtex c
pdflatexBiblatex c = do
let input = c ++ ".tex"
aux = c ++ ".aux"
pdf = c ++ ".pdf"
produce pdf $ do
produce aux $ do
chaseDeps input
cut $ _pdflatex c
produce (c ++ ".bbl") $ do
Text bibs <- getBibFiles input
mapM_ need bibs
use aux
when (not $ null bibs) $
cut $ _bibtex c
cut $ do _pdflatex c
overwrote aux
return ()
pdf_tex_biblatex = anyExtension [".pdf",".aux"] ==> \(_,c) ->
pdflatexBibtex c
_lhs2TeX i o = do
system ["lhs2TeX","-o",o,i]
lhs2tex c = do
let lhs = c ++ ".lhs"
tex = c ++ ".tex"
produce tex $ do
need lhs
_lhs2TeX lhs tex
tex_lhs = extension ".tex" ==> \(_,c) -> lhs2tex c
allRules = tex_markdown_standalone
<|> pdf_tex_biblatex
<|> tex_lhs