neil-0.0: src/Paper/Util/FileData.hs
module Paper.Util.FileData(
FileData(..), getFileData
) where
import Control.Monad
import Data.List
import System.Directory
import System.FilePath
data FileData = FileData
{directory :: FilePath -- ^ All files must reside in one directory
,mainFile :: FilePath -- ^ The main file
,argFiles :: [FilePath] -- ^ Files given on the command line
,allFiles :: [FilePath] -- ^ All files in the directory
,flags :: [String] -- ^ Any flags given
,darcs :: FilePath -- ^ The location of the _darcs directory
}
deriving Show
getFileData :: [String] -> IO FileData
getFileData args = do
let (opt,files) = partition ("-" `isPrefixOf`) args
files <- if null files then liftM (:[]) getCurrentDirectory else return files
(dirs,explicit,implicit) <- liftM unzip3 $ mapM f files
(explicit,implicit) <- return (concat explicit, concat implicit)
when (length (nub dirs) > 1) $
error "All files must be from the same directory"
let snub = nub . sort
nullErr x | null explicit = error $ "Error: No Latex files found in " ++ show (head dirs)
| otherwise = x
let dir = head dirs
darcs <- getDarcs dir
return $ FileData
dir
(nullErr $ head $ explicit)
(nullErr $ snub $ explicit)
(nullErr $ snub $ explicit ++ implicit)
(map tail opt)
darcs
where
-- return (directory, explicit, implicit)
f file = do
file <- canonicalizePath file
bDir <- doesDirectoryExist file
bFile <- doesFileExist file
if bDir then getDir file
else if bFile then getFile file
else error $ "Error: Could not find file " ++ show file
getDir dir = do
files <- getDirectoryContents dir
files <- return $ filter ((==) ".tex" . takeExtension) files
-- now pick the main file
let mainFile = snd $ maximum [(rank x, x) | x <- files]
dirs = reverse $ splitDirectories dir
rank x = liftM negate $ findIndex (== dropExtension x) dirs
return (dir, [mainFile | not $ null files] ++ files, [])
getFile file = do
(a,b,[]) <- getDir $ takeDirectory file
return (a, [file], b)
getDarcs = f . reverse . map joinPath . tail . inits . splitDirectories
where
f [] = return $ error "Darcs repo not found"
f (x:xs) = do
b <- doesDirectoryExist (x </> "_darcs")
if b then return $ dropTrailingPathSeparator x else f xs