acatalepsie/src/Projects.hs

102 lines
3.2 KiB
Haskell
Raw Normal View History

2020-09-25 23:45:58 +00:00
module Projects (build) where
2020-09-27 13:49:45 +00:00
import Lucid
import Data.Char (digitToInt)
import qualified Data.Map.Strict as Map
2020-09-25 23:45:58 +00:00
import Common
import Types
import Config
import Templates
2020-09-27 13:49:45 +00:00
data Project = Project
{ title :: Text
, subtitle :: Text
, year :: Text
, labels :: Map.Map Text Text
} deriving (Generic, Eq, FromJSON, Binary)
2020-09-25 23:45:58 +00:00
2020-09-27 13:49:45 +00:00
build :: Task IO ()
build = do
projects <- matchDir "projects/*/" buildProject
watch projects $ match_ "./projects.rst" do
intro <- compilePandocWith def wopts
write "projects.html" (renderIndex intro projects)
2020-09-25 23:45:58 +00:00
buildProject :: Recipe IO a (Project, FilePath)
buildProject = do
match "*" copyFile
name <- takeBaseName <$> getCurrentDir
children <- buildChildren name
watch children $ matchFile "index.*" do
(meta, doc) <- readPandocMetadataWith ropts
2020-09-27 13:49:45 +00:00
renderPandocWith wopts doc
<&> renderProject meta children
>>= saveFileAs (-<.> "html")
(meta,) <$> getCurrentDir
2020-09-25 23:45:58 +00:00
where
2020-09-27 13:49:45 +00:00
buildChildren :: String -> Recipe IO a [(Text, FilePath)]
2020-09-25 23:45:58 +00:00
buildChildren name = match "pages/*" do
filepath <- getInput
let (key, file) = getKey $ takeFileName filepath
(TitledPage title _, doc) <- readPandocMetadataWith ropts
renderPandocWith wopts doc
2020-09-26 23:33:50 +00:00
<&> toHtmlRaw
2020-09-27 13:49:45 +00:00
<&> outerWith (def {Config.title = title})
2020-09-25 23:45:58 +00:00
>>= saveFileAs (const $ file -<.> "html")
<&> (title,)
2020-09-27 13:49:45 +00:00
renderProject :: Project -> [(Text, FilePath)] -> Text -> Html ()
renderProject Project{..} children content =
outerWith def { Config.title = title
, Config.description = subtitle
} do
header_ [class_ "project"] do
div_ (img_ [src_ "logo.svg"])
div_ do
h1_ (toHtml title)
p_ (toHtml subtitle)
ul_ $ forM_ (Map.toList labels) \(k, v) -> li_ do
toHtml k <> ": "
if k == "repo" then
a_ [href_ $ "https://github.com/" <> v]
$ toHtml v
else toHtml v
when (length children > 0) $
ol_ [class_ "pages"] $ forM_ children \(title, path) ->
li_ $ a_ [href_ (fromString path)] (toHtml title)
toHtmlRaw content
2020-09-25 23:45:58 +00:00
2020-09-27 13:49:45 +00:00
renderIndex :: Text -> [(Project, FilePath)] -> Html ()
renderIndex intro projects =
outerWith def { Config.title = "projects"
, Config.description = intro
} do
toHtmlRaw intro
ul_ [class_ "projects"] $ forM_ projects projectLink
where
projectLink :: (Project, FilePath) -> Html ()
projectLink (Project{..}, path) =
li_ $ a_ [href_ (fromString path)] do
div_ $ img_ [src_ (fromString $ path </> "logo.svg")]
div_ $ h2_ (toHtml title) >> p_ (toHtml subtitle)
2020-09-25 23:45:58 +00:00
2020-09-27 13:49:45 +00:00
getKey :: String -> (Int, String)
getKey xs = getKey' 0 xs
where
getKey' :: Int -> String -> (Int, String)
getKey' k (x : xs) | x >= '0' && x <= '9' =
getKey' (k * 10 + digitToInt x) xs
getKey' k ('-' : xs) = (k, xs)
getKey' k xs = (k, xs)