Draft a data structure for pages and make it part of the Blog datastructure

This commit is contained in:
Tissevert 2019-08-27 16:49:47 +02:00
parent b080c32d4c
commit 46daaa2b7a
3 changed files with 32 additions and 13 deletions

View file

@ -41,6 +41,7 @@ executable hablo
, HTML , HTML
, JS , JS
, JSON , JSON
, Page
, Paths_hablo , Paths_hablo
, Pretty , Pretty
-- other-extensions: -- other-extensions:

View file

@ -27,16 +27,20 @@ import Data.Set (Set)
import qualified Data.Set as Set (empty, null, singleton, union) import qualified Data.Set as Set (empty, null, singleton, union)
import Files (File(..), absolute) import Files (File(..), absolute)
import qualified Files (find) import qualified Files (find)
import Page (Page)
import qualified Page (at)
import Prelude hiding (lookup) import Prelude hiding (lookup)
import System.Directory (doesFileExist, withCurrentDirectory) import System.Directory (doesFileExist, withCurrentDirectory)
import System.FilePath ((</>), dropTrailingPathSeparator, takeExtension, takeFileName) import System.FilePath ((</>), dropTrailingPathSeparator, takeExtension, takeFileName)
import Text.Parsec (ParseError) import Text.Parsec (ParseError)
type Collection = Map String Article type Collection = Map String
type Parsed a = Either ParseError (String, a)
data Blog = Blog { data Blog = Blog {
articles :: Collection articles :: Collection Article
, name :: String , name :: String
, pages :: Collection Page
, path :: Path , path :: Path
, skin :: Skin , skin :: Skin
, tags :: Map String (Set String) , tags :: Map String (Set String)
@ -46,25 +50,25 @@ data Blog = Blog {
get :: MonadReader Blog m => (Blog -> a) -> m a get :: MonadReader Blog m => (Blog -> a) -> m a
get = (<$> ask) get = (<$> ask)
keepOrWarn :: Map String Article -> Either ParseError (String, Article) -> IO (Map String Article) keepOrWarn :: Collection a -> Parsed a -> IO (Collection a)
keepOrWarn accumulator (Left parseErrors) = keepOrWarn accumulator (Left parseErrors) =
forM [show parseErrors, "=> Ignoring this article"] putStrLn forM [show parseErrors, "=> Ignoring this text"] putStrLn
>> return accumulator >> return accumulator
keepOrWarn accumulator (Right (key, article)) = keepOrWarn accumulator (Right (key, article)) =
return $ insert key article accumulator return $ insert key article accumulator
findArticles :: FilePath -> IO (Map String Article) find :: (FilePath -> IO (Parsed a)) -> FilePath -> IO (Collection a)
findArticles = find parser =
Files.find Files.find
>=> filterM isMarkDownFile >=> filterM isMarkDownFile
>=> mapM Article.at >=> mapM parser
>=> foldM keepOrWarn Map.empty >=> foldM keepOrWarn Map.empty
where where
isMarkDownFile path = do isMarkDownFile path = do
let correctExtension = takeExtension path == ".md" let correctExtension = takeExtension path == ".md"
(correctExtension &&) <$> doesFileExist path (correctExtension &&) <$> doesFileExist path
tagged :: Collection -> FilePath -> IO (String, Set String) tagged :: Collection Article -> FilePath -> IO (String, Set String)
tagged collection path = do tagged collection path = do
links <- Files.find path links <- Files.find path
keys <- forM links $ \link -> do keys <- forM links $ \link -> do
@ -75,12 +79,13 @@ tagged collection path = do
else Set.empty else Set.empty
return (takeFileName path, foldl Set.union Set.empty keys) return (takeFileName path, foldl Set.union Set.empty keys)
discover :: Path -> IO (Collection, Map String (Set String)) discover :: Path -> IO (Collection Article, Collection Page, Collection (Set String))
discover path = do discover path = do
articles <- findArticles $ articlesPath path articles <- find (Article.at) $ articlesPath path
pages <- maybe (return Map.empty) (find (Page.at)) $ pagesPath path
tags <- Map.fromList . filter (not . Set.null . snd) tags <- Map.fromList . filter (not . Set.null . snd)
<$> (Files.find (articlesPath path </> "tags") >>= mapM (articles `tagged`)) <$> (Files.find (articlesPath path </> "tags") >>= mapM (articles `tagged`))
return (articles, tags) return (articles, pages, tags)
build :: Arguments -> IO Blog build :: Arguments -> IO Blog
build arguments = do build arguments = do
@ -91,5 +96,5 @@ build arguments = do
let name = maybe (takeFileName $ dropTrailingPathSeparator root) id let name = maybe (takeFileName $ dropTrailingPathSeparator root) id
$ Arguments.name arguments $ Arguments.name arguments
skin <- Skin.build name arguments skin <- Skin.build name arguments
(articles, tags) <- discover path (articles, pages, tags) <- discover path
return $ Blog {articles, name, path, skin, tags, wording} return $ Blog {articles, name, pages, path, skin, tags, wording}

13
src/Page.hs Normal file
View file

@ -0,0 +1,13 @@
module Page (
Page(..)
, at
) where
import Text.ParserCombinators.Parsec (ParseError)
data Page = Page {
title :: String
}
at :: FilePath -> IO (Either ParseError (String, Page))
at = undefined