Skip to content

Libraries and tools for rendering math to images using real LaTeX, from Haskell, Pandoc and Hakyll

License

Notifications You must be signed in to change notification settings

liamoc/latex-formulae

Repository files navigation

https://travis-ci.org/liamoc/latex-formulae.svg https://img.shields.io/badge/language-Haskell-blue.svg 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 articles on my blog.

It contains three parts,

  • latex-formulae-image 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 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 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:

cabal update
cabal configure
cabal build
cabal install

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:

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 ()

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:

imagesForFormulae :: Pandoc -> IO Pandoc
imagesForFormulae doc = convertAllFormulaeDataURI defaultEnv defaultPandocFormulaOptions doc

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:

imagesForFormulae :: Pandoc -> IO Pandoc
imagesForFormulae doc = do ns <- newNameSupply 
                           convertAllFormulaeFiles ns "static" defaultEnv defaultPandocFormulaOptions doc

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:

main = do
   renderFormulae <- initFormulaCompilerDataURI 1000 defaultEnv
   hakyll $
     match "posts/*.markdown" $ do
       route $ setExtension "html"
       compile $ pandocCompilerWithTransformM defaultHakyllReaderOptions defaultHakyllWriterOptions
               $ renderFormulae defaultPandocFormulaOptions

If for whatever reason you don’t want to have formula caching for @watch@ servers, you can just use this simpler form:

main =
   hakyll $
     match "posts/*.markdown" $ do
       route $ setExtension "html"
       compile $ pandocCompilerWithTransformM defaultHakyllReaderOptions defaultHakyllWriterOptions
               $ compileFormulaeDataURI defaultEnv defaultPandocFormulaOptions

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:

pandoc -s --filter=latex-formulae-filter -o output.html input.html

The source code for this program is very simple:

import Image.LaTeX.Render.Pandoc
import Image.LaTeX.Render
import Text.Pandoc.JSON

main :: IO ()
main = toJSONFilter $ convertFormulaDataURI defaultEnv defaultPandocFormulaOptions

This filter embeds the images with data URIs. To use files, follow the same routine as above:

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

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:

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!

Leads to 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.

About

Libraries and tools for rendering math to images using real LaTeX, from Haskell, Pandoc and Hakyll

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published