Showing posts with label HaTeX. Show all posts
Showing posts with label HaTeX. Show all posts

Friday, May 16, 2014

HaTeX-3.13: A summary of the latest developments

This week I have been coding for HaTeX, the LaTeX library of Haskell. If this is the first time you read about this library, take a look at it in Hackage or in GitHub.

I have closed really old tickets and made some important changes, and now I will let the library have a more stable time to check if these changes are worth in the long run. I think all these changes are positive, but I have to apologize for releasing two major versions in a single week. I don't want to give my users headaches, but I also want to provide them with a better library if that's in my hands.

Property Tests (QuickCheck)

The first thing I want to mention is the addition of a test suite to HaTeX. It is rather small currently, but it is already giving us benefits. The greatest impact has been in the parser, when the following property has been added:

fmap render (parseLaTeX t) == Right t

Here t :: Text is a randomly generated syntactically correct LaTeX code. It is important to note that this property gives us two facts:

  • Given a valid LaTeX input, parseLaTeX returns a value of type LaTeX.
  • If the parsed value is again rendered, you get the initial input.

In other words, parseLaTeX is a partial function (if we consider Left values as errors) that is defined if and only if the input is a valid LaTeX file, and render is its left inverse. These are some properties that I would expect from parseLaTeX in order to do a reasonable job. The good thing is that now they are automatically checked and, thanks to that, I have discovered many small bugs I never noticed before (thanks QuickCheck!).

I want to say as well that having HaTeX added to Stackage is giving us good benefits. I have been quickly prompted when HaTeX did not build with the last version of transformers, or when a test suite was failing. Thank you Michael for your great work!

Removal of TeXOp constructor

The LaTeX type has now one constructor less: TeXOp. This has simplified a little bit some other functions, mostly reducing code in case-by-case pattern matching. The reason to remove such constructor is that is was not providing anything that others constructors could not. Therefore, it didn't have much sense to have it there in the first place.

Pretty-Printer

Some users have written me complaining that the output of the render function applied to LaTeX values is unreadable and hard to debug. It contains big lines of agglomerated code, making hard to distinguish - for example - where an environment starts and where it ends. This is on purpose. HaTeX won't add any line break that the user does not specify explicitly. If it were done that way it would, for instance, make a paragraph break where it should not be one. And worse, the user won't have any workaround to solve it. However, it is reasonable to ask for a prettier output. This is what the new Pretty module addresses. It has not been widely used yet, so it can probably be improved.

The LaTeXC instance for LaTeXT

Back when the LaTeXC class was implemented, we needed to get values of type LaTeXT m a from LaTeX values for any type a, and the only value inhabiting every type is bottom, so we used that one. This has been done this way until now. HaTeX has been following an use-as-few-extensions-as-you-can policy, meaning that we stick with Haskell2010 as much as we can. But, since there was interest, I have added the TypeFamilies extension. The current LaTeXC instance has a ~ () in its context. This is also true for the IsString and Monoid instances, and for the numerical classes. Being honest, I still have to check what are the consequences of this, but I think time will tell us. At the moment, this change has simplified significantly the code of the Base.Writer module.

Back to parsec

The first LaTeX parser was written in parsec, but was later rewritten by Tobias Schoofs using attoparsec. Since the new parser was better - in the sense that was closer to have the properties listed in the first section of this post - I accepted the patch gladly and we have been using it with some variations (some of them important) until today. With time, it became clear that the uninformative parsing error messages of attoparsec were unacceptable for this case, where many input files were written by hand or fixed manually, and most of them small enough to not be worth to have a faster parser. This is why today I decide to dedicate my evening to port the parser back to parsec, and so I did. A combination of the type checker and QuickCheck have made the work very amusing.

Closure

If you are interested in a more detailed list of changes, it's probably worth a look at the commit list. If you think something in HaTeX has to be improved or fixed, do not hesitate in filling a ticket at the issue tracker. Thank you for reading to this point.

Happy hacking,
Daniel Díaz.

Monday, November 4, 2013

haskintex: Haskell within LaTeX

I am here today to announce my new package: haskintex. Actually, the package has been around in Hackage for some time now, but I didn't want to announce it. Although everything was ready for this release some days (weeks?) ago, I have been waiting for the Hackage server to update its Cabal version (see #85@hackage-server) to the 1.18 branch. This is because haskintex depends on HaTeX >= 3.9, and the new 3.9.0.0 version was failing to upload to Hackage due to an undefined cabal field (extra-doc-files) warning. This field was defined for the 1.18 version of Cabal and quickly used by HaTeX. HaTeX still builds with previous versions of Cabal, the only difference is that images in the documentation do not appear.

What is haskintex

haskintex is a tool that processes files, usually files that follow the LaTeX syntax. Although it has been programmed with LaTeX in mind, it was later clear that it can be used with other formats as well (with some restrictions). The purpose of haskintex is to include Haskell code within LaTeX files, and evaluate it or display it as desired. Therefore, it is similar in purpose to lhs2tex, but with a different approach. The input file is usually a .htex file, which is a LaTeX file plus some commands and environments like \evalhaskell{2+3}. haskintex would process these declarations running GHC on their argument and substituting the result in the output file. Something like \verb`5`. You can add things to the scope within a \begin{writehaskell}...\end{writehaskell} environment.

Calling HaTeX functions

However, the most interesting way to use Haskell within LaTeX is in combination with HaTeX. HaTeX is library that implements the LaTeX syntax in Haskell. Inside the \hatex{...} command, you can put any Haskell expressions of type LaTeX. When processed by haskintex, it will be type checked, evaluated and rendered as LaTeX code. This brings all the benefits from HaTeX without the need to write all the boilerplate HaTeX code for things that plain LaTeX would do just fine. For example, suppose you want to draw a logarithmic spiral. The code below will do the job for you.

\documentclass{article}
\usepackage{tikz}
\usepackage[utf8]{inputenc}
\author{Daniel Díaz}
\title{Embedding HaTeX in \emph{haskintex}}
\begin{document}
\maketitle
Below is the \emph{Spira Mirabilis} inserted using the HaTeX
package.
\begin{writehaskell}
import Text.LaTeX
import Text.LaTeX.Packages.TikZ.Simple

spiral :: Figure
spiral = LineWidth (Pt 2) $
    pathImage 0.01 (0,4) $
      \t -> ( a * exp t * cos (b*t)
            , a * exp t * sin (b*t)
              )
  where
    a = 0.1 ; b = 4
\end{writehaskell}
\hatex{center $ tikzpicture $ figuretikz spiral}
\end{document}

See the documentation of the TikZ.Simple module of HaTeX to understand the functions used above. You may want to use different HaTeX modules for other tasks.

More info about haskintex and its usage at the homepage of the project.

Thanks for reading,
Daniel Díaz.

Tuesday, June 25, 2013

HaTeX 3.6: Texy class, Babel, Fontenc, TikZ and more

It has been a long time since the last release of HaTeX. However, the development of the Haskell LaTeX library has not stopped in all this time. In fact, this release comes full of new features and bug fixes. Below a short description of the changes.

Bug fixes

Let's start having a look to the bugs that have been fixed in HaTeX 3.6:

  • The family of autoBraces functions has been fixed. It didn't create correct code (credits to leftaroundabout).
  • The verbatim function now expects a Text value instead of LaTeX code (credits to leftaroundabout).
  • Size modifiers functions are now protected adequately (reported by jvilar).
  • Fixed Color Render instance.

Some of these bugs may have been annoying some people for a long time now. My apologies to this people for the late release.

Texy class

A new class has been defined. Its name: Texy. The definition is as follows:

class Texy t where
  texy :: LaTeXC l => t -> l

This class provides a function to render different types to a LaTeX value. Basically, it defines a pretty-printer which output is LaTeX code. Useful to render vectors, matrices or trees. More details are given in the proposal of this feature.

Babel

Babel is a well-known LaTeX package useful to deal with documents written in languages other than US English. It is a basic feature but it has not been added until now. The module exports a Language type and some functions that use values of this type. See the Text.LaTeX.Packages.Babel module.

Fontenc

A short package to select the desired font encoding of your document. Pretty basic feature now available in HaTeX.

TikZ

Doubtless, the most exciting new feature of this release. TikZ is a frontend for PGF (Portable Graphics Format), a package for creating graphics using scripts embedded in a LaTeX document. Using the TikZ package, writing some simple scripts gives you high quality results. The HaTeX TikZ module exports an interface to create this scripts and embed them in the rest of the HaTeX code, so you can program the graphics that appears in the LaTeX document from Haskell. Two layers of abstraction are provided. First, the module Text.LaTeX.Packages.TikZ exports an interface closer to the original TikZ. With this interface, you have to create paths and then use them to draw, fill, clip, etc. In addition, a PathBuilder monad is provided to create these paths. The alternative interface is much more attractive. Figures are created in a similar way to gloss. A simple, recursive and intuitive datatype describes how the figure looks like. Then, applying a certain function to the figure will generate the TikZ script, that you can insert in the HaTeX code right away. An example is worth a thousand words.

Definition of the figure.

myFigure :: Figure
myFigure = Scale 2 $ Figures
  [ RectangleFilled (0,0) 1 1
  , Colored Green $ RectangleFilled (-1,1) 1 1
  , Colored Red   $ RectangleFilled ( 0,2) 1 1
  , Colored Blue  $ RectangleFilled ( 1,1) 1 1
    ]

Output image.

Learn more about this in the Text.LaTeX.Packages.TikZ.Simple module.

Ending

I will probably be extending the documentation and testing different things. There are a lot of improvements to do in TikZ yet, but I thought that it is a good moment for a release. And, certainly, those suffering from the bugs described above will be thankful. Unfortunately, the HaTeX User's Guide keeps getting outdated.

Wednesday, April 17, 2013

HaTeX 3.6: Proposal for Texy class

Description

This is a proposal for a new feature I would like to see (and implement) in HaTeX for its next version. It consists in a new type class, with tentative name Texy (tex-like or tex-ify shortened). Other names are to be proposed, if any other better is found. The class would contain every type whose values can be pretty-printed in LaTeX form. Therefore, the definition of the class would be as follows:

class Texy t where
  texy :: LaTeXC l => t -> l

We can also make Texy a subclass of Render, so we can have a default implementation using rendertex.

class Render t => Texy t where
  texy :: LaTeXC l => t -> l
  -- Default implementation
  texy = rendertex

But I am not sure if this is suitable. The purpose of Texy is to build, from Haskell values, more complex LaTeX expressions than just rendering to Text, which, in the other hand, it is no more than a Show instance after all. It may work with numbers but not with more complex values like fractions or matrices.

Applications

A first application could be Rational pretty-printing as fractions using the frac function. However, we also have a problem here: the constructor % for rational numbers is already in use in our library. Perhaps we should rename the comment operator to %:? I have not seen an extensive use of this operator yet.

We would also be able to create LaTeX values for tuples, resizing the parenthesis in the tuple appropriately using autoParens.

Another application, perhaps more sofisticated, is pretty-printing matrices. Since the elements of the matrix would be a Texy instance as well, we can use texy to pretty-print to LaTeX matrices which may contain fractions or any other user-supplied value. This is an interface much more flexible than the current one (using a plain Render instance for the elements).

When rendering trees (see Text.LaTeX.Packages.Trees.Qtree), we are already using a LaTeXC l => (a -> l) parameter in order to pretty-print the elements of the tree. This is a more free version of the Texy class, which allow the user to supply different ways to generate LaTeX values from a single type. However, this is not a point against the current proposal, since this functionality can be kept as it is and added wherever is needed.

I honestly think this would be a good improvement.

Tuesday, March 19, 2013

HaTeX 3.5

It's time for a new release of HaTeX!

The following changes have been made since the last release:

  • Fixed some minor bugs.
  • Remake of the parser, now using attoparsec instead of parsec. Also more correct and tested. Thanks to Tobias Schoofs for his contributions.
  • Extension of the AMSMath module. Thanks to leftaroundabout for his contributions.
  • Applicative instance for LaTeXT.
  • New functions for rendering matrices. This includes a new dependency in the matrix package.
  • And some other minor changes.

A complete list of changes can be found at the commit history. The new version is up in Hackage so update yours!

Sunday, March 17, 2013

Writing a new library: Wavy

I have two proposals for this Spring Break.
  • Release the version 3.5 of HaTeX.
  • End up the first layer of my new library: Wavy.

HaTeX 3.5

HaTeX has been in stand-by for a while now and I want to upload a version of HaTeX that at least contains the changes I have made so far. Hopefully, I will add some new features. I am thinking about a matrix writer, since is a pain to write matrices right now. If you take a look to the last changes on github, better support for math typesetting has been added thanks to leftaroundabout. He is (or has been) also writing an extension for HaTeX to make math typesetting more sophisticated. Also, toschoo has improved the parser and now it uses attoparsec. These are good news for HaTeX.

Wavy

In the other hand, I am writing a new library. Its name is Wavy. It is a super kool library that read, writes and manipulates sounds very nicely. Yes, I know, lot of libraries have been written doing exactly the same. Exactly the same? Well, I think they are all different in some sense, and this is just another new approach. If it is going to be a better or worse approach is something I don't care, as long as is useful to somebody. And I already find it useful for myself! Although, of course, it would be great if somebody else find it interesting, so I will do my best to make of Wavy a nice library. To begin with, I started writing a user manual. I think is looking pretty good, but that is something that Haskell users should decide in my place. As an extension, I wrote a library that writes sound waves in PDFs. So yes, I am having a lot of fun! And it's everything written in Haskell!

I hope to have something more mature to show after the Spring Break, but I think is moment to start sharing this thoughts with the community. Below is a code example that shows Wavy in action writing a sine wave in a .wav file.

import Data.Sound
import Data.Sound.WAVE

main :: IO ()
main = encodeFile "sine.wav" $ fromSound 16 s
 where
  s = sine 5 1 100 0

Monday, April 30, 2012

HaTeX 3.3: Release notes

I was really really wishing this release! I put a lot of efforts on it and now I feel pretty good! All right, let's see quickly what's new. A list of changes is contained in the package source distribution, in the ReleaseNotes file.

Class system

Where are all those .Monad modules? They are missing!

Yes, yes. There is not .Monad modules now! Instead, there is a new class: LaTeXC. Both LaTeX and LaTeXT are instances of it, so a single module can contain both interfaces. More details in a previous post.

Trees

I have a tree in Haskell and I want to print it nicely. What can I do?

Now you can use HaTeX! How? Simple. Use directly the tree type defined in HaTeX or transform the one you have to it, choose a function to render the nodes and, finally, use the tree function to obtain the LaTeX code that prints the tree.

The HaTeX User's Guide

Finally I wrote a guide for HaTeX! At least, a stub of the guide.  And I made it open source! So you can contribute also to the guide!

I will change it, extend it and improve it all the time. A ready-to-read PDF version is also available.

Till the next time

I am going to continue working improving the library and the guide. I think HaTeX has reached a point of more stability. Good news, I guess. Now, I hope you enjoy these changes. I will write here any news.

Good luck,
Daniel Díaz.

Saturday, April 28, 2012

HaTeX 3.3: HaTeX with class

So I finally decided to merge the normal (what sometimes I called applicative) interface with the monadic one. It was not easy to me, but I feel like doing the right thing. I thought: "If I would release this library for the first time, how you would like it to be?" The answer then was "merge both interfaces!".

As a consequence of this decision, I have to admit that my work as maintainer has been reduced considerably. Now HaTeX-meta is deprecated, until HaTeX needs a similar tool, and I have about the half of modules to maintain.

Although the version has been bumped to 3.3 (being a major revision), everything code that worked until today must to work now. The only change you may need to do is to drop de .Monad in the import list. If you have some issue, please, make me know it.

I hope all you feel happy with this.

About the implementation

All I did is to define the following class:

class (Monoid l,IsString l) => LaTeXC l where
 liftListL :: ([LaTeX] -> LaTeX) -> [l] -> l

It allows to lift any function over LaTeX to a function over any type l of the class, as follows:

fromLaTeX :: LaTeXC l => LaTeX -> l
fromLaTeX l = liftListL (\_ -> l) []

liftL :: LaTeXC l => (LaTeX -> LaTeX) -> l -> l
liftL f x = liftListL (\[x] -> f x) [x]

liftL2 :: LaTeXC l => (LaTeX -> LaTeX -> LaTeX) -> l -> l -> l
liftL2 f x y = liftListL (\[x,y] -> f x y) [x,y]

And you can continue with number of arguments of your desire. For N arguments:

liftLN :: LaTeXC l => (LaTeX -> ... -> LaTeX) -> l -> ... -> l
liftLN f x1 ... xN = liftListL (\[x1 ... xN] -> f x1 ... xN) [x1 ... xN]

Now we are ready to express all functions changing each LaTeX with a type l instance of LaTeXC. The idea is to separate LaTeX arguments and other arguments and apply a liftLN function in the following way:

foo :: LaTeXC l => l -> A -> B -> l -> C -> l
foo l1 a b l2 c = liftL2 (\l1 l2 -> old l1 a b l2 c) l1 l2
 where
  old :: LaTeX -> A -> B -> LaTeX -> C -> LaTeX

Here, the function old is the original definition of foo. There are plenty of examples in the library (all funcions are now defined this way). As a contributor you may want to see it.

Since LaTeX and LaTeXT are instances of LaTeXC, now all functions work at the same time for both types.

The User's Guide

I started to write the HaTeX User's Guide. I'm doing it open source. It contains an introduction and explain some basics of HaTeX. The source code repository lives here.

The release in Hackage will be done when the User's Guide becomes more complete.

Sunday, April 15, 2012

HaTeX: Trees and problems

Trees

Since a time ago, I wanted to add trees to HaTeX. Some way to, given a Haskell tree, create a LaTeX output according to it. So I created the datatype:

data Tree a =
   Leaf a
 | Node (Maybe a) [Tree a]

and started thinking about what LaTeX package I should to use in order to drawing trees. Since there are several good options, I decided to keep the Tree datatype in a separated module and write different implementations in different modules with similar interfaces. Then, I started with the qtree package and, in a few minutes, I had an example working. So I was happy for the moment.

The problem

But my happiness did not last long. The method used to transform a Haskell tree into a LaTeX value was to have a function that creates a LaTeX value from each node and, then, build the tree following the LaTeX tree syntax. So, the type of the function, called tree, was:

tree :: (a -> LaTeX) -> Tree a -> LaTeX

And this worked pretty well. The problem came out when I wanted to run metahatex in order to create the analogous monadic version. The modus operandi of metahatex is to read the type of the functions and infer from it their monadic implementation, re-using the original implementation. For example, if we have:

foo :: LaTeX -> a -> LaTeX

then, metahatex (importing the former qualified as App) do:

foo :: Monad m => LaTeXT_ m -> a -> LaTeXT_ m
foo lm a = do
 l <- extractLaTeX_ lm
 textell $ App.foo l a

where extractLaTeX_ gets the LaTeX value produced by the LaTeXT monad and textell puts LaTeX values again in the monad (like the tell method of the writer monad).

This method has worked perfectly until now. But, what happens if we try to apply it to the tree function? As we needed to transform a value of type LaTeX to another of type LaTeXT_ m for foo, we will need to do so from a a -> LaTeXT_ m typed value to a a -> LaTeX typed value. And that is impossible!

Searching a solution

I never liked the idea of write the monadic code manually, that would be write duplicated code. I went then to eat a pizza and think about it. Typeclasses came to my mind. When I returned to my computer, I started to search what minimal functions I need to render the tree. Then, I wrote a typeclass and made LaTeX and LaTeXT_ instances of it. See the definition of the resulting typeclass:

class (Monoid l, IsString l) => LaTeXTree l where
  texbraces :: l -> l
  texcomms :: String -> l
  totex :: Render a => a -> l

The first and second method are abstractions of the TeXBraces and TeXCommS type constructors! And the other is the abstraction of the rendertex function! Making LaTeX and LaTeXT instances of this typeclass allow us to construct a tree function valid to both types. But this is not the end. The same idea is applicable to the whole library, so normal and .Monad modules can be merged using a typeclass with abstractions of all LaTeX constructors!

Conclusion

Well, this idea had come to me a time ago, but I just realized today how useful it can be. And now, I feel a bit odd taking this approach only to trees. What should I do?

Monday, February 20, 2012

HaTeX: Chapter 3.2

It's time for a new release of HaTeX: the version 3.2, as announced in my previous post. I'm glad each time I see my library get better. Although the major version is increased again, I expect backwards compatibility, in spite of the changes done in some type signatures. I have tried to get previous code working.

Get HaTeX 3.2 from Hackage: http://hackage.haskell.org/package/HaTeX-3.2.

This is how HaTeX has changed this time.

The LaTeX Parser

It makes me happy to get working a parser of LaTeX. I have tested it with some examples (for instance, with the "fibs.hs" example, included in the library) with a reasonable output. Anyway, the parser is not mature yet. Future working on it will be done when a bugged output is found parsing some LaTeX code.

Greek alphabet

The AMSMath module is still very incomplete, but now it contains the entire greek alphabet.

The graphicx package

A new module with a new LaTeX package has been added. This time was for the graphicx package. The point here is to get all to be done with types, wherever possible. The way to achieve this is to define datatypes that will force you to put correct arguments to the functions. So the includegraphics function receives a [IGOption] and a FilePath as arguments, where each IGOption is a typed representation of each valid argument for includegraphics.

Changes in documentclass

Until now, documentclass function had type:

documentclass :: [LaTeX] -> String -> LaTeX

So if you want to set the font size to 12pt, you had to do:

documentclass [rendertex $ Pt 12]

or to do the trick:

documentclass ["12pt"]

which looks quite dirty.

Following my all-typed approach, I defined a new datatype (ClassOption) for documentclass arguments. This way, the former get done like this:

documentclass [FontSize $ Pt 12]

I find this more correct. Anyway, the second way still work, while the first one don't.

Other minor changes

Other minor changes have been done, like GHC 7.4 compatibility (thanks to Alexey Khudyakov) or addition of some new functions. To view a complete list see the commit history of the library.

Thursday, February 2, 2012

News about HaTeX

A lot of news about HaTeX have happened since the last time I wrote here about it. I want to sum up all of them now, with the 3.2 version release in mind.

HaTeX-3.1.0 and warnings

There was a release of the version 3.1.0 (along HaTeX-meta-1.1.0). It was announced in Haskell-Cafe [1].

The key novelty in this release is the incorporation of Warnings. Warnings are data generated from a LaTeX value checking. They give you information about your LaTeX value (e.g. if you skipped the document environment, or if you called to an undefined label). They are called "Warnings" instead of "Error" because they won't stop the execution.

Other new features are: Num instance for LaTeX and LaTeXT, an implementation of the LaTeX AMSThm package and a directory with examples (currently only one) shipped with the package.

HaTeX-3.2

The next release will be the 3.2 version.

The main new feature is a LaTeX code parser. This means you can read a file with LaTeX code and get its AST in Haskell! Although is still uncompleted and untested, I'm sure this feature will become HaTeX in a more complete library.

Before the release, I want to ask: what do you think this new version must to have?

HaTeX closer

In order to make easier collaboration of developers, I hosted the HaTeX code in GitHub [2]. And I already receiving contributions!

It also was very useful to place all together the code repository, an issue tracker and a wiki. So, if you are interested in HaTeX, feel free to contribute by any of the ways.

A mailing list [3] is also open to everybody, so we can discuss there about any topic related someway to HaTeX.

I also created a Twitter account for HaTeX-related tweets [4].

As you can see, there are a lot of ways to being connected with this project! I have done this to make easier as possible contributions in the future.

The lack of a manual

But not all news are good! HaTeX still lacks a manual. I have been writing one, but I stopped a while ago and I'm thinking now to continue this work. Sorry for this!

Thanks

Finally, I want to say thanks to all people who has contributed in some way. Thanks!

References

[1] - Announce of HaTeX 3.1.0 in Haskell-Cafe: http://www.haskell.org/pipermail/haskell-cafe/2011-December/097416.html
[2] - HaTeX in Github: https://github.com/Daniel-Diaz/HaTeX
[3] - HaTeX mailing list: http://projects.haskell.org/cgi-bin/mailman/listinfo/hatex
[4] - HaTeX Twitter account: https://twitter.com/HaTeX_updates

Monday, November 7, 2011

HATEX pragma

Before start growing the HaTeX project with more features and modules, I decided to add a new feature: the HATEX pragma.

What problem this solves?

This pragma will save of modifying HaTeX-meta each time a new module is added or deleted from HaTeX. Until today, HaTeX-meta had a fix list of modules that it will process to generate the analogous .Monad modules, and each time a module is added or deleted from HaTeX, you needed to add (or delete) its module name in the HaTeX-meta code. I saw this too short-sighted, so I made a change.

How it is solved?

The solution was to order to HaTeX-meta to search HaTeX modules which have the MakeMonadic option in a HATEX pragma. This pragma looks like this:

{-# OPTIONS_HATEX MakeMonadic #-}

HaTeX-meta follows the next steps:
  1. Parse the HaTeX.cabal package description.
  2. Look for the exposed modules.
  3. Parse all modules and filter those with the MakeMonadic option enabled.
  4. Process them to create the .Monad modules, skipping the MakeMonadic option in the output (so in the next run of HaTeX-meta it will not process a .Monad module).
See the code of HaTeX-meta here.

Conclusion

I hope this will make easier future changes in HaTeX and avoid updates of HaTeX-meta with changes not directly related with it. Also, I think this will be handy to developers interested in add a new module to HaTeX to, for example, implement some new LaTeX package.
 
Thanks for read,
Daniel Díaz.

Thursday, October 6, 2011

HaTeX 3 - First release

Wow! I finally do the first release to Hackage of HaTeX 3:

http://hackage.haskell.org/package/HaTeX-3.0.0

You can try it with the next example!


{-# LANGUAGE OverloadedStrings #-}

import Text.LaTeX.Base.Monad

main :: IO ()
main = do
 l <- execLaTeXT example
 renderFile "Example.tex" l


example :: Monad m => LaTeXT_ m
example = do
 documentclass [] article

 document exampleBody


exampleBody :: Monad m => LaTeXT_ m
exampleBody = do
 "This is an example of how "
 hatex3
 " works, printing a table of "
 "the thirteen first elements of the "
 "Fibonacci sequence."
 bigskip
 center $ underline $ textbf "Fibonacci table"
 center $ tabular Nothing [RightColumn,VerticalLine,LeftColumn] $ do
   textbf "Fibonacci number" & textbf "Value"

   lnbk
   hline
   foldr (\n l -> do fromString (show n) & fromString (show $ fib n)
                     lnbk
                     l ) (return ()) [0..12]


fibs :: [Int]
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)


fib :: Int -> Int
fib = (fibs!!)

This example builds a table with the thirteen first elements of the Fibonacci sequence.

I'm writing a manual for the library, but it will take me some time (and time is sometimes hard to find).

Until the next time!
Daniel Díaz.

Saturday, October 1, 2011

HaTeX 3 - Two styles

Since the last post about this topic (previous notes), I worked on HaTeX 3 and it is almost ended. This post will response a question about the "Applicative vs Monadic" section of the last post.

Example over HaTeX 2

Let be the next simple example (it works with HaTeX 2):

{-# LANGUAGE OverloadedStrings #-}

example :: Monad m => LaTeX m
example = do
  documentclass [] article
  author "Daniel Díaz"
  title "Example"
  document $ do maketitle
                "Hello, world!"

Here, expressions like documentclass [] article and title "Example" have type Monad m => LaTeX m, where LaTeX is a monad transformer. Thus, they are actions over a monad and we can put all of them in a do sequence. Each action, appends in the state of the LaTeX monad a piece of LaTeX code. For instance, for title "Example" it appends the code \title{Example}.

Working with HaTeX 3: First style

As I mentioned in the last post, there is a new datatype LaTeX describing the LaTeX syntax. LaTeX combinators (like author an title) still exist, but now you can use them in two different ways. What I meant with applicative style is to use these combinators without the presence of any monad. You create an expression of type LaTeX, and you combine them with the monoid operator (<>), alias of the mappend method (See the Data.Monoid module).

Let's write the example this way:

{-# LANGUAGE OverloadedStrings #-}

example :: LaTeX
example =
    documentclass [] article
 <> author "Daniel Díaz"
 <> title "Example"
 <> document (maketitle
           <> "Hello, world!")

Yes, all these operators seem ugly. Even I was forced to write an extra parentheses. But I like you can do all the work without monads.

Working with HaTeX 3: Second style

Now, we are interested in take back the do notation. But we don't want to do every work twice. Indeed, if we did this work manually, we would have to define all entities (including commenting, type signature and exposing in the export list) twice! That's really bad!

The solution was HaTeX-meta. HaTeX-meta is a program that reads a subset of the HaTeX modules (those that define LaTeX combinators) and generates automatically an analogous module that export the combinators with monadic types. And preserving their documentation! These modules have the same module name, but followed by .Monad, and import their originals no-monadic functions to build the new monadic ones.

So, now you can write LaTeX code with HaTeX using do notation with the new type-system. The example above stay almost equal if you import the monadic modules of HaTeX 3:

{-# LANGUAGE OverloadedStrings #-}

example :: Monad m => LaTeXT_ m
example = do
  documentclass [] article
  author "Daniel Díaz"
  title "Example"
  document $ do maketitle
                "Hello, world!"



Closure

I hope this was understandable enough. For now, this is all about HaTeX 3. Next posts will be about HaTeX-meta and HaTeX 3 release notes. The official release will be soon, but the code will be available before.

Thanks for read,
Daniel Díaz.

Wednesday, September 14, 2011

HaTeX 3 - Previous notes

As I announced in my provisional webpage (here), I'm preparing a completly new version of HaTeX. It will be the third version. Firstly, I wanted to write some lines about what was, is and will be HaTeX. So here we are.

A bit of history

When I started to write this library, I didn't know too much about LaTeX. I thought: "Well, I want to get LaTeX results, but using Haskell instead of LaTeX". That was my first thinking. But quickly I found other utilities. Mainly, I started to write outputs of my own programs directly in a LaTeX document, or tables contrasting the time employed by different programs solving the same task.

When I did the first upload (it actually was my first upload to Hackage), the way the library worked was storing raw LaTeX code in the state of a writer monad transformer applied to IO. So, when you type author "Daniel Díaz", it appends "\author{Daniel Díaz}" at the end of the state. Thus, HaTeX was really a high-level way to append strings that ought contain LaTeX code. But the library was putting all those backslashes and braces for you!

In the second version, we said goodbye to the IO monad. The monad transformer now becomes free to be composable with the monad of your desire. This was thanks to Alexey Khudyakov, who gave me a very neat feedback and this change as a proposal.

The new datatype

However, I never liked that the LaTeX type was only a type synonym of the Writer monad with a difference string as state. And this is the main point I wanted to change. In HaTeX 3, I defined a datatype representing the LaTeX syntax, so author "Daniel Díaz", now means:

TeXComm "author" [FixArg (TeXRaw "Daniel Díaz")]

Far harder to read! But, if you take a look on it, it is only describing the syntax of that LaTeX expression. You can say that this is the abstract syntax of that expression. And I feel more comfortable working with this datatype. After you have built your LaTeX document, just use the render function to build your final code in the form of a value in the Text type. This also make possible to build a LaTeX parser (I guess I will write one some day).

Following this line, I have also restricted the input of functions to values of a type that make sense with that function. For instance, making a LaTeX tabular, you must to specify how columns are aligned and where to put vertical lines to divide them. Thus, the tabular function have an argument of type [TableSpec], being TableSpec a datatype containing the possible specifications for your table, so you can't put invalid data.

A new module hierarchy

While Text.LaTeX is still the main module, it forks in two submodules: Text.LaTeX.Base and Text.LaTeX.Packages. The former contains all commands and environments that you have without importing others with the usepackage command. The latter have a submodule per LaTeX package. Well, only a few of them are implemented! But you can always request one, or, much better, you can contribute implementing one! The aim of this breakup is to give you the freedom to import only the functions you want without a too big import header. Also, I thought this will help to do code better organized.

Applicative vs Monadic

Maybe, you realized that the author function no longer communicates with any kind of writer monad. In fact, it takes an author's name, and return something of the datatype LaTeX. No monad involved. LaTeX is instance of the Monoid class, so you can append these results with mappend (<>) in order to obtain your final output.

This will involve to repeat many times this operator. We can save this work by the same way we do that the last time: making use of the writer monad. But I have not written, at the moment, any monadic code. My idea is to use some program to, from the source code of a module with these applicative style functions, generate a module with monadic style functions. For instance, if we have:

author :: LaTeX -> LaTeX
author a = TeXComm "author" [FixArg a]


We can write:

author :: Monad m => LaTeX -> LaTeXM m ()
author = tell . App.author

End of this preview

And, for now, this is all I have to say about HaTeX 3. As always, you can do any pre-release suggestion, or discuss about the current course of the library, as it was described here. Finally, I want to apologize for so unstable library. I am only trying to make it better as possible.

Thanks for read,
Daniel Díaz.