mathblog-0.2: src/MB/Processing.hs
module MB.Processing
( processPost
)
where
import Control.Monad
( forM
)
import Data.List
( intercalate
)
import Data.Digest.Pure.SHA
( showDigest
, sha1
)
import Data.ByteString.Lazy.Char8
( pack
)
import System.Directory
( doesFileExist
)
import System.Process
( readProcessWithExitCode
)
import System.Exit
( ExitCode(..)
)
import qualified Text.Pandoc as Pandoc
import MB.Types
import qualified MB.Files as Files
processPost :: Config -> Post -> IO Post
processPost = renderGnuPlot
renderGnuPlot :: Config -> Post -> IO Post
renderGnuPlot config post = do
let Pandoc.Pandoc m blocks = postAst post
newBlocks <- forM blocks $ \blk ->
case blk of
Pandoc.CodeBlock (preambleName, classes, _) s ->
renderGnuPlotScript config preambleName s classes
b -> return b
return $ post { postAst = Pandoc.Pandoc m newBlocks }
loadPreamble :: Config -> String -> IO (Maybe String)
loadPreamble config preambleName = do
let filename = Files.eqPreambleFile config $ preambleName ++ ".txt"
e <- doesFileExist filename
case e of
False -> return Nothing
True -> do
s <- readFile filename
s `seq` return ()
return $ Just s
renderGnuPlotScript :: Config
-> String
-> String
-> [String]
-> IO Pandoc.Block
renderGnuPlotScript config preambleName rawScript classes = do
putStrLn $ "Rendering equation graph, type=" ++ preambleName
mPreamble <- loadPreamble config preambleName
case mPreamble of
Nothing -> do
putStrLn $ "Error: no such gnuplot preamble: " ++ preambleName
return $ Pandoc.Para [Pandoc.Str "[[COULD NOT DRAW EQUATION]]"]
Just preamble -> do
let scriptLines = lines rawScript
preambleLines = lines preamble
digestInput = preambleName ++ rawScript
-- Generate an image name in the images/ directory of the blog
-- data directory. Use a hash of the preamble name and script
-- contents so we can avoid rendering the image again if it
-- already exists.
let hash = showDigest $ sha1 $ pack digestInput
imageFilename = preambleName ++ "-" ++ hash ++ ".png"
imagePath = Files.imageFilename config imageFilename
outputLines = [ "set term png enhanced"
, "set output \"" ++ imagePath ++ "\""
]
fullScript = intercalate "; " $ outputLines ++ preambleLines ++ scriptLines
-- Invoke gnuplot to render the image
(status, out, err) <- readProcessWithExitCode "gnuplot" ["-e", fullScript] ""
case status of
ExitSuccess -> return ()
ExitFailure _ -> do
putStrLn "Could not render equation:"
putStrLn "Equation was:"
putStrLn rawScript
putStrLn "gnuplot output:"
putStrLn out
putStrLn err
return $ Pandoc.Para [Pandoc.HtmlInline $ concat [ "<img src=\"" ++ baseUrl config ++ "/generated-images/"
, imageFilename
, "\" class=\""
, intercalate " " classes
, "\">"
]
]