+{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE DuplicateRecordFields #-}
module Lib
- ( someFunc
+ ( someFunc, EntryList, allFilesIn, ProjectConfig
) where
import Data.Function (on)
import Data.Time.LocalTime
import Prelude hiding (lines)
import System.Directory
-import System.FilePath.Posix (takeBaseName)
+import System.FilePath.Posix (takeBaseName, takeDirectory)
+import Data.Data
+import Data.Typeable
+
+data Theme = Theme {
+ name :: String, -- works better with getHomeDirectory
+ templates :: [(String, Template)]
+ } deriving (Show)
+
+data ProjectConfig = ProjectConfig {
+ name :: Text,
+ description :: Text,
+ theme :: String -- as above
+ } deriving (Show, Data, Typeable)
+
+data Project = Project {
+ name :: Text,
+ description :: Text,
+ theme :: Theme,
+ entries :: EntryList
+ } deriving (Show)
data BlogEntry = BlogEntry {
postDate :: UTCTime,
foldl (\c -> \v ->
c ++ [(format (postDate v) "%Y", [(format (postDate v) "%B", v)])]) [] stamps
-entryListToPaths :: EntryList -> [Text]
-entryListToPaths el = concat $ concat $ map (\(year, months)
+getEntriesTemplate :: Project -> Template
+getEntriesTemplate p = case lookup "entry.html" $ templates $ theme (p :: Project) of
+ Just a -> a
+
+getEntriesVideoTemplate :: Project -> Template
+getEntriesVideoTemplate p = case lookup "entry-video.html" $ templates $ theme (p :: Project) of
+ Just a -> a
+
+getTemplateForEntry :: Project -> BlogEntry -> Template
+getTemplateForEntry p e = case video e of
+ Just _ -> getEntriesVideoTemplate p
+ Nothing -> getEntriesTemplate p
+
+getIndexTemplate :: Project -> Template
+getIndexTemplate p = case lookup "index.html" $ templates $ theme (p :: Project) of
+ Just a -> a
+
+getEntryPages :: Project -> [(Text, Text)]
+getEntryPages p = concat $ concat $ map (\(year, months)
-> map (\(month, entries)
-> map (\(entryNum, entry) ->
- year `append`
- "/" `append`
- month) entries) months) el
+ (intercalate "/" [
+ "build",
+ format (postDate entry) "%Y",
+ format (postDate entry) "%B",
+ urlify (title entry) `append` ".html"],
+ entryToMarkup entry (getTemplateForEntry p entry))
+ ) entries) months) (entries p)
entryListToIndex :: EntryList -> Text
entryListToIndex el = unorderedList Nothing $ map (\(year, monthList) -> unorderedList (Just year) $ map (\(month, entryList) -> unorderedList (Just month) $ map (\x -> "<a href=\"" <> year <> "/" <> month <> "/" <> ((urlify . title . snd) x) <> ".html\">" <> (title . snd) x <> "</a>") entryList) monthList) el
meta = splitOn "::" (fileLines !! 0)
fileLines = lines rawEntry
-allFilesIn dir = filter (/= "..")<$>(filter(/= "."))<$>(filter(/= ".gitignore"))<$>(getDirectoryContents dir)
-
-exportEntry entry = do
- rawTemplateNormal <- readFile "templates/entry.html"
- rawTemplateVideo <- readFile "templates/entry-video.html"
-
- let entryTemplate = template . pack $ case (video entry) of
- Nothing -> rawTemplateNormal
- Just a -> rawTemplateVideo
+allFilesIn dir = filter (/= "..")<$>(filter(/= "."))<$>(getDirectoryContents dir)
- writeFile (unpack $ intercalate "/" [
- "build",
- format (postDate entry) "%Y",
- format (postDate entry) "%B",
- urlify (title entry) `append` ".html"]) $ unpack $ entryToMarkup entry entryTemplate
-
-exportIndex :: EntryList -> IO()
-exportIndex entryList = do
- rawTemplate <- readFile "templates/index.html"
-
- let indexTemplate = template . pack $ rawTemplate
- let indexContext = context [("index", entryListToIndex entryList)]
-
- writeFile "build/index.html" $ unpack $ toStrict $ render indexTemplate indexContext
-
-someFunc = do
+someFunc projectConfig files = do
files <- fmap (reverse . sort) $ allFilesIn "entries"
rawEntries <- mapM (\x -> (readFile ("entries/" ++ x)) >>= (\y -> (return . fromString) y)) files
entryList <- mapM (\raw -> return $ rawTextToEntry raw) rawEntries
- entryPaths <- return $ entryListToPaths $ stampsToEntryList entryList
- mapM_ (createDirectoryIfMissing True . ("build/" ++) . unpack) entryPaths
- mapM_ exportEntry entryList
- exportIndex $ stampsToEntryList entryList
+ homeDir <- getHomeDirectory
+
+ let themeName = theme (projectConfig :: ProjectConfig)
+ themeTemplatePaths <- allFilesIn $ homeDir ++ "/.xyz/themes/" ++ themeName
+ themeTemplates <- mapM (\x -> (readFile $ homeDir ++ "/.xyz/themes/" ++ themeName ++ "/" ++ x) >>= (\y -> return (x, (template . fromString) y))) themeTemplatePaths
+
+ let projectName = name (projectConfig :: ProjectConfig)
+ let projectDescription = description (projectConfig :: ProjectConfig)
+ let project = Project projectName projectDescription (Theme themeName themeTemplates) (stampsToEntryList entryList)
+
+ mapM_ (createDirectoryIfMissing True . takeDirectory . unpack . fst) $ getEntryPages project
+ mapM_ (\x -> writeFile (unpack $ fst x) (unpack $ snd x)) $ getEntryPages project
+ writeFile "build/index.html" $ unpack $ toStrict $ render (getIndexTemplate project) $ context [("index", entryListToIndex (entries project))]
context :: [(Text, Text)] -> Context
context assocs x = case lookup x $ assocs of