├── Setup.hs ├── math-samples.png ├── stack.yaml ├── .gitignore ├── pandoc-tex2svg.cabal ├── README.md ├── math-samples.md ├── LICENSE ├── pandoc-tex2svg.hs └── math-samples.html /Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /math-samples.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgm/pandoc-tex2svg/HEAD/math-samples.png -------------------------------------------------------------------------------- /stack.yaml: -------------------------------------------------------------------------------- 1 | resolver: lts-7.9 2 | packages: 3 | - '.' 4 | extra-deps: 5 | - pandoc-types-1.17.0.4 6 | flags: {} 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | dist-* 3 | cabal-dev 4 | *.o 5 | *.hi 6 | *.chi 7 | *.chs.h 8 | *.dyn_o 9 | *.dyn_hi 10 | .hpc 11 | .hsenv 12 | .cabal-sandbox/ 13 | cabal.sandbox.config 14 | *.prof 15 | *.aux 16 | *.hp 17 | *.eventlog 18 | .stack-work/ 19 | cabal.project.local 20 | -------------------------------------------------------------------------------- /pandoc-tex2svg.cabal: -------------------------------------------------------------------------------- 1 | name: pandoc-tex2svg 2 | version: 0.1.0.0 3 | synopsis: Pandoc filter to convert tex math to SVG 4 | description: Please see README.md 5 | homepage: https://github.com/githubuser/pandoc-tex2svg#readme 6 | license: BSD3 7 | license-file: LICENSE 8 | author: John MacFarlane 9 | maintainer: jgm@berkeley.edu 10 | copyright: 2016 John MacFarlane 11 | category: Text 12 | build-type: Simple 13 | -- extra-source-files: 14 | cabal-version: >=1.10 15 | 16 | executable pandoc-tex2svg 17 | hs-source-dirs: . 18 | main-is: pandoc-tex2svg.hs 19 | ghc-options: -threaded -rtsopts -with-rtsopts=-N 20 | build-depends: base, pandoc-types > 1.17 && < 1.18, process, containers, 21 | directory 22 | default-language: Haskell2010 23 | 24 | source-repository head 25 | type: git 26 | location: https://github.com/githubuser/pandoc-tex2svg 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | pandoc-tex2svg 2 | ============== 3 | 4 | pandoc-tex2svg is a pandoc filter that renders math as SVG. 5 | It can be used with HTML5 based output formats, including 6 | EPUB and HTML-based slide shows like reveal.js. 7 | 8 | Here's an example of its output: 9 | [math-samples.html](math-samples.html). This renders 10 | like this in a modern browser: 11 | 12 |  13 | 14 | The filter uses `tex2svg` from 15 | [MathJax-node](https://github.com/mathjax/MathJax-node). 16 | To install using npm, 17 | 18 | npm install -g mathjax-node 19 | 20 | `tex2svg` is assumed to be in the path. Note that the default 21 | install does not put it in the path; you will have to do this 22 | manually. 23 | 24 | To compile and install the filter: 25 | 26 | stack install 27 | 28 | or 29 | 30 | cabal install 31 | 32 | Make sure the filter is in your path (stack puts executables in 33 | `$HOME/.local/bin`). 34 | 35 | To use the filter with pandoc (currently pandoc 1.18 is required): 36 | 37 | pandoc math-samples.md --filter pandoc-tex2svg -s -t html5 -o math-samples.html 38 | 39 | The filter is rather slow, and it adds significantly to file 40 | size, but the resulting HTML renders quickly and does not depend 41 | on an internet connection or JavaScript. 42 | 43 | Thanks to Kolen Cheung for the suggestion. 44 | 45 | -------------------------------------------------------------------------------- /math-samples.md: -------------------------------------------------------------------------------- 1 | Inline math 2 | ----------- 3 | 4 | The area of a circle with radius $r$ is $\pi r^2$. 5 | The volume of a cube with radius $r$ is $\frac{4}{3} \pi r^3$. 6 | 7 | The Lorenz Equations 8 | -------------------- 9 | 10 | $$ 11 | \begin{aligned} \dot{x} & = \sigma(y-x) \\ \dot{y} & = \rho x - y 12 | - xz \\ \dot{z} & = -\beta z + xy \end{aligned} 13 | $$ 14 | 15 | 16 | The Cauchy-Schwarz Inequality 17 | ----------------------------- 18 | 19 | $$ 20 | \left( \sum_{k=1}^n a_k b_k \right)^{\!\!2} \leq 21 | \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n 22 | b_k^2 \right) 23 | $$ 24 | 25 | A Cross Product Formula 26 | ----------------------- 27 | 28 | $$ 29 | \mathbf{V}_1 \times \mathbf{V}_2 = \begin{vmatrix} 30 | \mathbf{i} & \mathbf{j} & \mathbf{k} \\ \frac{\partial 31 | X}{\partial u} & \frac{\partial Y}{\partial u} & 0 \\ 32 | \frac{\partial X}{\partial v} & \frac{\partial Y}{\partial v} & 33 | 0 \\ \end{vmatrix} 34 | $$ 35 | 36 | The probability of getting \(k\) heads when flipping \(n\) coins is: 37 | ------------------------------------------------------------------------ 38 | $$ 39 | P(E) = {n \choose k} p^k (1-p)^{ n-k} 40 | $$ 41 | 42 | An Identity of Ramanujan 43 | ------------------------ 44 | $$ 45 | \frac{1}{(\sqrt{\phi \sqrt{5}}-\phi) e^{\frac25 \pi}} = 46 | 1+\frac{e^{-2\pi}} {1+\frac{e^{-4\pi}} {1+\frac{e^{-6\pi}} 47 | {1+\frac{e^{-8\pi}} {1+\ldots} } } } 48 | $$ 49 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright John MacFarlane (c) 2016 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above 11 | copyright notice, this list of conditions and the following 12 | disclaimer in the documentation and/or other materials provided 13 | with the distribution. 14 | 15 | * Neither the name of Author name here nor the names of other 16 | contributors may be used to endorse or promote products derived 17 | from this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /pandoc-tex2svg.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE ScopedTypeVariables #-} 2 | 3 | module Main where 4 | import Text.Pandoc.JSON 5 | import Control.Monad (when) 6 | import System.Exit 7 | import System.Process 8 | import Data.IORef 9 | import qualified Data.Map as M 10 | import System.Directory (findExecutable) 11 | import System.IO (stderr, hPutStrLn) 12 | 13 | newtype Cache = Cache (M.Map (MathType, String) String) 14 | 15 | lookupCache :: (MathType, String) -> Cache -> Maybe String 16 | lookupCache s (Cache c) = M.lookup s c 17 | 18 | addToCache :: (MathType, String) -> String -> Cache -> Cache 19 | addToCache s v (Cache c) = Cache $ M.insert s v c 20 | 21 | main :: IO () 22 | main = do 23 | cache <- newIORef (Cache M.empty) 24 | toJSONFilter (tex2svg cache) 25 | 26 | tex2svg :: IORef Cache -> Inline -> IO Inline 27 | tex2svg cr (Math mt math) = do 28 | mbfp <- findExecutable "tex2svg" 29 | when (mbfp == Nothing) $ do 30 | hPutStrLn stderr $ "The tex2svg program was not found in the path.\n" ++ 31 | "Install MathJax-node (https://github.com/mathjax/MathJax-node)\n" ++ 32 | "and ensure that tex2svg is in your path." 33 | exitWith $ ExitFailure 1 34 | cache <- readIORef cr 35 | svg <- case lookupCache (mt, math) cache of 36 | Just s -> return s 37 | Nothing -> do 38 | svg' <- readProcess "tex2svg" 39 | (["--inline" | mt == InlineMath] ++ [math]) "" 40 | modifyIORef cr (addToCache (mt, math) svg') 41 | return svg' 42 | if null svg -- indicates an error -- tex2svg doesn't return error status 43 | then do 44 | hPutStrLn stderr $ "Could not convert: " ++ math 45 | return $ Math mt math 46 | else return $ RawInline (Format "html") $ 47 | "" ++ 49 | svg ++ "" 50 | tex2svg _ il = return il 51 | 52 | -------------------------------------------------------------------------------- /math-samples.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 |The area of a circle with radius 23 | is 37 | . The volume of a cube with radius 45 | is 65 | .
66 |131 |
132 |211 |
212 |324 |
325 |373 |
374 |503 |
504 | 505 | 506 | --------------------------------------------------------------------------------