hablo/src/Blog/Wording.hs

67 lines
2.1 KiB
Haskell
Raw Normal View History

2019-02-17 19:52:28 +01:00
{-# LANGUAGE OverloadedStrings #-}
module Blog.Wording (
Wording(..)
, build
, variables
2019-02-17 19:52:28 +01:00
) where
import Arguments (Arguments(..))
import Control.Monad (foldM)
import Data.Aeson (ToJSON(..))
import Data.Map (Map)
import qualified Data.Map as Map (empty, fromList, keys, map, union)
2019-02-17 19:52:28 +01:00
import Data.Text (Text)
import qualified Data.Text as Text (pack)
2019-02-17 19:52:28 +01:00
import Paths_hablo (getDataFileName)
import Text.ParserCombinators.Parsec (
Parser
, (<|>)
, char, choice, endBy, eof, many, many1, noneOf, optional, parse, string, try
2019-02-17 19:52:28 +01:00
)
import System.Exit (die)
newtype Wording = Wording (Map String Text)
2019-02-17 19:52:28 +01:00
variables :: Map String [Text]
variables = Map.fromList [
("allLink", [])
, ("allPage", ["tag"])
, ("commentsLink", [])
, ("commentsSection", [])
, ("dateFormat", [])
, ("latestLink", [])
, ("latestPage", ["tag"])
, ("metadata", ["author", "date", "tags"])
, ("rssLink", [])
, ("rssTitle", ["tag"])
, ("tagsList", [])
2019-02-17 19:52:28 +01:00
]
instance ToJSON Wording where
toJSON (Wording m) = toJSON m
toEncoding (Wording m) = toEncoding m
2019-02-17 19:52:28 +01:00
addWording :: Map String Text -> FilePath -> IO (Map String Text)
addWording currentWording wordingFile = do
parsed <- parse wordingP wordingFile <$> readFile wordingFile
case parsed of
Left errorMessage -> die $ show errorMessage
Right newWording -> return $ Map.union currentWording newWording
wordingP :: Parser (Map String Text)
wordingP = Map.map Text.pack . Map.fromList <$>
(many skip *> line `endBy` (many1 skip) <* eof)
2019-02-17 19:52:28 +01:00
where
restOfLine = many $ noneOf "\r\n"
2019-02-17 19:52:28 +01:00
eol = try (string "\r\n") <|> string "\r" <|> string "\n"
skip = optional (char '#' *> restOfLine) *> eol
varEqual = choice (try . string <$> Map.keys variables) <* equal
line = (,) <$> varEqual <*> restOfLine
equal = many (char ' ') *> char '=' *> many (char ' ')
2019-02-17 19:52:28 +01:00
build :: Arguments -> IO Wording
build arguments = do
defaultWording <- getDataFileName "defaultWording.conf"
let wordingFiles = maybe id (:) (wording arguments) $ [defaultWording]
Wording <$> foldM addWording Map.empty wordingFiles