-
-
Save lierdakil/6a95278d02256a74a0fc to your computer and use it in GitHub Desktop.
{-# 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 |
Sorry, I seem to have lacked a library. I've now installed "missingH" via debians package manager but get more serious looking errors (see below).
/home/pazz/.pandoc/filters/texsvg.hs:43:53: error:
• Couldn't match expected type ‘[Char]’
with actual type ‘Data.Text.Internal.Text’
• In the first argument of ‘wrap’, namely ‘x’
In the expression: wrap x
In the first argument of ‘(++)’, namely ‘[wrap x]’
|
43 | _ <- readProcess "latex" (preamble ++ [wrap x] ++ postamble) []
| ^
/home/pazz/.pandoc/filters/texsvg.hs:49:30: error:
• Couldn't match expected type ‘Data.Text.Internal.Text’
with actual type ‘[Char]’
• In the first argument of ‘Format’, namely ‘"html"’
In the first argument of ‘RawInline’, namely ‘(Format "html")’
In the expression: RawInline (Format "html")
|
49 | return $ RawInline (Format "html") $ case mathType of
| ^^^^^^
/home/pazz/.pandoc/filters/texsvg.hs:50:19: error:
• Couldn't match type ‘[Char]’ with ‘Data.Text.Internal.Text’
Expected type: Data.Text.Internal.Text
Actual type: String
• In the expression: svg
In a case alternative: InlineMath -> svg
In the second argument of ‘($)’, namely
‘case mathType of
InlineMath -> svg
DisplayMath -> "<p>" ++ svg ++ "</p>"’
|
50 | InlineMath -> svg
| ^^^
/home/pazz/.pandoc/filters/texsvg.hs:51:20: error:
• Couldn't match expected type ‘Data.Text.Internal.Text’
with actual type ‘[Char]’
• In the expression: "<p>" ++ svg ++ "</p>"
In a case alternative: DisplayMath -> "<p>" ++ svg ++ "</p>"
In the second argument of ‘($)’, namely
‘case mathType of
InlineMath -> svg
DisplayMath -> "<p>" ++ svg ++ "</p>"’
|
51 | DisplayMath -> "<p>"++svg++"</p>"
| ^^^^^^^^^^^^^^^^^^
Error running filter /home/pazz/.pandoc/filters/texsvg.hs:
Filter returned error status 1
Yeah... this filter is pretty outdated. Let me see if I can easily update it.
Okay, updated, but tbh, it'd be probably easier to write a lua filter that would essentially do the same thing. All this filter does is basically run latex
and then convert its output to SVG using dvisvgm
for each math element in document. Should be pretty easy to implement in pandoc Lua I think. The only caveat is it does some hashing for caching, because otherwise it's very slow, and hashing isn't that easy with Lua. Doable though.
Hi @lierdakil i try to make a lua filter, but i am a newer in either lua or haskell, and i failed to install pandoc via cabal...thus i try to make a lua version:
local default_template = [[
\documentclass[12pt,preview]{standalone}
{{ preamble }}
\begin{document}
\begin{preview}
{{ code }}
\end{preview}
\end{document}
]]
local default_preamble = [[
\usepackage[utf8x]{inputenc}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{amstext}
\usepackage{newtxtext}
\usepackage{mhchem}
\usepackage{chemfig}
\usepackage[libertine]{newtxmath}
\DeclareOldFontCommand{\rm}{\normalfont\rmfamily}{\mathrm}
\DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\mathsf}
\DeclareOldFontCommand{\tt}{\normalfont\ttfamily}{\mathtt}
\DeclareOldFontCommand{\bf}{\normalfont\bfseries}{\mathbf}
\DeclareOldFontCommand{\it}{\normalfont\itshape}{\mathit}
\DeclareOldFontCommand{\sl}{\normalfont\slshape}{\@nomath\sl}
\DeclareOldFontCommand{\sc}{\normalfont\scshape}{\@nomath\sc}
\newcommand{\N}{\mathbb{N}}
\newcommand{\R}{\mathbb{R}}
\newcommand{\Z}{\mathbb{Z}}
]]
function exec_math (elem)
-- Convert Math El -> DVI via latex --
mathEq = default_template:gsub("{{ preamble }}", default_preamble):gsub("{{ code }}", elem.text)
local tex = io.open("input.tex", "w")
tex:write(mathEq)
io.close(tex)
os.execute("latex input.tex")
os.execute("dvisvgm --no-fonts input.dvi output.svg")
local svg = io.open("output.svg", "rb")
if not svg then
return nil
end
local content = svg:read "*a"
local output
if elem.mathtype == 'InlineMath' then
output = content
else
output = "<p>" .. content .. "<p>"
end
elem = pandoc.RawInline('html', output)
return elem
end
return {
{ Math = exec_math }
}
but after generating svg with markdown math $\chemfig{C([2]-H)([6]=H)}$
and return a RawInline elem, it still renders a <span class="math inline">$\chemfig{C([2]-H)([6]=H)}$</span>
, and log a warning in the console:
[WARNING] Could not convert TeX math \chemfig{C([2]-H)([6]=H)}, rendering as TeX:
\chemfig{C([2]-H)([6]=H)}
^
unexpected control sequence \chemfig
expecting "%", "\\label", "\\tag", "\\nonumber" or whitespace
Do you have any idea how to fix it?.....
a google group link pubed by myself.. https://groups.google.com/g/pandoc-discuss/c/4CirnNd-ETs
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.
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 :)
Sorry but how do I run this? I tried
but this gives me syntax errors as it expects bash syntax.
Adding
to the top yields
I'm on pandoc 2.9.1.1. Cheers!