module Text.Hakyll
( defaultHakyllConfiguration
, hakyll
, hakyllWithConfiguration
, runDefaultHakyll
) where
import Control.Concurrent (forkIO, threadDelay)
import Control.Monad.Reader (runReaderT, liftIO, ask)
import Control.Monad (when)
import Data.Monoid (mempty)
import System.Environment (getArgs, getProgName)
import System.Directory (doesDirectoryExist, removeDirectoryRecursive)
import System.Time (getClockTime)
import Text.Pandoc
import Text.Hamlet (defaultHamletSettings)
import Network.Hakyll.SimpleServer (simpleServer)
import Text.Hakyll.HakyllMonad
import Text.Hakyll.File
defaultPandocParserState :: ParserState
defaultPandocParserState = defaultParserState
{
stateSmart = True
}
defaultPandocWriterOptions :: WriterOptions
defaultPandocWriterOptions = defaultWriterOptions
{
writerLiterateHaskell = True
}
defaultHakyllConfiguration :: String
-> HakyllConfiguration
defaultHakyllConfiguration absoluteUrl' = HakyllConfiguration
{ absoluteUrl = absoluteUrl'
, additionalContext = mempty
, siteDirectory = "_site"
, cacheDirectory = "_cache"
, enableIndexUrl = False
, previewMode = BuildOnRequest
, pandocParserState = defaultPandocParserState
, pandocWriterOptions = defaultPandocWriterOptions
, hamletSettings = defaultHamletSettings
}
hakyll :: String
-> Hakyll ()
-> IO ()
hakyll absolute = hakyllWithConfiguration configuration
where
configuration = defaultHakyllConfiguration absolute
hakyllWithConfiguration :: HakyllConfiguration -> Hakyll () -> IO ()
hakyllWithConfiguration configuration buildFunction = do
args <- getArgs
let f = case args of ["build"] -> buildFunction
["clean"] -> clean
["preview", p] -> preview (read p)
["preview"] -> preview defaultPort
["rebuild"] -> clean >> buildFunction
["server", p] -> server (read p) (return ())
["server"] -> server defaultPort (return ())
_ -> help
runReaderT f configuration
where
preview port = case previewMode configuration of
BuildOnRequest -> server port buildFunction
BuildOnInterval -> do
let pIO = runReaderT (previewThread buildFunction) configuration
_ <- liftIO $ forkIO pIO
server port (return ())
defaultPort = 8000
previewThread :: Hakyll ()
-> Hakyll ()
previewThread buildFunction = run =<< liftIO getClockTime
where
delay = 1000000
run time = do liftIO $ threadDelay delay
contents <- getRecursiveContents "."
valid <- isMoreRecent time contents
when valid buildFunction
run =<< liftIO getClockTime
clean :: Hakyll ()
clean = do askHakyll siteDirectory >>= remove'
askHakyll cacheDirectory >>= remove'
where
remove' dir = liftIO $ do putStrLn $ "Removing " ++ dir ++ "..."
exists <- doesDirectoryExist dir
when exists $ removeDirectoryRecursive dir
help :: Hakyll ()
help = liftIO $ do
name <- getProgName
putStrLn $ "This is a Hakyll site generator program. You should always\n"
++ "run it from the project root directory.\n"
++ "\n"
++ "Usage:\n"
++ name ++ " build Generate the site.\n"
++ name ++ " clean Clean up and remove cache.\n"
++ name ++ " help Show this message.\n"
++ name ++ " preview [port] Run a server and autocompile.\n"
++ name ++ " rebuild Clean up and build again.\n"
++ name ++ " server [port] Run a local test server.\n"
server :: Integer
-> Hakyll ()
-> Hakyll ()
server port preRespond = do
configuration <- ask
root <- askHakyll siteDirectory
let preRespondIO = runReaderT preRespond configuration
liftIO $ simpleServer (fromIntegral port) root preRespondIO
runDefaultHakyll :: Hakyll a -> IO a
runDefaultHakyll f =
runReaderT f $ defaultHakyllConfiguration "http://example.com"