heckle 2.0.0.1 → 2.0.0.2
raw patch · 4 files changed
+55/−74 lines, 4 files
Files
- Files.hs +6/−2
- Heckle.hs +35/−38
- Main.hs +13/−33
- heckle.cabal +1/−1
Files.hs view
@@ -22,6 +22,10 @@ , "This is an example MD/HTML post" ] -exampleHklFile :: String-exampleHklFile = unlines+exampleIndexFile :: String+exampleIndexFile = unlines [ "<ul id='blog-posts'></ul>"]++exampleTemplateFile :: String+exampleTemplateFile = unlines+ [ "<div id='blog-post'></div>"]
Heckle.hs view
@@ -5,8 +5,6 @@ module Heckle where --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.Pretty@@ -57,12 +55,13 @@ --DRY postToHtml :: Post -> Html-postToHtml p@(MD _ _ _ _) = li ! class_ "blog-post" $ do- a ! class_ "post-link" ! href (stringValue ("posts/"++fileName p++".html")) $ toHtml (postTitle p)- H.div ! class_ "post-date" $ toHtml ((displayDate . postDate) p)-postToHtml p@(LaTeX _ _ _ _) = li ! class_ "blog-post" $ do- a ! class_ "post-link" ! href (stringValue ("posts/"++fileName p++".pdf")) $ toHtml (postTitle p)+postToHtml p = li ! class_ "blog-post" $ do+ a ! class_ "post-link" ! href (stringValue ("posts/"++fileName p++ext)) $ toHtml (postTitle p) H.div ! class_ "post-date" $ toHtml ((displayDate . postDate) p)+ where+ ext = case p of+ (MD _ _ _ _) -> ".html"+ (LaTeX _ _ _ _) -> ".pdf" data Post = LaTeX {@@ -82,16 +81,6 @@ instance Ord Post where compare p1 p2 = compare (postDate p1) (postDate p2) -getPDF :: FilePath -> Either String String-getPDF s = case splitOn "." s of- [fn, "pdf"] -> Right fn - _ -> Left "Not a PDF file"--getMD :: FilePath -> Either String String-getMD s = case splitOn "." s of- [fn, "md"] -> Right fn- _ -> Left "Not a PDF file"- extractFromArgs :: String -> [[TeXArg]] -> Either String Text extractFromArgs _ (((FixArg (TeXRaw s)):_):_) = Right s extractFromArgs s [] = Left ("Command not found: " ++ s)@@ -111,10 +100,9 @@ I also wanted to stick with strings for error messages, so this just shows the ParseErrors from parseDate -} parseAbsoluteDate :: String -> Either String DateTime-parseAbsoluteDate s = case parseDate fakeNow s of+parseAbsoluteDate s = case parseDate mempty s of (Left e) -> Left (show e) (Right res) -> (Right res)- where fakeNow = DateTime 0 0 0 0 0 0 getMeta :: (Meta -> [Inline]) -> Pandoc -> Either String String getMeta f (Pandoc m _) = case f m of@@ -137,25 +125,34 @@ date = (getCommandValue "date" t) >>= parseAbsoluteDate -- Either monad title = getCommandValue "title" t -mdToPost :: String -> IO (Either String Post)-mdToPost fn = do- native <- fmap (readMarkdown def) (readFile ("posts/" ++ fn ++ ".md"))- return (createMDPost fn native)+fileToPost :: String -> IO (Either String Post)+fileToPost fn = + case splitOn "." fn of+ [fn, "pdf"] -> do+ latexFile <- fmap (parseLaTeXWith (ParserConf ["verbatim", "minted"]) . pack) (readFile ("posts/"++fn++".tex"))+ return (createLaTeXPost fn latexFile)+ [fn, "md"] -> do+ native <- fmap (readMarkdown def) (readFile ("posts/" ++ fn++".md"))+ return (createMDPost fn native)+ _ -> return (Left "Not a LaTeX or MD file") -latexToPost :: String -> IO (Either String Post) -latexToPost fn = do- latexFile <- fmap (parseLaTeXWith (ParserConf ["verbatim", "minted"]) . pack) (readFile ("posts/"++fn++".tex"))- return (createLaTeXPost fn latexFile)+injectIndex :: String -> Html -> Either String String +injectIndex layout ul = injectAt [(TagOpen "ul" [("id","blog-posts")]), (TagClose "ul")] layout (show ul) -injectPosts :: String -> Html -> Either String String -injectPosts layout ul = case splitFile of- [beginning, end] -> Right (renderTags (beginning ++ parseTags (show ul) ++ end))- _ -> Left "Broken layout file"- where- splitFile = splitOn [(TagOpen "ul" [("id","blog-posts")]), (TagClose "ul")] (parseTags layout)+injectTemplate :: String -> Post -> Either String String +injectTemplate layout (MD fn _ _ t) = injectAt tags layout inp + where + tags = [(TagOpen "div" [("id","blog-post")]), (TagClose "div")]+ inp = "<div id='blog-post'>" ++ (writeHtmlString def t) ++ "</div>" -writeHTML :: Post -> IO ()-writeHTML (MD fn _ _ t) = do- let html = writeHtmlString def t- writeFile ("posts/" ++ fn ++ ".html") html -writeHTML (LaTeX _ _ _ _) = return ()+injectAt :: [Text.HTML.TagSoup.Tag String] -> String -> String -> Either String String+injectAt p layout insert = case splitOn p (parseTags layout) of + [beg, end] -> Right (renderTags (beg ++ parseTags insert ++ end))+ _ -> Left "Broken layout file"++writeHTML :: String -> Post -> IO ()+writeHTML template p@(MD fn _ _ t) = do+ case injectTemplate template p of+ Right html -> writeFile ("posts/" ++ fn ++ ".html") html + _ -> return ()+writeHTML _ (LaTeX _ _ _ _) = return ()
Main.hs view
@@ -10,59 +10,39 @@ args <- getArgs case args of ["build"] -> do- --get all pdf files from directory- putStrLn "Getting directory contents"- latexFileNames <- fmap (rights . map getPDF) (getDirectoryContents "posts")- mdFileNames <- fmap (rights . map getMD) (getDirectoryContents "posts")- --print brokenFiles- --print fileNames-- --turn the list of files into a list of posts- putStrLn "Turning directory contents into posts"- latexPostsToBeCreated <- (mapM latexToPost latexFileNames)- mdPostsToBeCreated <- (mapM mdToPost mdFileNames)- --print mdPostsToBeCreated- let posts = (reverse . sort . rights) (mdPostsToBeCreated ++ latexPostsToBeCreated)- --print posts- --let brokenPosts = lefts postsToBeCreated- --if length (brokenPosts) > 1 - -- then print brokenPosts- -- else putStrLn "All posts are well formed"- --print posts+ + putStrLn "Reading directory and turning into native posts"+ postsToBeCreated <- mapM fileToPost =<< (getDirectoryContents "posts")+ let posts = (reverse . sort . rights) (postsToBeCreated) - --convert posts to their html if needed- mapM_ writeHTML posts+ putStrLn "Writing markdown files into template HTML"+ template <- readFile "template.html.hkl"+ mapM_ (writeHTML template) posts - --generate a ul from the list of posts- putStrLn "Turning posts into an HTML element"+ putStrLn "Creating HTML <ul> element for index file" let generatedHtml = postsToHtml posts- --print generatedHtml - --read the layout file- putStrLn "Reading the layout file"+ putStrLn "Inserting HTML <ul> element into layout file" layoutFile <- readFile "index.html.hkl"-- --put the ul into the layout file- putStrLn "Inserting HTML element into layout file"- let injectedOutput = layoutFile `injectPosts` generatedHtml+ let injectedOutput = layoutFile `injectIndex` generatedHtml case injectedOutput of (Left e) -> putStrLn e (Right s) -> do- --put the results into the index.html file- putStrLn "Writing resulting file into index.html" writeFile "index.html" s putStrLn "Success building!" ["init"] -> do --Create the basic layout file- writeFile "index.html.hkl" exampleHklFile --Change to layout when testing, index when deploying"+ writeFile "index.html.hkl" exampleIndexFile --Change to layout when testing, index when deploying"+ writeFile "template.html.hkl" exampleTemplateFile --Create directory for posts and basic post createDirectoryIfMissing True "posts" setCurrentDirectory "posts" writeFile "example-latex.tex" exampleTeXPost writeFile "example-markdown.md" exampleMDPost --Compile the LaTeX file into a PDF+ --Could do this for every .tex file if wanted to readProcess "pdflatex" ["example-latex.tex"] "" print "Success initializing!"
heckle.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: heckle-version: 2.0.0.1+version: 2.0.0.2 synopsis: Jekyll in Haskell description: Static site generator that lets you write your blog in LaTeX/MD and publish it to github pages. description: Markdown and HTML are the standard tools used to write your every day tech blog with. But they have pretty weak support for embedding mathematical formulas, and are not conducive to writing for an extended period of time. Plus, they aren't even Turing complete! So use BlaTeX to start blogging in LaTeX! (Oh btw you can still use Markdown too tho lol).