diff options
Diffstat (limited to 'compiler/site')
-rw-r--r-- | compiler/site/Main.hs | 86 | ||||
-rw-r--r-- | compiler/site/Rules.hs | 54 | ||||
-rw-r--r-- | compiler/site/site.cabal | 16 |
3 files changed, 156 insertions, 0 deletions
diff --git a/compiler/site/Main.hs b/compiler/site/Main.hs new file mode 100644 index 0000000..e7fb92f --- /dev/null +++ b/compiler/site/Main.hs @@ -0,0 +1,86 @@ +module Main + ( main + ) where + +import Control.Applicative ((<**>)) +import System.Exit (exitWith) + +import qualified Options.Applicative as O +import System.FilePath ((</>)) + +import qualified Hakyll.Commands as Cmd +import qualified Hakyll.Core.Configuration as Conf +import qualified Hakyll.Core.Logger as Logger + +import Rules (rules) + +data Command + = Build + | Clean + | Check Cmd.Check + +parseCheck :: O.Parser Cmd.Check +parseCheck = + O.flag + Cmd.InternalLinks + Cmd.All + (O.long "all" <> O.short 'a' <> O.help "Check external links as well") + +parseCommand :: O.Parser Command +parseCommand = + O.subparser $ + O.command "build" (O.info (pure Build) (O.progDesc "Build the site")) <> + O.command "clean" (O.info (pure Clean) (O.progDesc "Clean")) <> + O.command + "check" + (O.info ((Check <$> parseCheck) <**> O.helper) (O.progDesc "Check links")) + +data Options = Options + { verbose :: Bool + , outDir :: FilePath + , srcDir :: FilePath + , cacheDir :: FilePath + , command :: Command + } + +parseOptions :: O.Parser Options +parseOptions = + Options <$> + O.switch (O.long "verbose" <> O.short 'v' <> O.help "Run in verbose mode") <*> + O.strOption + (O.long "output" <> O.short 'o' <> O.metavar "DIR" <> O.showDefault <> + O.value (Conf.destinationDirectory Conf.defaultConfiguration) <> + O.help "Output directory") <*> + O.strOption + (O.long "source" <> O.short 's' <> O.metavar "DIR" <> O.showDefault <> + O.value ("." </> "src") <> + O.help "Source directory") <*> + O.strOption + (O.long "cache" <> O.short 'c' <> O.metavar "DIR" <> O.showDefault <> + O.value (Conf.storeDirectory Conf.defaultConfiguration) <> + O.help "Cache directory") <*> + parseCommand + +main :: IO () +main = do + opts <- + O.execParser + (O.info + (parseOptions <**> O.helper) + (O.fullDesc <> O.header "Static site compiler")) + let conf = + Conf.defaultConfiguration + { Conf.destinationDirectory = outDir opts + , Conf.providerDirectory = srcDir opts + , Conf.storeDirectory = cacheDir opts + , Conf.tmpDirectory = cacheDir opts </> "tmp" + } + log <- + Logger.new + (if verbose opts + then Logger.Debug + else Logger.Message) + case command opts of + Build -> Cmd.build conf log rules >>= exitWith + Clean -> Cmd.clean conf log + Check chk -> Cmd.check conf log chk >>= exitWith diff --git a/compiler/site/Rules.hs b/compiler/site/Rules.hs new file mode 100644 index 0000000..0cbf772 --- /dev/null +++ b/compiler/site/Rules.hs @@ -0,0 +1,54 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Rules + ( rules + ) where + +import Hakyll + +postCtx :: Context String +postCtx = dateField "date" "%B %e, %Y" <> defaultContext + +rules :: Rules () +rules = do + match "images/*" $ do + route idRoute + compile copyFileCompiler + match "css/*" $ do + route idRoute + compile compressCssCompiler + match (fromList ["about.rst", "contact.markdown"]) $ do + route $ setExtension "html" + compile $ + pandocCompiler >>= + loadAndApplyTemplate "templates/default.html" defaultContext >>= + relativizeUrls + match "posts/*" $ do + route $ setExtension "html" + compile $ + pandocCompiler >>= loadAndApplyTemplate "templates/post.html" postCtx >>= + loadAndApplyTemplate "templates/default.html" postCtx >>= + relativizeUrls + create ["archive.html"] $ do + route idRoute + compile $ do + posts <- recentFirst =<< loadAll "posts/*" + let archiveCtx = + listField "posts" postCtx (return posts) <> + constField "title" "Archives" <> + defaultContext + makeItem "" >>= loadAndApplyTemplate "templates/archive.html" archiveCtx >>= + loadAndApplyTemplate "templates/default.html" archiveCtx >>= + relativizeUrls + match "index.html" $ do + route idRoute + compile $ do + posts <- recentFirst =<< loadAll "posts/*" + let indexCtx = + listField "posts" postCtx (return posts) <> + constField "title" "Home" <> + defaultContext + getResourceBody >>= applyAsTemplate indexCtx >>= + loadAndApplyTemplate "templates/default.html" indexCtx >>= + relativizeUrls + match "templates/*" $ compile templateBodyCompiler diff --git a/compiler/site/site.cabal b/compiler/site/site.cabal new file mode 100644 index 0000000..072e8f2 --- /dev/null +++ b/compiler/site/site.cabal @@ -0,0 +1,16 @@ +cabal-version: >=1.10 +name: site +version: 0.1.0.0 +build-type: Simple + +executable site + main-is: Main.hs + other-modules: + Rules + default-language: Haskell2010 + ghc-options: -threaded + build-depends: + base -any, + filepath -any, + hakyll >=4.10, + optparse-applicative -any |