Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Pandoc filter to convert math to inline svg using latex and dvisvgm
import Text.Pandoc.JSON
import System.Directory
import System.FilePath ((</>))
import qualified Data.Hash.MD5 as MD5
import System.IO.Temp
import System.Process
import Control.Monad (unless)
main :: IO ()
main = toJSONFilter mathToSvg
mathToSvg :: Inline -> IO Inline
mathToSvg m@(Math mathType x) = do
let wrap = removeNewline . case mathType of
InlineMath -> \x' -> "\\("++x'++"\\)"
DisplayMath -> \x' -> "\\["++x'++"\\]"
preamble =[
"\\documentclass[border=1pt,varwidth]{standalone}",
"\\usepackage{standalone}" ++
"\\usepackage{amsmath}" ++
"\\usepackage{amssymb}" ++
"\\usepackage{cancel}" ++
"\\begin{document}"
]
postamble = [ "\\end{document}" ]
removeNewline = filter (`notElem` "\r\n")
tempDir <- getTemporaryDirectory
let cacheDir = tempDir </> "pandoc.texsvg.cache"
createDirectoryIfMissing True cacheDir
let mathHash = MD5.md5s $ MD5.Str $ show m
outfilename = cacheDir </> mathHash ++ ".svg"
fileExists <- doesFileExist outfilename
unless fileExists $
withSystemTempDirectory "pandoc.dir" $ \tmpDir ->
do
origDir <- getCurrentDirectory
setCurrentDirectory tmpDir
_ <- readProcess "latex" (preamble ++ [wrap x] ++ postamble) []
_ <- readProcess "dvisvgm"
["-b2pt", "-Z1.2", "-n", "-o", outfilename, "standalone.dvi"] []
setCurrentDirectory origDir
svg <- readFile outfilename
return $ RawInline (Format "html") $ case mathType of
InlineMath -> svg
DisplayMath -> "<p>"++svg++"</p>"
mathToSvg x = return x
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.