module Text.Hakyll.File
( toDestination
, toCache
, toURL
, toRoot
, removeSpaces
, makeDirectories
, getRecursiveContents
, havingExtension
, isCacheValid
, directory
) where
import System.Directory
import System.FilePath
import Control.Monad
import Data.List (isPrefixOf)
removeLeadingSeparator :: FilePath -> FilePath
removeLeadingSeparator [] = []
removeLeadingSeparator path
| (head path') `elem` pathSeparators = (tail path')
| otherwise = path'
where
path' = if "$root" `isPrefixOf` path then drop 5 path
else path
toDestination :: FilePath -> FilePath
toDestination path = "_site" </> (removeLeadingSeparator path)
toCache :: FilePath -> FilePath
toCache path = "_cache" </> (removeLeadingSeparator path)
toURL :: FilePath -> FilePath
toURL path = if takeExtension path `elem` [".markdown", ".md", ".tex"]
then flip addExtension ".html" $ dropExtension path
else path
toRoot :: FilePath -> FilePath
toRoot = emptyException . joinPath . map parent . splitPath
. takeDirectory . removeLeadingSeparator
where
parent = const ".."
emptyException [] = "."
emptyException x = x
removeSpaces :: FilePath -> FilePath
removeSpaces = map swap
where
swap ' ' = '-'
swap x = x
makeDirectories :: FilePath -> IO ()
makeDirectories path = createDirectoryIfMissing True dir
where
dir = takeDirectory path
getRecursiveContents :: FilePath -> IO [FilePath]
getRecursiveContents topdir = do
names <- getDirectoryContents topdir
let properNames = filter isProper names
paths <- forM properNames $ \name -> do
let path = topdir </> name
isDirectory <- doesDirectoryExist path
if isDirectory
then getRecursiveContents path
else return [path]
return (concat paths)
where
isProper = not . (== '.') . head
havingExtension :: String -> [FilePath] -> [FilePath]
havingExtension extension = filter ((==) extension . takeExtension)
directory :: (FilePath -> IO ()) -> FilePath -> IO ()
directory action dir = getRecursiveContents dir >>= mapM_ action
isCacheValid :: FilePath -> [FilePath] -> IO Bool
isCacheValid cache depends = doesFileExist cache >>= \exists ->
if not exists then return False
else do dependsModified <- (mapM getModificationTime depends) >>= return . maximum
cacheModified <- getModificationTime cache
return (cacheModified >= dependsModified)