latex-svg-hakyll-0.2: src/Hakyll/Contrib/LaTeX.hs
-- | This module provides a basic framework to render LaTeX formulae inside Pandoc documents
-- for Hakyll pages.
--
-- See the latex-svg page on GitHub for more information.
--
-- https://github.com/phadej/latex-svg#readme
--
module Hakyll.Contrib.LaTeX (
initFormulaCompilerSVG,
initFormulaCompilerSVGPure,
CacheSize,
compileFormulaeSVG,
) where
import Data.Char (isSpace)
import Data.Maybe (fromMaybe)
import Hakyll.Core.Compiler (Compiler, unsafeCompiler)
import Text.Pandoc.Definition (Pandoc)
import Image.LaTeX.Render
import Image.LaTeX.Render.Pandoc
import qualified Data.Cache.LRU.IO as LRU
-- | Number of formula images to keep in memory during a @watch@ session.
type CacheSize = Integer
-- | Creates a formula compiler with caching. Can be used as in the following minimal example:
--
-- @
-- main = do
-- renderFormulae <- 'initFormulaCompilerSVG' 1000 'defaultEnv"
-- hakyll $
-- match "posts/*.markdown" $ do
-- route $ setExtension "html"
-- compile $ pandocCompilerWithTransformM
-- defaultHakyllReaderOptions
-- defaultHakyllWriterOptions
-- (renderFormulae 'defaultPandocFormulaOptions')
-- @
--
initFormulaCompilerSVG
:: CacheSize
-> EnvironmentOptions
-> IO (PandocFormulaOptions -> Pandoc -> Compiler Pandoc)
initFormulaCompilerSVG cs eo = do
mImageForFormula <- curry <$> memoizeLru (Just cs) (uncurry drawFormula)
let eachFormula x y = do
putStrLn $ " formula (" ++ environment' x ++ ") \"" ++ equationPreview y ++ "\""
mImageForFormula x y
return $ \fo -> unsafeCompiler . convertFormulaSvgPandocWith eachFormula fo
where
drawFormula x y = do
putStrLn " drawing..."
imageForFormula eo x y
--
-- | Creates a formula compiler. Can be used as in the following minimal example:
--
-- @
-- main = hakyll $ do
-- let renderFormulae = 'initFormulaCompilerSVGPure' 'defaultEnv"
-- match "posts/*.markdown" $ do
-- route $ setExtension "html"
-- compile $ pandocCompilerWithTransformM
-- defaultHakyllReaderOptions
-- defaultHakyllWriterOptions
-- (renderFormulae 'defaultPandocFormulaOptions')
-- @
--
initFormulaCompilerSVGPure
:: EnvironmentOptions
-> PandocFormulaOptions -> Pandoc -> Compiler Pandoc
initFormulaCompilerSVGPure eo fo pandoc = do
let mImageForFormula = drawFormula
let eachFormula x y = do
putStrLn $ " formula (" ++ environment' x ++ ") \"" ++ equationPreview y ++ "\""
mImageForFormula x y
unsafeCompiler (convertFormulaSvgPandocWith eachFormula fo pandoc)
where
drawFormula x y = do
putStrLn " drawing..."
imageForFormula eo x y
-- | A formula compiler that does not use caching, which works in a more drop-in fashion, as in:
--
-- > compile $ pandocCompilerWithTransformM (compileFormulaeSVG defaultEnv defaultPandocFormulaOptions)
--
compileFormulaeSVG
:: EnvironmentOptions
-> PandocFormulaOptions
-> Pandoc -> Compiler Pandoc
compileFormulaeSVG eo po =
let eachFormula x y = do
putStrLn $ " formula (" ++ environment' x ++ ") \"" ++ equationPreview y ++ "\""
putStrLn " drawing..."
imageForFormula eo x y
in unsafeCompiler . convertFormulaSvgPandocWith eachFormula po
equationPreview :: String -> String
equationPreview x'
| length x <= 16 = x
| otherwise = take 16 $ filter (/= '\n') x ++ "..."
where
x = dropWhile isSpace x'
memoizeLru :: Ord a => Maybe Integer -> (a -> IO b) -> IO (a -> IO b)
memoizeLru msize action = do
lru <- LRU.newAtomicLRU msize
return $ \arg -> do
mret <- LRU.lookup arg lru
case mret of
Just ret -> return ret
Nothing -> do
ret <- action arg
LRU.insert arg ret lru
return ret
environment' :: FormulaOptions -> String
environment' = fromMaybe "-" . environment