{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE FlexibleInstances #-} --Stuff for BlazeHTML import Control.Monad (forM_) import Text.Blaze.Html5 as H hiding (main, map) import Text.Blaze.Html5.Attributes as A import Text.Blaze.Html.Renderer.String --Stuff for HaTeX import Text.LaTeX import Text.LaTeX.Base.Parser import Text.LaTeX.Base.Syntax import Data.Text (unlines, pack, unpack) import qualified Data.Text.IO as T --Stuff for TagSoup import Text.HTML.TagSoup --Other stuff I'm using import System.Directory import Data.List.Split import Data.Maybe import Control.Applicative instance Show Html where show = renderHtml postsToHtml :: [Post] -> Html postsToHtml xs = do ul ! class_ "blog-posts" $ forM_ xs h where h s = li ! class_ "blog-post" $ a ! href (stringValue ("posts/"++fileName s++".pdf")) $ toHtml (postTitle s) data Post = Post { fileName :: String , postTitle :: String , postAuthor :: String , postDate :: String , syntaxTree :: LaTeX } instance Show Post where show (Post fn t a d _) = t ++ " written by " ++ (a) ++ " on " ++ (d) getPDF :: FilePath -> Maybe String getPDF xs = if splitUp !! 1 == "pdf" then Just (splitUp !! 0) else Nothing where splitUp = splitOn "." xs extractCommandArgs :: String -> LaTeX -> Maybe [TeXArg] extractCommandArgs s (TeXSeq lt rt) = if isJust lst then lst else rst where lst = extractCommandArgs s lt rst = extractCommandArgs s rt extractCommandArgs s (TeXComm name args) | name == s = Just args | otherwise = Nothing extractCommandArgs _ _ = Nothing extractFromArgs :: [TeXArg] -> Text extractFromArgs ((FixArg (TeXRaw s)):xs) = s getCommandValue :: String -> LaTeX -> Maybe Text getCommandValue s = (fmap extractFromArgs . extractCommandArgs s) createPost :: String -> Either ParseError LaTeX -> Maybe Post createPost _ (Left err) = Nothing createPost s (Right t) = Post <$> pure s <*> title <*> author <*> date <*> pure t where date = fmap unpack (getCommandValue "date" t) author = fmap unpack (getCommandValue "author" t) title = fmap unpack (getCommandValue "title" t) fileNameToPost :: String -> IO (Maybe Post) fileNameToPost fn = do latexFile <- fmap (parseLaTeX . pack) (readFile ("posts/"++fn++".tex")) return (createPost "post1" latexFile) injectPosts :: String -> Html -> String injectPosts layout ul = renderTags (beginning ++ parseTags (show ul) ++ end) where splitFile = splitOn [(TagOpen "ul" [("id","blog-posts")]), (TagClose "ul")] (parseTags layout) beginning = splitFile !! 0 end = splitFile !! 1 main = do fileNames <- fmap (catMaybes . map getPDF) (getDirectoryContents "posts") posts <- fmap (catMaybes) (mapM fileNameToPost fileNames) --print posts let generatedHtml = postsToHtml posts --print generatedHtml layoutFile <- readFile "index.html.bltx" let outputFile = layoutFile `injectPosts` generatedHtml writeFile "index.html" outputFile