aboutsummaryrefslogtreecommitdiff
path: root/src/Main.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Main.hs')
-rw-r--r--src/Main.hs188
1 files changed, 135 insertions, 53 deletions
diff --git a/src/Main.hs b/src/Main.hs
index fd1e076..d66e67b 100644
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -1,67 +1,149 @@
{-# LANGUAGE OverloadedStrings #-}
-module Main
- ( main
- ) where
+import Control.Applicative (empty)
+import qualified Data.Text as T
+import Hakyll ((.&&.))
+import Hakyll (Compiler, Configuration (..),
+ Context (Context),
+ ContextField (ListField), Identifier,
+ Item, MonadMetadata, TmpFile (TmpFile))
+import qualified Hakyll as H
+import qualified System.FilePath as FilePath (replaceExtension,
+ takeDirectory)
+import qualified System.Process as Process (readCreateProcess, shell,
+ system)
+import qualified Text.Pandoc as Pandoc
-import Control.Concurrent (forkIO)
-import Control.Monad.IO.Class (liftIO)
+main :: IO ()
+main = H.hakyllWith configuration $ do
-import Network.Wai.Middleware.Static
+ -- Static files
+ H.match "assets/**" $ do
+ H.route H.idRoute
+ H.compile H.copyFileCompiler
-import Web.Scotty
+ H.match "css/**.hs" $ do
+ H.route . H.customRoute $ const "style.css"
+ H.compile $ do
+ H.unsafeCompiler (Process.readCreateProcess (Process.shell "cd css && runghc Style.hs") "")
+ >>= H.makeItem
-import Data.Text.Lazy (isPrefixOf)
-import Data.Yaml (decodeFileEither)
+ H.match "cv/**" $ H.version "html" $ do
+ H.route $ H.setExtension "html"
+ let context =
+ metadataListField `mappend`
+ H.defaultContext
+ H.compile $ H.pandocCompiler
+ >>= H.loadAndApplyTemplate "templates/resume.html" context
+ >>= H.relativizeUrls
-import Model
-import Model.Translation.Language
+ H.match "cv/**" $ H.version "tex" $ do
+ H.route $ H.setExtension "tex"
+ let context =
+ metadataListField `mappend`
+ H.defaultContext
+ H.compile $ H.getResourceBody
+ >>= H.readPandoc
+ >>= writeLaTeX
+ >>= H.loadAndApplyTemplate "templates/resume.tex" context
-import View.NotFound (renderNotFound)
-import View.Page (renderPage)
-import View.Project (renderProjects)
-import View.Resume (renderResume)
+ H.match "project/**" $ do
+ H.route $ H.setExtension "html"
+ let context =
+ metadataListField `mappend`
+ H.defaultContext
+ H.compile $ H.pandocCompiler
+ >>= H.loadAndApplyTemplate "templates/project.html" context
+ >>= H.relativizeUrls
-import Design.Global (compactDesign)
+ H.match "index.html" $ do
+ H.route H.idRoute
+ let layoutContext =
+ H.constField "isResume" "true" `mappend`
+ H.defaultContext
+ let context =
+ H.listField "experience" H.defaultContext (H.loadAll ("cv/experience/*" .&&. H.hasVersion "html")) `mappend`
+ H.listField "education" H.defaultContext (H.loadAll ("cv/education/*" .&&. H.hasVersion "html")) `mappend`
+ H.listField "skills" H.defaultContext (H.loadAll ("cv/skill/*" .&&. H.hasVersion "html")) `mappend`
+ H.listField "hobbies" H.defaultContext (H.loadAll ("cv/hobby/*" .&&. H.hasVersion "html")) `mappend`
+ H.defaultContext
+ H.compile $
+ H.getResourceBody
+ >>= H.applyAsTemplate context
+ >>= H.loadAndApplyTemplate "templates/layout.html" layoutContext
+ >>= H.relativizeUrls
-import qualified Conf as Conf
+ H.match "projects.html" $ do
+ H.route H.idRoute
+ let layoutContext =
+ H.constField "isProjects" "true" `mappend`
+ H.defaultContext
+ let context =
+ H.listField "projects" H.defaultContext (H.loadAll "project/*") `mappend`
+ H.defaultContext
+ H.compile $
+ H.getResourceBody
+ >>= H.applyAsTemplate context
+ >>= H.loadAndApplyTemplate "templates/layout.html" layoutContext
+ >>= H.relativizeUrls
-import Date (getCurrentDate)
+ H.match "cv.tex" $ do
+ H.route $ H.setExtension ".pdf"
+ let context =
+ H.listField "experience" H.defaultContext (H.loadAll ("cv/experience/*" .&&. H.hasVersion "tex")) `mappend`
+ H.listField "education" H.defaultContext (H.loadAll ("cv/education/*" .&&. H.hasVersion "tex")) `mappend`
+ H.listField "skills" H.defaultContext (H.loadAll ("cv/skill/*" .&&. H.hasVersion "tex")) `mappend`
+ H.listField "hobbies" H.defaultContext (H.loadAll ("cv/hobby/*" .&&. H.hasVersion "tex")) `mappend`
+ H.defaultContext
+ H.compile $
+ H.getResourceBody
+ >>= H.applyAsTemplate context
+ >>= H.readPandoc
+ >>= writeLaTeX
+ >>= H.loadAndApplyTemplate "templates/layout.tex" context
+ >>= generatePdf
-import Daemon (runDaemon)
+ H.match "templates/**" $
+ H.compile H.templateBodyCompiler
-import Resume (generateResumes)
+writeLaTeX :: Item Pandoc.Pandoc -> Compiler (Item String)
+writeLaTeX = traverse $ \pandoc ->
+ case Pandoc.runPure (Pandoc.writeLaTeX Pandoc.def pandoc) of
+ Left err -> fail $ show err
+ Right x -> return (T.unpack x)
-main :: IO ()
-main = do
- modelOrError <- decodeFileEither "data.yaml"
- confOrError <- Conf.getConf "application.conf"
- case (modelOrError, confOrError) of
- (Left modelError, _) ->
- putStrLn $ "Model error: " ++ (show modelError)
- (_, Left confError) ->
- putStrLn $ "Configuration error: " ++ (show confError)
- (Right model, Right conf) -> do
- _ <- forkIO . runDaemon (Conf.generateResumes conf) $ \() -> generateResumes model conf
- scotty (Conf.port conf) $ do
- middleware $ staticPolicy (noDots >-> addBase "public")
- get "/design" $ do
- addHeader "Content-Type" "text/css"
- text compactDesign
- get "/" $ do
- language <- getLanguage
- currentDate <- liftIO getCurrentDate
- html $ renderPage model (renderResume conf language currentDate model)
- get "/projects" $ do
- language <- getLanguage
- html $ renderPage model (renderProjects conf language (projects model))
- notFound $ do
- language <- getLanguage
- html $ renderPage model (renderNotFound language)
-
-getLanguage :: ActionM Language
-getLanguage = do
- mbLang <- header "Accept-Language"
- case mbLang of
- Just lang | "fr" `isPrefixOf` lang -> return French
- _ -> return English
+configuration :: Configuration
+configuration = H.defaultConfiguration
+ { destinationDirectory = "public"
+ }
+
+metadataListField :: Context a
+metadataListField = Context $ \k _ i -> do
+ values <- getMetadataListField (H.itemIdentifier i) k
+ case values of
+ Just vs -> do
+ listItems <- mapM H.makeItem vs
+ return $ ListField (H.field "item" (return . H.itemBody)) listItems
+ Nothing ->
+ empty
+
+getMetadataListField :: MonadMetadata m => Identifier -> String -> m (Maybe [String])
+getMetadataListField identifier key = do
+ metadata <- H.getMetadata identifier
+ return $ H.lookupStringList key metadata
+
+generatePdf :: Item String -> Compiler (Item TmpFile)
+generatePdf item = do
+ TmpFile texPath <- H.newTmpFile "file.tex"
+ let tmpDir = FilePath.takeDirectory texPath
+ pdfPath = FilePath.replaceExtension texPath "pdf"
+
+ H.unsafeCompiler $ do
+ writeFile texPath $ H.itemBody item
+ _ <- Process.system $ unwords ["cd resume", "&&", "pdflatex", "-halt-on-error",
+ "-output-directory", "../" ++ tmpDir, "../" ++ texPath, ">/dev/null", "2>&1"]
+ _ <- Process.system $ unwords ["cd resume", "&&", "pdflatex", "-halt-on-error",
+ "-output-directory", "../" ++ tmpDir, "../" ++ texPath, ">/dev/null", "2>&1"]
+ return ()
+
+ H.makeItem $ TmpFile pdfPath