hablo/src/Blog.hs

81 lines
2.5 KiB
Haskell
Raw Normal View History

2019-01-27 21:41:21 +01:00
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE FlexibleContexts #-}
2019-01-27 21:41:21 +01:00
module Blog (
Blog(..)
, Path(..)
, Skin(..)
2019-02-17 19:52:28 +01:00
, Wording(..)
, build
2019-01-27 21:41:21 +01:00
, get
) where
import Arguments (Arguments)
import qualified Arguments (name)
import Article (Article)
import qualified Article (at, getKey)
import Blog.Path (Path(..))
import qualified Blog.Path as Path (build)
import Blog.Skin (Skin(..))
import qualified Blog.Skin as Skin (build)
2019-02-17 19:52:28 +01:00
import Blog.Wording (Wording(..))
import qualified Blog.Wording as Wording (build)
2019-01-27 21:41:21 +01:00
import Control.Monad ((>=>), filterM, forM)
import Control.Monad.Reader (MonadReader, ask)
2019-02-15 14:13:43 +01:00
import Data.Either (rights)
2019-02-17 19:52:28 +01:00
import Data.Map (Map, (!?))
import qualified Data.Map as Map (fromList)
2019-01-27 21:41:21 +01:00
import Data.Set (Set)
import qualified Data.Set as Set (empty, null, singleton, union)
import qualified Files (find)
import System.Directory (doesFileExist, withCurrentDirectory)
import System.FilePath ((</>), dropTrailingPathSeparator, takeExtension, takeFileName)
2019-01-27 21:41:21 +01:00
type Collection = Map String Article
2019-01-27 21:41:21 +01:00
data Blog = Blog {
articles :: Collection
, name :: String
, path :: Path
, skin :: Skin
, tags :: Map String (Set String)
2019-02-17 19:52:28 +01:00
, wording :: Wording
2019-01-27 21:41:21 +01:00
}
get :: MonadReader Blog m => (Blog -> a) -> m a
get = (<$> ask)
findArticles :: FilePath -> IO (Map String Article)
2019-02-15 14:13:43 +01:00
findArticles =
Files.find
>=> filterM isMarkDownFile
2019-02-15 14:13:43 +01:00
>=> mapM Article.at
>=> return . Map.fromList . rights
2019-01-27 21:41:21 +01:00
where
isMarkDownFile path = do
let correctExtension = takeExtension path == ".md"
(correctExtension &&) <$> doesFileExist path
2019-01-27 21:41:21 +01:00
tagged :: Collection -> FilePath -> IO (String, Set String)
2019-01-27 21:41:21 +01:00
tagged collection path = do
links <- Files.find path
keys <- forM links $ \link -> do
fileExists <- doesFileExist link
return $ if fileExists
then let articleKey = Article.getKey link in
2019-02-17 19:52:28 +01:00
maybe Set.empty (\_ -> Set.singleton articleKey) (collection !? articleKey)
else Set.empty
return (takeFileName path, foldl Set.union Set.empty keys)
2019-01-27 21:41:21 +01:00
build :: Arguments -> IO Blog
build arguments = withCurrentDirectory (root path) $ do
skin <- Skin.build name arguments
2019-02-17 19:52:28 +01:00
wording <- Wording.build arguments
articles <- findArticles $ articlesPath path
2019-01-27 21:41:21 +01:00
tags <- Map.fromList . filter (not . Set.null . snd)
<$> (Files.find (articlesPath path </> "tags") >>= mapM (articles `tagged`))
2019-02-17 19:52:28 +01:00
return $ Blog {articles, name, path, skin, tags, wording}
where
path = Path.build arguments
name = maybe (takeFileName . dropTrailingPathSeparator $ root path) id
$ Arguments.name arguments