noli 0.1.0.3 → 0.1.1.0
raw patch · 4 files changed
+79/−41 lines, 4 filesdep +aesondep +bytestringdep +frontmatterPVP ok
version bump matches the API change (PVP)
Dependencies added: aeson, bytestring, frontmatter, yaml
API changes (from Hackage documentation)
+ Noli.Types: FrontMatter :: Text -> FrontMatter
+ Noli.Types: [frontmatter_title] :: FrontMatter -> Text
+ Noli.Types: instance Data.Aeson.Types.FromJSON.FromJSON Noli.Types.FrontMatter
+ Noli.Types: instance Data.Aeson.Types.ToJSON.ToJSON Noli.Types.FrontMatter
+ Noli.Types: instance GHC.Generics.Generic Noli.Types.FrontMatter
+ Noli.Types: instance GHC.Show.Show Noli.Types.FrontMatter
+ Noli.Types: newtype FrontMatter
Files
- noli.cabal +7/−3
- src/Noli.hs +3/−2
- src/Noli/Types.hs +53/−25
- src/PostUtils.hs +16/−11
noli.cabal view
@@ -1,7 +1,7 @@ name: noli-version: 0.1.0.3+version: 0.1.1.0 synopsis: A static site generator-description: Yet Another static site generator for Haskell. This time easier to use.+description: A static site generator homepage: https://github.com/Endi1/noli#readme license: MIT license-file: LICENSE@@ -23,4 +23,8 @@ lucid >= 2.9, cmark >= 0.6, directory >= 1.3.6,- regex-compat >= 0.95+ regex-compat >= 0.95,+ frontmatter,+ yaml,+ bytestring,+ aeson
src/Noli.hs view
@@ -9,6 +9,7 @@ ( unless, when, )+import Data.ByteString hiding (unpack) import Data.Text (unpack) import qualified Data.Text.IO as DT import Data.Text.Internal (Text)@@ -61,7 +62,7 @@ Prelude.mapM_ ( \p -> DT.writeFile- (unpack (pagename p) ++ ".html")+ (Data.Text.unpack (pagename p) ++ ".html") (toStrict $ renderText $ template p) ) (pages project)@@ -70,7 +71,7 @@ Prelude.mapM_ ( \p -> DT.writeFile- (unpack (filename p) ++ ".html")+ (Data.Text.unpack (filename p) ++ ".html") (toStrict $ renderText $ compiled_html p) ) (posts project)
src/Noli/Types.hs view
@@ -1,35 +1,63 @@-module Noli.Types (Settings (..), Post (..), Project (..), Page (..), PostTemplate) where+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE OverloadedStrings #-} +module Noli.Types+ ( Settings (..),+ Post (..),+ Project (..),+ Page (..),+ PostTemplate,+ FrontMatter (..),+ )+where++import Data.Aeson import Data.Text+import GHC.Generics import Lucid.Base -- | The "dynamic" representation of the static site-data Project = Project- { posts :: [Post],- pages :: [Page]- }+data Project+ = Project+ { posts :: [Post],+ pages :: [Page]+ } -data Settings = Settings- { -- | The name of the site- name :: Text,- -- | The author's full name- author :: Text,- -- | The path to the folder that contains the markdown files- posts_location :: FilePath,- -- | The path to where the compiled static site will be saved- dist_location :: FilePath,- -- | The path to the static folder- static_location :: FilePath- }+data Settings+ = Settings+ { -- | The name of the site+ name :: Text,+ -- | The author's full name+ author :: Text,+ -- | The path to the folder that contains the markdown files+ posts_location :: FilePath,+ -- | The path to where the compiled static site will be saved+ dist_location :: FilePath,+ -- | The path to the static folder+ static_location :: FilePath+ } -data Post = Post- { title :: Text,- location :: FilePath,- filename :: Text,- raw :: Text,- raw_html :: Text,- compiled_html :: Html ()- }+newtype FrontMatter+ = FrontMatter+ { frontmatter_title :: Text+ }+ deriving (Show, Generic, ToJSON)++instance FromJSON FrontMatter where+ parseJSON = withObject "FrontMatter" $ \obj -> do+ frontmatter_title <- obj .: "title"+ return (FrontMatter frontmatter_title)++data Post+ = Post+ { title :: Text,+ location :: FilePath,+ filename :: Text,+ raw :: Text,+ raw_html :: Text,+ compiled_html :: Html ()+ } deriving (Show) data Page = Page {pagename :: Text, template :: Html ()}
src/PostUtils.hs view
@@ -1,10 +1,14 @@-module PostUtils (compilePost, extname, copyFolder) where+module PostUtils (compilePost, extname, copyFolder, parseFrontMatter) where import CMark (commonmarkToHtml) import Control.Monad (unless)+import qualified Data.ByteString as BS+import Data.Frontmatter (IResult (Done), parseYamlFrontmatter) import Data.Maybe (fromJust) import Data.Text (pack)+import Data.Text.Encoding (decodeUtf8) import Data.Text.Internal (Text)+import Data.Yaml (Object) import Lucid.Base (Html) import Noli.Types import System.Directory (copyFile, createDirectory, doesDirectoryExist, doesFileExist, listDirectory)@@ -18,14 +22,14 @@ compilePost :: PostTemplate -> FilePath -> IO Post compilePost postCompiler fp = do- fileContents <- pack <$> readFile fp+ (frontMatter, fileContents) <- parseFrontMatter fp let compiledFileContents = commonmarkToHtml [] fileContents fn = fromJust $ getPostFileName fp- t = getPostName fn- compiledHtml = postCompiler (pack t) compiledFileContents+ t = frontmatter_title frontMatter+ compiledHtml = postCompiler t compiledFileContents return Post- { title = pack t,+ { title = t, location = fp, filename = pack fn, raw = fileContents,@@ -33,18 +37,19 @@ compiled_html = compiledHtml } +parseFrontMatter :: FilePath -> IO (FrontMatter, Text)+parseFrontMatter fp = do+ f <- BS.readFile fp+ case parseYamlFrontmatter f of+ Done ri fm -> return (fm, decodeUtf8 ri)+ _ -> error "Parse failure"+ getPostFileName :: FilePath -> Maybe String getPostFileName fp = case match of Nothing -> Nothing Just (x : xs) -> Just x where match = matchRegex postNameRegex fp--getPostName :: String -> String-getPostName fn =- let repl '_' = ' '- repl x = x- in Prelude.map repl fn copyFolder :: FilePath -> FilePath -> IO () copyFolder source destination = do