packages feed

neil-0.0: src/Paper/Main.hs

{-# LANGUAGE CPP #-}
module Paper.Main(main) where

import System.Directory
import System.Environment
import System.FilePath

import Paper.Util.FileData
#ifndef SMALL
import Paper.Graph
#endif
import Paper.Make
import Paper.Talk
import Paper.WordCount
import Paper.Haskell
import Paper.Haskell2.All
import Paper.Push
import Paper.Sync
import Paper.Ftp
import Paper.Ref
import Paper.Todo


{-
COMMANDS:
make -- compile the document
wc -- word count
wcmin -- minimal word count
graph -- make a graph
spell -- complete spell check
colin -- auto-colin grammar check
haskell -- auto-haskell checking

CONVENTIONS:
all object files go in obj/ directory
all stored files go in paper/ directory
    the output from chart
    word count logs (used for charting)
    grammar checking logs

all commands that take arguments take either:
    nothing - use the current directory
    a directory name - index.tex is the main file, all other *.tex files are extras
    a list of files - first is the main file, all others are extras (all must be the same directory)
-}

main :: IO ()
main = do
    args <- getArgs
    case args of
        (cmd:files) -> do
            files <- getFileData files
            process cmd files
        _ -> error "No arguments given"


wc :: (FilePath -> IO Int) -> FileData -> IO ()
wc f files = do
    let shw = fixed ("total" : map dropExtension (allFiles files))
    res <- flip mapM (allFiles files) $ \file -> do
        putStr $ shw (dropExtension file) ++ "  "
        count <- f (directory files </> file)
        putStrLn $ int count
        return (file,count)
    putStrLn $ shw "Total" ++ "  " ++ int (sum $ map snd res)
#ifndef SMALL
    root <- settingsDir files
    graphLog (root </> "graph.txt") res
#endif

process :: String -> FileData -> IO ()
process "wc" files = wc wordCountNorm files
process "wcmin" files = wc wordCountMin files

#ifndef SMALL
process "graph" files = do
    root <- settingsDir files
    let res = root </> "graph.png"
    graphCreate (root </> "graph.txt") res (allFiles files)
    putStrLn $ "Written graph, " ++ res
#endif

process "make" files = do
    dat <- dataDir
    obj <- objDir "make" files
    make dat obj (directory files) (mainFile files) (allFiles files)

process "haskell" files = do
    obj <- objDir "haskell" files
    haskell obj files

process "haskell2" files = do
    obj <- objDir "haskell2" files
    haskell2 obj (argFiles files)

process "talk" files = do
    tlk <- objDir "talk" files
    talk tlk (argFiles files) (flags files)

process "push" files = push (darcs files)

process "sync" files = do
    dat <- dataDir
    sync (takeDirectory $ takeDirectory dat)

process "ref" files = ref (argFiles files)

process "todo" files = todo (argFiles files)

process "ftp" files = ftp (darcs files)

process "check" files = do
    mapM_ (`process` files) ["ref","todo"]
    putStrLn "All checks succeeded"

process x files = putStrLn $ "Error: Unknown action, " ++ show x


----- utility stuff

-- the directory where data files (paper.bib/paper.fmt) live
dataDir :: IO FilePath
dataDir = do
    x <- findExecutable "paper"
    case x of
        Nothing -> error "Couldn't find the data directory"
        Just y -> return $ dropFileName y </> "data"

settingsDir :: FileData -> IO FilePath
settingsDir = ensureDir "paper"

objDir :: String -> FileData -> IO String
objDir cmd = ensureDir ("obj" </> cmd)


ensureDir :: FilePath -> FileData -> IO FilePath
ensureDir name files = do
    let s = directory files </> name
    createDirectoryIfMissing True s
    return s


----- mini formatting library

padR, padL :: Int -> String -> String
padL n s = replicate (n - length s) ' ' ++ s
padR n s = s ++ replicate (n - length s) ' '


maxIntWidth = maximum $ map (length . show) [minBound::Int, maxBound]

int :: Int -> String
int = padL maxIntWidth . show


fixed :: [String] -> String -> String
fixed ss = let n = maximum $ map length ss
           in \s -> padR n s