figure elyxer.png eLyXer User Guide

Alex Fernández (elyxer@gmail.com)

Table of Contents

1 The Basics

elixir, n: a substance believed to cure all ills[1].
eLyXer (pronounced elixir) is a LyX to HTML converter. While there are a ton of such projects all over the web, eLyXer has a clear focus on flexibility and elegant output.
eLyXer (including this guide and all accompanying materials) is licensed under the GPL version 3 or, at your option, any later version. See the LICENSE file for details.
Please visit the main page to find out about the latest developments.

1.1 System Requirements

eLyXer requires Python 2.3.4, and should work with versions up to 2.6.x; it will convert documents generated by LyX 1.5.x to 1.6.y. It has been tested on the most common operating systems: on Mac OS X, Linux and Windows, with and without CygWin.
Resource usage should be quite frugal; eLyXer runs quite happily on my 1st-gen Asus Eee, with its puny Celeron@570MHz and 512 MB of RAM. It should also be fast — the Eee can convert ~200 pages of LyX text in just over 50 seconds. Performance is fairly linear: 200 pages take 10 ×  as long as 20, so there are no scalability problems. Memory usage stays low even when processing large documents, and conversion can be done on the fly (with --lowmem) for even lower memory requirements.

1.2 Installation

This section looks at how to install eLyXer on your system.

Download eLyXer

First you will need to fetch the official distribution file from the download area. Now, there is more than one way to install eLyXe, but all of them start by uncompressing the distributed file to a suitable directory. Just write at the command prompt:
$ tar -xzf elyxer-[version].tar.gz
Or for the .zip version:
$ unzip elyxer-[version].zip
A directory called elyxer should appear, where the main executable file elyxer.py resides.

Using the Installer

An installer is provided in the root directory, called install.py; it is the recommended way to install eLyXer. To run it just type in a console as root:
# python install.py
On Windows you can type (as a regular user):
> python.exe install.py
In any case, the script will look at your Python version and decide if it can install eLyXer as a Python module or as a binary. By default it will install eLyXer as a binary, so you can check if it was installed successfully:
$ elyxer.py --help
If it is possible (i.e. if your Python version is above 2.3), it will also install eLyXer as a module:
$ python -m elyxer --help
In any case, a brief help text and the list of command line options should appear.
In what follows we will assume that eLyXer has been installed as a binary, except where stated; substitute "elyxer.py" with "python -m elyxer" if your system has eLyXer as a module and you want to use it.
The installer will also copy existing translation files to your hard drive so that they can be used from within eLyXer for internationalization.

Prepackaged Versions

The easiest way to install eLyXer is if someone has prepackaged it for your system. Some Linux distributions include eLyXer: Debian squeeze and Ubuntu Lucid. In this case eLyXer needs to be run as "elyxer":
$ elyxer --help
Another way is with the LyX installer: the alternate LyX installer includes eLyXer in the default installation. See 1.6↓ for LyX integration.

Manual Installation

If the installer did not work for you, you can manually install it as a module. On Linux go to the elyxer directory and type, as root:
# python setup.py install
On Windows just type:
> python.exe setup.py install
On Mac OS X you can use sudo to have permission:
% sudo python setup.py install
Now you can run eLyXer as a Python module:
$ python -m elyxer --help
The list of command line options should appear. You can also manually copy the file elyxer.py to a directory found in the execution path (for instance, /usr/bin on Linux or c:\windows\system32 on Windows).

1.3 Test Drive

Now you may want to try to convert the user guide:
$ elyxer.py --css lyx.css --title "eLyXer User Guide" docs/userguide.lyx docs/userguide2.html
or, to run eLyXer as a Python module:
$ python -m elyxer --css lyx.css --title "eLyXer User Guide" docs/userguide.lyx docs/userguide2.html
It should generate a working web page identical to the one distributed:
$ diff docs/userguide.html docs/userguide2.html
The typical output will contain just the changed lines, which in this case should be only the header with the file creation date. An example is shown on listing 1↓.
7c7
< <meta name="create-date" content="2009-09-11"/>

> <meta name="create-date" content="2009-09-12"/>
Algorithm 1 Example of diff output for functionally identical HTML files.
If nothing else appears (i.e. both files are functionally equal) then everything is working fine. If you have bash installed, to test that everything really works fine you can just run the included tests:
$ ./run-tests
It will run a number of test and check the results, so you can see if everything is well. You also need to have installed the command-line tool diff to show differences between two files.

1.4 Usage

eLyXer is a standalone command line tool. It can be invoked from the command line as:
$ elyxer.py [options] [source file] [destination file]
or, again for the module:
$ python -m elyxer [options] [source file] [destination file]
If the source file is omitted then STDIN is used; likewise, if no destination file is specified eLyXer will output to STDOUT. This allows its use in pipes and other flexible configurations. Some examples:
$ elyxer.py file.lyx file.html
converts file.lyx to file.html. Debug messages are shown.
$ cat file.lyx | elyxer.py > file.html
converts file.lyx to file.html, as before. This time debug messages are not shown.
$ elyxer.py file.lyx | grep "<blockquote>" | wc
counts all blockquote paragraphs.
$ elyxer.py file.lyx | wget --no-check-certificate --spider -nv -F -i -
checks all external links in a document recursively. (Local links will appear as unresolved, but they can be ignored.)

1.5 Image Processing

HTML pages do not contain images, as PDF documents; rather they have pointers to image locations on disk. (Luckily LyX documents are the same in this respect.) eLyXer will generate pages that point to the same locations as the original images, when they are PNG images. Other image types like Encapsulated PostScript cannot be used directly from within pages. If the ImageMagick package is installed eLyXer will use the convert tool to create PNG versions of the images embedded in the document. If it is not installed eLyXer will show an error message and will not try to convert further images.
Image location is fragile. All images should be placed in the same location (and with the same structure) as the original document; and they should all be referenced relatively to the current document. During conversion from within LyX (in those versions where it is available) image locations can be lost. Your best bet is to do conversion in place.

1.6 LyX Integration

If you used the eLyXer installer LyX will automatically detect it after reconfiguration. Just make sure that you are running LyX 1.6.5 or later, and click on Tools ▷ Reconfigure.
LyX should be able to detect if eLyXer was installed as a module or as a binary, or even if it has been installed from a Linux distribution. In any case you can verify that it has been recognized by LyX by opening Tools ▷ Preferences…, going to External formats ▷ Converters, and finding the converter for “LyX -> HTML”. If eLyXer is there, it worked! Now you can convert your documents using View ▷ HTML. Otherwise try to reinstall eLyXer from scratch and then reconfigure LyX.

2 Advanced Use

There are some advanced uses for eLyXer if you want to extract the most of it.

2.1 Command Line Options

eLyXer supports a few command line options:
--help: show command line help.
--debug: show debug messages. They may help a developer understand your problem.
--quiet: be quiet and do not output messages (except errors). This way you can avoid the comforting “Parsing line 1000” messages. When STDIN or STDOUT are used (e.g. in a pipeline) --quiet is always enabled.
--copyright: include a copyright notice at the bottom.
--nocopy (deprecated): no effect since the copyright notice is now optional, maintained for backwards compatibility.
--title "title": change the title of the generated web page.
--directory "images_dir": look for images in the directory specified.
--destdirectory "dest_dir": converted images will end up into this directory.
--css "new.css": change default CSS. See section 2.2↓: CSS.
--version: show version number and date. Use to check which version you are actually running.
--nofooter: omit the footer message “Document generated by eLyXer” (shown at the bottom).
--html: generate HTML 4.0 (instead of XHTML). The resulting pages should be easier to import from certain word processors. See section 2.6↓: HTML code.
--unicode: restore full Unicode output. Right now switches midspaces to medium mathematical spaces. See also section 2.6↓: HTML code.
--iso885915: generate a document using ISO-8859-1 encoding. Again, see section 2.6↓: HTML code.
--forceformat ".extension": Force the format implied by the extension (e.g. ".jpg" for JPEG) for output images.
--lyxformat: Return the highest LyX version that eLyXer understands. This parameter is provided to help with lyx2lyx integration, so that this tool knows if it must convert the file to a lower LyX format.
--toc: Activate table of contents generation; this option is on by default. See section 2.4↓: TOC.
--toctarget "original.html": Generate a table of contents with links to the original HTML file. See section 2.4↓: TOC.
--target "frame": Add a target attribute to every link in the generated HTML, making all links point to the provided frame. Again, see section 2.4↓: TOC.
--lowmem: Activate a low memory mode which does not keep the whole document in memory: conversion is done on the fly. Keep in mind that some features as the TOC will be missing from the generated document.
--converter "converter":Use the given converter to convert images. Right now only two converters are supported: imagemagick (default) and inkscape. The latter chooses Inkscape as the image converter, instead of the default ImageMagick. Inkscape uses some non-standard extensions so it might be needed to convert SVG images to PNG.
--numberfoot:Label footnotes using numbers, instead of letters. Useful when bibliographical references are not numbered and therefore cannot be confused with footnotes.
--jsmath "URL": use the excellent JavaScript library jsMath at the given URL to pretty-print mathematical equations. See section 2.8↓.
--mathjax "URL": use the promising JavaScript library MathJax at the given URL to pretty-print mathematical equations. See also section 2.8↓.
--template "file": use an HTML template. The raw converted document will be placed where <!--$content--> appears in the template. Available variables: <!--$content-->, <!--$title-->, <!--$author-->, <!--$encoding-->, <!--$css-->, <!--$navigation-->, <!--$year-->, <!--$date-->, <!--$datetime-->, <!--$version-->, <!--$script-->, <!--$mathjax-->, <!--$jsmath-->.
When an option accepts an argument it can be added after a space as --target "frame", or with an equals sign as in --target="frame". The quotes are optional and can be useful if your arguments include e.g. spaces.

Adding Options In LyX

To add one of these options so that it is used from within LyX, you have to modify the converter line. To this effect open Tools ▷ Preferences…, go to External formats ▷ Converters, find the converter for “LyX -> HTML” and edit the converter line. It should read something like this:
python -m elyxer --directory $$r $$i $$o
(By default LyX will prefer to use eLyXer as a module.) If you want to generate pure HTML instead of XHTML, change the line to:
python -m elyxer --html --directory $$r $$i $$o
And so on. If eLyXer was only installed as a binary the original line will be:
elyxer.py --directory $$r $$i $$o
So you will have to change it accordingly. Figure 1 shows what to do to add the --html option when eLyXer is installed as a module: after editing the line and adding the new option, click on “Modify” and then “Save” or “Apply” the changes. You should never remove the $$i $$o at the end, since it is what tells eLyXer where to find the input and output files.
figure converters.png
Figure 1 eLyXer converter in LyX 1.6.5.
LyX 1.6.5 supports a new “extra flag” line; however, at this moment it does not work with eLyXer.

2.2 CSS

HTML output, as generated, can be a bit crude. Some CSS wizardry can go a long way to make eLyXer output look nicer.
eLyXer tags most elements with the type so you can later modify them using a CSS. The HTML header reads like listing 2↓, so the default remote CSS file is used.
<head>
<title>Your title here</title>
<link rel="stylesheet" href="http://www.nongnu.org/elyxer/lyx.css" type="text/css" media="screen"/>
</head>
Algorithm 2 CSS link automatically added to HTML
This sample CSS file is published on nongnu.org and distributed along with the scripts, docs/lyx.css. (You may have found that your document changes its appearance with time — this is the reason. The main author regularly publishes a new, updated version of lyx.css on nongnu.org, and all documents using it automatically appear with the changes.)
To give your document a customized appearance (or for pages to be accessible offline) you probably will want to use your own CSS file; to use it first copy it to the directory where your document resides (e.g. renaming it to custom.css), and customize as needed. Then run elyxer.py with the following option:
$ elyxer.py --css=custom.css document.lyx page.html
This will make the generated page.html use your custom.css file. The ‘=’ sign between the constant ‘--css’ and the name of the CSS file is optional.

2.3 Title

By default the generated web pages have the title “Converted Document”. If a PDF title is found then it is used instead. The proper LyX title (a paragraph of type “Title” embedded in the text) will also be used if found. But when --lowmem is in use eLyXer does not try to get the proper title, since it may be found in the middle of the document or not be present at all; scanning for it would mean doing two passes, one to look for the title in all the document and another to output the web page, and --lowmem implies on-the-fly conversion to save memory.
You can change the title of the generated web page with the --title option:
$ elyxer.py --title "My Beautiful Document" document.lyx page.html

2.4 Table Of Contents

A table of contents (or TOC) can be generated for every converted LyX document. You can optionally also add a target frame to every link. The trick is to combine both options to generate a TOC that links to the original document on a different frame. For example, if the original page is called page.html and you generated it with this command:
$ elyxer.py document.lyx page.html
you can generate the TOC linking to this page, and at the same time point it to frame contents:
$ elyxer.py --toc --toctarget page.html --target contents document.lyx page-toc.html
Then you can put it all together with a simple frameset generated manually. Just remember to place the original document in the frame called contents.
<html>
  <frameset cols="30%,70%">
    <frame name="toc" src="page-toc.html" />
    <frame name="contents" src="page.html" />
  </frameset>
</html>
Algorithm 3 An example frameset for TOC navegation
TOC generation accepts the same options as normal document conversion. For example, if you follow these instructions literally you will notice that the TOC has very wide margins and looks a bit weird; that is because it is using the default CSS. A special CSS file for TOC files is provided in docs/toc.css, so better results should be obtained with the --css option:
$ elyxer.py --toc --toctarget page.html --css docs/toc.css --target contents document.lyx page-toc.html
With a little bit of practice you will be able to generate useful (and nice looking) TOC files. You can see an example for the user guide (if you are not already looking at it).

2.5 Segmenting Pages

Quite often you don’t want a huge monolithic page, but a set of linked pages. To do so you can use the --splitpart option, specifying the level at which eLyXer should split pages. For instance:
$ elyxer.py --splitpart 1 document.lyx output.html
will split document.lyx into pages at level 1, using output.html as the root page. Each page will get a number that starts with output and ends with .html, with a suffix that depends on the page — output-2.html will correspond to the second split part.
The level corresponding to 1 depends on the document class: books will be split at chapters, but articles will get a section per page. And so on with lower levels.

2.6 HTML Code

The HTML code generated is technically XHTML Transitional, version 1.0 [2], using UTF-8 encoding. Some programs have (in this day and age) trouble importing XHTML, notably some popular word processors. To work around this problem and provide more flexible output in general you can output HTML 4.0:
$ elyxer.py --html document.lyx page-to-import.html
Again, technically the code generated is HTML 4.01 Transitional [3] using UTF-8 encoding. Both versions should pass the W3C tests [4]. If your particular web page doesn’t pass the tests, then it is a bug and it will be treated as such.
The CSS file for eLyXer uses some CSS2 features for math structures (fractions, arrays). This makes the output incompatible with older browsers; it requires Microsoft Internet Explorer 7, Firefox 3, Safari 3 or Chrome 1. Check the Math Showcase to see if your browser can render eLyXer output correctly.

Character Encodings

For better browser compatibility, medium mathematical spaces are substituted in the output with midspaces — improving the output for some popular browsers. If you want your mathematical spaces back, just use the --unicode option:
$ elyxer.py --unicode document.lyx page-to-import.html
Check out the Math Showcase with Unicode to see the results. In the future other non-Unicode substitutions might be used.
In case you want to use the ISO-8859-15 encoding in your generated document, you can add the --iso885915 option:
$ elyxer.py --iso885915 document.lyx page.html
This will make eLyXer output a document with all non-ASCII characters encoded as &nbsp;, &#x2005; and so on. This encoding is similar to ISO-8859-1, also called Latin-1, but including the Euro sign. The Math Showcase (ISO-8859-15 edition) has been generated using this option.
Both encoding options can be combined with --html at will.

2.7 Internationalization

eLyXer is distributed along with a few translation files. They are automatically regenerated every time make is run, and reside in the folder po/. Internationalization is done using GNU gettext, so every locale is identified by a two-letter code (such as “en” for English and “es” for Spanish). There are two kinds of files: the text .po file (which can be found in po/my.po for locale “my”), and the binary .mo file (found in po/my/elyxer.po).
For internationalization to work properly, Linux distributors should take all binary .mo files and place them in the directory corresponding to locale files, which we will call $localedir. As the Python gettext page explains, this is distribution-dependent: for example on Debian $localedir is /usr/share/locale, so for locale “es” the correct route would be
/usr/share/locale/es/LC_MESSAGES/elyxer.mo
Windows distributors on the other hand should place files in %PYTHONHOME%\share\locale, for example for locale “es” on a machine where Python is in C:\python:
C:\python\share\locale\es\LC_MESSAGES\elyxer.mo
To generate a new translation file (we will use “my” as an example locale here, corresponding to Burmese): you need to have the GNU gettext package installed. Then go to the directory where elyxer.pot resides:
$ cd src/conf
and generate a .po file for your locale:
$ msginit --output-file=my.po --locale=my
Then move the file to the po/ directory:
$ mv my.po ../../po/
and start translating it to Burmese! Once you are done run make from the root directory:
$ ./make
and it will generate the file po/my/elyxer.mo. Finally, place this file in
$localedir/my/LC_MESSAGES/elyxer.mo
and you are done.

2.8 Math

Math equations are an important part of what takes LyX apart from other editors, since it supports the full LaTeX feature set — that is, about everything under the sun. Unfortunately, math support is hard to get right. Many developers are focusing on MathML, but at the time of this writing (Q2 2010) support on some common browsers is still missing.
eLyXer follows its usual minimalistic approach and doesn’t try to be everything to everybody — instead, it supports out of the box a set of usual constructs (fraction, square root) and tries to simulate others (binomial, overbrace). See the Math showcase for yourself and learn what eLyXer supports and what not.
For more sophisticated math equations there are a couple of advanced features.

jsMath

The first is to use jsMath, for which you have to run eLyXer with the option --jsmath:
$ elyxer.py --jsmath jsMath/ math.lyx math-jsmath.html
It uses the given URL (in this case the relative URL jsMath/) to load the required JavaScript files and start rendering. Unfortunately, all JavaScript code has to be loaded from the same domain as the main document, so if you wish to use this method you will have to host jsMath on your site. See the Math showcase (jsMath edition) to see how jsMath improves (or deteriorates) the picture for you.

MathJax

Another possibility is to use MathJax, which is just as simple with the option --mathjax:
$ elyxer.py --mathjax MathJax/ math.lyx math-jsmath.html
This option also uses the given URL (now MathJax/) to load MathJax from and set it up. Although some code needs to be hosted on the same site as the pages, MathJax uses a feature called web-fonts which can be downloaded from a public server; this is quite easier to host. See the Math showcase (MathJax edition) to see how MathJax fares with eLyXer. Keep in mind that MathJax is still prerelease quality; it should improve greatly during 2010.

Client-side Rendering

Something to note is that both jsMath and MathJax are JavaScript libraries; all rendering is done client-side by the user’s browser. This has quite a few advantages:
It also brings some disadvantages:
Publishers should carefully consider pros and cons before deciding what to use.

3 Work in Progress

As you can see eLyXer is a mature and tried package, but it has some rough edges.

3.1 Known Issues

The following issues (including bugs and missing features) are acknowledged. Some of them should be solved soon; others may take longer.
  1. On Mac OS X the output of a message with Unicode characters may cause an error. Workaround: run elyxer.py with the --quiet option.
  2. Some phonetic alphabet symbols are not well supported — if generated with LyX they only appear in a different color: [sample].
  3. Multi-column layouts are lost. This one is almost impossible to get right in CSS, so there are no plans to even try.
  4. Many BibTeX styles are missing. (They are quite trivial to add though.)
  5. ERT (bare TeX code) is ignored.
  6. Many AMS environments (like alignat, gather…) are not working or look strange — some non-AMS environments too.
  7. Images are never scaled above their nominal resolution. This is seldom needed if at all, so there are no plans to change it; if people really need the feature just let the author know so it can be added as an option.

3.2 Contact Information

If your problem does not appear in the above list, please let the author know; you can find him at elyxer@gmail.com. In the words of Rich Talley: “the tool’s author really likes getting challenging documents and making eLyXer work with them”. You can send your sample documents and we will try to make eLyXer convert them acceptably. Any documents sent will be treated with the utmost confidentiality.
You can also join the mailing list to discuss any information related to eLyXer. The author monitors the official LyX lists for mentions of eLyXer. Bugs can also be reported at the Savannah page.

3.3 Extending eLyXer

eLyXer should now support most LyX features; but sometimes it will ignore a command, sometimes it will signal it, and it might even refuse to work with certain documents. What can you do if eLyXer does not work with your LyX file? Worry not! Its flexible approach to processing allows anyone to write support for the missing commands.
eLyXer is written in Python so that it does not need to be compiled; its code is interpreted on the fly. See the accompanying developer guide to learn how to extend eLyXer for your own purposes. If you know how to program in Python it should not be difficult to support other LyX features. If you don’t your best bet is to ask the author.

4 FAQ

Q: What versions of LyX are supported?
A: The tool is slowly improving; it now should work with LyX versions 1.5.5 to 1.6.5. It has been tested on Linux, Mac OS X and Windows.
Q: There are indeed a ton of similar projects over the web. Why add another one?
A: The four tools supported by LyX (tex4ht, hevea, tth and latex2html) gave inferior results a couple of years ago, and were quite inflexible. The author found the need for a good converter, while at the same time acknowledging the difficulty of the problem.
Q: Speaking of that: why build a LyX to HTML converter, instead of a more generic LaTeX to HTML converter?
A: The problem space is quite simplified, and therefore progress is much faster. To make it even easier eLyXer has historically centered on the subset of LyX functionality that is useful to most LyX users, leaving the rest for a later stage. Nowadays eLyXer aims to support the full LyX feature set.
Q: What can we expect from the tool in the future?
A: eLyXer should fulfill the needs of 99% of LyX users in the short term. It has also learned a couple of tricks of its own such as page segmenting. Eventually it could be distributed along with LyX as part of the standard installer.
Q: Why did you leave out my favorite feature <insert random LyX command here>?
A: In short, because nobody asked for it. Every feature which has been requested (either to me personally or to the list) has been tended to, unless it was too far out or I forgot about it. At this point of development every missing LyX feature will be considered a high priority item for the next version, if at all possible to implement.
Q: My document changed its appearance without my intervention. Was it black magic, elves or what?
A: It probably uses the online CSS file, which is regularly updated. See section 2.2↑ for details.
Q: Why use an online CSS, instead of placing the CSS file in the same directory as the converted file?
A: There were pros and cons. An online CSS resource allowed me to update it for everyone at the same time, but might make it more difficult for people without an internet connection; local CSS files are more flexible but can also be confusing to novice users. In the end the online solution was preferred, with the --css option as a fallback.
Q: My jsMath (MathJax) pages are not rendering correctly; equations are silently ignored.
A: Check that jsMath (MathJax) is installed on the same server as your pages; for security reasons the browser’s “same-origin” policy mandates that JavaScript can only be loaded from the same site as the original page. Also make sure that JavaScript is enabled on the browser.
Q: I found a bug, what should I do?
A: Just send it to the author at elyxer@gmail.com. You can also report it to the Savannah interface.

Bibliography

[1] WordReference.com: “definition of elixir”, accessed March 2009. http://www.wordreference.com/definition/elixir

[2] W3C: “XHTML™ 1.0 The Extensible HyperText Markup Language (Second Edition)”, revised 1 August 2002. http://www.w3.org/TR/xhtml1/

[3] W3C: “HTML 4.01 Specification”, 24 December 1999. http://www.w3.org/TR/REC-html40/

[4] W3C: “Markup Validation Service”, accessed March 2009. http://validator.w3.org/