latex-formulae
latex-formulae copied to clipboard
Libraries and tools for rendering math to images using real LaTeX, from Haskell, Pandoc and Hakyll
[[https://travis-ci.org/liamoc/latex-formulae][file:https://travis-ci.org/liamoc/latex-formulae.svg]] [[http://haskell.org][file:https://img.shields.io/badge/language-Haskell-blue.svg]] [[https://github.com/liamoc/latex-formulae/blob/master/LICENSE][file:http://img.shields.io/badge/license-BSD3-brightgreen.svg]]
- LaTeX Formulae
This is a suite of tools and libraries to make rendering LaTeX equations to images easy from Haskell and Pandoc. For an example of what they're capable of, take a look at [[http://liamoc.net/posts/2013-11-13-imperativereasoning.html][articles on my blog]].
It contains three parts,
- ~latex-formulae-image~ [[http://hackage.haskell.org/package/latex-formulae-image][file:https://img.shields.io/hackage/v/latex-formulae-image.svg]] - A library which uses LaTeX, ~dvips~ and ImageMagick to convert a latex formula into an image, and does baseline detection so that the image can be positioned correctly when inline with other text.
- ~latex-formulae-pandoc~ [[http://hackage.haskell.org/package/latex-formulae-pandoc][file:https://img.shields.io/hackage/v/latex-formulae-pandoc.svg]] - Provides some functions on ~Pandoc~ documents that renders embedded math to images intended for HTML output. These functions can be easily used to create small pandoc filter programs that can be run with ~pandoc~ as a standalone application. An example executable is provided with the library. The library is capable of storing the images in separate files or embedding them inside the page with data URIs.
- ~latex-formulae-hakyll~ [[http://hackage.haskell.org/package/latex-formulae-hakyll][file:https://img.shields.io/hackage/v/latex-formulae-hakyll.svg]] - Provides simple compilers that can be integrated with Hakyll, to render all equations in Pandoc-compiled pages inside Hakyll websites. Includes a simple LRU cache so that the ~watch~ server only recompiles changed equations.
These libraries also give you precise control over the output DPI and over the dimensions of the image in the HTML output, so it can be configured to give crisp images even on high DPI displays, like Retina displays.
Because they use just regular LaTeX, any of the packages available to your system LaTeX installation are also available in these formulae. Just add the necessary ~usepackage~ invocations to the preamble inside your ~FormulaOptions~ value.
** Requirements
You must have a LaTeX installation available, which includes ~latex~ and ~dvips~. ImageMagick's ~convert~ is also required, and must be able to understand PostScript (for example, using ~gs~). Most recent binary distributions of LaTeX and ImageMagick satisfy these dependencies.
** Building/Installing
If you're using ~stack~, it should just be a matter of ~stack build~, and ~stack install~ if you want to use the example pandoc filter, ~latex-formulae-filter~.
Users of ~cabal~ will have to build each package using the usual ~cabal~ ceremony:
#+BEGIN_SRC sh cabal update cabal configure cabal build cabal install #+END_SRC
** Using
As always, see the Haddocks for more thorough details. Here are some simple example usages.
*** As a library
**** ~latex-formulae-image~
The ~latex-formulae-image~ package really only has one major function, ~imageForFormula~. You can use it like so:
#+BEGIN_SRC haskell import Image.LaTeX.Render (imageForFormula, defaultEnv, displaymath) import Codec.Picture (writeDynamicPng) -- JuicyPixels
main = do x <- imageforFormula defaultEnv displaymath "y = mx + b" case x of Left e -> return () Right (baseline, img) -> do _ <- writeDynamicPng "image.png" img return () #+END_SRC
Settings such as where to find LaTeX etc. can be set by altering the ~EnvironmentOptions~ value, in this case we just use ~defaultEnv~ defaults. Settings such as the LaTeX environment to use, the preamble, and the DPI can be set in the ~FormulaOptions~ value, in this case we use the ~displaymath~ defaults.
**** ~latex-formulae-pandoc~
If you want to integrate with ~pandoc~ programmatically, you can use the ~latex-formulae-pandoc~ package. This package includes functions that allow you to transform ~pandoc~ documents. If you're happy to embed the images directly inside the HTML, then ~convertAllFormulaeDataURI~ is easiest:
#+BEGIN_SRC haskell imagesForFormulae :: Pandoc -> IO Pandoc imagesForFormulae doc = convertAllFormulaeDataURI defaultEnv defaultPandocFormulaOptions doc #+END_SRC
The above example function can be inserted between any ~Pandoc~ reader and an HTML writer, producing embedded images inside the HTML output using data URIs.
If you would rather they be stored as separate PNG images in a directory called ~static~, ~convertAllFormulaeFiles~ can be used:
#+BEGIN_SRC haskell imagesForFormulae :: Pandoc -> IO Pandoc imagesForFormulae doc = do ns <- newNameSupply convertAllFormulaeFiles ns "static" defaultEnv defaultPandocFormulaOptions doc #+END_SRC
There are also more general versions of the ~convertFormula*~ functions, named convertFormula*With
, which allow the
actual function that does the rendering of formulae to be altered. This is so that you can insert image caching or
other image postprocessing into the renderer.
**** ~latex-formulae-hakyll~
Currently only Data URI embedding is supported for Hakyll, but using it should be as simple as the following minimal example:
#+BEGIN_SRC haskell main = do renderFormulae <- initFormulaCompilerDataURI 1000 defaultEnv hakyll $ match "posts/*.markdown" $ do route $ setExtension "html" compile $ pandocCompilerWithTransformM defaultHakyllReaderOptions defaultHakyllWriterOptions $ renderFormulae defaultPandocFormulaOptions #+END_SRC
If for whatever reason you don't want to have formula caching for @watch@ servers, you can just use this simpler form:
#+BEGIN_SRC haskell main = hakyll $ match "posts/*.markdown" $ do route $ setExtension "html" compile $ pandocCompilerWithTransformM defaultHakyllReaderOptions defaultHakyllWriterOptions $ compileFormulaeDataURI defaultEnv defaultPandocFormulaOptions #+END_SRC
*** As a pandoc filter
The ~latex-formulae-pandoc~ library comes with a simple example filter executable, called ~latex-formulae-filter~. If you ~stack install~ or ~cabal install~ it to your ~$PATH~, you can use it with ~pandoc~ like so:
#+BEGIN_SRC sh pandoc -s --filter=latex-formulae-filter -o output.html input.html #+END_SRC sh
The source code for this program is very simple:
#+BEGIN_SRC haskell import Image.LaTeX.Render.Pandoc import Image.LaTeX.Render import Text.Pandoc.JSON
main :: IO () main = toJSONFilter $ convertFormulaDataURI defaultEnv defaultPandocFormulaOptions #+END_SRC haskell
This filter embeds the images with data URIs. To use files, follow the same routine as above:
#+BEGIN_SRC haskell import Image.LaTeX.Render.Pandoc import Image.LaTeX.Render import Text.Pandoc.JSON
main :: IO () main = do ns <- newNameSupply toJSONFilter $ convertFormulaFiles ns "static" defaultEnv defaultPandocFormulaOptions #+END_SRC haskell
Adjust the various options by altering the ~defaultPandocFormulaOptions~ and ~defaultEnv~ terms in this program, as described in the Haddock documentation.
** Example/Demo
Writing the following markdown:
#+BEGIN_SRC markdown Lines (that is, $f(x) = mx + b$) are of degree 1, whereas quadratics (that is, $f(x) = ax^2 + bx + c$) are of degree 2. Solve quadratics with the quadratic formula:
$$x=\frac{-b\pm\sqrt{b^2-4ac}}{2a}$$
Enough high school algebra for now! #+END_SRC
Leads to [[https://htmlpreview.github.io/?https://github.com/liamoc/latex-formulae/blob/master/example.html][this output]]! Pretty nifty :)
** Future work
I would like to add files support for Hakyll websites, but it's not clear how this would interact with Hakyll's compiler system.