Skip to content

Instantly share code, notes, and snippets.

@lierdakil
Last active February 19, 2022 07:29
Show Gist options
  • Save lierdakil/6a95278d02256a74a0fc to your computer and use it in GitHub Desktop.
Save lierdakil/6a95278d02256a74a0fc to your computer and use it in GitHub Desktop.
Pandoc filter to convert math to inline svg using latex and dvisvgm
{-# LANGUAGE OverloadedStrings #-}
import Text.Pandoc.JSON
import System.Directory
import System.FilePath ((</>))
import qualified Data.Hash.MD5 as MD5
import qualified Data.Text as T
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 = T.unpack . 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 = T.filter (`notElem` ("\r\n" :: [Char]))
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 <- T.pack <$> readFile outfilename
return $ RawInline (Format "html") $ case mathType of
InlineMath -> svg
DisplayMath -> "<p>" <> svg <> "</p>"
mathToSvg x = return x
@PassionPenguin
Copy link

PassionPenguin commented Feb 14, 2022

a google group link pubed by myself.. https://groups.google.com/g/pandoc-discuss/c/4CirnNd-ETs

@lierdakil
Copy link
Author

To begin with, your call to dvisvgm is not quite right... Try using dvisvgm --no-fonts input.dvi -o output.svg. Besides, I'm pretty sure that call to table.insert will fail, since neither argument is a table. I don't think you need it to begin with.

@PassionPenguin
Copy link

PassionPenguin commented Feb 18, 2022

sorry but i find that you're right... as i have read a wrong document... thx:)

Here's my gist https://gist.github.com/PassionPenguin/43fc09b942cedc428ae246bff8b6e193 :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment