A static site generator written in Haskell
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

Main.hs 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. module Main where
  2. import Control.Monad
  3. import Data.Aeson
  4. import qualified Data.Map as M
  5. import qualified Data.Text as T
  6. import Path ( parseAbsDir
  7. , toFilePath
  8. )
  9. import Path.IO ( copyDirRecur )
  10. import System.Console.ArgParser
  11. import System.Directory
  12. import System.FilePath
  13. import Text.Pandoc
  14. import Build ( buildRawPost
  15. , buildIndexPage
  16. , buildRSSFeed
  17. , buildPostListing
  18. , buildPostListingItem
  19. )
  20. import CLI ( argParser
  21. , Config
  22. , Config(..)
  23. )
  24. import Post ( parsePost
  25. , parsePosts
  26. , renderPost
  27. , renderPosts
  28. , RawPost
  29. , RichPost
  30. )
  31. import Read ( readIndexTemplate
  32. , readPostTemplate
  33. , readRSSTemplate
  34. , readPostContents
  35. )
  36. import Templates ( defaultIndexTemplate
  37. , defaultPostTemplate
  38. )
  39. import Utils ( errorsAndResults
  40. , lookupMeta'
  41. , makeFullFilePath
  42. , sortByDate
  43. )
  44. import Write ( writeIndexPage
  45. , writePost
  46. , writeRSSFeed
  47. )
  48. setUpBuildDirectory :: FilePath -> IO ()
  49. setUpBuildDirectory path = do
  50. buildPathExists <- doesDirectoryExist path
  51. when buildPathExists $ removeDirectoryRecursive path
  52. createDirectory path
  53. createDirectory $ joinPath [path, "posts"]
  54. copyAssetsDir :: FilePath -> FilePath -> IO ()
  55. copyAssetsDir root build = do
  56. sourcePath <- parseAbsDir $ joinPath [root, "assets"]
  57. destPath <- parseAbsDir $ joinPath [build, "assets"]
  58. sourcePathExists <- doesDirectoryExist $ toFilePath sourcePath
  59. when sourcePathExists $ copyDirRecur sourcePath destPath
  60. build :: FilePath -> Bool -> IO ()
  61. build dir drafts = do
  62. cwd <- getCurrentDirectory
  63. root <- if dir == "." then makeAbsolute cwd else makeAbsolute dir
  64. build <- makeAbsolute $ joinPath [root, "build"]
  65. indexTemplate <- readIndexTemplate root
  66. postTemplate <- readPostTemplate root
  67. rssTemplate <- readRSSTemplate root
  68. postContents <- readPostContents root drafts
  69. let (parseErrors, parsedPosts) = errorsAndResults $ parsePosts postContents
  70. case parseErrors of
  71. [] ->
  72. let (renderErrors, renderedPosts) =
  73. errorsAndResults $ renderPosts postTemplate parsedPosts
  74. in case renderErrors of
  75. [] -> do
  76. setUpBuildDirectory build
  77. mapM_ (writePost build) renderedPosts
  78. case buildIndexPage indexTemplate parsedPosts of
  79. Left err -> putStrLn err
  80. Right indexPage -> writeIndexPage build indexPage
  81. case buildRSSFeed rssTemplate parsedPosts of
  82. Left err -> putStrLn err
  83. Right rssFeed -> writeRSSFeed build rssFeed
  84. copyAssetsDir root build
  85. _ -> putStrLn $ unlines $ map show renderErrors
  86. _ -> putStrLn $ unlines $ map show parseErrors
  87. new :: String -> IO ()
  88. new name = do
  89. path <- makeAbsolute name
  90. directoryExists <- doesDirectoryExist path
  91. if directoryExists
  92. then putStrLn $ "Error: Directory " ++ name ++ " already exists"
  93. else do
  94. createDirectory path
  95. createDirectory $ joinPath [path, "posts"]
  96. createDirectory $ joinPath [path, "drafts"]
  97. createDirectory $ joinPath [path, "templates"]
  98. writeFile (joinPath [path, "templates", "_index.html"])
  99. defaultIndexTemplate
  100. writeFile (joinPath [path, "templates", "_post.html"]) defaultPostTemplate
  101. run :: Config -> IO ()
  102. run config = case config of
  103. (Build dir drafts) -> build dir drafts
  104. (New name ) -> new name
  105. main :: IO ()
  106. main = do
  107. config <- argParser
  108. runApp config run