module Build where import Data.Aeson import qualified Data.Text as T import Data.Time import GHC.Exts ( fromList ) import System.FilePath import Text.Pandoc import Post ( renderPost , RawPost , RichPost ) import Utils ( escapeHTML , lookupMeta' , sortByDate ) parseDay :: String -> Day parseDay = parseTimeOrError True defaultTimeLocale "%Y-%m-%d" buildRawPost :: FilePath -> IO RawPost buildRawPost path = do contents <- readFile path return (path, T.pack contents) buildIndexPage :: String -> [RichPost] -> Either String T.Text buildIndexPage layout rawPosts = case compileTemplate (T.pack layout) of Left err -> Left err Right template -> Right $ renderTemplate template (buildPostListing rawPosts) buildPostListing :: [RichPost] -> Value buildPostListing posts = let postListing = map buildPostListingItem (sortByDate posts) in object [(T.pack "posts", Array $ fromList postListing)] buildPostListingItem :: RichPost -> Value buildPostListingItem (path, Pandoc m b) = let keys = ["title", "date", "slug"] bindings = map (\key -> T.pack key .= lookupMeta' key m) keys body = case renderPost "
$body$
" (path, Pandoc m b) of Left _error -> "" Right contents -> T.unpack contents in object $ bindings ++ [ ( T.pack "link" , toJSON $ T.concat [T.pack "/posts/", lookupMeta' "slug" m, T.pack "/"] ) , (T.pack "body", toJSON $ escapeHTML body) , ( T.pack "iso_date" , toJSON $ formatTime defaultTimeLocale "%a, %d %b %Y 00:00:00 +0000" (parseDay (T.unpack $ lookupMeta' "date" m)) ) ] buildRSSFeed :: String -> [RichPost] -> Either String T.Text buildRSSFeed layout posts = case compileTemplate (T.pack layout) of Left err -> Left err Right template -> Right $ renderTemplate template (buildPostListing posts)