HaTeX User's Guide
Preface
Introduction
If you are here because you want to learn more about HaTeX, or just feel curious, you are in the right place. First of all, note that this guide is addressed to that people that already knows the basics of both Haskell and LaTeX. Otherwise, try to learn first a bit of these languages (both are quite useful learnings). To learn Haskell, though I guess you already learned it since you are reading these lines, go to the Haskell web [1] and search for some tutorials or books. To learn LaTeX, you can start withThe not so short introduction to LaTeX [2].
The HaTeX library aspires to be the tool that Haskellers could want to make theirLaTeX things without exit of their language (we understand that is difficult to leave Haskell after the first date), trying to be the most comprehensive and well done as possible. Do you think, anyway, that something could be done better? Perhaps something is lacked? Go then to the HaTeX mailing list [3] and leave your complain without mercy! Or, in the case you are a GitHub user, say your word in the issue list [4] or, to be awesome, make yourself a patch and send a pull request. This is the great thing about open source projects!
What is HaTeX?
Before we explain how HaTeX works, it is convenient to say what actually HaTeX is.
HaTeX is a Haskell library that provides functions to create, manipulate and parse LaTeX code.
People often says that HaTeX is a LaTeX DSL. With it you can enjoy all the advantages you already have in Haskell while creating LaTeX documents. A common purpose is to automatize the creation of such documents, perhaps from a source data in Haskell. A more exotic one is to render chess tables. Possibilities are in a wide range. The idea is the following: if you can do it with LaTeX, you can do it with HaTeX, but adding all the Haskell features.
Basics
Through this section you will learn the basics of HaTeX. Essentially, how it works.
The Monoid class
If you are already familiar with the Monoid
class, jump to the next point. The Monoid
class is something that you must get used to in Haskell. But don't worry, it is quite simple (in spite of the similarity in the name with the Monad
class). A monoid in Mathematics is an algebraic structure consisting of a set of objects with an operation between them, being this operation associative and with a neutral element. Phew! But what is the meaning of this? By associative we mean that, if you have three elements, and , then . A neutral element is the one that does not worth to operate with, because it does nothing! To say, is a neutral element if , given any object . As an example, you may take the real numbers as objects and the ordinary multiplication as operation.
Now that you know the math basics behind the
Monoid
class, let's see its definition:class Monoid m where
mempty :: m
mappend :: m -> m -> m
mconcat :: [m] -> m
mappend
corresponds to the monoid operation and mempty
to its neutral element. The names of the methods may seem insuitable, but they correspond to an example of monoid: the lists with the appending (++)
operation. Who is the neutral element here? The empty list:xs ++ [] = [] ++ xs = xs
LaTeX blocks
Suppose we have a well-formed1 piece of LaTeX code, call it . Now, let LaTeX
be a Haskell type in which each element represents a well-formed piece of LaTeX code. Then, can be seen as a Haskell expression a
of type LaTeX
. We can say that a
is a LaTeX
block. What happens if we append, by juxtaposition, two LaTeX
blocks? As both are well-formed, so is the result. Thus, two blocks appended form another block. This way, we can define an operation over the LaTeX
blocks. If we consider that a totally empty code is a well-formed piece of LaTeX code, we can speak about the empty block. And, as the reader may notice, these blocks with its appending form a monoid. Namely, LaTeX
can be done an instance of the Monoid
class.
Of course, our mission using HaTeX is to create a LaTeX
block that fits our purpose. The way to achieve this is to create a multitude of LaTeX
blocks and, then, use the Monoid
operation to collapse them all in a single block.
Creating blocks
We have now an universe of blocks forming a monoid. What we need now is a way to create these blocks. As we said, a block is the representation of a well-formed piece of LaTeX code. Let a
be the block of the LaTeX expression \delta{}
2. Since this is a constant expression, it has a constant value in Haskell, named delta
. Calling this value will generate the desired block.
\linespread{x}
, where x
is a number. How we deal with this? As you expect, with functions. We can create blocks that depend on values with functions that take these values as arguments, where these arguments can be blocks as well. For instance, we have the function linespread
with type:linespread :: Float -> LaTeX
title
is:title :: LaTeX -> LaTeX
From strings
Inserting text in a LaTeX document is a constant task. You can create a block with text given an arbitraryString
with the fromString
function, method of the IsString
class:class IsString a where
fromString :: String -> a
\
is replaced with the \backslash{}
command.
The function that avoids reserved characteres is exported with the name protectString
. Also, there is a variant for Text
values called protectText
.
The use of the IsString
class is because the Overloaded Strings extension. This one is similar to the Overloaded Numbers Haskell feature, which translates the number4
to fromInteger 4
. In a similar way, with OverloadedStrings
enabled, the string"foo"
is translated to fromString "foo"
. If we now apply this to our blocks, the string "foo"
will be automatically translated to a LaTeX block with foo as content. Quite handy! We will assume the OverloadedStrings
extension enabled from now.
More blocks
There is a lot of functions for create blocks. In fact, we can say that this is the main purpose of the library. LaTeX has a lot of commands, in order to set font attributes, create tables, insert graphics, include mathematical symbols, ... So HaTeX have a function for each command defined in LaTeX (to tell the truth, only for a small subset). Please, go to the API documentation to read about particular functions.
Putting blocks together
Once you have the blocks, as we said before, you need to append them. Themappend
method of the Monoid
class does this work. If a
and b
are two blocks,mappend a b
, or a `mappend` b
, or even a <> b
3, is the block witha
and b
juxtaposed. For long lists of blocks, you can try it with mconcat
as follows:mconcat [ "I can see a " , textbf "rainbow"
, " in the blue " , textit "sky" , "." ]
Rendering
This is the last step in our LaTeX document creation. When we have our finalLaTeX block a
, the function renderFile
can output it into a file, in the form of its correspondent LaTeX code.
short =
documentclass [] article
<> title "A short message"
<> author "John Short"
<> document (maketitle <> "This is all.")
renderFile "short.tex" short
it appears the following file in the current working directory (line formatting added for easier visualization):\documentclass{article}
\title{A short message}
\author{John Short}
\begin{document}
\maketitle{}
This is all
\end{document}
renderFile
is not only for LaTeX
values. Let's see its type:renderFile :: Render a => FilePath -> a -> IO ()
Render
class that appears in the context is defined:class Render a where
render :: a -> Text
Text
value. The type LaTeX
is an instance, but other types, like Int
or Float
, so are too. These instances are useful for creating blocks from other values. With the functionrendertex
, any value in the Render
class can be transformed to a block. First, the value is converted to Text
, and then to LaTeX
the same way we did with strings. But, be careful! Because rendertex
does not escape reserved characters.
Try yourself
As always, the best way to learn something well is to try it by yourself. Since to see code examples can give you a great help, HaTeX comes with several examples where you can see by yourself how to get the work done.
The API reference is also a good point to keep in mind. Descriptions of functions make you know how exactly they works. And, when they are not present, function names with type signatures may be a very helpful and descriptive.
Footnotes
1: With well-formed we mean that all braces, environments, math expressions, ... are closed.
2: Please, note that the LaTeX
block is not the same that the LaTeX expression. The former
is a Haskell value, not the LaTeX code itself.
3: From GHC 7.4, (<>)
is defined as a synonym for mappend
. For previous
versions of GHC, HaTeX exports the synonym.