Permalink
Find file
1072d65 Apr 16, 2011
188 lines (151 sloc) 6.68 KB
{-# LANGUAGE OverloadedStrings, Arrows #-}
module Main where
import Prelude hiding (id)
import Control.Category (id)
import Control.Arrow ((>>>), (>>^), (***), arr)
import Control.Monad (forM_)
import Data.Monoid (mempty, mconcat)
import System.FilePath
import Hakyll
main :: IO ()
main = hakyll $ do
-----------------------------------------------------------------------
-- compile templates
-----------------------------------------------------------------------
match "templates/*" $ compile templateCompiler
-----------------------------------------------------------------------
-- copy resources files & process css as necessary
-----------------------------------------------------------------------
match "resources/css/**" $ do
route $ setRoot `composeRoutes` setExtension "css"
compile sass
-- compile $ byExtension (error "not a valid css file")
-- [ (".css", sass)
-- , (".scss", sass) ]
match (predicate (\i -> matches "resources/**" i && not (matches "resources/css/**" i))) $ do
route setRoot
compile copyFileCompiler
-- create site pages
-----------------------------------------------------------------------
forM_ indexPages $ \p -> match p $ do
route $ setRoot `composeRoutes` toIndex
compile $ unGitHubCompiler
>>> applyTemplateCompiler "templates/page.html"
>>> applyTemplateCompiler "templates/default.html"
forM_ markdownPages $ \p -> match p $ do
route $ setRoot `composeRoutes` cleanURL
compile $ unGitHubCompiler
>>> applyTemplateCompiler "templates/page.html"
>>> applyTemplateCompiler "templates/default.html"
match "p*/**/index.html" $ do
route setRoot
compile defaultCompiler
match "p*/***.html" $ do
route $ setRoot `composeRoutes` cleanURL
compile defaultCompiler
match (predicate (\i -> matches "p*/**" i && not (matches "*.m*d" i))) $ do
route $ setRoot `composeRoutes` idRoute
compile copyFileCompiler
-- special root pages
-----------------------------------------------------------------------
match "index.html" $ route idRoute
create "index.html" $ constA mempty
>>> arr (setField "pagetitle" "Ethan Schoonover")
>>> requireAllA "posts/***.md" (id *** arr newest10 >>> postList)
>>> requireAllA "projects/*/*.md" projectList
>>> applyTemplateCompiler "templates/home.html"
>>> applyTemplateCompiler "templates/default.html"
match "./posts/index.html" $ route idRoute
create "./posts/index.html" $ constA mempty
>>> arr (setField "pagetitle" "Posts - Ethan Schoonover")
>>> requireAllA "posts/***.md" postList
>>> applyTemplateCompiler "templates/posts.html"
>>> applyTemplateCompiler "templates/default.html"
match "./projects/index.html" $ route idRoute
create "./projects/index.html" $ constA mempty
>>> arr (setField "pagetitle" "Projects - Ethan Schoonover")
>>> requireAllA "projects/*/*.md" projectList
>>> applyTemplateCompiler "templates/projects.html"
>>> applyTemplateCompiler "templates/default.html"
-- render rss feed
-----------------------------------------------------------------------
match "atom.xml" $ route idRoute
create "atom.xml" $
requireAll_ "projects/*/*.md" >>> renderAtom feedConfiguration
where
indexPages = [ "p*/**README.*"
, "p*/**index.*" ]
markdownPages = [ "p*/***.md"
, "p*/***.mkd"
, "p*/***.mkdn"
, "p*/***.mdown"
, "p*/***.markdown"
, "p*/***.pandoc"
, "p*/***.pdc"
, "p*/***.lhs" ]
-----------------------------------------------------------------------
-- custom compilers
-----------------------------------------------------------------------
sass :: Compiler Resource String
sass = getResourceString >>> unixFilter "sass" ["-s", "--scss"]
>>> arr compressCss
unGitHub :: Compiler String String
unGitHub = unixFilter "sed" ["s+https://github.com/[^/]*/\\([^:/]*\\)/raw/master+/\\1+g"]
defaultCompiler :: Compiler Resource (Page String)
defaultCompiler = getResourceString
>>> arr readPage
>>> addDefaultFields
>>> arr applySelf
>>> arr buildTitle
>>> pageRenderPandoc
>>> applyTemplateCompiler "templates/default.html"
unGitHubCompiler :: Compiler Resource (Page String)
unGitHubCompiler = getResourceString
>>> unGitHub
>>> arr readPage
>>> addDefaultFields
>>> arr applySelf
>>> arr buildTitle
>>> pageRenderPandoc
-- custom routes
-----------------------------------------------------------------------
setRoot :: Routes
setRoot = customRoute stripTopDir
stripTopDir :: Identifier -> FilePath
stripTopDir = joinPath . tail . splitPath . toFilePath
cleanURL :: Routes
cleanURL = customRoute fileToDirectory
fileToDirectory :: Identifier -> FilePath
fileToDirectory = (flip combine) "index.html" . dropExtension . toFilePath
toIndex :: Routes
toIndex = customRoute fileToIndex
fileToIndex :: Identifier -> FilePath
fileToIndex = (flip combine) "index.html" . dropFileName . toFilePath
-- misc functions
-----------------------------------------------------------------------
newest10 :: [Page a] -> [Page a]
newest10 = take 10 . reverse . sortByBaseName
stripIndexLink :: Page a -> Page a
stripIndexLink = changeField "url" dropFileName
buildTitle :: Page a -> Page a
buildTitle = renderField "title" "pagetitle" (++ " - Ethan Schoonover")
postList :: Compiler (Page String, [Page String]) (Page String)
postList = buildList "postlist" "templates/item.html"
projectList :: Compiler (Page String, [Page String]) (Page String)
projectList = buildList "projectlist" "templates/item.html"
buildList :: String -> Identifier -> Compiler (Page String, [Page String]) (Page String)
buildList field template = setFieldA field $
arr (reverse . sortByBaseName)
>>> arr (map stripIndexLink)
>>> require template (\p t -> map (applyTemplate t) p)
>>> arr mconcat
>>> arr pageBody
-- misc functions
-----------------------------------------------------------------------
feedConfiguration :: FeedConfiguration
feedConfiguration = FeedConfiguration
{ feedTitle = "EthanSchoonover.com"
, feedDescription = "Projects & Posts from Ethan Schoonover"
, feedAuthorName = "Ethan Schoonover"
, feedRoot = "http://ethanschoonover.com"
}