Hugh Sparks
Version 2.9, November 17, 2007
http://www.csparks.com
JEuler (pronounced J-Oy-luhr) is a tool for publishing mathematics on the web.
With JEuler installed on your web server, you can use use <latex> math elements in your web pages. They will be automatically rendered as high-quality gifs for the client browser. Here are some examples.
I resorted to writing JEuler after trying nearly every open-source math tool for the web. They all either produced ugly output, required complex external editing tools, or were impossible to integrate with an automatic publishing system like Cocoon.
After concluding that Latex made the best looking results, I wanted to have, as far as possible, the ability to write Latex elements in my web pages and have them rendered as if the capability were native to the browser.
"But shouldn't everyone be using MathML instead?" Yes.
Latex is a very popular system for pre-press document preparation. It is especially good for highly-formatted technical books and academic journal articles. For people concerned about typographical quality, Latex and it's parent software Tex, "rule." You can download a book-length introduction to Latex for mathematics here.
Cocoon is a comprehensive web publishing framework. Perhaps too comprehensive. I think of it more as a character-building framework.
For JEuler to function "auto-magically," you must have a functioning Cocoon installation on your your web server. For help with this, see the main site linked above. Also, you will find countless tutorials on the web. I've written one as well which, like most, is always slightly out of date.
If the whole idea of writing a web page with XML is new to you, you might like this tutorial: XML web pages without tears.
It is possible to use Cocoon even if you don't run your own server. In that case, you would use JEuler as a preprocessor to produce html and upload it to your ISP's server. In theory, this might even be done under Windows using Cygwin or a native installation of Tomcat and Cocoon. If you do this, I'd like to hear about the results.
Once the package is installed, you can put tags with latex expressions anywhere in your web page source. For example:
<latex>
\int_{0}^{\pi} \sin x\, dx = 2
</latex>
The element above is rendered:
Images only need to be rendered when their associated latex elements change. When you modify the equations on a web page, the first browser visit will take more time while the changed equations are rendered. Subsequent visits will see a gif from the JEuler cache sent immediately.
That's right. It couldn't be that easy.
Rendering attributes
JEuler has two rendering attributes: size and grey.
The size attribute sets the font size in "web points." Relating this to the typographer's point size of 1/72 inch is beyond me, but the results will agree with point sizes set on other fonts in most browsers. The default value is 14 points, which is larger than the default font size 12 used by many browsers. This was done to make the fine detail found in many equations look better when set on lines by themselves. If you want to render inline equations, you will need to specify the appropriate size attribute.
You can set this value on a per-element basis by adding a size attribute to the latex tag:
<latex size="24">
\int_{0}^{\pi} \sin x\, dx = 2
</latex>
This element is rendered:
The grey attribute controls blending with the web page background color. Although the gifs created by JEuler are transparent, there is a pixel "halo" around the contours of anti-aliased characters that must be blended with a selected color. If this is not done correctly, the outlines will have visible defects.
Currently, JEuler only supports grey or white backgrounds. The value used for grey should be the fraction of total white used to specify the grey level. For example, this site uses a background of rgb(204,204,204) . The value for white is rgb(255,255,255). So we would use a grey attribute value of 204/255 = 0.8. The value would obviously be 1.0 for a white background. The grey value should always be a floating-point number less than or equal to 1.
It isn't necessary to supply a grey attribute in every latex element because you can specify default values in the Cocoon sitemap.
Sitemap rendering parameters
The sitemap sections used to process JEuler elements can specify values for all the rendering parameters. These settings will apply to all latex elements that don't explictly set them using element attributes. Here are the values used for this page:
... <map:parameter name="size" value="14"/> <map:parameter name="grey" value="0.8"/> ...
Sitemap element parameters
JEuler is designed to work within a Cocoon publishing framework. To do this properly, it must create image elements that fit into your existing system of tags and namespaces.
You can set several options in the sitemap such as the name of the image element JEuler will create and the attribute that will contain the name of the generated gif file.
For example, on my site, I use a stylesheet that expects to handle jeuler images with a tag like this:
<jeuler url="somefile.gif"/>
My site's xsl stylesheet transforms this to an html img element:
<img src="somefile.gif"/>
The stylesheet also expects tags from this namespace: "http://www.csparks.com/XMLWithoutTears"
To get jeuler to emit these tags, there is a section in the sitemap with these parameters:
... <map:parameter name="element" value="jeuler"/> <map:parameter name="attribute" value="url"/> <map:parameter name="namespace" value="http://www.csparks.com/XMLWithoutTears"/> ...
It is also possible to set the element, attribute, or namespace using latex element attributes. These settings override the sitemap settings and apply only to the modified element.
Default parameters
Finally, if no sitemap parameters or element attributes are used, the following default settings apply:
<map:parameter name="size" value="14"/> <map:parameter name="grey" value="1.0"/> <map:parameter name="element" value="'img'"/> <map:parameter name="attribute" value="'src'"/> <map:parameter name="namespace" value="'http://www.w3.org/1999/xhtml'"/>
In other words, it makes a regular html <img> element.
The latex elements themselves are part of the JEuler namespace and if you inspect the source of this document, you will see that they all have the prefix "je" defined as "http://www.csparks.com/jeuler"
Alternate text display
The jeuler element is generated with a source attribute that contains the original latex expression used to create the image. The stylesheet you use to create html can reference this element to provide an alterative display for the image. This will appear in a pop-up window when the user hovers the cursor over the image.
Here is the stylesheet matcher used on this site demonstrating the alternate text option:
<xsl:template match="my:jeuler">
<img src="{@url}" title="{@source}"/>
</xsl:template>
The server's Cocoon sitemap must recognize documents that contain latex tags. These documents are sent through the JEuler pipeline.
The pipeline filters the document using an xslt stylesheet that passes through all non-latex elements. The latex elements are compared to previously rendered elements stored in the equation cache. If the elements match, an existing gif will be returned. If the elements don't match, they are passed to a Bash CGI script that creates a new gif.
The pipeline then applies the user's stylesheet which converts the entire document to html and returns it to the client browser.
The browser renders the document as usual. It will find <img> elements wherever latex elements appeared in the orignal document. These gifs actually exist in a subdirectory of the document directory called "equations." This is also the directory where the cached copies of latex expressions are stored. Each equation is in a file named by concatenating the original document name, the equation number, and an ".xml" extension.
Requirements
You will need a web server that runs Cocoon. I'm running Fedora Linux with the Apache web server and the Tomcat servlet container. (Cocoon is simply a huge Java servlet.)
The script uses only two TeX-related commands: latex and dvigif. On recent Fedora systems, latex is provided by the texlive package and dvigif is provided by the dvipng package.
To run jeuler under Windows, you will also need to install Cygwin because JEuler depends on a bash script as well as latex command line tools.
JEuler components
Only two files from the distribution directory are required: the jeuler.xsl stylesheet and the jeuler.cgi script. The stylesheet should be copied to your website home directory. The CGI script must go into a special directory so the server will know it's supposed to run the program. On redhat-ish systems, this location will be /var/www/cgi-bin.
Configuration
The JEuler package contains an example Cocoon sitemap fragment that you must edit and integrate with your own cocoon sitemap. As supplied, the sitemap looks for the jeuler.xsl file in a "jeuler" subdirectory of the website and only processes files that have ".jhtml" extension. It also attempts to use a "stylesheet.xsl" for the final conversion of the page to html. Your site will no doubt handle these things differently.
Each directory on your website that will contain JEuler documents must also have an "equations" subdirectory. This directory, initially empty, will contain the cache for the images created when you modify equations in your web pages.
The directory attributes must be set so it is writable by the Apache server and by the user associated with the Cocoon servlet container. (Probably Tomcat) This is best done by adding tomcat to the apache group:
usermod -G apache tomcat
Test your installation by browsing to the sampler.jhtml on your own server.
Real Soon Now...
The name "JEuler" and the most direct inspiration came from the pioneering work of Stephen Michels, the creator of the JEuclid package. The JEuclid system converts MathML markup into gifs using a Cocoon serializer. It is written in Java, hence the "J".
I started writing JEuler in Java as well, but found that I was using the Java Native Interface (JNI) to run all sorts of external programs. Bash proved to be the path of least resistance, although I'm sure Cocoon purists would have prefered a Java solution.
The image processing sequence is based on ideas from John Walker's textogif Perl script. First, latex renders the expression as a dvi, then dvigif creates the gif displayed by the browser. A caching scheme keeps the gif image for reuse until the source expression is modified.